From 393c1278b300e930acd0312726437ee968b625fd Mon Sep 17 00:00:00 2001 From: Joao Roberto Date: Wed, 9 Sep 2026 07:57:28 -0300 Subject: [PATCH] Revert "trait_selection: Keep type-op region constraints in borrowck" This reverts commit 9318843e0d1a5fec51e270683efbbbe2a71eaf08, reversing changes made to 37719fa2b61719c163067edbdf32da0742307e65. The new region constraint handling runs on hot codepaths even when assumptions-on-binders is off and the constraint is just `true`, so we pay for it in the common case. Reverting to re-land it later with the new logic behind checks for whether AoB is enabled, so it can get a perf run. --- .../rustc_borrowck/src/handle_placeholders.rs | 8 --- .../src/type_check/constraint_conversion.rs | 6 +-- compiler/rustc_borrowck/src/type_check/mod.rs | 30 ----------- .../src/infer/canonical/query_response.rs | 52 +++++++------------ .../src/infer/outlives/obligations.rs | 11 ++-- .../src/infer/solver_region_constraints.rs | 19 +------ .../infer/solver_region_constraints/tests.rs | 22 -------- compiler/rustc_middle/src/infer/canonical.rs | 29 ++--------- .../src/solve/delegate.rs | 5 -- .../src/traits/outlives_bounds.rs | 5 +- .../src/traits/query/type_op/custom.rs | 11 +--- .../src/traits/query/type_op/mod.rs | 5 +- .../rustc_traits/src/coroutine_witnesses.rs | 4 -- .../assumptions_on_binders/alias_outlives.rs | 28 +--------- .../alias_outlives.stderr | 17 +----- 15 files changed, 37 insertions(+), 215 deletions(-) diff --git a/compiler/rustc_borrowck/src/handle_placeholders.rs b/compiler/rustc_borrowck/src/handle_placeholders.rs index bdb30090925d0..11b8890346dfb 100644 --- a/compiler/rustc_borrowck/src/handle_placeholders.rs +++ b/compiler/rustc_borrowck/src/handle_placeholders.rs @@ -246,16 +246,8 @@ pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>( mut outlives_constraints, universe_causes, type_tests, - solver_constraints, } = constraints; - // These have already been destructured into `outlives_constraints` at the - // end of MIR type checking. - assert!( - solver_constraints.is_true(), - "solver region constraints not lowered to NLL = {solver_constraints:#?}", - ); - let fr_static = universal_regions.fr_static; let compute_sccs = |constraints: &OutlivesConstraintSet<'tcx>, diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 113908fba6702..e20f9a646a953 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -67,8 +67,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { #[instrument(skip(self), level = "debug")] pub(super) fn convert_all(&mut self, query_constraints: &QueryRegionConstraints<'tcx>) { - let QueryRegionConstraints { constraints, assumptions, solver_constraints } = - query_constraints; + let QueryRegionConstraints { constraints, assumptions } = query_constraints; let assumptions = elaborate::elaborate_outlives_assumptions(self.infcx.tcx, assumptions.iter().copied()); @@ -77,9 +76,6 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { self.convert(predicate, category, &assumptions); }); } - - self.constraints - .register_solver_constraint(solver_constraints.clone().with_spans(self.span)); } /// Given an instance of the closure type, this method instantiates the "extra" requirements diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 96147fc934df4..dde44e7e57713 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -17,7 +17,6 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::region_constraints::RegionConstraintData; use rustc_infer::infer::{ BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, - SolverRegionConstraint, }; use rustc_infer::traits::{Obligation, ObligationCause, PredicateObligations}; use rustc_middle::bug; @@ -114,7 +113,6 @@ pub(crate) fn type_check<'tcx>( outlives_constraints: OutlivesConstraintSet::default(), type_tests: Vec::default(), universe_causes: FxIndexMap::default(), - solver_constraints: SolverRegionConstraint::new_true(), }; let CreateResult { @@ -136,13 +134,6 @@ pub(crate) fn type_check<'tcx>( pre_assumptions.is_empty(), "there should be no incoming region assumptions = {pre_assumptions:#?}", ); - // Solver region constraints from computing the implied bounds went through - // `ConstraintConversion` and are already stored in `constraints`. - let pre_solver_constraints = infcx.take_solver_region_constraints(); - assert!( - pre_solver_constraints.is_true(), - "there should be no incoming solver region constraints = {pre_solver_constraints:#?}", - ); } debug!(?normalized_inputs_and_output); @@ -183,10 +174,6 @@ pub(crate) fn type_check<'tcx>( let polonius_context = typeck.polonius_context; if infcx.tcx.assumptions_on_binders() { - let solver_constraints = mem::replace( - &mut typeck.constraints.solver_constraints, - SolverRegionConstraint::new_true(), - ); let mut converter = constraint_conversion::ConstraintConversion::new( typeck.infcx, typeck.universal_regions, @@ -198,7 +185,6 @@ pub(crate) fn type_check<'tcx>( typeck.constraints, ); typeck.infcx.destructure_solver_region_constraints_for_borrowck( - solver_constraints, &mut converter, typeck.known_type_outlives_obligations, typeck.region_bound_pairs, @@ -308,25 +294,9 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> { pub(crate) universe_causes: FxIndexMap>, pub(crate) type_tests: Vec>, - - /// The region constraints emitted by the next solver under - /// `-Zassumptions-on-binders`. Unlike the constraints above these are not yet - /// lowered to NLL, we destructure them into `outlives_constraints` at the end - /// of MIR type checking. - pub(crate) solver_constraints: SolverRegionConstraint<'tcx>, } impl<'tcx> MirTypeckRegionConstraints<'tcx> { - /// Adds `constraint` to the constraints we've accumulated so far. - pub(crate) fn register_solver_constraint(&mut self, constraint: SolverRegionConstraint<'tcx>) { - // FIXME(-Zassumptions-on-binders): This is pretty bad for perf, we rebuild the - // entire constraint every time instead of updating it incrementally. - self.solver_constraints = SolverRegionConstraint::build_and( - constraint, - mem::replace(&mut self.solver_constraints, SolverRegionConstraint::new_true()), - ); - } - /// Creates a `Region` for a given `PlaceholderRegion`, or returns the /// region that corresponds to a previously created one. pub(crate) fn placeholder_region( diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index d1c4480b59347..cd35af8be73cf 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -146,13 +146,11 @@ impl<'tcx> InferCtxt<'tcx> { let region_obligations = self.take_registered_region_obligations(); let region_assumptions = self.take_registered_region_assumptions(); debug!(?region_obligations); - let solver_constraints = self.take_solver_region_constraints(); let region_constraints = self.with_region_constraints(|region_constraints| { make_query_region_constraints( region_obligations, region_constraints, region_assumptions, - solver_constraints, ) }); debug!(?region_constraints); @@ -197,10 +195,9 @@ impl<'tcx> InferCtxt<'tcx> { let InferOk { value: result_args, obligations } = self.query_response_instantiation(cause, param_env, original_values, query_response)?; - let QueryRegionConstraints { constraints, assumptions, solver_constraints } = - &query_response.value.region_constraints; - - for QueryRegionConstraint { constraint, visible_for_leak_check: vis, .. } in constraints { + for QueryRegionConstraint { constraint, visible_for_leak_check: vis, .. } in + &query_response.value.region_constraints.constraints + { let constraint = instantiate_value(self.tcx, &result_args, *constraint); match constraint { ty::RegionConstraint::Outlives(clause) => { @@ -212,15 +209,11 @@ impl<'tcx> InferCtxt<'tcx> { } } - for assumption in assumptions { + for assumption in &query_response.value.region_constraints.assumptions { let assumption = instantiate_value(self.tcx, &result_args, *assumption); self.register_region_assumption(assumption); } - let solver_constraints = - instantiate_value(self.tcx, &result_args, solver_constraints.clone()); - self.register_solver_region_constraint(solver_constraints.with_spans(cause.span)); - let user_result: R = query_response.instantiate_projected(self.tcx, &result_args, |q_r| q_r.value.clone()); @@ -332,31 +325,27 @@ impl<'tcx> InferCtxt<'tcx> { } } - let QueryRegionConstraints { constraints, assumptions, solver_constraints } = - &query_response.value.region_constraints; - // ...also include the other query region constraints from the query. - output_query_region_constraints.constraints.extend(constraints.iter().filter_map(|&r_c| { - let r_c = instantiate_value(self.tcx, &result_args, r_c); + output_query_region_constraints.constraints.extend( + query_response.value.region_constraints.constraints.iter().filter_map(|&r_c| { + let r_c = instantiate_value(self.tcx, &result_args, r_c); - // Screen out `'a: 'a` or `'a == 'a` cases. - if r_c.constraint.is_trivial() { None } else { Some(r_c) } - })); + // Screen out `'a: 'a` or `'a == 'a` cases. + if r_c.constraint.is_trivial() { None } else { Some(r_c) } + }), + ); // FIXME(higher_ranked_auto): Optimize this to instantiate all assumptions // at once, rather than calling `instantiate_value` repeatedly which may // create more universes. - output_query_region_constraints - .assumptions - .extend(assumptions.iter().map(|&r_c| instantiate_value(self.tcx, &result_args, r_c))); - - let solver_constraints = - instantiate_value(self.tcx, &result_args, solver_constraints.clone()); - output_query_region_constraints.solver_constraints = - ty::region_constraint::RegionConstraint::build_and( - std::mem::take(&mut output_query_region_constraints.solver_constraints), - solver_constraints, - ); + output_query_region_constraints.assumptions.extend( + query_response + .value + .region_constraints + .assumptions + .iter() + .map(|&r_c| instantiate_value(self.tcx, &result_args, r_c)), + ); let user_result: R = query_response.instantiate_projected(self.tcx, &result_args, |q_r| q_r.value.clone()); @@ -630,7 +619,6 @@ pub fn make_query_region_constraints<'tcx>( outlives_obligations: Vec>, region_constraints: &RegionConstraintData<'tcx>, assumptions: Vec>, - solver_constraints: ty::region_constraint::RegionConstraint>, ) -> QueryRegionConstraints<'tcx> { let RegionConstraintData { constraints, verifys } = region_constraints; @@ -675,5 +663,5 @@ pub fn make_query_region_constraints<'tcx>( )) .collect(); - QueryRegionConstraints { constraints, assumptions, solver_constraints } + QueryRegionConstraints { constraints, assumptions } } diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index a6c610edebf02..dbe85e5315500 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -251,16 +251,11 @@ impl<'tcx> InferCtxt<'tcx> { region_outlives.freeze(), ty::UniverseIndex::ROOT, ); - let constraint = self.inner.borrow().solver_region_constraint_storage.get_constraint(); - self.destructure_solver_region_constraints(constraint, assumptions, self); + self.destructure_solver_region_constraints(assumptions, self); } - /// Unlike regionck, borrowck doesn't keep these constraints in the `InferCtxt`. - /// It stores them in `MirTypeckRegionConstraints` alongside its other region - /// constraints, so it hands us the constraint to destructure. pub fn destructure_solver_region_constraints_for_borrowck( &self, - constraint: SolverRegionConstraint<'tcx>, // this is always ConstraintConversion but lol conversion: impl TypeOutlivesDelegate<'tcx>, known_type_outlives: &[PolyTypeOutlivesClause<'tcx>], @@ -273,19 +268,19 @@ impl<'tcx> InferCtxt<'tcx> { region_outlives.maybe_map(|r| Some(Region::new_var(self.tcx, r))).unwrap(), ty::UniverseIndex::ROOT, ); - self.destructure_solver_region_constraints(constraint, assumptions, conversion); + self.destructure_solver_region_constraints(assumptions, conversion); } #[instrument(level = "debug", skip(self, conversion))] pub fn destructure_solver_region_constraints( &self, - constraint: SolverRegionConstraint<'tcx>, assumptions: rustc_type_ir::region_constraint::Assumptions>, mut conversion: impl TypeOutlivesDelegate<'tcx>, ) { assert!(self.tcx.assumptions_on_binders()); assert!(self.next_trait_solver()); + let constraint = self.inner.borrow().solver_region_constraint_storage.get_constraint(); debug!(?constraint); let constraint = region_constraint::destructure_type_outlives_constraints_in_root( self, diff --git a/compiler/rustc_infer/src/infer/solver_region_constraints.rs b/compiler/rustc_infer/src/infer/solver_region_constraints.rs index 965ccf70442b8..09baae2ca8a42 100644 --- a/compiler/rustc_infer/src/infer/solver_region_constraints.rs +++ b/compiler/rustc_infer/src/infer/solver_region_constraints.rs @@ -1,11 +1,9 @@ use rustc_middle::ty::TyCtxt; use rustc_span::Span; -use rustc_type_ir::region_constraint::RegionConstraint; use tracing::instrument; -use super::InferCtxt; - -pub type SolverRegionConstraint<'tcx> = RegionConstraint, Span>; +pub type SolverRegionConstraint<'tcx> = + rustc_type_ir::region_constraint::RegionConstraint, Span>; #[derive(Clone, Debug)] pub(crate) struct SolverRegionConstraintStorage<'tcx>(SolverRegionConstraint<'tcx>); @@ -19,24 +17,11 @@ impl<'tcx> SolverRegionConstraintStorage<'tcx> { self.0.clone() } - pub(crate) fn take(&mut self) -> SolverRegionConstraint<'tcx> { - core::mem::replace(&mut self.0, SolverRegionConstraint::new_true()) - } - #[instrument(level = "debug", skip(self))] pub(crate) fn overwrite(&mut self, constraint: SolverRegionConstraint<'tcx>) { self.0 = constraint; } } -impl<'tcx> InferCtxt<'tcx> { - /// Trait queries just want to pass back the solver region constraints "as is", - /// mirroring `take_registered_region_obligations`. - pub fn take_solver_region_constraints(&self) -> RegionConstraint> { - assert!(!self.in_snapshot(), "cannot take solver region constraints in a snapshot"); - self.inner.borrow_mut().solver_region_constraint_storage.take().without_spans() - } -} - #[cfg(test)] mod tests; diff --git a/compiler/rustc_infer/src/infer/solver_region_constraints/tests.rs b/compiler/rustc_infer/src/infer/solver_region_constraints/tests.rs index 540aa5e4f8cb2..529ecf43f5ee1 100644 --- a/compiler/rustc_infer/src/infer/solver_region_constraints/tests.rs +++ b/compiler/rustc_infer/src/infer/solver_region_constraints/tests.rs @@ -1,29 +1,7 @@ -use rustc_middle::infer::canonical::QueryRegionConstraints; use rustc_middle::ty::TyCtxt; use rustc_span::{BytePos, Span}; use rustc_type_ir::region_constraint::{And, LeafRegionConstraint, Or}; -use super::{SolverRegionConstraint, SolverRegionConstraintStorage}; - -#[test] -fn true_constraint_keeps_query_response_empty() { - // Mirrors `register_solver_region_constraint`, which registers unconditionally: - // anding a trivially true constraint into an empty store has to leave the store - // trivially true, as the resulting query response would otherwise no longer be - // empty. This relies on `And`/`Or` being kept in canonical form. - let mut storage = SolverRegionConstraintStorage::<'static>::new(); - storage.overwrite(SolverRegionConstraint::build_and( - SolverRegionConstraint::new_true(), - storage.get_constraint(), - )); - - let constraints = QueryRegionConstraints { - solver_constraints: storage.get_constraint().without_spans(), - ..Default::default() - }; - assert!(constraints.is_empty()); -} - #[test] fn canonicalization_preserves_only_one_ambiguity() { let first = Span::with_root_ctxt(BytePos(1), BytePos(2)); diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index f99280bb744a1..46429f7adfb12 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -76,21 +76,13 @@ pub struct QueryResponse<'tcx, R> { pub value: R, } -#[derive(Clone, Debug, Default, PartialEq, Hash)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[derive(StableHash, TypeFoldable, TypeVisitable)] pub struct QueryRegionConstraints<'tcx> { pub constraints: Vec>, pub assumptions: Vec>, - /// Region constraints emitted by the next solver under - /// `-Zassumptions-on-binders`. - /// - /// These stay unspanned while passing through a canonical query. The type-op - /// caller attaches its origin span when consuming the response. - pub solver_constraints: ir::region_constraint::RegionConstraint>, } -impl Eq for QueryRegionConstraints<'_> {} - impl QueryRegionConstraints<'_> { /// Represents an empty (trivially true) set of region constraints. /// @@ -99,23 +91,8 @@ impl QueryRegionConstraints<'_> { /// discharge a requirement from another query, which is a potential problem if we did throw /// away these assumptions because there were no constraints. pub fn is_empty(&self) -> bool { - let QueryRegionConstraints { constraints, assumptions, solver_constraints } = self; - constraints.is_empty() && assumptions.is_empty() && solver_constraints.is_true() - } - - pub fn extend(&mut self, other: &Self) { - let QueryRegionConstraints { constraints, assumptions, solver_constraints } = self; - let QueryRegionConstraints { - constraints: other_constraints, - assumptions: other_assumptions, - solver_constraints: other_solver_constraints, - } = other; - constraints.extend(other_constraints.iter().cloned()); - assumptions.extend(other_assumptions.iter().cloned()); - *solver_constraints = ir::region_constraint::RegionConstraint::build_and( - std::mem::take(solver_constraints), - other_solver_constraints.clone(), - ); + let QueryRegionConstraints { constraints, assumptions } = self; + constraints.is_empty() && assumptions.is_empty() } } diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 60339b1982233..818d8e1a4e0c3 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -374,11 +374,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< region_obligations, region_constraints, region_assumptions, - // We're only called with `-Zassumptions-on-binders` disabled, in which - // case the solver never emits new-style region constraints. With it - // enabled the solver instead returns `ExternalRegionConstraints::NextGen`, - // reading the constraint straight out of the `InferCtxt`. - Default::default(), ) }); diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index bcb932f74b1f8..84cae1e7bfa0a 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -82,10 +82,7 @@ fn implied_outlives_bounds<'a, 'tcx>( // FIXME(higher_ranked_auto): Should we register assumptions here? // We otherwise would get spurious errors if normalizing an implied // outlives bound required proving some higher-ranked coroutine obl. - let QueryRegionConstraints { constraints, assumptions: _, solver_constraints } = - constraints; - infcx.register_solver_region_constraint(solver_constraints.with_spans(span)); - + let QueryRegionConstraints { constraints, assumptions: _ } = constraints; let cause = ObligationCause::misc(span, body_def_id); for &QueryRegionConstraint { constraint, visible_for_leak_check: vis, .. } in &constraints { match constraint { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index 39f439cad64d3..25385d15e36f4 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -60,8 +60,8 @@ impl fmt::Debug for CustomTypeOp { } } -/// Executes `op` and then scrapes out all resulting region constraints -/// in the `infcx`, creating query-region-constraints. +/// Executes `op` and then scrapes out all the "old style" region +/// constraints that result, creating query-region-constraints. pub fn scrape_region_constraints<'tcx, Op, R>( infcx: &InferCtxt<'tcx>, root_def_id: LocalDefId, @@ -88,11 +88,6 @@ where pre_assumptions.is_empty(), "scrape_region_constraints: incoming region assumptions = {pre_assumptions:#?}", ); - let pre_solver_constraints = infcx.take_solver_region_constraints(); - assert!( - pre_solver_constraints.is_true(), - "scrape_region_constraints: incoming solver constraints = {pre_solver_constraints:#?}", - ); let value = infcx.commit_if_ok(|_| { let ocx = ObligationCtxt::new(infcx); @@ -149,13 +144,11 @@ where let region_obligations = infcx.take_registered_region_obligations(); let region_assumptions = infcx.take_registered_region_assumptions(); - let solver_constraints = infcx.take_solver_region_constraints(); let region_constraint_data = infcx.take_and_reset_region_constraints(); let region_constraints = query_response::make_query_region_constraints( region_obligations, ®ion_constraint_data, region_assumptions, - solver_constraints, ); if region_constraints.is_empty() { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index ac516afbc783c..250579a2b064a 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -151,8 +151,9 @@ where Ok(output) })?; output.error_info = error_info; - if let Some(constraints) = output.constraints { - region_constraints.extend(constraints); + if let Some(QueryRegionConstraints { constraints, assumptions }) = output.constraints { + region_constraints.constraints.extend(constraints.iter().cloned()); + region_constraints.assumptions.extend(assumptions.iter().cloned()); } output.constraints = if region_constraints.is_empty() { None diff --git a/compiler/rustc_traits/src/coroutine_witnesses.rs b/compiler/rustc_traits/src/coroutine_witnesses.rs index b7ff4cca0bb1f..762471eefe4dd 100644 --- a/compiler/rustc_traits/src/coroutine_witnesses.rs +++ b/compiler/rustc_traits/src/coroutine_witnesses.rs @@ -84,10 +84,6 @@ fn compute_assumptions<'tcx>( region_obligations, ®ion_constraints, region_assumptions, - // We return early above unless the old solver is used globally, while - // `-Zassumptions-on-binders` enables the next solver globally. So there - // are never any new-style region constraints to pass along here. - Default::default(), ) .constraints .fold_with(&mut OpportunisticRegionResolver::new(&infcx)); diff --git a/tests/ui/assumptions_on_binders/alias_outlives.rs b/tests/ui/assumptions_on_binders/alias_outlives.rs index 9e1516132dd9d..0c2ed6585cf45 100644 --- a/tests/ui/assumptions_on_binders/alias_outlives.rs +++ b/tests/ui/assumptions_on_binders/alias_outlives.rs @@ -23,11 +23,11 @@ where } fn borrowck_env_fail<'a, T: AliasHaver>() +// FIXME: ^ this should raise an ERROR: unsatisfied lifetime constraint from -Zassumptions-on-binders where ::Assoc: 'a, { let _: ReqTrait; - //~^ ERROR: higher-ranked lifetime bound could not be satisfied } const REGIONCK_ENV_PASS<'a, T: AliasHaver>: ReqTrait = todo!() @@ -39,30 +39,4 @@ const REGIONCK_ENV_FAIL<'a, T: AliasHaver>: ReqTrait = todo!() where ::Assoc: 'a; -// Solver constraints produced while normalizing implied bounds must be returned -// to lexical regionck. -trait Project { - type Assoc; -} - -impl Project for (T,) -where - T::Assoc: for<'a> Trait<'a>, -{ - type Assoc = (); -} - -struct Normalizes(T) -where - T::Assoc: Clone; - -trait TestTrait {} - -impl<'a, T: AliasHaver> TestTrait for [Normalizes<(T,)>; 1] -//~^ ERROR: higher-ranked lifetime bound could not be satisfied -where - T::Assoc: 'a, -{ -} - fn main() {} diff --git a/tests/ui/assumptions_on_binders/alias_outlives.stderr b/tests/ui/assumptions_on_binders/alias_outlives.stderr index a6eaf3e11bad7..1787c1912ae4f 100644 --- a/tests/ui/assumptions_on_binders/alias_outlives.stderr +++ b/tests/ui/assumptions_on_binders/alias_outlives.stderr @@ -4,20 +4,5 @@ error: higher-ranked lifetime bound could not be satisfied LL | const REGIONCK_ENV_FAIL<'a, T: AliasHaver>: ReqTrait = todo!() | ^^^^^^^^^^^^^^^^^^ -error: higher-ranked lifetime bound could not be satisfied - --> $DIR/alias_outlives.rs:61:1 - | -LL | / impl<'a, T: AliasHaver> TestTrait for [Normalizes<(T,)>; 1] -LL | | -LL | | where -LL | | T::Assoc: 'a, - | |_________________^ - -error: higher-ranked lifetime bound could not be satisfied - --> $DIR/alias_outlives.rs:29:12 - | -LL | let _: ReqTrait; - | ^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error