Skip to content

Commit 46ad825

Browse files
committed
Auto merge of #159649 - adwinwhite:norm-before-regionck, r=<try>
Normalize region obligations before regionck
2 parents b803f36 + f5b6af2 commit 46ad825

17 files changed

Lines changed: 233 additions & 314 deletions

File tree

compiler/rustc_borrowck/src/type_check/constraint_conversion.rs

Lines changed: 33 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,11 @@ use rustc_infer::infer::canonical::{QueryRegionConstraint, QueryRegionConstraint
55
use rustc_infer::infer::outlives::env::RegionBoundPairs;
66
use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
77
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
8-
use rustc_infer::traits::query::type_op::Normalize;
9-
use rustc_middle::bug;
108
use rustc_middle::ty::{
11-
self, GenericArgKind, RegionExt, RegionUtilitiesExt, Ty, TyCtxt, TypeFoldable,
12-
TypeVisitableExt, elaborate, fold_regions,
9+
self, GenericArgKind, RegionExt, RegionUtilitiesExt, TyCtxt, TypeFoldable, TypeVisitableExt,
10+
elaborate, fold_regions,
1311
};
1412
use rustc_span::Span;
15-
use rustc_trait_selection::traits::query::type_op::TypeOpOutput;
1613
use tracing::{debug, instrument};
1714

1815
use crate::constraints::OutlivesConstraint;
@@ -137,83 +134,49 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
137134

138135
// Extract out various useful fields we'll need below.
139136
let ConstraintConversion {
140-
infcx,
137+
infcx: _,
141138
universal_regions,
142139
region_bound_pairs,
143140
known_type_outlives_obligations,
144141
..
145142
} = *self;
146143

147-
let mut outlives_predicates = vec![(predicate, constraint_category)];
148-
for iteration in 0.. {
149-
if outlives_predicates.is_empty() {
150-
break;
151-
}
144+
let pred = predicate;
145+
// Constraint is implied by a coroutine's well-formedness.
146+
if self.infcx.tcx.sess.opts.unstable_opts.higher_ranked_assumptions
147+
&& higher_ranked_assumptions.contains(&pred)
148+
{
149+
return;
150+
}
152151

153-
if !tcx.recursion_limit().value_within_limit(iteration) {
154-
// This may actually be reachable. If so, we should convert
155-
// this to a proper error/consider whether we should detect
156-
// this somewhere else.
157-
bug!(
158-
"unexpected overflowed when processing region obligations: {outlives_predicates:#?}"
159-
);
152+
let ty::OutlivesPredicate(k1, r2) = pred;
153+
match k1.kind() {
154+
GenericArgKind::Lifetime(r1) => {
155+
let r1_vid = self.to_region_vid(r1);
156+
let r2_vid = self.to_region_vid(r2);
157+
self.add_outlives(r1_vid, r2_vid, constraint_category);
160158
}
161159

162-
let mut next_outlives_predicates = vec![];
163-
for (pred, constraint_category) in outlives_predicates {
164-
// Constraint is implied by a coroutine's well-formedness.
165-
if self.infcx.tcx.sess.opts.unstable_opts.higher_ranked_assumptions
166-
&& higher_ranked_assumptions.contains(&pred)
167-
{
168-
continue;
169-
}
170-
171-
let ty::OutlivesPredicate(k1, r2) = pred;
172-
match k1.kind() {
173-
GenericArgKind::Lifetime(r1) => {
174-
let r1_vid = self.to_region_vid(r1);
175-
let r2_vid = self.to_region_vid(r2);
176-
self.add_outlives(r1_vid, r2_vid, constraint_category);
177-
}
178-
179-
GenericArgKind::Type(mut t1) => {
180-
// Scraped constraints may have had inference vars.
181-
t1 = self.infcx.resolve_vars_if_possible(t1);
182-
183-
// Normalize the type we receive from a `TypeOutlives` obligation
184-
// in the new trait solver.
185-
if infcx.next_trait_solver() {
186-
t1 = self.normalize_and_add_type_outlives_constraints(
187-
ty::Unnormalized::new_wip(t1),
188-
&mut next_outlives_predicates,
189-
);
190-
}
160+
GenericArgKind::Type(mut t1) => {
161+
// Scraped constraints may have had inference vars.
162+
t1 = self.infcx.resolve_vars_if_possible(t1);
191163

192-
let implicit_region_bound =
193-
ty::Region::new_var(tcx, universal_regions.implicit_region_bound());
194-
// we don't actually use this for anything, but
195-
// the `TypeOutlives` code needs an origin.
196-
let origin = SubregionOrigin::RelateParamBound(self.span, t1, None);
197-
TypeOutlives::new(
198-
&mut *self,
199-
tcx,
200-
region_bound_pairs,
201-
Some(implicit_region_bound),
202-
known_type_outlives_obligations,
203-
)
204-
.type_must_outlive(
205-
origin,
206-
t1,
207-
r2,
208-
constraint_category,
209-
);
210-
}
211-
212-
GenericArgKind::Const(_) => unreachable!(),
213-
}
164+
let implicit_region_bound =
165+
ty::Region::new_var(tcx, universal_regions.implicit_region_bound());
166+
// we don't actually use this for anything, but
167+
// the `TypeOutlives` code needs an origin.
168+
let origin = SubregionOrigin::RelateParamBound(self.span, t1, None);
169+
TypeOutlives::new(
170+
&mut *self,
171+
tcx,
172+
region_bound_pairs,
173+
Some(implicit_region_bound),
174+
known_type_outlives_obligations,
175+
)
176+
.type_must_outlive(origin, t1, r2, constraint_category);
214177
}
215178

216-
outlives_predicates = next_outlives_predicates;
179+
GenericArgKind::Const(_) => unreachable!(),
217180
}
218181
}
219182

@@ -279,32 +242,6 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
279242
debug!("add_type_test(type_test={:?})", type_test);
280243
self.constraints.type_tests.push(type_test);
281244
}
282-
283-
// FIXME(trait-refactor-initiative#260): This function should be
284-
// removed.
285-
fn normalize_and_add_type_outlives_constraints(
286-
&self,
287-
ty: ty::Unnormalized<'tcx, Ty<'tcx>>,
288-
next_outlives_predicates: &mut Vec<(
289-
ty::ArgOutlivesPredicate<'tcx>,
290-
ConstraintCategory<'tcx>,
291-
)>,
292-
) -> Ty<'tcx> {
293-
match self.infcx.fully_perform(Normalize { value: ty }, self.span) {
294-
Ok(TypeOpOutput { output: ty, constraints, .. }) => {
295-
// FIXME(higher_ranked_auto): What should we do with the assumptions here?
296-
if let Some(QueryRegionConstraints { constraints, assumptions: _ }) = constraints {
297-
next_outlives_predicates.extend(constraints.iter().flat_map(
298-
|QueryRegionConstraint { constraint, category, .. }| {
299-
constraint.iter_outlives().map(|outlives| (outlives, *category))
300-
},
301-
));
302-
}
303-
ty
304-
}
305-
Err(_) => ty.skip_norm_wip(),
306-
}
307-
}
308245
}
309246

