Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3ba5334

Browse files
authoredFeb 6, 2024
Rollup merge of rust-lang#120513 - compiler-errors:normalize-regions-for-nll, r=lcnr
Normalize type outlives obligations in NLL for new solver Normalize the type outlives assumptions and obligations in MIR borrowck. This should fix any of the lazy-norm-related MIR borrowck problems. Also some cleanups from last PR: 1. Normalize obligations in a loop in lexical region resolution 2. Use `deeply_normalize_with_skipped_universes` in lexical resolution since we may have, e.g. `for<'a> Alias<'a>: 'b`. r? lcnr
2 parents ab20137 + e951bcf commit 3ba5334

File tree

14 files changed

+250
-94
lines changed

14 files changed

+250
-94
lines changed
 

‎compiler/rustc_borrowck/src/type_check/constraint_conversion.rs

+96-22
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelega
55
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
66
use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
77
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
8-
use rustc_middle::ty::GenericArgKind;
9-
use rustc_middle::ty::{self, TyCtxt};
10-
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
8+
use rustc_middle::traits::query::NoSolution;
9+
use rustc_middle::traits::ObligationCause;
10+
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
1111
use rustc_span::{Span, DUMMY_SP};
12+
use rustc_trait_selection::solve::deeply_normalize;
13+
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
14+
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
1215

