From e8f0b1761fa2fadc525938c64f7b54a75e2d9706 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 16 Jul 2025 12:17:38 +0200 Subject: [PATCH 1/2] yikes --- .../src/solve/trait_goals.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 650b85d99d2cd..ccb77c6299fc9 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -1428,6 +1428,21 @@ where &mut self, goal: Goal>, ) -> Result<(CanonicalResponse, Option), NoSolution> { + if goal + .param_env + .caller_bounds() + .iter() + .filter_map(|c| c.as_trait_clause()) + .filter_map(|c| c.no_bound_vars()) + .any(|p| p == goal.predicate) + { + let candidate = self + .probe_trait_candidate(CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) + .unwrap(); + return Ok((candidate.result, Some(TraitGoalProvenVia::ParamEnv))); + } + let candidates = self.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::All); self.merge_trait_candidates(candidates) } From 8c737ce51fa365798929671edf631991c6aee51f Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 21 Jul 2025 16:08:20 +0200 Subject: [PATCH 2/2] rarw --- .../rustc_hir_typeck/src/typeck_root_ctxt.rs | 7 ++- compiler/rustc_infer/src/infer/at.rs | 2 + compiler/rustc_infer/src/infer/context.rs | 4 ++ compiler/rustc_infer/src/infer/mod.rs | 18 ++++++- .../src/canonicalizer.rs | 54 +++++++++++++------ .../src/solve/eval_ctxt/canonical.rs | 2 + .../src/solve/eval_ctxt/mod.rs | 30 +++++++++-- .../src/solve/inspect/build.rs | 2 +- .../rustc_next_trait_solver/src/solve/mod.rs | 2 +- compiler/rustc_type_ir/src/infer_ctxt.rs | 4 ++ tests/crashes/139409.rs | 12 ----- ...refer-sized-builtin-over-wc.current.stderr | 2 +- ...e-prefer-sized-builtin-over-wc.next.stderr | 2 +- ...incomplete-prefer-sized-builtin-over-wc.rs | 9 +++- ...iguity-due-to-uniquification-1.next.stderr | 19 +++++++ .../ambiguity-due-to-uniquification-1.rs | 17 ++++++ ...iguity-due-to-uniquification-2.next.stderr | 17 ++++++ .../ambiguity-due-to-uniquification-2.rs | 20 +++++++ .../cycles/inductive-cycle-but-err.rs | 2 - .../cycles/inductive-cycle-but-err.stderr | 21 ++------ .../normalize/normalize-param-env-2.stderr | 38 +------------ .../normalize-param-env-4.next.stderr | 9 ---- .../normalize/normalize-param-env-4.rs | 8 ++- 23 files changed, 190 insertions(+), 111 deletions(-) delete mode 100644 tests/crashes/139409.rs create mode 100644 tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-1.next.stderr create mode 100644 tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-1.rs create mode 100644 tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-2.next.stderr create mode 100644 tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-2.rs delete mode 100644 tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs index 9f4ab8ca5d412..20844dee7932f 100644 --- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs +++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs @@ -85,8 +85,11 @@ impl<'tcx> TypeckRootCtxt<'tcx> { pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { let hir_owner = tcx.local_def_id_to_hir_id(def_id).owner; - let infcx = - tcx.infer_ctxt().ignoring_regions().build(TypingMode::typeck_for_body(tcx, def_id)); + let infcx = tcx + .infer_ctxt() + .ignoring_regions() + .in_hir_typeck() + .build(TypingMode::typeck_for_body(tcx, def_id)); let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner)); let fulfillment_cx = RefCell::new(>::new(&infcx)); diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 5fe795bd23a15..ad19cdef4e752 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -71,6 +71,7 @@ impl<'tcx> InferCtxt<'tcx> { tcx: self.tcx, typing_mode: self.typing_mode, considering_regions: self.considering_regions, + in_hir_typeck: self.in_hir_typeck, skip_leak_check: self.skip_leak_check, inner: self.inner.clone(), lexical_region_resolutions: self.lexical_region_resolutions.clone(), @@ -95,6 +96,7 @@ impl<'tcx> InferCtxt<'tcx> { tcx: self.tcx, typing_mode, considering_regions: self.considering_regions, + in_hir_typeck: self.in_hir_typeck, skip_leak_check: self.skip_leak_check, inner: self.inner.clone(), lexical_region_resolutions: self.lexical_region_resolutions.clone(), diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index bb9c88500936f..21e999b080d51 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -22,6 +22,10 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.next_trait_solver } + fn in_hir_typeck(&self) -> bool { + self.in_hir_typeck + } + fn typing_mode(&self) -> ty::TypingMode<'tcx> { self.typing_mode() } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 2d269e320b64d..cb6115661db93 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -247,6 +247,7 @@ pub struct InferCtxt<'tcx> { /// the root universe. Most notably, this is used during hir typeck as region /// solving is left to borrowck instead. pub considering_regions: bool, + pub in_hir_typeck: bool, /// If set, this flag causes us to skip the 'leak check' during /// higher-ranked subtyping operations. This flag is a temporary one used @@ -506,6 +507,7 @@ pub struct TypeOutlivesConstraint<'tcx> { pub struct InferCtxtBuilder<'tcx> { tcx: TyCtxt<'tcx>, considering_regions: bool, + in_hir_typeck: bool, skip_leak_check: bool, /// Whether we should use the new trait solver in the local inference context, /// which affects things like which solver is used in `predicate_may_hold`. @@ -518,6 +520,7 @@ impl<'tcx> TyCtxt<'tcx> { InferCtxtBuilder { tcx: self, considering_regions: true, + in_hir_typeck: false, skip_leak_check: false, next_trait_solver: self.next_trait_solver_globally(), } @@ -535,6 +538,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> { self } + pub fn in_hir_typeck(mut self) -> Self { + self.in_hir_typeck = true; + self + } + pub fn skip_leak_check(mut self, skip_leak_check: bool) -> Self { self.skip_leak_check = skip_leak_check; self @@ -568,12 +576,18 @@ impl<'tcx> InferCtxtBuilder<'tcx> { } pub fn build(&mut self, typing_mode: TypingMode<'tcx>) -> InferCtxt<'tcx> { - let InferCtxtBuilder { tcx, considering_regions, skip_leak_check, next_trait_solver } = - *self; + let InferCtxtBuilder { + tcx, + considering_regions, + in_hir_typeck, + skip_leak_check, + next_trait_solver, + } = *self; InferCtxt { tcx, typing_mode, considering_regions, + in_hir_typeck, skip_leak_check, inner: RefCell::new(InferCtxtInner::new()), lexical_region_resolutions: RefCell::new(None), diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index a418aa82100c4..d7af0468dc4b0 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -19,6 +19,12 @@ const NEEDS_CANONICAL: TypeFlags = TypeFlags::from_bits( ) .unwrap(); +#[derive(Debug, Clone, Copy)] +enum CanonicalizeInputKind { + ParamEnv, + Predicate { is_hir_typeck_root_goal: bool }, +} + /// Whether we're canonicalizing a query input or the query response. /// /// When canonicalizing an input we're in the context of the caller @@ -29,7 +35,7 @@ enum CanonicalizeMode { /// When canonicalizing the `param_env`, we keep `'static` as merging /// trait candidates relies on it when deciding whether a where-bound /// is trivial. - Input { keep_static: bool }, + Input(CanonicalizeInputKind), /// FIXME: We currently return region constraints referring to /// placeholders and inference variables from a binder instantiated /// inside of the query. @@ -122,7 +128,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { let mut variables = Vec::new(); let mut env_canonicalizer = Canonicalizer { delegate, - canonicalize_mode: CanonicalizeMode::Input { keep_static: true }, + canonicalize_mode: CanonicalizeMode::Input(CanonicalizeInputKind::ParamEnv), variables: &mut variables, variable_lookup_table: Default::default(), @@ -154,7 +160,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { } else { let mut env_canonicalizer = Canonicalizer { delegate, - canonicalize_mode: CanonicalizeMode::Input { keep_static: true }, + canonicalize_mode: CanonicalizeMode::Input(CanonicalizeInputKind::ParamEnv), variables, variable_lookup_table: Default::default(), @@ -180,6 +186,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { pub fn canonicalize_input>( delegate: &'a D, variables: &'a mut Vec, + is_hir_typeck_root_goal: bool, input: QueryInput, ) -> ty::Canonical> { // First canonicalize the `param_env` while keeping `'static` @@ -189,7 +196,9 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { // while *mostly* reusing the canonicalizer from above. let mut rest_canonicalizer = Canonicalizer { delegate, - canonicalize_mode: CanonicalizeMode::Input { keep_static: false }, + canonicalize_mode: CanonicalizeMode::Input(CanonicalizeInputKind::Predicate { + is_hir_typeck_root_goal, + }), variables, variable_lookup_table, @@ -413,10 +422,10 @@ impl, I: Interner> TypeFolder for Canonicaliz // We don't canonicalize `ReStatic` in the `param_env` as we use it // when checking whether a `ParamEnv` candidate is global. ty::ReStatic => match self.canonicalize_mode { - CanonicalizeMode::Input { keep_static: false } => { + CanonicalizeMode::Input(CanonicalizeInputKind::Predicate { .. }) => { CanonicalVarKind::Region(ty::UniverseIndex::ROOT) } - CanonicalizeMode::Input { keep_static: true } + CanonicalizeMode::Input(CanonicalizeInputKind::ParamEnv) | CanonicalizeMode::Response { .. } => return r, }, @@ -428,12 +437,12 @@ impl, I: Interner> TypeFolder for Canonicaliz // `ReErased`. We may be able to short-circuit registering region // obligations if we encounter a `ReErased` on one side, for example. ty::ReErased | ty::ReError(_) => match self.canonicalize_mode { - CanonicalizeMode::Input { .. } => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), + CanonicalizeMode::Input(_) => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), CanonicalizeMode::Response { .. } => return r, }, ty::ReEarlyParam(_) | ty::ReLateParam(_) => match self.canonicalize_mode { - CanonicalizeMode::Input { .. } => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), + CanonicalizeMode::Input(_) => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), CanonicalizeMode::Response { .. } => { panic!("unexpected region in response: {r:?}") } @@ -441,7 +450,7 @@ impl, I: Interner> TypeFolder for Canonicaliz ty::RePlaceholder(placeholder) => match self.canonicalize_mode { // We canonicalize placeholder regions as existentials in query inputs. - CanonicalizeMode::Input { .. } => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), + CanonicalizeMode::Input(_) => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), CanonicalizeMode::Response { max_input_universe } => { // If we have a placeholder region inside of a query, it must be from // a new universe. @@ -459,9 +468,7 @@ impl, I: Interner> TypeFolder for Canonicaliz "region vid should have been resolved fully before canonicalization" ); match self.canonicalize_mode { - CanonicalizeMode::Input { keep_static: _ } => { - CanonicalVarKind::Region(ty::UniverseIndex::ROOT) - } + CanonicalizeMode::Input(_) => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), CanonicalizeMode::Response { .. } => { CanonicalVarKind::Region(self.delegate.universe_of_lt(vid).unwrap()) } @@ -469,13 +476,28 @@ impl, I: Interner> TypeFolder for Canonicaliz } }; - let var = self.get_or_insert_bound_var(r, kind); + let var = if let CanonicalizeMode::Input(CanonicalizeInputKind::Predicate { + is_hir_typeck_root_goal: true, + }) = self.canonicalize_mode + { + let var = ty::BoundVar::from(self.variables.len()); + self.variables.push(r.into()); + self.var_kinds.push(kind); + var + } else { + self.get_or_insert_bound_var(r, kind) + }; Region::new_anon_bound(self.cx(), self.binder_index, var) } fn fold_ty(&mut self, t: I::Ty) -> I::Ty { - if let Some(&ty) = self.cache.get(&(self.binder_index, t)) { + if let CanonicalizeMode::Input(CanonicalizeInputKind::Predicate { + is_hir_typeck_root_goal: true, + }) = self.canonicalize_mode + { + self.cached_fold_ty(t) + } else if let Some(&ty) = self.cache.get(&(self.binder_index, t)) { ty } else { let res = self.cached_fold_ty(t); @@ -541,9 +563,9 @@ impl, I: Interner> TypeFolder for Canonicaliz fn fold_clauses(&mut self, c: I::Clauses) -> I::Clauses { match self.canonicalize_mode { - CanonicalizeMode::Input { keep_static: true } + CanonicalizeMode::Input(CanonicalizeInputKind::ParamEnv) | CanonicalizeMode::Response { max_input_universe: _ } => {} - CanonicalizeMode::Input { keep_static: false } => { + CanonicalizeMode::Input(CanonicalizeInputKind::Predicate { .. }) => { panic!("erasing 'static in env") } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index 5ed316aa6b131..de1330ca82a4e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -55,6 +55,7 @@ where /// for each bound variable. pub(super) fn canonicalize_goal( &self, + is_hir_typeck_root_goal: bool, goal: Goal, ) -> (Vec, CanonicalInput) { // We only care about one entry per `OpaqueTypeKey` here, @@ -67,6 +68,7 @@ where let canonical = Canonicalizer::canonicalize_input( self.delegate, &mut orig_values, + is_hir_typeck_root_goal, QueryInput { goal, predefined_opaques_in_body: self diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index ce9b794d40d30..8ac7c8e8e5380 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -197,7 +197,14 @@ where self.cx().recursion_limit(), GenerateProofTree::No, span, - |ecx| ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal, stalled_on), + |ecx| { + ecx.evaluate_goal( + GoalEvaluationKind::Root { in_hir_typeck: self.in_hir_typeck() }, + GoalSource::Misc, + goal, + stalled_on, + ) + }, ) .0 } @@ -209,7 +216,12 @@ where ) -> bool { self.probe(|| { EvalCtxt::enter_root(self, root_depth, GenerateProofTree::No, I::Span::dummy(), |ecx| { - ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal, None) + ecx.evaluate_goal( + GoalEvaluationKind::Root { in_hir_typeck: self.in_hir_typeck() }, + GoalSource::Misc, + goal, + None, + ) }) .0 }) @@ -230,7 +242,14 @@ where self.cx().recursion_limit(), GenerateProofTree::Yes, span, - |ecx| ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal, None), + |ecx| { + ecx.evaluate_goal_raw( + GoalEvaluationKind::Root { in_hir_typeck: self.in_hir_typeck() }, + GoalSource::Misc, + goal, + None, + ) + }, ); (result, proof_tree.unwrap()) } @@ -447,7 +466,10 @@ where )); } - let (orig_values, canonical_goal) = self.canonicalize_goal(goal); + let is_hir_typeck_root_goal = + matches!(goal_evaluation_kind, GoalEvaluationKind::Root { in_hir_typeck: true }); + + let (orig_values, canonical_goal) = self.canonicalize_goal(is_hir_typeck_root_goal, goal); let mut goal_evaluation = self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind); let canonical_result = self.search_graph.evaluate_goal( diff --git a/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs b/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs index c8521624ebbf9..48c0772c21425 100644 --- a/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs +++ b/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs @@ -237,7 +237,7 @@ impl, I: Interner> ProofTreeBuilder { kind: GoalEvaluationKind, ) -> ProofTreeBuilder { self.opt_nested(|| match kind { - GoalEvaluationKind::Root => Some(WipGoalEvaluation { + GoalEvaluationKind::Root { in_hir_typeck: _ } => Some(WipGoalEvaluation { uncanonicalized_goal, orig_values: orig_values.to_vec(), encountered_overflow: false, diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 5ea3f0d10617d..96060e6dcf266 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -43,7 +43,7 @@ const FIXPOINT_STEP_LIMIT: usize = 8; #[derive(Debug, Copy, Clone, PartialEq, Eq)] enum GoalEvaluationKind { - Root, + Root { in_hir_typeck: bool }, Nested, } diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index e86a2305e2334..b4873c8c71cbb 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -148,6 +148,10 @@ pub trait InferCtxtLike: Sized { true } + fn in_hir_typeck(&self) -> bool { + false + } + fn typing_mode(&self) -> TypingMode; fn universe(&self) -> ty::UniverseIndex; diff --git a/tests/crashes/139409.rs b/tests/crashes/139409.rs deleted file mode 100644 index 68cbfa153deb0..0000000000000 --- a/tests/crashes/139409.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: #139409 -//@ compile-flags: -Znext-solver=globally - -fn main() { - trait B {} - impl B for () {} - trait D: B + B { - fn f(&self) {} - } - impl D for () {} - (&() as &dyn D<&(), &()>).f() -} diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr index d99a4cbd37802..c6728932965dd 100644 --- a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr +++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.current.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:20:5 + --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:27:5 | LL | fn foo<'a, T: ?Sized>() | -- lifetime `'a` defined here diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr index d99a4cbd37802..c6728932965dd 100644 --- a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr +++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.next.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:20:5 + --> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:27:5 | LL | fn foo<'a, T: ?Sized>() | -- lifetime `'a` defined here diff --git a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs index 6ddc0628dd192..48716340ca56f 100644 --- a/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs +++ b/tests/ui/traits/lifetime-incomplete-prefer-sized-builtin-over-wc.rs @@ -8,9 +8,16 @@ struct MyType<'a, T: ?Sized>(&'a (), T); fn is_sized() {} +trait Id { + type This: ?Sized; +} +impl Id for T { + type This = T; +} + fn foo<'a, T: ?Sized>() where - (MyType<'a, T>,): Sized, + (MyType<'a, ::This>,): Sized, MyType<'static, T>: Sized, { // Preferring the builtin `Sized` impl of tuples diff --git a/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-1.next.stderr b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-1.next.stderr new file mode 100644 index 0000000000000..141a07b4be7c0 --- /dev/null +++ b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-1.next.stderr @@ -0,0 +1,19 @@ +error[E0283]: type annotations needed: cannot satisfy `dyn D<&(), &()>: B<&()>` + --> $DIR/ambiguity-due-to-uniquification-1.rs:15:31 + | +LL | (&() as &dyn D<&(), &()>).f() + | ^ + | + = note: cannot satisfy `dyn D<&(), &()>: B<&()>` + = help: the trait `B` is implemented for `()` +note: required by a bound in `D::f` + --> $DIR/ambiguity-due-to-uniquification-1.rs:10:16 + | +LL | trait D: B + B { + | ^^^^ required by this bound in `D::f` +LL | fn f(&self) {} + | - required by a bound in this associated function + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-1.rs b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-1.rs new file mode 100644 index 0000000000000..cfdf74046fbd6 --- /dev/null +++ b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-1.rs @@ -0,0 +1,17 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[current] check-pass + +// Regression test for #139409 and trait-system-refactor-initiative#27. + +trait B {} +impl B for () {} +trait D: B + B { + fn f(&self) {} +} +impl D for () {} +fn main() { + (&() as &dyn D<&(), &()>).f() + //[next]~^ ERROR type annotations needed: cannot satisfy `dyn D<&(), &()>: B<&()>` +} diff --git a/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-2.next.stderr b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-2.next.stderr new file mode 100644 index 0000000000000..3b47888999695 --- /dev/null +++ b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-2.next.stderr @@ -0,0 +1,17 @@ +error[E0283]: type annotations needed: cannot satisfy `impl Trait<'x> + Trait<'y>: Trait<'y>` + --> $DIR/ambiguity-due-to-uniquification-2.rs:16:23 + | +LL | impls_trait::<'y, _>(foo::<'x, 'y>()); + | ^ + | + = note: cannot satisfy `impl Trait<'x> + Trait<'y>: Trait<'y>` + = help: the trait `Trait<'t>` is implemented for `()` +note: required by a bound in `impls_trait` + --> $DIR/ambiguity-due-to-uniquification-2.rs:13:23 + | +LL | fn impls_trait<'x, T: Trait<'x>>(_: T) {} + | ^^^^^^^^^ required by this bound in `impls_trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-2.rs b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-2.rs new file mode 100644 index 0000000000000..2a9a8b80cc069 --- /dev/null +++ b/tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-2.rs @@ -0,0 +1,20 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[current] check-pass + +// Regression test from trait-system-refactor-initiative#27. + +trait Trait<'t> {} +impl<'t> Trait<'t> for () {} + +fn foo<'x, 'y>() -> impl Trait<'x> + Trait<'y> {} + +fn impls_trait<'x, T: Trait<'x>>(_: T) {} + +fn bar<'x, 'y>() { + impls_trait::<'y, _>(foo::<'x, 'y>()); + //[next]~^ ERROR type annotations needed: cannot satisfy `impl Trait<'x> + Trait<'y>: Trait<'y>` +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.rs b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.rs index 754fc872e457c..55e62753ee3bb 100644 --- a/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.rs +++ b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.rs @@ -41,10 +41,8 @@ where // These overflow errors will disappear once we treat these cycles as either // productive or an error. impl Trait for MultipleNested -//~^ ERROR overflow evaluating the requirement `MultipleNested: Trait` where MultipleCandidates: Trait, - //~^ ERROR overflow evaluating the requirement `MultipleCandidates: Trait` DoesNotImpl: Trait, {} diff --git a/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.stderr b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.stderr index 7895a2636345a..4122118a4b53c 100644 --- a/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.stderr +++ b/tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.stderr @@ -1,29 +1,16 @@ -error[E0275]: overflow evaluating the requirement `MultipleNested: Trait` - --> $DIR/inductive-cycle-but-err.rs:43:16 - | -LL | impl Trait for MultipleNested - | ^^^^^^^^^^^^^^ - -error[E0275]: overflow evaluating the requirement `MultipleCandidates: Trait` - --> $DIR/inductive-cycle-but-err.rs:46:25 - | -LL | MultipleCandidates: Trait, - | ^^^^^ - error[E0277]: the trait bound `MultipleCandidates: Trait` is not satisfied - --> $DIR/inductive-cycle-but-err.rs:54:19 + --> $DIR/inductive-cycle-but-err.rs:52:19 | LL | impls_trait::(); | ^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `MultipleCandidates` | = help: the trait `Trait` is implemented for `MultipleCandidates` note: required by a bound in `impls_trait` - --> $DIR/inductive-cycle-but-err.rs:51:19 + --> $DIR/inductive-cycle-but-err.rs:49:19 | LL | fn impls_trait() {} | ^^^^^ required by this bound in `impls_trait` -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0275, E0277. -For more information about an error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr index d179c80596238..81015ccdbd7be 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr @@ -1,24 +1,3 @@ -error[E0275]: overflow evaluating the requirement `<() as A>::Assoc: A` - --> $DIR/normalize-param-env-2.rs:24:22 - | -LL | Self::Assoc: A, - | ^^^^ - | -note: the requirement `<() as A>::Assoc: A` appears on the `impl`'s associated function `f` but not on the corresponding trait's associated function - --> $DIR/normalize-param-env-2.rs:12:8 - | -LL | trait A { - | - in this trait -... -LL | fn f() - | ^ this trait's associated function doesn't have the requirement `<() as A>::Assoc: A` - -error[E0275]: overflow evaluating the requirement `<() as A>::Assoc: A` - --> $DIR/normalize-param-env-2.rs:24:22 - | -LL | Self::Assoc: A, - | ^^^^ - error[E0275]: overflow evaluating the requirement `<() as A>::Assoc well-formed` --> $DIR/normalize-param-env-2.rs:24:22 | @@ -31,21 +10,6 @@ error[E0275]: overflow evaluating the requirement `(): A` LL | <() as A>::f(); | ^^ -error[E0275]: overflow evaluating the requirement `<() as A>::Assoc: A` - --> $DIR/normalize-param-env-2.rs:27:9 - | -LL | <() as A>::f(); - | ^^^^^^^^^^^^^^^^^ - | -note: required by a bound in `A::f` - --> $DIR/normalize-param-env-2.rs:14:22 - | -LL | fn f() - | - required by a bound in this associated function -LL | where -LL | Self::Assoc: A, - | ^^^^ required by this bound in `A::f` - -error: aborting due to 5 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr deleted file mode 100644 index f5fd9ce9864ce..0000000000000 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0275]: overflow evaluating the requirement `::Assoc: Trait` - --> $DIR/normalize-param-env-4.rs:19:26 - | -LL | ::Assoc: Trait, - | ^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.rs b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.rs index ed7f6899bdee6..4d423d77a7e71 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.rs +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.rs @@ -1,8 +1,6 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver -//@[next] known-bug: #92505 -//@[current] check-pass +//@ check-pass trait Trait { type Assoc; @@ -24,11 +22,11 @@ where // // We therefore check whether `T: Trait` is proven by the environment. // For that we try to apply the `::Assoc: Trait` candidate, - // trying to normalize its self type results in overflow. + // trying to normalize its self type encounters a cycle. // // In the old solver we eagerly normalize the environment, ignoring the // unnormalized `::Assoc: Trait` where-bound when normalizing - // `::Asosc` + // `::Assoc`. impls_trait::(); }