mirror of https://github.com/rust-lang/rust.git
Apply suggestions from review
This commit is contained in:
parent
dc050f6d5b
commit
720d7a7a03
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -45,12 +45,14 @@ type NormalizedInputsAndOutput<'tcx> = Vec<Ty<'tcx>>;
|
|||
pub(crate) struct CreateResult<'tcx> {
|
||||
pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
|
||||
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<UniversalRegions<'tcx>>,
|
||||
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<UniversalRegions<'tcx>>,
|
||||
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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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>, Ty<'tcx>>,
|
||||
deeply_normalize_ty: impl Fn(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, Ty<'tcx>>,
|
||||
) -> Vec<RegionResolutionError<'tcx>> {
|
||||
match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) {
|
||||
Ok(()) => {}
|
||||
|
|
|
@ -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<E>(
|
||||
&self,
|
||||
outlives_env: &OutlivesEnvironment<'tcx>,
|
||||
mut deeply_normalize_ty: impl FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
|
||||
mut deeply_normalize_ty: impl FnMut(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, 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<ty::Region<'tcx>>,
|
||||
caller_bounds: &'cx [ty::Clause<'tcx>],
|
||||
caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>],
|
||||
) -> Self {
|
||||
Self {
|
||||
delegate,
|
||||
|
|
|
@ -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<ty::Region<'tcx>>,
|
||||
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<ty::Region<'tcx>>,
|
||||
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<Item = ty::Clause<'tcx>>,
|
||||
) -> impl Iterator<Item = ty::Binder<'tcx, ty::OutlivesPredicate<Ty<'tcx>, 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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,12 +20,15 @@ impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> {
|
|||
&self,
|
||||
outlives_env: &OutlivesEnvironment<'tcx>,
|
||||
) -> Vec<RegionResolutionError<'tcx>> {
|
||||
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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() {}
|
|
@ -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`.
|
Loading…
Reference in New Issue