1316
use crate::{
1417
constraints::OutlivesConstraint,
@@ -33,6 +36,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
3336
/// our special inference variable there, we would mess that up.
3437
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
3538
implicit_region_bound: ty::Region<'tcx>,
39+
param_env: ty::ParamEnv<'tcx>,
3640
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
3741
locations: Locations,
3842
span: Span,
@@ -47,6 +51,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
4751
universal_regions: &'a UniversalRegions<'tcx>,
4852
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
4953
implicit_region_bound: ty::Region<'tcx>,
54+
param_env: ty::ParamEnv<'tcx>,
5055
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
5156
locations: Locations,
5257
span: Span,
@@ -59,6 +64,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
5964
universal_regions,
6065
region_bound_pairs,
6166
implicit_region_bound,
67+
param_env,
6268
known_type_outlives_obligations,
6369
locations,
6470
span,
@@ -137,36 +143,68 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
137143
// Extract out various useful fields we'll need below.
138144
let ConstraintConversion {
139145
tcx,
146+
infcx,
140147
region_bound_pairs,
141148
implicit_region_bound,
142149
known_type_outlives_obligations,
143150
..
144151
} = *self;
145152

146-
let ty::OutlivesPredicate(k1, r2) = predicate;
147-
match k1.unpack() {
148-
GenericArgKind::Lifetime(r1) => {
149-
let r1_vid = self.to_region_vid(r1);
150-
let r2_vid = self.to_region_vid(r2);
151-
self.add_outlives(r1_vid, r2_vid, constraint_category);
153+
let mut outlives_predicates = vec![(predicate, constraint_category)];
154+
for iteration in 0.. {
155+
if outlives_predicates.is_empty() {
156+
break;
157+
}
158+
159+
if !self.tcx.recursion_limit().value_within_limit(iteration) {
160+
bug!(
161+
"FIXME(-Znext-solver): Overflowed when processing region obligations: {outlives_predicates:#?}"
162+
);
152163
}
153164

154-
GenericArgKind::Type(t1) => {
155-
// we don't actually use this for anything, but
156-
// the `TypeOutlives` code needs an origin.
157-
let origin = infer::RelateParamBound(DUMMY_SP, t1, None);
165+
let mut next_outlives_predicates = vec![];
166+
for (ty::OutlivesPredicate(k1, r2), constraint_category) in outlives_predicates {
167+
match k1.unpack() {
168+
GenericArgKind::Lifetime(r1) => {
169+
let r1_vid = self.to_region_vid(r1);
170+
let r2_vid = self.to_region_vid(r2);
171+
self.add_outlives(r1_vid, r2_vid, constraint_category);
172+
}
158173

159-
TypeOutlives::new(
160-
&mut *self,
161-
tcx,
162-
region_bound_pairs,
163-
Some(implicit_region_bound),
164-
known_type_outlives_obligations,
165-
)
166-
.type_must_outlive(origin, t1, r2, constraint_category);
174+
GenericArgKind::Type(mut t1) => {
175+
// Normalize the type we receive from a `TypeOutlives` obligation
176+
// in the new trait solver.
177+
if infcx.next_trait_solver() {
178+
t1 = self.normalize_and_add_type_outlives_constraints(
179+
t1,
180+
&mut next_outlives_predicates,
181+
);
182+
}
183+
184+
// we don't actually use this for anything, but
185+
// the `TypeOutlives` code needs an origin.
186+
let origin = infer::RelateParamBound(DUMMY_SP, t1, None);
187+
188+
TypeOutlives::new(
189+
&mut *self,
190+
tcx,
191+
region_bound_pairs,
192+
Some(implicit_region_bound),
193+
known_type_outlives_obligations,
194+
)
195+
.type_must_outlive(
196+
origin,
197+
t1,
198+
r2,
199+
constraint_category,
200+
);
201+
}
202+
203+
GenericArgKind::Const(_) => unreachable!(),
204+
}
167205
}
168206

169-
GenericArgKind::Const(_) => unreachable!(),
207+
outlives_predicates = next_outlives_predicates;
170208
}
171209
}
172210

@@ -232,6 +270,42 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
232270
debug!("add_type_test(type_test={:?})", type_test);
233271
self.constraints.type_tests.push(type_test);
234272
}
273+
274+
fn normalize_and_add_type_outlives_constraints(
275+
&self,
276+
ty: Ty<'tcx>,
277+
next_outlives_predicates: &mut Vec<(
278+
ty::OutlivesPredicate<ty::GenericArg<'tcx>, ty::Region<'tcx>>,
279+
ConstraintCategory<'tcx>,
280+
)>,
281+
) -> Ty<'tcx> {
282+
let result = CustomTypeOp::new(
283+
|ocx| {
284+
deeply_normalize(
285+
ocx.infcx.at(&ObligationCause::dummy_with_span(self.span), self.param_env),
286+
ty,
287+
)
288+
.map_err(|_| NoSolution)
289+
},
290+
"normalize type outlives obligation",
291+
)
292+
.fully_perform(self.infcx, self.span);
293+
294+
match result {
295+
Ok(TypeOpOutput { output: ty, constraints, .. }) => {
296+
if let Some(constraints) = constraints {
297+
assert!(
298+
constraints.member_constraints.is_empty(),
299+
"no member constraints expected from normalizing: {:#?}",
300+
constraints.member_constraints
301+
);
302+
next_outlives_predicates.extend(constraints.outlives.iter().copied());
303+
}
304+
ty
305+
}
306+
Err(_) => ty,
307+
}
308+
}
235309
}
236310

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

‎compiler/rustc_borrowck/src/type_check/free_region_relations.rs

+44-25
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ use rustc_infer::infer::region_constraints::GenericKind;
88
use rustc_infer::infer::InferCtxt;
99
use rustc_middle::mir::ConstraintCategory;
1010
use rustc_middle::traits::query::OutlivesBound;
11+
use rustc_middle::traits::ObligationCause;
1112
use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt};
12-
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
13+
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
14+
use rustc_trait_selection::solve::deeply_normalize;
15+
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
1316
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
1417
use std::rc::Rc;
1518
use type_op::TypeOpOutput;
@@ -52,15 +55,13 @@ pub(crate) struct CreateResult<'tcx> {
5255
pub(crate) fn create<'tcx>(
5356
infcx: &InferCtxt<'tcx>,
5457
param_env: ty::ParamEnv<'tcx>,
55-
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
5658
implicit_region_bound: ty::Region<'tcx>,
5759
universal_regions: &Rc<UniversalRegions<'tcx>>,
5860
constraints: &mut MirTypeckRegionConstraints<'tcx>,
5961
) -> CreateResult<'tcx> {
6062
UniversalRegionRelationsBuilder {
6163
infcx,
6264
param_env,
63-
known_type_outlives_obligations,
6465
implicit_region_bound,
6566
constraints,
6667
universal_regions: universal_regions.clone(),
@@ -178,7 +179,6 @@ impl UniversalRegionRelations<'_> {
178179
struct UniversalRegionRelationsBuilder<'this, 'tcx> {
179180
infcx: &'this InferCtxt<'tcx>,
180181
param_env: ty::ParamEnv<'tcx>,
181-
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>],
182182
universal_regions: Rc<UniversalRegions<'tcx>>,
183183
implicit_region_bound: ty::Region<'tcx>,
184184
constraints: &'this mut MirTypeckRegionConstraints<'tcx>,
@@ -222,6 +222,32 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
222222
self.relate_universal_regions(fr, fr_fn_body);
223223
}
224224

