diff options
| author | Michael Goulet <michael@errs.io> | 2025-03-19 17:53:43 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-04-23 18:04:25 +0000 |
| commit | 257f68777f469bdd26d4763dc0cbd99c99b74e1d (patch) | |
| tree | 07ac0b5e8b6931c5ccf470de705404cfcf84752b | |
| parent | be181dd75c83d72fcc95538e235768bc367b76b9 (diff) | |
| download | rust-257f68777f469bdd26d4763dc0cbd99c99b74e1d.tar.gz rust-257f68777f469bdd26d4763dc0cbd99c99b74e1d.zip | |
Use the new solver in the impossible_predicates
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/mod.rs | 14 | ||||
| -rw-r--r-- | tests/ui/traits/vtable/impossible-method.rs | 38 |
2 files changed, 43 insertions, 9 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 0987c5b42d8..7a744dfc2ad 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -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 } diff --git a/tests/ui/traits/vtable/impossible-method.rs b/tests/ui/traits/vtable/impossible-method.rs new file mode 100644 index 00000000000..ff7910cfac8 --- /dev/null +++ b/tests/ui/traits/vtable/impossible-method.rs @@ -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>(&()); +} |
