Skip to content

Commit 1a663c0

Browse files
committed
Cleanup free_region_relations a bit
1 parent 8996ea9 commit 1a663c0

File tree

6 files changed

+90
-71
lines changed

6 files changed

+90
-71
lines changed

compiler/rustc_borrowck/src/region_infer/values.rs

+1
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ pub(crate) struct PlaceholderIndices {
187187
}
188188

189189
impl PlaceholderIndices {
190+
/// Returns the `PlaceholderIndex` for the inserted `PlaceholderRegion`
190191
pub(crate) fn insert(&mut self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex {
191192
let (index, _) = self.indices.insert_full(placeholder);
192193
index.into()

compiler/rustc_borrowck/src/type_check/free_region_relations.rs

+83-69
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_infer::infer::InferCtxt;
88
use rustc_middle::mir::ConstraintCategory;
99
use rustc_middle::traits::query::OutlivesBound;
1010
use rustc_middle::ty::{self, RegionVid, Ty};
11+
use rustc_span::Span;
1112
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
1213
use std::rc::Rc;
1314
use type_op::TypeOpOutput;
@@ -217,8 +218,28 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
217218
self.inverse_outlives.add(fr_b, fr_a);
218219
}
219220

221+
#[instrument(level = "debug", skip(self))]
220222
pub(crate) fn create(mut self) -> CreateResult<'tcx> {
221223
let span = self.infcx.tcx.def_span(self.universal_regions.defining_ty.def_id());
224+
225+
// Insert the facts we know from the predicates. Why? Why not.
226+
let param_env = self.param_env;
227+
self.add_outlives_bounds(outlives::explicit_outlives_bounds(param_env));
228+
229+
// Finally:
230+
// - outlives is reflexive, so `'r: 'r` for every region `'r`
231+
// - `'static: 'r` for every region `'r`
232+
// - `'r: 'fn_body` for every (other) universally quantified
233+
// region `'r`, all of which are provided by our caller
234+
let fr_static = self.universal_regions.fr_static;
235+
let fr_fn_body = self.universal_regions.fr_fn_body;
236+
for fr in self.universal_regions.universal_regions() {
237+
debug!("build: relating free region {:?} to itself and to 'static", fr);
238+
self.relate_universal_regions(fr, fr);
239+
self.relate_universal_regions(fr_static, fr);
240+
self.relate_universal_regions(fr, fr_fn_body);
241+
}
242+
222243
let unnormalized_input_output_tys = self
223244
.universal_regions
224245
.unnormalized_input_tys
@@ -236,78 +257,52 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
236257
// the `relations` is built.
237258
let mut normalized_inputs_and_output =
238259
Vec::with_capacity(self.universal_regions.unnormalized_input_tys.len() + 1);
239-
let constraint_sets: Vec<_> = unnormalized_input_output_tys
240-
.flat_map(|ty| {
241-
debug!("build: input_or_output={:?}", ty);
242-
// We add implied bounds from both the unnormalized and normalized ty.
243-
// See issue #87748
244-
let constraints_implied1 = self.add_implied_bounds(ty);
245-
let TypeOpOutput { output: norm_ty, constraints: constraints1, .. } = self
246-
.param_env
247-
.and(type_op::normalize::Normalize::new(ty))
248-
.fully_perform(self.infcx)
249-
.unwrap_or_else(|_| {
250-
let reported = self
251-
.infcx
252-
.tcx
253-
.sess
254-
.delay_span_bug(span, &format!("failed to normalize {:?}", ty));
255-
TypeOpOutput {
256-
output: self.infcx.tcx.ty_error_with_guaranteed(reported),
257-
constraints: None,
258-
error_info: None,
259-
}
260-
});
261-
// Note: we need this in examples like
262-
// ```
263-
// trait Foo {
264-
// type Bar;
265-
// fn foo(&self) -> &Self::Bar;
266-
// }
267-
// impl Foo for () {
268-
// type Bar = ();
269-
// fn foo(&self) -> &() {}
270-
// }
271-
// ```
272-
// Both &Self::Bar and &() are WF
273-
let constraints_implied2 =
274-
if ty != norm_ty { self.add_implied_bounds(norm_ty) } else { None };
275-
normalized_inputs_and_output.push(norm_ty);
276-
constraints1.into_iter().chain(constraints_implied1).chain(constraints_implied2)
277-
})
278-
.collect();
279-
280-
// Insert the facts we know from the predicates. Why? Why not.
281-
let param_env = self.param_env;
282-
self.add_outlives_bounds(outlives::explicit_outlives_bounds(param_env));
260+
let mut constraints = vec![];
261+
for ty in unnormalized_input_output_tys {
262+
debug!("build: input_or_output={:?}", ty);
263+
// We add implied bounds from both the unnormalized and normalized ty.
264+
// See issue #87748
265+
let constraints_unnorm = self.add_implied_bounds(ty);
266+
constraints_unnorm.map(|c| constraints.push(c));
267+
let TypeOpOutput { output: norm_ty, constraints: constraints_normalize, .. } = self
268+
.param_env
269+
.and(type_op::normalize::Normalize::new(ty))
270+
.fully_perform(self.infcx)
271+
.unwrap_or_else(|_| {
272+
self.infcx
273+
.tcx
274+
.sess
275+
.delay_span_bug(span, &format!("failed to normalize {:?}", ty));
276+
TypeOpOutput {
277+
output: self.infcx.tcx.ty_error(),
278+
constraints: None,
279+
error_info: None,
280+
}
281+
});
282+
constraints_normalize.map(|c| constraints.push(c));
283+
284+
// Note: we need this in examples like
285+
// ```
286+
// trait Foo {
287+
// type Bar;
288+
// fn foo(&self) -> &Self::Bar;
289+
// }
290+
// impl Foo for () {
291+
// type Bar = ();
292+
// fn foo(&self) ->&() {}
293+
// }
294+
// ```
295+
// Both &Self::Bar and &() are WF
296+
if ty != norm_ty {
297+
let constraints_norm = self.add_implied_bounds(norm_ty);
298+
constraints_norm.map(|c| constraints.push(c));
299+
}
283300

284-
// Finally:
285-
// - outlives is reflexive, so `'r: 'r` for every region `'r`
286-
// - `'static: 'r` for every region `'r`
287-
// - `'r: 'fn_body` for every (other) universally quantified
288-
// region `'r`, all of which are provided by our caller
289-
let fr_static = self.universal_regions.fr_static;
290-
let fr_fn_body = self.universal_regions.fr_fn_body;
291-
for fr in self.universal_regions.universal_regions() {
292-
debug!("build: relating free region {:?} to itself and to 'static", fr);
293-
self.relate_universal_regions(fr, fr);
294-
self.relate_universal_regions(fr_static, fr);
295-
self.relate_universal_regions(fr, fr_fn_body);
301+
normalized_inputs_and_output.push(norm_ty);
296302
}
297303

298-
for data in &constraint_sets {
299-
constraint_conversion::ConstraintConversion::new(
300-
self.infcx,
301-
&self.universal_regions,
302-
&self.region_bound_pairs,
303-
self.implicit_region_bound,
304-
self.param_env,
305-
Locations::All(span),
306-
span,
307-
ConstraintCategory::Internal,
308-
&mut self.constraints,
309-
)
310-
.convert_all(data);
304+
for c in constraints {
305+
self.push_region_constraints(c, span);
311306
}
312307

313308
CreateResult {
@@ -321,6 +316,24 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
321316
}
322317
}
323318

319+
#[instrument(skip(self, data), level = "debug")]
320+
fn push_region_constraints(&mut self, data: &QueryRegionConstraints<'tcx>, span: Span) {
321+
debug!("constraints generated: {:#?}", data);
322+
323+
constraint_conversion::ConstraintConversion::new(
324+
self.infcx,
325+
&self.universal_regions,
326+
&self.region_bound_pairs,
327+
self.implicit_region_bound,
328+
self.param_env,
329+
Locations::All(span),
330+
span,
331+
ConstraintCategory::Internal,
332+
&mut self.constraints,
333+
)
334+
.convert_all(data);
335+
}
336+
324337
/// Update the type of a single local, which should represent
325338
/// either the return type of the MIR or one of its arguments. At
326339
/// the same time, compute and add any implied bounds that come
@@ -332,6 +345,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
332345
.and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty })
333346
.fully_perform(self.infcx)
334347
.unwrap_or_else(|_| bug!("failed to compute implied bounds {:?}", ty));
348+
debug!(?bounds, ?constraints);
335349
self.add_outlives_bounds(bounds);
336350
constraints
337351
}

compiler/rustc_borrowck/src/type_check/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,8 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> {
910910
}
911911

912912
impl<'tcx> MirTypeckRegionConstraints<'tcx> {
913+
/// Creates a `Region` that for a given `PlaceholderRegion`, or returns the
914+
/// region that corresponds to a previously created one.
913915
fn placeholder_region(
914916
&mut self,
915917
infcx: &InferCtxt<'tcx>,

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

+1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
207207
///
208208
/// In some cases, such as when `erased_ty` represents a `ty::Param`, however,
209209
/// the result is precise.
210+
#[instrument(level = "debug", skip(self))]
210211
fn declared_generic_bounds_from_env_for_erased_ty(
211212
&self,
212213
erased_ty: Ty<'tcx>,

compiler/rustc_traits/src/implied_outlives_bounds.rs

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ fn compute_implied_outlives_bounds<'tcx>(
8181
// From the full set of obligations, just filter down to the
8282
// region relationships.
8383
outlives_bounds.extend(obligations.into_iter().filter_map(|obligation| {
84+
debug!(?obligation);
8485
assert!(!obligation.has_escaping_bound_vars());
8586
match obligation.predicate.kind().no_bound_vars() {
8687
None => None,

tests/ui/nll/issue-52057.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Regression test for #52057. There is an implied bound
2-
// that `I: 'a` where `'a` is the lifetime of `self` in `parse_first`;
3-
// but to observe that, one must normalize first.
2+
// that `I: 'x` where `'x` is the lifetime of the reference `&mut Self::Input`
3+
// in `parse_first`; but to observe that, one must normalize first.
44
//
55
// run-pass
66

0 commit comments

Comments
 (0)