225+
// Normalize the assumptions we use to borrowck the program.
226+
let mut constraints = vec![];
227+
let mut known_type_outlives_obligations = vec![];
228+
for bound in param_env.caller_bounds() {
229+
let Some(mut outlives) = bound.as_type_outlives_clause() else { continue };
230+
231+
// In the new solver, normalize the type-outlives obligation assumptions.
232+
if self.infcx.next_trait_solver() {
233+
match deeply_normalize(
234+
self.infcx.at(&ObligationCause::misc(span, defining_ty_def_id), self.param_env),
235+
outlives,
236+
) {
237+
Ok(normalized_outlives) => {
238+
outlives = normalized_outlives;
239+
}
240+
Err(e) => {
241+
self.infcx.err_ctxt().report_fulfillment_errors(e);
242+
}
243+
}
244+
}
245+
246+
known_type_outlives_obligations.push(outlives);
247+
}
248+
let known_type_outlives_obligations =
249+
self.infcx.tcx.arena.alloc_slice(&known_type_outlives_obligations);
250+
225251
let unnormalized_input_output_tys = self
226252
.universal_regions
227253
.unnormalized_input_tys
@@ -239,7 +265,6 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
239265
// the `relations` is built.
240266
let mut normalized_inputs_and_output =
241267
Vec::with_capacity(self.universal_regions.unnormalized_input_tys.len() + 1);
242-
let mut constraints = vec![];
243268
for ty in unnormalized_input_output_tys {
244269
debug!("build: input_or_output={:?}", ty);
245270
// We add implied bounds from both the unnormalized and normalized ty.
@@ -304,7 +329,19 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
304329
}
305330

306331
for c in constraints {
307-
self.push_region_constraints(c, span);
332+
constraint_conversion::ConstraintConversion::new(
333+
self.infcx,
334+
&self.universal_regions,
335+
&self.region_bound_pairs,
336+
self.implicit_region_bound,
337+
param_env,
338+
known_type_outlives_obligations,
339+
Locations::All(span),
340+
span,
341+
ConstraintCategory::Internal,
342+
self.constraints,
343+
)
344+
.convert_all(c);
308345
}
309346

310347
CreateResult {
@@ -313,30 +350,12 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
313350
outlives: self.outlives.freeze(),
314351
inverse_outlives: self.inverse_outlives.freeze(),
315352
}),
316-
known_type_outlives_obligations: self.known_type_outlives_obligations,
353+
known_type_outlives_obligations,
317354
region_bound_pairs: self.region_bound_pairs,
318355
normalized_inputs_and_output,
319356
}
320357
}
321358

322-
#[instrument(skip(self, data), level = "debug")]
323-
fn push_region_constraints(&mut self, data: &QueryRegionConstraints<'tcx>, span: Span) {
324-
debug!("constraints generated: {:#?}", data);
325-
326-
constraint_conversion::ConstraintConversion::new(
327-
self.infcx,
328-
&self.universal_regions,
329-
&self.region_bound_pairs,
330-
self.implicit_region_bound,
331-
self.known_type_outlives_obligations,
332-
Locations::All(span),
333-
span,
334-
ConstraintCategory::Internal,
335-
self.constraints,
336-
)
337-
.convert_all(data);
338-
}
339-
340359
/// Update the type of a single local, which should represent
341360
/// either the return type of the MIR or one of its arguments. At
342361
/// the same time, compute and add any implied bounds that come

‎compiler/rustc_borrowck/src/type_check/mod.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
156156
} = free_region_relations::create(
157157
infcx,
158158
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-
),
163159
implicit_region_bound,
164160
universal_regions,
165161
&mut constraints,
@@ -1144,6 +1140,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
11441140
self.borrowck_context.universal_regions,
11451141
self.region_bound_pairs,
11461142
self.implicit_region_bound,
1143+
self.param_env,
11471144
self.known_type_outlives_obligations,
11481145
locations,
11491146
locations.span(self.body),
@@ -2759,6 +2756,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
27592756
self.borrowck_context.universal_regions,
27602757
self.region_bound_pairs,
27612758
self.implicit_region_bound,
2759+
self.param_env,
27622760
self.known_type_outlives_obligations,
27632761
locations,
27642762
DUMMY_SP, // irrelevant; will be overridden.

‎compiler/rustc_infer/src/infer/error_reporting/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ use rustc_hir::lang_items::LangItem;
7171
use rustc_middle::dep_graph::DepContext;
7272
use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError};
7373
use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
74+
use rustc_middle::ty::ToPredicate;
7475
use rustc_middle::ty::{
7576
self, error::TypeError, IsSuggestable, List, Region, Ty, TyCtxt, TypeFoldable,
7677
TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
@@ -519,10 +520,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
519520
self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
520521
}
521522

522-
RegionResolutionError::CannotNormalize(ty, origin) => {
523+
RegionResolutionError::CannotNormalize(clause, origin) => {
524+
let clause: ty::Clause<'tcx> =
525+
clause.map_bound(ty::ClauseKind::TypeOutlives).to_predicate(self.tcx);
523526
self.tcx
524527
.dcx()
525-
.struct_span_err(origin.span(), format!("cannot normalize `{ty}`"))
528+
.struct_span_err(origin.span(), format!("cannot normalize `{clause}`"))
526529
.emit();
527530
}
528531
}

