From da7f6c04cc3d719560146650f65f1e7af7e406c9 Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Thu, 3 Sep 2026 13:59:10 -0700 Subject: [PATCH 1/2] don't manually instantiate binders in `explain_hrtb_projection` --- .../src/error_reporting/traits/suggestions.rs | 19 ++++++------------- .../issue-62529-3.stderr | 8 -------- .../closure-mismatch.next.stderr | 16 ---------------- ....stderr => universe-error1.current.stderr} | 4 ++-- .../universe-error1.next.stderr | 18 ++++++++++++++++++ .../non_lifetime_binders/universe-error1.rs | 4 ++++ 6 files changed, 30 insertions(+), 39 deletions(-) rename tests/ui/traits/non_lifetime_binders/{universe-error1.stderr => universe-error1.current.stderr} (87%) create mode 100644 tests/ui/traits/non_lifetime_binders/universe-error1.next.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 7921250a85a9e..d64197936ded6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -6022,19 +6022,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { { self.probe(|_| { let ocx = ObligationCtxt::new(self); - self.enter_forall(pred, |pred| { - let pred = ocx.normalize( - &ObligationCause::dummy(), - param_env, - Unnormalized::new_wip(pred), - ); - ocx.register_obligation(Obligation::new( - self.tcx, - ObligationCause::dummy(), - param_env, - pred, - )); - }); + ocx.register_obligation(Obligation::new( + self.tcx, + ObligationCause::dummy(), + param_env, + pred, + )); if !ocx.try_evaluate_obligations().no_errors() { // encountered errors. return; diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr index 96cef0a6a5c9e..2671765ef8e6b 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr @@ -8,14 +8,6 @@ LL | call(f, ()); | = note: expected a closure with signature `for<'a> fn(<_ as ATC<'a>>::Type)` found a closure with signature `fn(())` -note: this is a known limitation of the trait solver that will be lifted in the future - --> $DIR/issue-62529-3.rs:25:14 - | -LL | call(f, ()); - | -----^----- - | | | - | | the trait solver is unable to infer the generic types that should be inferred from this argument - | add turbofish arguments to this call to specify the types manually, even if it's redundant note: required by a bound in `call` --> $DIR/issue-62529-3.rs:9:36 | diff --git a/tests/ui/mismatched_types/closure-mismatch.next.stderr b/tests/ui/mismatched_types/closure-mismatch.next.stderr index 6b4620aa8d1ba..a6380b7487dad 100644 --- a/tests/ui/mismatched_types/closure-mismatch.next.stderr +++ b/tests/ui/mismatched_types/closure-mismatch.next.stderr @@ -9,14 +9,6 @@ LL | baz(|_| ()); = help: the trait `for<'a> FnOnce(&'a ())` is not implemented for closure `{closure@$DIR/closure-mismatch.rs:12:9: 12:12}` = note: expected a closure with signature `for<'a> fn(&'a ())` found a closure with signature `fn(&())` -note: this is a known limitation of the trait solver that will be lifted in the future - --> $DIR/closure-mismatch.rs:12:9 - | -LL | baz(|_| ()); - | ----^^^---- - | | | - | | the trait solver is unable to infer the generic types that should be inferred from this argument - | add turbofish arguments to this call to specify the types manually, even if it's redundant note: required for `{closure@$DIR/closure-mismatch.rs:12:9: 12:12}` to implement `Foo` --> $DIR/closure-mismatch.rs:7:18 | @@ -41,14 +33,6 @@ LL | baz(|x| ()); = help: the trait `for<'a> FnOnce(&'a ())` is not implemented for closure `{closure@$DIR/closure-mismatch.rs:16:9: 16:12}` = note: expected a closure with signature `for<'a> fn(&'a ())` found a closure with signature `fn(&())` -note: this is a known limitation of the trait solver that will be lifted in the future - --> $DIR/closure-mismatch.rs:16:9 - | -LL | baz(|x| ()); - | ----^^^---- - | | | - | | the trait solver is unable to infer the generic types that should be inferred from this argument - | add turbofish arguments to this call to specify the types manually, even if it's redundant note: required for `{closure@$DIR/closure-mismatch.rs:16:9: 16:12}` to implement `Foo` --> $DIR/closure-mismatch.rs:7:18 | diff --git a/tests/ui/traits/non_lifetime_binders/universe-error1.stderr b/tests/ui/traits/non_lifetime_binders/universe-error1.current.stderr similarity index 87% rename from tests/ui/traits/non_lifetime_binders/universe-error1.stderr rename to tests/ui/traits/non_lifetime_binders/universe-error1.current.stderr index 899378b2bce4e..1ef4cc1034bc3 100644 --- a/tests/ui/traits/non_lifetime_binders/universe-error1.stderr +++ b/tests/ui/traits/non_lifetime_binders/universe-error1.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `T: Other<_>` is not satisfied - --> $DIR/universe-error1.rs:16:11 + --> $DIR/universe-error1.rs:20:11 | LL | foo::<_>(); | ^ the trait `Other<_>` is not implemented for `T` | note: required by a bound in `foo` - --> $DIR/universe-error1.rs:13:15 + --> $DIR/universe-error1.rs:17:15 | LL | fn foo() | --- required by a bound in this function diff --git a/tests/ui/traits/non_lifetime_binders/universe-error1.next.stderr b/tests/ui/traits/non_lifetime_binders/universe-error1.next.stderr new file mode 100644 index 0000000000000..1ef4cc1034bc3 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/universe-error1.next.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `T: Other<_>` is not satisfied + --> $DIR/universe-error1.rs:20:11 + | +LL | foo::<_>(); + | ^ the trait `Other<_>` is not implemented for `T` + | +note: required by a bound in `foo` + --> $DIR/universe-error1.rs:17:15 + | +LL | fn foo() + | --- required by a bound in this function +LL | where +LL | for T: Other {} + | ^^^^^^^^ required by this bound in `foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/non_lifetime_binders/universe-error1.rs b/tests/ui/traits/non_lifetime_binders/universe-error1.rs index 1c99794b6a641..b6c954cf56f47 100644 --- a/tests/ui/traits/non_lifetime_binders/universe-error1.rs +++ b/tests/ui/traits/non_lifetime_binders/universe-error1.rs @@ -1,3 +1,7 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + #![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] From 368791e6d4e3ad9e7b0981bd870700fac8978205 Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Thu, 3 Sep 2026 13:59:10 -0700 Subject: [PATCH 2/2] make `poly_select` delegate to next-solver directly --- .../traits/fulfillment_errors.rs | 4 +- .../rustc_trait_selection/src/solve/select.rs | 6 +-- .../src/traits/select/mod.rs | 8 ++-- .../universe-error-host-effect.rs | 28 ++++++++++++ .../universe-error-host-effect.stderr | 44 +++++++++++++++++++ 5 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 tests/ui/traits/non_lifetime_binders/universe-error-host-effect.rs create mode 100644 tests/ui/traits/non_lifetime_binders/universe-error-host-effect.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 1c4f0ca5069df..9b1f0f9294b7f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -890,9 +890,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } if let Ok(Some(ImplSource::UserDefined(impl_data))) = - self.enter_forall(trait_ref, |trait_ref_for_select| { - SelectionContext::new(self).select(&obligation.with(self.tcx, trait_ref_for_select)) - }) + SelectionContext::new(self).poly_select(&obligation.with(self.tcx, trait_ref)) { let impl_did = impl_data.impl_def_id; let trait_did = trait_ref.def_id(); diff --git a/compiler/rustc_trait_selection/src/solve/select.rs b/compiler/rustc_trait_selection/src/solve/select.rs index b413b8b5ed9c7..53b999e4e5244 100644 --- a/compiler/rustc_trait_selection/src/solve/select.rs +++ b/compiler/rustc_trait_selection/src/solve/select.rs @@ -5,7 +5,7 @@ use rustc_infer::traits::solve::inspect::ProbeKind; use rustc_infer::traits::solve::{CandidateSource, Certainty, Goal}; use rustc_infer::traits::{ BuiltinImplSource, ImplSource, ImplSourceUserDefinedData, Obligation, ObligationCause, - Selection, SelectionError, SelectionResult, TraitObligation, + PolyTraitObligation, Selection, SelectionError, SelectionResult, }; use rustc_macros::extension; use rustc_middle::{bug, span_bug}; @@ -16,10 +16,10 @@ use crate::solve::inspect::{self, InferCtxtProofTreeExt}; #[extension(pub trait InferCtxtSelectExt<'tcx>)] impl<'tcx> InferCtxt<'tcx> { - /// Do not use this directly. This is called from [`crate::traits::SelectionContext::select`]. + /// Do not use this directly. This is called from [`crate::traits::SelectionContext::poly_select`]. fn select_in_new_trait_solver( &self, - obligation: &TraitObligation<'tcx>, + obligation: &PolyTraitObligation<'tcx>, ) -> SelectionResult<'tcx, Selection<'tcx>> { assert!(self.next_trait_solver()); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index f1eaa50797c49..8d93d9b4b44ff 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -255,7 +255,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> SelectionResult<'tcx, Selection<'tcx>> { - assert!(!self.infcx.next_trait_solver()); + if self.infcx.next_trait_solver() { + return self.infcx.select_in_new_trait_solver(obligation); + } let candidate = match self.select_from_obligation(obligation) { Err(SelectionError::Overflow(OverflowError::Canonical)) => { @@ -292,10 +294,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &TraitObligation<'tcx>, ) -> SelectionResult<'tcx, Selection<'tcx>> { - if self.infcx.next_trait_solver() { - return self.infcx.select_in_new_trait_solver(obligation); - } - self.poly_select(&Obligation { cause: obligation.cause.clone(), param_env: obligation.param_env, diff --git a/tests/ui/traits/non_lifetime_binders/universe-error-host-effect.rs b/tests/ui/traits/non_lifetime_binders/universe-error-host-effect.rs new file mode 100644 index 0000000000000..6d763a86ab271 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/universe-error-host-effect.rs @@ -0,0 +1,28 @@ +//@ compile-flags: -Znext-solver + +#![feature(const_trait_impl, non_lifetime_binders, sized_hierarchy)] +#![allow(incomplete_features)] + +use std::marker::PointeeSized; + +const trait Other: PointeeSized {} + +trait Guard {} + +const impl Other for X {} + +impl Other for X where u8: Guard {} +//~^ ERROR the trait bound `u8: Guard` is not satisfied + +fn foo() +where + for T: const Other, +{ +} + +fn bar() { + foo::<_, _>(); + //~^ ERROR the trait bound `u8: Guard` is not satisfied +} + +fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/universe-error-host-effect.stderr b/tests/ui/traits/non_lifetime_binders/universe-error-host-effect.stderr new file mode 100644 index 0000000000000..a634c86afa534 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/universe-error-host-effect.stderr @@ -0,0 +1,44 @@ +error[E0277]: the trait bound `u8: Guard` is not satisfied + --> $DIR/universe-error-host-effect.rs:14:50 + | +LL | impl Other for X where u8: Guard {} + | ^^^^^^^^^ the trait `Guard` is not implemented for `u8` + | +help: this trait has no implementations, consider adding one + --> $DIR/universe-error-host-effect.rs:10:1 + | +LL | trait Guard {} + | ^^^^^^^^^^^ +help: add `#![feature(trivial_bounds)]` to the crate attributes to enable + | +LL + #![feature(trivial_bounds)] + | + +error[E0277]: the trait bound `u8: Guard` is not satisfied + --> $DIR/universe-error-host-effect.rs:24:11 + | +LL | foo::<_, _>(); + | ^ the trait `Guard` is not implemented for `u8` + | +help: this trait has no implementations, consider adding one + --> $DIR/universe-error-host-effect.rs:10:1 + | +LL | trait Guard {} + | ^^^^^^^^^^^ +note: required for `T` to implement `Other` + --> $DIR/universe-error-host-effect.rs:14:23 + | +LL | impl Other for X where u8: Guard {} + | ^^^^^^^^^^^^^^ ^ ----- unsatisfied trait bound introduced here +note: required by a bound in `foo` + --> $DIR/universe-error-host-effect.rs:19:15 + | +LL | fn foo() + | --- required by a bound in this function +LL | where +LL | for T: const Other, + | ^^^^^^^^^^^^^^^^^ required by this bound in `foo` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`.