310247
impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'b, 'tcx> {

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use rustc_session::diagnostics::feature_err;
3131
use rustc_span::{DUMMY_SP, Span, sym};
3232
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
3333
use rustc_trait_selection::regions::{
34-
InferCtxtRegionExt, OutlivesEnvironmentBuildExt, region_known_to_outlive, ty_known_to_outlive,
34+
OutlivesEnvironmentBuildExt, region_known_to_outlive, ty_known_to_outlive,
3535
};
3636
use rustc_trait_selection::traits::misc::{
3737
ConstParamTyImplementationError, type_allowed_to_implement_const_param_ty,

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

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
use std::iter;
44

55
use rustc_data_structures::undo_log::UndoLogs;
6-
use rustc_middle::traits::query::{NoSolution, OutlivesBound};
6+
use rustc_middle::traits::query::OutlivesBound;
77
use rustc_middle::ty;
88
use rustc_span::Span;
99
use tracing::instrument;
1010

1111
use self::env::OutlivesEnvironment;
1212
use super::region_constraints::{RegionConstraintData, UndoLog};
13-
use super::{InferCtxt, RegionResolutionError, SubregionOrigin};
13+
use super::{InferCtxt, RegionResolutionError};
1414
use crate::infer::free_regions::RegionRelations;
1515
use crate::infer::lexical_region_resolve;
1616
use crate::infer::region_constraints::ConstraintKind;
@@ -38,25 +38,15 @@ impl<'tcx> InferCtxt<'tcx> {
3838
/// done -- or the compiler will panic -- but it is legal to use
3939
/// `resolve_vars_if_possible` as well as `fully_resolve`.
4040
///
41-
/// If you are in a crate that has access to `rustc_trait_selection`,
42-
/// then it's probably better to use `resolve_regions`,
43-
/// which knows how to normalize registered region obligations.
41+
/// Don't call this directly unless you know what you're doing.
42+
/// You probably want to use `resolve_regions` instead.
4443
#[must_use]
45-
pub fn resolve_regions_with_normalize(
44+
pub fn resolve_regions_with_outlives_env(
4645
&self,
4746
outlives_env: &OutlivesEnvironment<'tcx>,
48-
deeply_normalize_ty: impl Fn(
49-
ty::PolyTypeOutlivesPredicate<'tcx>,
50-
SubregionOrigin<'tcx>,
51-
) -> Result<ty::PolyTypeOutlivesPredicate<'tcx>, NoSolution>,
5247
span: Span,
5348
) -> Vec<RegionResolutionError<'tcx>> {
54-
match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty, span) {
55-
Ok(()) => {}
56-
Err((clause, origin)) => {
57-
return vec![RegionResolutionError::CannotNormalize(clause, origin)];
58-
}
59-
};
49+
self.process_registered_region_obligations(outlives_env, span);
6050

6151
let mut storage = {
6252
let mut inner = self.inner.borrow_mut();

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

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,10 @@ use rustc_data_structures::transitive_relation::TransitiveRelation;
6363
use rustc_data_structures::undo_log::UndoLogs;
6464
use rustc_middle::bug;
6565
use rustc_middle::mir::ConstraintCategory;
66-
use rustc_middle::traits::query::NoSolution;
6766
use rustc_middle::ty::outlives::{Component, push_outlives_components};
6867
use rustc_middle::ty::{
6968
self, GenericArgKind, GenericArgsRef, PolyTypeOutlivesPredicate, Region, RegionExt, RegionVid,
70-
Ty, TyCtxt, TypeFoldable as _, TypeVisitableExt,
69+
Ty, TyCtxt, TypeVisitableExt, eager_resolve_vars,
7170
};
7271
use rustc_span::Span;
7372
use smallvec::smallvec;
@@ -76,7 +75,6 @@ use tracing::{debug, instrument};
7675
use super::env::OutlivesEnvironment;
7776
use crate::infer::outlives::env::RegionBoundPairs;
7877
use crate::infer::outlives::verify::VerifyBoundCx;
79-
use crate::infer::resolve::OpportunisticRegionResolver;
8078
use crate::infer::snapshot::undo_log::UndoLog;
8179
use crate::infer::{
8280
self, GenericKind, InferCtxt, SubregionOrigin, TypeOutlivesConstraint, VerifyBound,
@@ -288,17 +286,12 @@ impl<'tcx> InferCtxt<'tcx> {
288286
/// flow of the inferencer. The key point is that it is
289287
/// invoked after all type-inference variables have been bound --
290288
/// right before lexical region resolution.
291-
#[instrument(level = "debug", skip(self, outlives_env, deeply_normalize_ty))]
289+
#[instrument(level = "debug", skip(self, outlives_env))]
292290
pub fn process_registered_region_obligations(
293291
&self,
294292
outlives_env: &OutlivesEnvironment<'tcx>,
295-
mut deeply_normalize_ty: impl FnMut(
296-
PolyTypeOutlivesPredicate<'tcx>,
297-
SubregionOrigin<'tcx>,
298-
)
299-
-> Result<PolyTypeOutlivesPredicate<'tcx>, NoSolution>,
300293
span: Span,
301-
) -> Result<(), (PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>)> {
294+
) {
302295
assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot");
303296

304297
if self.tcx.assumptions_on_binders() {
@@ -322,17 +315,10 @@ impl<'tcx> InferCtxt<'tcx> {
322315
}
323316

324317
for TypeOutlivesConstraint { sup_type, sub_region, origin } in my_region_obligations {
325-
let outlives = ty::Binder::dummy(ty::OutlivesPredicate(sup_type, sub_region));
326-
let ty::OutlivesPredicate(sup_type, sub_region) =
327-
deeply_normalize_ty(outlives, origin.clone())
328-
.map_err(|NoSolution| (outlives, origin.clone()))?
329-
.no_bound_vars()
330-
.expect("started with no bound vars, should end with no bound vars");
331318
// `TypeOutlives` is structural, so we should try to opportunistically resolve all
332319
// region vids before processing regions, so we have a better chance to match clauses
333320
// in our param-env.
334-
let (sup_type, sub_region) =
335-
(sup_type, sub_region).fold_with(&mut OpportunisticRegionResolver::new(self));
321+
let (sup_type, sub_region) = eager_resolve_vars(self, (sup_type, sub_region));
336322

337323
if self.tcx.sess.opts.unstable_opts.higher_ranked_assumptions
338324
&& outlives_env
@@ -355,8 +341,6 @@ impl<'tcx> InferCtxt<'tcx> {
355341
outlives.type_must_outlive(origin, sup_type, sub_region, category);
356342
}
357343
}
358-
359-
Ok(())
360344
}
361345
}
362346

@@ -435,6 +419,8 @@ where
435419
category: ConstraintCategory<'tcx>,
436420
) {
437421
assert!(!ty.has_escaping_bound_vars());
422+
debug_assert!(!ty.has_non_region_infer());
423+
debug_assert!(!self.tcx.next_trait_solver_globally() || !ty.has_non_rigid_aliases());
438424

439425
let mut components = smallvec![];
440426
push_outlives_components(self.tcx, ty, &mut components);

compiler/rustc_next_trait_solver/src/canonical/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,11 @@ use rustc_type_ir::relate::{
1919
};
2020
use rustc_type_ir::{
2121
self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, InferCtxtLike, Interner, Region,
22-
TypeFoldable, TypingMode, TypingModeEqWrapper,
22+
TypeFoldable, TypingMode, TypingModeEqWrapper, eager_resolve_vars,
2323
};
2424
use tracing::instrument;
2525

2626
use crate::delegate::SolverDelegate;
27-
use crate::resolve::eager_resolve_vars;
2827
use crate::solve::{
2928
CanonicalInput, CanonicalResponse, Certainty, ExternalConstraintsData,
3029
ExternalRegionConstraints, Goal, NestedNormalizationGoals, QueryInput, Response,

compiler/rustc_next_trait_solver/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,4 @@ pub mod coherence;
1515
pub mod delegate;
1616
pub mod normalize;
1717
pub mod placeholder;
18-
pub mod resolve;
1918
pub mod solve;

compiler/rustc_next_trait_solver/src/normalize.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_type_ir::data_structures::ensure_sufficient_stack;
44
use rustc_type_ir::inherent::*;
55
use rustc_type_ir::{
66
self as ty, AliasTerm, Binder, FallibleTypeFolder, InferCtxtLike, Interner, TypeFoldable,
7-
TypeSuperFoldable, TypeVisitableExt, UniverseIndex,
7+
TypeSuperFoldable, TypeVisitableExt, UniverseIndex, eager_resolve_vars,
88
};
99
use tracing::instrument;
1010

@@ -143,8 +143,8 @@ where
143143

144144
if self.cx().renormalize_rigid_aliases() && orig_is_rigid == ty::IsRigid::Yes {
145145
// find out missing typing env change.
146-
let original = crate::resolve::eager_resolve_vars(infcx, original);
147-
let normalized = crate::resolve::eager_resolve_vars(infcx, normalized);
146+
let original = eager_resolve_vars(infcx, original);
147+
let normalized = eager_resolve_vars(infcx, normalized);
148148
assert_eq!(original, normalized, "rigid alias is further normalized");
149149
}
150150
Ok(normalized)
@@ -196,8 +196,8 @@ where
196196

197197
if self.cx().renormalize_rigid_aliases() && orig_is_rigid == ty::IsRigid::Yes {
198198
// find out missing typing env change.
199-
let original = crate::resolve::eager_resolve_vars(infcx, original);
200-
let normalized = crate::resolve::eager_resolve_vars(infcx, normalized);
199+
let original = eager_resolve_vars(infcx, original);
200+
let normalized = eager_resolve_vars(infcx, normalized);
201201
assert_eq!(original, normalized, "rigid alias is further normalized");
202202
}
203203

0 commit comments

Comments
 (0)