Skip to content

Commit 720d7a7

Browse files
Apply suggestions from review
1 parent dc050f6 commit 720d7a7

File tree

11 files changed

+77
-50
lines changed

11 files changed

+77
-50
lines changed

compiler/rustc_borrowck/src/type_check/constraint_conversion.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
3333
/// our special inference variable there, we would mess that up.
3434
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
3535
implicit_region_bound: ty::Region<'tcx>,
36-
param_env: ty::ParamEnv<'tcx>,
36+
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
3737
locations: Locations,
3838
span: Span,
3939
category: ConstraintCategory<'tcx>,
@@ -47,7 +47,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
4747
universal_regions: &'a UniversalRegions<'tcx>,
4848
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
4949
implicit_region_bound: ty::Region<'tcx>,
50-
param_env: ty::ParamEnv<'tcx>,
50+
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
5151
locations: Locations,
5252
span: Span,
5353
category: ConstraintCategory<'tcx>,
@@ -59,7 +59,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
5959
universal_regions,
6060
region_bound_pairs,
6161
implicit_region_bound,
62-
param_env,
62+
known_type_outlives_obligations,
6363
locations,
6464
span,
6565
category,
@@ -136,7 +136,11 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
136136

137137
// Extract out various useful fields we'll need below.
138138
let ConstraintConversion {
139-
tcx, region_bound_pairs, implicit_region_bound, param_env, ..
139+
tcx,
140+
region_bound_pairs,
141+
implicit_region_bound,
142+
known_type_outlives_obligations,
143+
..
140144
} = *self;
141145

142146
let ty::OutlivesPredicate(k1, r2) = predicate;
@@ -157,8 +161,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
157161
tcx,
158162
region_bound_pairs,
159163
Some(implicit_region_bound),
160-
// FIXME(-Znext-solver): These bounds are not normalized!
161-
param_env.caller_bounds(),
164+
known_type_outlives_obligations,
162165
)
163166
.type_must_outlive(origin, t1, r2, constraint_category);
164167
}

compiler/rustc_borrowck/src/type_check/free_region_relations.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,22 @@ type NormalizedInputsAndOutput<'tcx> = Vec<Ty<'tcx>>;
4545
pub(crate) struct CreateResult<'tcx> {
4646
pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
4747
pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>,
48+
pub(crate) known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
4849
pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
4950
}
5051

5152
pub(crate) fn create<'tcx>(
5253
infcx: &InferCtxt<'tcx>,
5354
param_env: ty::ParamEnv<'tcx>,
55+
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
5456
implicit_region_bound: ty::Region<'tcx>,
5557
universal_regions: &Rc<UniversalRegions<'tcx>>,
5658
constraints: &mut MirTypeckRegionConstraints<'tcx>,
5759
) -> CreateResult<'tcx> {
5860
UniversalRegionRelationsBuilder {
5961
infcx,
6062
param_env,
63+
known_type_outlives_obligations,
6164
implicit_region_bound,
6265
constraints,
6366
universal_regions: universal_regions.clone(),
@@ -175,6 +178,7 @@ impl UniversalRegionRelations<'_> {
175178
struct UniversalRegionRelationsBuilder<'this, 'tcx> {
176179
infcx: &'this InferCtxt<'tcx>,
177180
param_env: ty::ParamEnv<'tcx>,
181+
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
178182
universal_regions: Rc<UniversalRegions<'tcx>>,
179183
implicit_region_bound: ty::Region<'tcx>,
180184
constraints: &'this mut MirTypeckRegionConstraints<'tcx>,
@@ -200,7 +204,8 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
200204
let defining_ty_def_id = self.universal_regions.defining_ty.def_id().expect_local();
201205
let span = tcx.def_span(defining_ty_def_id);
202206

203-
// Insert the facts we know from the predicates. Why? Why not.
207+
// Insert the `'a: 'b` we know from the predicates.
208+
// This does not consider the type-outlives.
204209
let param_env = self.param_env;
205210
self.add_outlives_bounds(outlives::explicit_outlives_bounds(param_env));
206211

@@ -308,6 +313,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
308313
outlives: self.outlives.freeze(),
309314
inverse_outlives: self.inverse_outlives.freeze(),
310315
}),
316+
known_type_outlives_obligations: self.known_type_outlives_obligations,
311317
region_bound_pairs: self.region_bound_pairs,
312318
normalized_inputs_and_output,
313319
}
@@ -322,7 +328,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
322328
&self.universal_regions,
323329
&self.region_bound_pairs,
324330
self.implicit_region_bound,
325-
self.param_env,
331+
self.known_type_outlives_obligations,
326332
Locations::All(span),
327333
span,
328334
ConstraintCategory::Internal,

