From 028d29301f9cbd174f3e21652d1c20d58af132ce Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 18 Dec 2023 22:45:34 +0000 Subject: Deeply normalize when processing registered region obligations --- compiler/rustc_trait_selection/src/lib.rs | 1 + compiler/rustc_trait_selection/src/regions.rs | 37 ++++++++++++++++++++++ .../rustc_trait_selection/src/traits/auto_trait.rs | 2 +- .../rustc_trait_selection/src/traits/coherence.rs | 1 + .../rustc_trait_selection/src/traits/engine.rs | 1 + compiler/rustc_trait_selection/src/traits/misc.rs | 1 + compiler/rustc_trait_selection/src/traits/mod.rs | 1 + 7 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 compiler/rustc_trait_selection/src/regions.rs (limited to 'compiler/rustc_trait_selection') diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 995ed1e3b57..5ec45212bc7 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -39,6 +39,7 @@ extern crate smallvec; pub mod errors; pub mod infer; +pub mod regions; pub mod solve; pub mod traits; diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs new file mode 100644 index 00000000000..3c53da32d0a --- /dev/null +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -0,0 +1,37 @@ +use rustc_infer::infer::outlives::env::OutlivesEnvironment; +use rustc_infer::infer::{InferCtxt, RegionResolutionError}; +use rustc_middle::traits::ObligationCause; + +pub trait InferCtxtRegionExt<'tcx> { + /// Resolve regions, using the deep normalizer to normalize any type-outlives + /// obligations in the process. This is in `rustc_trait_selection` because + /// we need to normalize. + /// + /// Prefer this method over `resolve_regions_with_normalize`, unless you are + /// doing something specific for normalization. + fn resolve_regions( + &self, + outlives_env: &OutlivesEnvironment<'tcx>, + ) -> Vec>; +} + +impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> { + fn resolve_regions( + &self, + outlives_env: &OutlivesEnvironment<'tcx>, + ) -> Vec> { + self.resolve_regions(outlives_env, |ty| { + let ty = self.resolve_vars_if_possible(ty); + + if self.next_trait_solver() { + crate::solve::deeply_normalize( + self.at(&ObligationCause::dummy(), outlives_env.param_env), + ty, + ) + .map_err(|_| ty) + } else { + Ok(ty) + } + }) + } +} diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index c4344758574..87b68a8bd2d 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -179,7 +179,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { } let outlives_env = OutlivesEnvironment::new(full_env); - infcx.process_registered_region_obligations(&outlives_env); + let _ = infcx.process_registered_region_obligations::(&outlives_env, |ty| Ok(ty)); let region_data = infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone(); diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index ecbb92ca5b9..c49185a52c7 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -6,6 +6,7 @@ use crate::infer::outlives::env::OutlivesEnvironment; use crate::infer::InferOk; +use crate::regions::InferCtxtRegionExt; use crate::solve::inspect::{InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor}; use crate::solve::{deeply_normalize_for_diagnostics, inspect}; use crate::traits::engine::TraitEngineExt; diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 013a50f9fa1..caf950037fd 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -3,6 +3,7 @@ use std::fmt::Debug; use super::FulfillmentContext; use super::TraitEngine; +use crate::regions::InferCtxtRegionExt; use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt; use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::NormalizeExt; diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 0cd376fcbbd..93f9c2333f0 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -1,5 +1,6 @@ //! Miscellaneous type-system utilities that are too small to deserve their own modules. +use crate::regions::InferCtxtRegionExt; use crate::traits::{self, ObligationCause, ObligationCtxt}; use hir::LangItem; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 080ad7bd549..a7f6021d57a 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -25,6 +25,7 @@ pub mod wf; use crate::infer::outlives::env::OutlivesEnvironment; use crate::infer::{InferCtxt, TyCtxtInferExt}; +use crate::regions::InferCtxtRegionExt; use crate::traits::error_reporting::TypeErrCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorGuaranteed; -- cgit 1.4.1-3-g733a5 From 720d7a7a03b9997644fe28a12a80a910b2652760 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 26 Jan 2024 19:18:14 +0000 Subject: Apply suggestions from review --- .../src/type_check/constraint_conversion.rs | 15 +++++++----- .../src/type_check/free_region_relations.rs | 10 ++++++-- compiler/rustc_borrowck/src/type_check/mod.rs | 13 +++++++++-- compiler/rustc_hir_analysis/src/check/dropck.rs | 2 +- compiler/rustc_infer/src/infer/outlives/mod.rs | 8 +++---- .../rustc_infer/src/infer/outlives/obligations.rs | 23 ++++++++++-------- compiler/rustc_infer/src/infer/outlives/verify.rs | 27 ++++------------------ compiler/rustc_trait_selection/src/regions.rs | 7 ++++-- .../rustc_trait_selection/src/traits/auto_trait.rs | 2 +- .../next-solver/unsound-region-obligation.rs | 13 +++++++++++ .../next-solver/unsound-region-obligation.stderr | 7 ++++++ 11 files changed, 77 insertions(+), 50 deletions(-) create mode 100644 tests/ui/traits/next-solver/unsound-region-obligation.rs create mode 100644 tests/ui/traits/next-solver/unsound-region-obligation.stderr (limited to 'compiler/rustc_trait_selection') diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 02ef7357d66..52559f9039b 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -33,7 +33,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> { /// our special inference variable there, we would mess that up. region_bound_pairs: &'a RegionBoundPairs<'tcx>, implicit_region_bound: ty::Region<'tcx>, - param_env: ty::ParamEnv<'tcx>, + known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], locations: Locations, span: Span, category: ConstraintCategory<'tcx>, @@ -47,7 +47,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { universal_regions: &'a UniversalRegions<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>, implicit_region_bound: ty::Region<'tcx>, - param_env: ty::ParamEnv<'tcx>, + known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], locations: Locations, span: Span, category: ConstraintCategory<'tcx>, @@ -59,7 +59,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { universal_regions, region_bound_pairs, implicit_region_bound, - param_env, + known_type_outlives_obligations, locations, span, category, @@ -136,7 +136,11 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { // Extract out various useful fields we'll need below. let ConstraintConversion { - tcx, region_bound_pairs, implicit_region_bound, param_env, .. + tcx, + region_bound_pairs, + implicit_region_bound, + known_type_outlives_obligations, + .. } = *self; let ty::OutlivesPredicate(k1, r2) = predicate; @@ -157,8 +161,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { tcx, region_bound_pairs, Some(implicit_region_bound), - // FIXME(-Znext-solver): These bounds are not normalized! - param_env.caller_bounds(), + known_type_outlives_obligations, ) .type_must_outlive(origin, t1, r2, constraint_category); } diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 011b5b760c2..d518f54fd25 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -45,12 +45,14 @@ type NormalizedInputsAndOutput<'tcx> = Vec>; pub(crate) struct CreateResult<'tcx> { pub(crate) universal_region_relations: Frozen>, pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>, + pub(crate) known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>, } pub(crate) fn create<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, + known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], implicit_region_bound: ty::Region<'tcx>, universal_regions: &Rc>, constraints: &mut MirTypeckRegionConstraints<'tcx>, @@ -58,6 +60,7 @@ pub(crate) fn create<'tcx>( UniversalRegionRelationsBuilder { infcx, param_env, + known_type_outlives_obligations, implicit_region_bound, constraints, universal_regions: universal_regions.clone(), @@ -175,6 +178,7 @@ impl UniversalRegionRelations<'_> { struct UniversalRegionRelationsBuilder<'this, 'tcx> { infcx: &'this InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, + known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], universal_regions: Rc>, implicit_region_bound: ty::Region<'tcx>, constraints: &'this mut MirTypeckRegionConstraints<'tcx>, @@ -200,7 +204,8 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { let defining_ty_def_id = self.universal_regions.defining_ty.def_id().expect_local(); let span = tcx.def_span(defining_ty_def_id); - // Insert the facts we know from the predicates. Why? Why not. + // Insert the `'a: 'b` we know from the predicates. + // This does not consider the type-outlives. let param_env = self.param_env; self.add_outlives_bounds(outlives::explicit_outlives_bounds(param_env)); @@ -308,6 +313,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { outlives: self.outlives.freeze(), inverse_outlives: self.inverse_outlives.freeze(), }), + known_type_outlives_obligations: self.known_type_outlives_obligations, region_bound_pairs: self.region_bound_pairs, normalized_inputs_and_output, } @@ -322,7 +328,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { &self.universal_regions, &self.region_bound_pairs, self.implicit_region_bound, - self.param_env, + self.known_type_outlives_obligations, Locations::All(span), span, ConstraintCategory::Internal, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 488dfc64cf6..59c4d9a6c78 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -152,9 +152,14 @@ pub(crate) fn type_check<'mir, 'tcx>( universal_region_relations, region_bound_pairs, normalized_inputs_and_output, + known_type_outlives_obligations, } = free_region_relations::create( infcx, param_env, + // FIXME(-Znext-solver): These are unnormalized. Normalize them. + infcx.tcx.arena.alloc_from_iter( + param_env.caller_bounds().iter().filter_map(|clause| clause.as_type_outlives_clause()), + ), implicit_region_bound, universal_regions, &mut constraints, @@ -176,6 +181,7 @@ pub(crate) fn type_check<'mir, 'tcx>( body, param_env, ®ion_bound_pairs, + known_type_outlives_obligations, implicit_region_bound, &mut borrowck_context, ); @@ -850,6 +856,7 @@ struct TypeChecker<'a, 'tcx> { /// all of the promoted items. user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>, + known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], implicit_region_bound: ty::Region<'tcx>, reported_errors: FxIndexSet<(Ty<'tcx>, Span)>, borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, @@ -1000,6 +1007,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { body: &'a Body<'tcx>, param_env: ty::ParamEnv<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>, + known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], implicit_region_bound: ty::Region<'tcx>, borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, ) -> Self { @@ -1010,6 +1018,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { user_type_annotations: &body.user_type_annotations, param_env, region_bound_pairs, + known_type_outlives_obligations, implicit_region_bound, borrowck_context, reported_errors: Default::default(), @@ -1127,7 +1136,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.borrowck_context.universal_regions, self.region_bound_pairs, self.implicit_region_bound, - self.param_env, + self.known_type_outlives_obligations, locations, locations.span(self.body), category, @@ -2731,7 +2740,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.borrowck_context.universal_regions, self.region_bound_pairs, self.implicit_region_bound, - self.param_env, + self.known_type_outlives_obligations, locations, DUMMY_SP, // irrelevant; will be overridden. ConstraintCategory::Boring, // same as above. diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 3d2d667763a..7b60457affa 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -189,7 +189,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( RegionResolutionError::UpperBoundUniverseConflict(a, _, _, _, b) => { format!("{b}: {a}", a = ty::Region::new_var(tcx, a)) } - RegionResolutionError::CannotNormalize(..) => todo!(), + RegionResolutionError::CannotNormalize(..) => unreachable!(), }; guar = Some( struct_span_code_err!( diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 97ab2f32c40..926e198b219 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -1,7 +1,7 @@ //! Various code related to computing outlives relations. use self::env::OutlivesEnvironment; use super::region_constraints::RegionConstraintData; -use super::{InferCtxt, RegionResolutionError}; +use super::{InferCtxt, RegionResolutionError, SubregionOrigin}; use crate::infer::free_regions::RegionRelations; use crate::infer::lexical_region_resolve; use rustc_middle::traits::query::OutlivesBound; @@ -42,14 +42,14 @@ impl<'tcx> InferCtxt<'tcx> { /// done -- or the compiler will panic -- but it is legal to use /// `resolve_vars_if_possible` as well as `fully_resolve`. /// - /// If you are in a crate that has access to `rustc_trai_selection`, - /// then it's probably better to use `resolve_regions_normalizing_outlives_obligations`, + /// If you are in a crate that has access to `rustc_trait_selection`, + /// then it's probably better to use `resolve_regions`, /// which knows how to normalize registered region obligations. #[must_use] pub fn resolve_regions_with_normalize( &self, outlives_env: &OutlivesEnvironment<'tcx>, - deeply_normalize_ty: impl Fn(Ty<'tcx>) -> Result, Ty<'tcx>>, + deeply_normalize_ty: impl Fn(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result, Ty<'tcx>>, ) -> Vec> { match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) { Ok(()) => {} diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index bc66522a8b6..b10bf98e8b5 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -68,8 +68,8 @@ use crate::infer::{ use crate::traits::{ObligationCause, ObligationCauseCode}; use rustc_data_structures::undo_log::UndoLogs; use rustc_middle::mir::ConstraintCategory; +use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt}; -use rustc_middle::ty::{GenericArgKind, ToPredicate}; use rustc_span::DUMMY_SP; use smallvec::smallvec; @@ -128,7 +128,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn process_registered_region_obligations( &self, outlives_env: &OutlivesEnvironment<'tcx>, - mut deeply_normalize_ty: impl FnMut(Ty<'tcx>) -> Result, E>, + mut deeply_normalize_ty: impl FnMut(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result, E>, ) -> Result<(), (E, SubregionOrigin<'tcx>)> { assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot"); @@ -141,20 +141,23 @@ impl<'tcx> InferCtxt<'tcx> { let ty::ClauseKind::TypeOutlives(outlives) = bound_clause.skip_binder() else { return None; }; - Some(deeply_normalize_ty(outlives.0).map(|ty| { - bound_clause - .rebind(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, outlives.1))) - .to_predicate(self.tcx) - })) + Some( + deeply_normalize_ty( + outlives.0, + SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP), + ) + .map(|ty| bound_clause.rebind(ty::OutlivesPredicate(ty, outlives.1))), + ) }) - // FIXME: How do we accurately report an error here :( + // FIXME(-Znext-solver): How do we accurately report an error here :( .try_collect() .map_err(|e| (e, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP)))?; let my_region_obligations = self.take_registered_region_obligations(); for RegionObligation { sup_type, sub_region, origin } in my_region_obligations { - let sup_type = deeply_normalize_ty(sup_type).map_err(|e| (e, origin.clone()))?; + let sup_type = + deeply_normalize_ty(sup_type, origin.clone()).map_err(|e| (e, origin.clone()))?; debug!(?sup_type, ?sub_region, ?origin); let outlives = &mut TypeOutlives::new( @@ -216,7 +219,7 @@ where tcx: TyCtxt<'tcx>, region_bound_pairs: &'cx RegionBoundPairs<'tcx>, implicit_region_bound: Option>, - caller_bounds: &'cx [ty::Clause<'tcx>], + caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>], ) -> Self { Self { delegate, diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 2ad8b6b98e3..5d2f51c689b 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -23,7 +23,7 @@ pub struct VerifyBoundCx<'cx, 'tcx> { /// Outside of borrowck the only way to prove `T: '?0` is by /// setting `'?0` to `'empty`. implicit_region_bound: Option>, - caller_bounds: &'cx [ty::Clause<'tcx>], + caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>], } impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { @@ -31,7 +31,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { tcx: TyCtxt<'tcx>, region_bound_pairs: &'cx RegionBoundPairs<'tcx>, implicit_region_bound: Option>, - caller_bounds: &'cx [ty::Clause<'tcx>], + caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>], ) -> Self { Self { tcx, region_bound_pairs, implicit_region_bound, caller_bounds } } @@ -219,8 +219,9 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // To start, collect bounds from user environment. Note that // parameter environments are already elaborated, so we don't // have to worry about that. - let param_bounds = - self.collect_outlives_from_clause_list(erased_ty, self.caller_bounds.iter().copied()); + let param_bounds = self.caller_bounds.iter().copied().filter(move |outlives_predicate| { + super::test_type_match::can_match_erased_ty(tcx, *outlives_predicate, erased_ty) + }); // Next, collect regions we scraped from the well-formedness // constraints in the fn signature. To do that, we walk the list @@ -307,22 +308,4 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { .filter_map(|p| p.no_bound_vars()) .map(|OutlivesPredicate(_, r)| r) } - - /// Searches through a predicate list for a predicate `T: 'a`. - /// - /// Careful: does not elaborate predicates, and just uses `==` - /// when comparing `ty` for equality, so `ty` must be something - /// that does not involve inference variables and where you - /// otherwise want a precise match. - fn collect_outlives_from_clause_list( - &self, - erased_ty: Ty<'tcx>, - clauses: impl Iterator>, - ) -> impl Iterator, ty::Region<'tcx>>>> - { - let tcx = self.tcx; - clauses.filter_map(|p| p.as_type_outlives_clause()).filter(move |outlives_predicate| { - super::test_type_match::can_match_erased_ty(tcx, *outlives_predicate, erased_ty) - }) - } } diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs index 3c53da32d0a..e8929f114e1 100644 --- a/compiler/rustc_trait_selection/src/regions.rs +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -20,12 +20,15 @@ impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> { &self, outlives_env: &OutlivesEnvironment<'tcx>, ) -> Vec> { - self.resolve_regions(outlives_env, |ty| { + self.resolve_regions_with_normalize(outlives_env, |ty, origin| { let ty = self.resolve_vars_if_possible(ty); if self.next_trait_solver() { crate::solve::deeply_normalize( - self.at(&ObligationCause::dummy(), outlives_env.param_env), + self.at( + &ObligationCause::dummy_with_span(origin.span()), + outlives_env.param_env, + ), ty, ) .map_err(|_| ty) diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 87b68a8bd2d..b258007787d 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -179,7 +179,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { } let outlives_env = OutlivesEnvironment::new(full_env); - let _ = infcx.process_registered_region_obligations::(&outlives_env, |ty| Ok(ty)); + let _ = infcx.process_registered_region_obligations::(&outlives_env, |ty, _| Ok(ty)); let region_data = infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone(); diff --git a/tests/ui/traits/next-solver/unsound-region-obligation.rs b/tests/ui/traits/next-solver/unsound-region-obligation.rs new file mode 100644 index 00000000000..b8bfa035388 --- /dev/null +++ b/tests/ui/traits/next-solver/unsound-region-obligation.rs @@ -0,0 +1,13 @@ +//~ ERROR the type `<() as StaticTy>::Item<'a>` does not fulfill the required lifetime +// compile-flags: -Znext-solver +// Regression test for rust-lang/trait-system-refactor-initiative#59 + +trait StaticTy { + type Item<'a>: 'static; +} + +impl StaticTy for () { + type Item<'a> = &'a (); +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/unsound-region-obligation.stderr b/tests/ui/traits/next-solver/unsound-region-obligation.stderr new file mode 100644 index 00000000000..518de7ea3e0 --- /dev/null +++ b/tests/ui/traits/next-solver/unsound-region-obligation.stderr @@ -0,0 +1,7 @@ +error[E0477]: the type `<() as StaticTy>::Item<'a>` does not fulfill the required lifetime + | + = note: type must satisfy the static lifetime + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0477`. -- cgit 1.4.1-3-g733a5