‎compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ pub enum RegionResolutionError<'tcx> {
9999
Region<'tcx>, // the placeholder `'b`
100100
),
101101

102-
CannotNormalize(Ty<'tcx>, SubregionOrigin<'tcx>),
102+
CannotNormalize(ty::PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>),
103103
}
104104

105105
impl<'tcx> RegionResolutionError<'tcx> {

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

+8-5
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use super::region_constraints::RegionConstraintData;
44
use super::{InferCtxt, RegionResolutionError, SubregionOrigin};
55
use crate::infer::free_regions::RegionRelations;
66
use crate::infer::lexical_region_resolve;
7-
use rustc_middle::traits::query::OutlivesBound;
8-
use rustc_middle::ty::{self, Ty};
7+
use rustc_middle::traits::query::{NoSolution, OutlivesBound};
8+
use rustc_middle::ty;
99

1010
pub mod components;
1111
pub mod env;
@@ -49,12 +49,15 @@ impl<'tcx> InferCtxt<'tcx> {
4949
pub fn resolve_regions_with_normalize(
5050
&self,
5151
outlives_env: &OutlivesEnvironment<'tcx>,
52-
deeply_normalize_ty: impl Fn(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, Ty<'tcx>>,
52+
deeply_normalize_ty: impl Fn(
53+
ty::PolyTypeOutlivesPredicate<'tcx>,
54+
SubregionOrigin<'tcx>,
55+
) -> Result<ty::PolyTypeOutlivesPredicate<'tcx>, NoSolution>,
5356
) -> Vec<RegionResolutionError<'tcx>> {
5457
match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) {
5558
Ok(()) => {}
56-
Err((ty, origin)) => {
57-
return vec![RegionResolutionError::CannotNormalize(ty, origin)];
59+
Err((clause, origin)) => {
60+
return vec![RegionResolutionError::CannotNormalize(clause, origin)];
5861
}
5962
};
6063

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

+50-30
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,9 @@ 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;
71+
use rustc_middle::traits::query::NoSolution;
7272
use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt};
73+
use rustc_middle::ty::{GenericArgKind, PolyTypeOutlivesPredicate};
7374
use rustc_span::DUMMY_SP;
7475
use smallvec::smallvec;
7576

@@ -125,50 +126,69 @@ impl<'tcx> InferCtxt<'tcx> {
125126
/// invoked after all type-inference variables have been bound --
126127
/// right before lexical region resolution.
127128
#[instrument(level = "debug", skip(self, outlives_env, deeply_normalize_ty))]
128-
pub fn process_registered_region_obligations<E>(
129+
pub fn process_registered_region_obligations(
129130
&self,
130131
outlives_env: &OutlivesEnvironment<'tcx>,
131-
mut deeply_normalize_ty: impl FnMut(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, E>,
132-
) -> Result<(), (E, SubregionOrigin<'tcx>)> {
132+
mut deeply_normalize_ty: impl FnMut(
133+
PolyTypeOutlivesPredicate<'tcx>,
134+
SubregionOrigin<'tcx>,
135+
)
136+
-> Result<PolyTypeOutlivesPredicate<'tcx>, NoSolution>,
137+
) -> Result<(), (PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>)> {
133138
assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot");
134139

135140
let normalized_caller_bounds: Vec<_> = outlives_env
136141
.param_env
137142
.caller_bounds()
138143
.iter()
139144
.filter_map(|clause| {
140-
let bound_clause = clause.kind();
141-
let ty::ClauseKind::TypeOutlives(outlives) = bound_clause.skip_binder() else {
142-
return None;
143-
};
145+
let outlives = clause.as_type_outlives_clause()?;
144146
Some(
145147
deeply_normalize_ty(
146-
outlives.0,
148+
outlives,
147149
SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP),
148150
)
149-
.map(|ty| bound_clause.rebind(ty::OutlivesPredicate(ty, outlives.1))),
151+
// FIXME(-Znext-solver): How do we accurately report an error span here :(
152+
.map_err(|NoSolution| {
153+
(outlives, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP))
154+
}),
150155
)
151156
})
152-
// FIXME(-Znext-solver): How do we accurately report an error here :(
153-
.try_collect()
154-
.map_err(|e| (e, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP)))?;
155-
156-
let my_region_obligations = self.take_registered_region_obligations();
157-
158-
for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
159-
let sup_type =
160-
deeply_normalize_ty(sup_type, origin.clone()).map_err(|e| (e, origin.clone()))?;
161-
debug!(?sup_type, ?sub_region, ?origin);
162-
163-
let outlives = &mut TypeOutlives::new(
164-
self,
165-
self.tcx,
166-
outlives_env.region_bound_pairs(),
167-
None,
168-
&normalized_caller_bounds,
169-
);
170-
let category = origin.to_constraint_category();
171-
outlives.type_must_outlive(origin, sup_type, sub_region, category);
157+
.try_collect()?;
158+
159+
// Must loop since the process of normalizing may itself register region obligations.
160+
for iteration in 0.. {
161+
let my_region_obligations = self.take_registered_region_obligations();
162+
if my_region_obligations.is_empty() {
163+
break;
164+
}
165+
166+
if !self.tcx.recursion_limit().value_within_limit(iteration) {
167+
bug!(
168+
"FIXME(-Znext-solver): Overflowed when processing region obligations: {my_region_obligations:#?}"
169+
);
170+
}
171+
172+
for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
173+
let outlives = ty::Binder::dummy(ty::OutlivesPredicate(sup_type, sub_region));
174+
let ty::OutlivesPredicate(sup_type, sub_region) =
175+
deeply_normalize_ty(outlives, origin.clone())
176+
.map_err(|NoSolution| (outlives, origin.clone()))?
177+
.no_bound_vars()
178+
.expect("started with no bound vars, should end with no bound vars");
179+
180+
debug!(?sup_type, ?sub_region, ?origin);
181+
182+
let outlives = &mut TypeOutlives::new(
183+
self,
184+
self.tcx,
185+
outlives_env.region_bound_pairs(),
186+
None,
187+
&normalized_caller_bounds,
188+
);
189+
let category = origin.to_constraint_category();
190+
outlives.type_must_outlive(origin, sup_type, sub_region, category);
191+
}
172192
}
173193

174194
Ok(())

‎compiler/rustc_trait_selection/src/regions.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
22
use rustc_infer::infer::{InferCtxt, RegionResolutionError};
3+
use rustc_middle::traits::query::NoSolution;
34
use rustc_middle::traits::ObligationCause;
45

56
pub trait InferCtxtRegionExt<'tcx> {
@@ -31,7 +32,7 @@ impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> {
3132
),
3233
ty,
3334
)
34-
.map_err(|_| ty)
35+
.map_err(|_| NoSolution)
3536
} else {
3637
Ok(ty)
3738
}

‎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
@@ -1,4 +1,4 @@
1-
// revisions: normalize_param_env normalize_obligation
1+
// revisions: normalize_param_env normalize_obligation hrtb
22
// check-pass
33
// compile-flags: -Znext-solver
44

@@ -7,16 +7,23 @@ trait Foo {
77
type Gat<'a> where <Self as Mirror>::Assoc: 'a;
88
#[cfg(normalize_obligation)]
99
type Gat<'a> where Self: 'a;
10+
#[cfg(hrtb)]
11+
type Gat<'b> where for<'a> <Self as MirrorRegion<'a>>::Assoc: 'b;
1012
}
1113

1214
trait Mirror { type Assoc: ?Sized; }
1315
impl<T: ?Sized> Mirror for T { type Assoc = T; }
1416

17+
trait MirrorRegion<'a> { type Assoc: ?Sized; }
18+
impl<'a, T> MirrorRegion<'a> for T { type Assoc = T; }
19+
1520
impl<T> Foo for T {
1621
#[cfg(normalize_param_env)]
1722
type Gat<'a> = i32 where T: 'a;
1823
#[cfg(normalize_obligation)]
1924
type Gat<'a> = i32 where <T as Mirror>::Assoc: 'a;
25+
#[cfg(hrtb)]
26+
type Gat<'b> = i32 where Self: 'b;
2027
}
2128

2229
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// check-pass
2+
// compile-flags: -Znext-solver
3+
4+
trait Mirror {
5+
type Assoc;
6+
}
7+
8+
impl<T> Mirror for T {
9+
type Assoc = T;
10+
}
11+
12+
fn is_static<T: 'static>() {}
13+
14+
fn test<T>() where <T as Mirror>::Assoc: 'static {
15+
is_static::<T>();
16+
}
17+
18+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// check-pass
2+
3+
trait Tr<'a> {
4+
type Assoc;
5+
}
6+
7+
fn outlives<'o, T: 'o>() {}
8+
9+
fn foo<'a, 'b, T: Tr<'a, Assoc = ()>>() {
10+
outlives::<'b, T::Assoc>();
11+
}
12+
13+
fn main() {}

‎tests/ui/traits/next-solver/specialization-transmute.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// compile-flags: -Znext-solver
2-
//~^ ERROR cannot normalize `<T as Default>::Id`
2+
//~^ ERROR cannot normalize `<T as Default>::Id: '_`
33

44
#![feature(specialization)]
55
//~^ WARN the feature `specialization` is incomplete

‎tests/ui/traits/next-solver/specialization-transmute.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | #![feature(specialization)]
88
= help: consider using `min_specialization` instead, which is more stable and complete
99
= note: `#[warn(incomplete_features)]` on by default
1010

11-
error: cannot normalize `<T as Default>::Id`
11+
error: cannot normalize `<T as Default>::Id: '_`
1212

1313
error[E0284]: type annotations needed: cannot satisfy `<T as Default>::Id == _`
1414
--> $DIR/specialization-transmute.rs:16:23

0 commit comments

Comments
 (0)
Please sign in to comment.