compiler/rustc_borrowck/src/type_check/mod.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,14 @@ pub(crate) fn type_check<'mir, 'tcx>(
152152
universal_region_relations,
153153
region_bound_pairs,
154154
normalized_inputs_and_output,
155+
known_type_outlives_obligations,
155156
} = free_region_relations::create(
156157
infcx,
157158
param_env,
159+
// FIXME(-Znext-solver): These are unnormalized. Normalize them.
160+
infcx.tcx.arena.alloc_from_iter(
161+
param_env.caller_bounds().iter().filter_map(|clause| clause.as_type_outlives_clause()),
162+
),
158163
implicit_region_bound,
159164
universal_regions,
160165
&mut constraints,
@@ -176,6 +181,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
176181
body,
177182
param_env,
178183
&region_bound_pairs,
184+
known_type_outlives_obligations,
179185
implicit_region_bound,
180186
&mut borrowck_context,
181187
);
@@ -850,6 +856,7 @@ struct TypeChecker<'a, 'tcx> {
850856
/// all of the promoted items.
851857
user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
852858
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
859+
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
853860
implicit_region_bound: ty::Region<'tcx>,
854861
reported_errors: FxIndexSet<(Ty<'tcx>, Span)>,
855862
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
@@ -1000,6 +1007,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10001007
body: &'a Body<'tcx>,
10011008
param_env: ty::ParamEnv<'tcx>,
10021009
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
1010+
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
10031011
implicit_region_bound: ty::Region<'tcx>,
10041012
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
10051013
) -> Self {
@@ -1010,6 +1018,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10101018
user_type_annotations: &body.user_type_annotations,
10111019
param_env,
10121020
region_bound_pairs,
1021+
known_type_outlives_obligations,
10131022
implicit_region_bound,
10141023
borrowck_context,
10151024
reported_errors: Default::default(),
@@ -1127,7 +1136,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
11271136
self.borrowck_context.universal_regions,
11281137
self.region_bound_pairs,
11291138
self.implicit_region_bound,
1130-
self.param_env,
1139+
self.known_type_outlives_obligations,
11311140
locations,
11321141
locations.span(self.body),
11331142
category,
@@ -2731,7 +2740,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
27312740
self.borrowck_context.universal_regions,
27322741
self.region_bound_pairs,
27332742
self.implicit_region_bound,
2734-
self.param_env,
2743+
self.known_type_outlives_obligations,
27352744
locations,
27362745
DUMMY_SP, // irrelevant; will be overridden.
27372746
ConstraintCategory::Boring, // same as above.

compiler/rustc_hir_analysis/src/check/dropck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
189189
RegionResolutionError::UpperBoundUniverseConflict(a, _, _, _, b) => {
190190
format!("{b}: {a}", a = ty::Region::new_var(tcx, a))
191191
}
192-
RegionResolutionError::CannotNormalize(..) => todo!(),
192+
RegionResolutionError::CannotNormalize(..) => unreachable!(),
193193
};
194194
guar = Some(
195195
struct_span_code_err!(

compiler/rustc_infer/src/infer/outlives/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Various code related to computing outlives relations.
22
use self::env::OutlivesEnvironment;
33
use super::region_constraints::RegionConstraintData;
4-
use super::{InferCtxt, RegionResolutionError};
4+
use super::{InferCtxt, RegionResolutionError, SubregionOrigin};
55
use crate::infer::free_regions::RegionRelations;
66
use crate::infer::lexical_region_resolve;
77
use rustc_middle::traits::query::OutlivesBound;
@@ -42,14 +42,14 @@ impl<'tcx> InferCtxt<'tcx> {
4242
/// done -- or the compiler will panic -- but it is legal to use
4343
/// `resolve_vars_if_possible` as well as `fully_resolve`.
4444
///
45-
/// If you are in a crate that has access to `rustc_trai_selection`,
46-
/// then it's probably better to use `resolve_regions_normalizing_outlives_obligations`,
45+
/// If you are in a crate that has access to `rustc_trait_selection`,
46+
/// then it's probably better to use `resolve_regions`,
4747
/// which knows how to normalize registered region obligations.
4848
#[must_use]
4949
pub fn resolve_regions_with_normalize(
5050
&self,
5151
outlives_env: &OutlivesEnvironment<'tcx>,
52-
deeply_normalize_ty: impl Fn(Ty<'tcx>) -> Result<Ty<'tcx>, Ty<'tcx>>,
52+
deeply_normalize_ty: impl Fn(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, Ty<'tcx>>,
5353
) -> Vec<RegionResolutionError<'tcx>> {
5454
match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) {
5555
Ok(()) => {}

compiler/rustc_infer/src/infer/outlives/obligations.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ use crate::infer::{
6868
use crate::traits::{ObligationCause, ObligationCauseCode};
6969
use rustc_data_structures::undo_log::UndoLogs;
7070
use rustc_middle::mir::ConstraintCategory;
71+
use rustc_middle::ty::GenericArgKind;
7172
use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt};
72-
use rustc_middle::ty::{GenericArgKind, ToPredicate};
7373
use rustc_span::DUMMY_SP;
7474
use smallvec::smallvec;
7575

@@ -128,7 +128,7 @@ impl<'tcx> InferCtxt<'tcx> {
128128
pub fn process_registered_region_obligations<E>(
129129
&self,
130130
outlives_env: &OutlivesEnvironment<'tcx>,
131-
mut deeply_normalize_ty: impl FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>,
131+
mut deeply_normalize_ty: impl FnMut(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, E>,
132132
) -> Result<(), (E, SubregionOrigin<'tcx>)> {
133133
assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot");
134134

@@ -141,20 +141,23 @@ impl<'tcx> InferCtxt<'tcx> {
141141
let ty::ClauseKind::TypeOutlives(outlives) = bound_clause.skip_binder() else {
142142
return None;
143143
};
144-
Some(deeply_normalize_ty(outlives.0).map(|ty| {
145-
bound_clause
146-
.rebind(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, outlives.1)))
147-
.to_predicate(self.tcx)
148-
}))
144+
Some(
145+
deeply_normalize_ty(
146+
outlives.0,
147+
SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP),
148+
)
149+
.map(|ty| bound_clause.rebind(ty::OutlivesPredicate(ty, outlives.1))),
150+
)
149151
})
150-
// FIXME: How do we accurately report an error here :(
152+
// FIXME(-Znext-solver): How do we accurately report an error here :(
151153
.try_collect()
152154
.map_err(|e| (e, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP)))?;
153155

154156
let my_region_obligations = self.take_registered_region_obligations();
155157

156158
for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
157-
let sup_type = deeply_normalize_ty(sup_type).map_err(|e| (e, origin.clone()))?;
159+
let sup_type =
160+
deeply_normalize_ty(sup_type, origin.clone()).map_err(|e| (e, origin.clone()))?;
158161
debug!(?sup_type, ?sub_region, ?origin);
159162

160163
let outlives = &mut TypeOutlives::new(
@@ -216,7 +219,7 @@ where
216219
tcx: TyCtxt<'tcx>,
217220
region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
218221
implicit_region_bound: Option<ty::Region<'tcx>>,
219-
caller_bounds: &'cx [ty::Clause<'tcx>],
222+
caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>],
220223
) -> Self {
221224
Self {
222225
delegate,

compiler/rustc_infer/src/infer/outlives/verify.rs

+5-22
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ pub struct VerifyBoundCx<'cx, 'tcx> {
2323
/// Outside of borrowck the only way to prove `T: '?0` is by
2424
/// setting `'?0` to `'empty`.
2525
implicit_region_bound: Option<ty::Region<'tcx>>,
26-
caller_bounds: &'cx [ty::Clause<'tcx>],
26+
caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>],
2727
}
2828

2929
impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
3030
pub fn new(
3131
tcx: TyCtxt<'tcx>,
3232
region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
3333
implicit_region_bound: Option<ty::Region<'tcx>>,
34-
caller_bounds: &'cx [ty::Clause<'tcx>],
34+
caller_bounds: &'cx [ty::PolyTypeOutlivesPredicate<'tcx>],
3535
) -> Self {
3636
Self { tcx, region_bound_pairs, implicit_region_bound, caller_bounds }
3737
}
@@ -219,8 +219,9 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
219219
// To start, collect bounds from user environment. Note that
220220
// parameter environments are already elaborated, so we don't
221221
// have to worry about that.
222-
let param_bounds =
223-
self.collect_outlives_from_clause_list(erased_ty, self.caller_bounds.iter().copied());
222+
let param_bounds = self.caller_bounds.iter().copied().filter(move |outlives_predicate| {
223+
super::test_type_match::can_match_erased_ty(tcx, *outlives_predicate, erased_ty)
224+
});
224225

