Auto merge of #136988 - compiler-errors:impossible_predicates, r=lcnr
Use the new solver in the `impossible_predicates` The old solver is unsound for many reasons. One of which was weaponized by `@lcnr` in #140212, where the old solver was incompletely considering a dyn vtable method to be impossible and replacing its vtable entry with a null value. This null function could be called post-mono. The new solver is expected to be less incomplete due to its correct handling of higher-ranked aliases in relate. This PR switches the `impossible_predicates` query to use the new solver, which patches this UB. r? lcnr
This commit is contained in:
commit
c4e05e53d1
2 changed files with 43 additions and 9 deletions
|
|
@ -690,8 +690,11 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
|
|||
/// used during analysis.
|
||||
pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause<'tcx>>) -> bool {
|
||||
debug!("impossible_predicates(predicates={:?})", predicates);
|
||||
let (infcx, param_env) =
|
||||
tcx.infer_ctxt().build_with_typing_env(ty::TypingEnv::fully_monomorphized());
|
||||
let (infcx, param_env) = tcx
|
||||
.infer_ctxt()
|
||||
.with_next_trait_solver(true)
|
||||
.build_with_typing_env(ty::TypingEnv::fully_monomorphized());
|
||||
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let predicates = ocx.normalize(&ObligationCause::dummy(), param_env, predicates);
|
||||
for predicate in predicates {
|
||||
|
|
@ -704,13 +707,6 @@ pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause
|
|||
return true;
|
||||
}
|
||||
|
||||
// Leak check for any higher-ranked trait mismatches.
|
||||
// We only need to do this in the old solver, since the new solver already
|
||||
// leak-checks.
|
||||
if !infcx.next_trait_solver() && infcx.leak_check(ty::UniverseIndex::ROOT, None).is_err() {
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
|
|
|
|||
38
tests/ui/traits/vtable/impossible-method.rs
Normal file
38
tests/ui/traits/vtable/impossible-method.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//@ run-pass
|
||||
//@ revisions: current next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
trait Id {
|
||||
type This<'a>;
|
||||
}
|
||||
impl<T> Id for T {
|
||||
type This<'a> = T;
|
||||
}
|
||||
|
||||
trait Trait<T> {}
|
||||
impl<T: Id> Trait<for<'a> fn(T::This<'a>)> for T {}
|
||||
|
||||
trait Method<T: Id> {
|
||||
fn call_me(&self)
|
||||
where
|
||||
T: Trait<for<'a> fn(T::This<'a>)>;
|
||||
}
|
||||
|
||||
impl<T, U> Method<U> for T {
|
||||
fn call_me(&self) {
|
||||
println!("method was reachable");
|
||||
}
|
||||
}
|
||||
|
||||
fn generic<T: Id>(x: &dyn Method<T>) {
|
||||
// Proving `T: Trait<for<'a> fn(T::This<'a>)>` holds.
|
||||
x.call_me();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Proving `u32: Trait<fn(u32)>` fails due to incompleteness.
|
||||
// We don't add the method to the vtable of `dyn Method`, so
|
||||
// calling it causes UB.
|
||||
generic::<u32>(&());
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue