Skip to content

Commit 5775190

Browse files
Make sure to scrape region constraints from deeply normalizing type outlives assumptions in borrowck
1 parent 8c39ce5 commit 5775190

File tree

2 files changed

+61
-19
lines changed

2 files changed

+61
-19
lines changed

compiler/rustc_borrowck/src/type_check/free_region_relations.rs

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ use rustc_infer::infer::canonical::QueryRegionConstraints;
55
use rustc_infer::infer::outlives::env::RegionBoundPairs;
66
use rustc_infer::infer::region_constraints::GenericKind;
77
use rustc_infer::infer::{InferCtxt, outlives};
8+
use rustc_infer::traits::ScrubbedTraitError;
89
use rustc_middle::mir::ConstraintCategory;
910
use rustc_middle::traits::ObligationCause;
1011
use rustc_middle::traits::query::OutlivesBound;
1112
use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt};
1213
use rustc_span::{ErrorGuaranteed, Span};
13-
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
14-
use rustc_trait_selection::solve::deeply_normalize;
14+
use rustc_trait_selection::solve::NoSolution;
15+
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
1516
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
1617
use tracing::{debug, instrument};
1718
use type_op::TypeOpOutput;
@@ -229,24 +230,14 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
229230
let mut constraints = vec![];
230231
let mut known_type_outlives_obligations = vec![];
231232
for bound in param_env.caller_bounds() {
232-
let Some(mut outlives) = bound.as_type_outlives_clause() else { continue };
233-
234-
// In the new solver, normalize the type-outlives obligation assumptions.
235-
if self.infcx.next_trait_solver() {
236-
match deeply_normalize(
237-
self.infcx.at(&ObligationCause::misc(span, defining_ty_def_id), param_env),
233+
if let Some(outlives) = bound.as_type_outlives_clause() {
234+
self.normalize_and_push_type_outlives_obligation(
238235
outlives,
239-
) {
240-
Ok(normalized_outlives) => {
241-
outlives = normalized_outlives;
242-
}
243-
Err(e) => {
244-
self.infcx.err_ctxt().report_fulfillment_errors(e);
245-
}
246-
}
247-
}
248-
249-
known_type_outlives_obligations.push(outlives);
236+
span,
237+
&mut known_type_outlives_obligations,
238+
&mut constraints,
239+
);
240+
};
250241
}
251242

252243
let unnormalized_input_output_tys = self
@@ -356,6 +347,44 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
356347
}
357348
}
358349

350+
fn normalize_and_push_type_outlives_obligation(
351+
&self,
352+
mut outlives: ty::PolyTypeOutlivesPredicate<'tcx>,
353+
span: Span,
354+
known_type_outlives_obligations: &mut Vec<ty::PolyTypeOutlivesPredicate<'tcx>>,
355+
constraints: &mut Vec<&QueryRegionConstraints<'tcx>>,
356+
) {
357+
// In the new solver, normalize the type-outlives obligation assumptions.
358+
if self.infcx.next_trait_solver() {
359+
let Ok(TypeOpOutput {
360+
output: normalized_outlives,
361+
constraints: constraints_normalize,
362+
error_info: _,
363+
}) = CustomTypeOp::new(
364+
|ocx| {
365+
ocx.deeply_normalize(
366+
&ObligationCause::dummy_with_span(span),
367+
self.param_env,
368+
outlives,
369+
)
370+
.map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution)
371+
},
372+
"normalize type outlives obligation",
373+
)
374+
.fully_perform(self.infcx, span)
375+
else {
376+
self.infcx.dcx().delayed_bug(format!("could not normalize {outlives:?}"));
377+
return;
378+
};
379+
outlives = normalized_outlives;
380+
if let Some(c) = constraints_normalize {
381+
constraints.push(c);
382+
}
383+
}
384+
385+
known_type_outlives_obligations.push(outlives);
386+
}
387+
359388
/// Update the type of a single local, which should represent
360389
/// either the return type of the MIR or one of its arguments. At
361390
/// the same time, compute and add any implied bounds that come
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//@ compile-flags: -Znext-solver
2+
//@ check-pass
3+
4+
trait Norm {
5+
type Out;
6+
}
7+
impl<'a, T: 'a> Norm for &'a T {
8+
type Out = T;
9+
}
10+
11+
fn hello<'a, T: 'a>() where <&'a T as Norm>::Out: 'a {}
12+
13+
fn main() {}

0 commit comments

Comments
 (0)