225226
// Next, collect regions we scraped from the well-formedness
226227
// constraints in the fn signature. To do that, we walk the list
@@ -307,22 +308,4 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
307308
.filter_map(|p| p.no_bound_vars())
308309
.map(|OutlivesPredicate(_, r)| r)
309310
}
310-
311-
/// Searches through a predicate list for a predicate `T: 'a`.
312-
///
313-
/// Careful: does not elaborate predicates, and just uses `==`
314-
/// when comparing `ty` for equality, so `ty` must be something
315-
/// that does not involve inference variables and where you
316-
/// otherwise want a precise match.
317-
fn collect_outlives_from_clause_list(
318-
&self,
319-
erased_ty: Ty<'tcx>,
320-
clauses: impl Iterator<Item = ty::Clause<'tcx>>,
321-
) -> impl Iterator<Item = ty::Binder<'tcx, ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>>
322-
{
323-
let tcx = self.tcx;
324-
clauses.filter_map(|p| p.as_type_outlives_clause()).filter(move |outlives_predicate| {
325-
super::test_type_match::can_match_erased_ty(tcx, *outlives_predicate, erased_ty)
326-
})
327-
}
328311
}

compiler/rustc_trait_selection/src/regions.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,15 @@ impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> {
2020
&self,
2121
outlives_env: &OutlivesEnvironment<'tcx>,
2222
) -> Vec<RegionResolutionError<'tcx>> {
23-
self.resolve_regions(outlives_env, |ty| {
23+
self.resolve_regions_with_normalize(outlives_env, |ty, origin| {
2424
let ty = self.resolve_vars_if_possible(ty);
2525

2626
if self.next_trait_solver() {
2727
crate::solve::deeply_normalize(
28-
self.at(&ObligationCause::dummy(), outlives_env.param_env),
28+
self.at(
29+
&ObligationCause::dummy_with_span(origin.span()),
30+
outlives_env.param_env,
31+
),
2932
ty,
3033
)
3134
.map_err(|_| ty)

compiler/rustc_trait_selection/src/traits/auto_trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
179179
}
180180

181181
let outlives_env = OutlivesEnvironment::new(full_env);
182-
let _ = infcx.process_registered_region_obligations::<!>(&outlives_env, |ty| Ok(ty));
182+
let _ = infcx.process_registered_region_obligations::<!>(&outlives_env, |ty, _| Ok(ty));
183183

184184
let region_data =
185185
infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//~ ERROR the type `<() as StaticTy>::Item<'a>` does not fulfill the required lifetime
2+
// compile-flags: -Znext-solver
3+
// Regression test for rust-lang/trait-system-refactor-initiative#59
4+
5+
trait StaticTy {
6+
type Item<'a>: 'static;
7+
}
8+
9+
impl StaticTy for () {
10+
type Item<'a> = &'a ();
11+
}
12+
13+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
error[E0477]: the type `<() as StaticTy>::Item<'a>` does not fulfill the required lifetime
2+
|
3+
= note: type must satisfy the static lifetime
4+
5+
error: aborting due to 1 previous error
6+
7+
For more information about this error, try `rustc --explain E0477`.

0 commit comments

Comments
 (0)