Skip to content

Commit fd26c38

Browse files
committed
in opaque type handling lift region vars to static if they outlive placeholders
1 parent 9725c4b commit fd26c38

File tree

5 files changed

+75
-26
lines changed

5 files changed

+75
-26
lines changed

compiler/rustc_borrowck/src/handle_placeholders.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>(
344344
}
345345
}
346346

347-
fn rewrite_placeholder_outlives<'tcx>(
347+
pub(crate) fn rewrite_placeholder_outlives<'tcx>(
348348
sccs: &Sccs<RegionVid, ConstraintSccIndex>,
349349
annotations: &SccAnnotations<'_, '_, RegionTracker>,
350350
fr_static: RegionVid,

compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub(super) fn apply_member_constraints<'tcx>(
3939
debug!(?member_constraints);
4040
for scc_a in rcx.constraint_sccs.all_sccs() {
4141
debug!(?scc_a);
42-
// Start by adding the region values required by outlives constraints. This
42+
// Start by adding the region values required by outlives constraints. This
4343
// matches how we compute the final region values in `fn compute_regions`.
4444
//
4545
// We need to do this here to get a lower bound when applying member constraints.
@@ -64,6 +64,7 @@ fn apply_member_constraint<'tcx>(
6464
// If the member region lives in a higher universe, we currently choose
6565
// the most conservative option by leaving it unchanged.
6666
if !rcx.max_placeholder_universe_reached(member).is_root() {
67+
debug!("member region reached non root universe, bailing");
6768
return;
6869
}
6970

compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ fn collect_defining_uses<'tcx>(
253253
}
254254
} else {
255255
errors.push(DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err));
256+
debug!(
257+
"collect_defining_uses: InvalidOpaqueTypeArgs for {:?} := {:?}",
258+
non_nll_opaque_type_key, hidden_type
259+
);
256260
}
257261
continue;
258262
}
@@ -286,26 +290,31 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
286290
let tcx = infcx.tcx;
287291
let mut decls_modulo_regions: FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueTypeKey<'tcx>, Span)> =
288292
FxIndexMap::default();
289-
for &DefiningUse { opaque_type_key, ref arg_regions, hidden_type } in defining_uses {
293+
for this_use @ &DefiningUse { opaque_type_key, ref arg_regions, hidden_type } in defining_uses {
290294
// After applying member constraints, we now map all regions in the hidden type
291295
// to the `arg_regions` of this defining use. In case a region in the hidden type
292296
// ended up not being equal to any such region, we error.
293-
let hidden_type =
294-
match hidden_type.try_fold_with(&mut ToArgRegionsFolder::new(rcx, arg_regions)) {
295-
Ok(hidden_type) => hidden_type,
296-
Err(r) => {
297-
errors.push(DeferredOpaqueTypeError::UnexpectedHiddenRegion {
298-
hidden_type,
299-
opaque_type_key,
300-
member_region: ty::Region::new_var(tcx, r),
301-
});
302-
let guar = tcx.dcx().span_delayed_bug(
303-
hidden_type.span,
304-
"opaque type with non-universal region args",
305-
);
306-
ty::OpaqueHiddenType::new_error(tcx, guar)
307-
}
308-
};
297+
let hidden_type = match hidden_type
298+
.try_fold_with(&mut ToArgRegionsFolder::new(rcx, arg_regions))
299+
{
300+
Ok(hidden_type) => hidden_type,
301+
Err(r) => {
302+
errors.push(DeferredOpaqueTypeError::UnexpectedHiddenRegion {
303+
hidden_type,
304+
opaque_type_key,
305+
member_region: ty::Region::new_var(tcx, r),
306+
});
307+
debug!(
308+
"compute_definition_site_hidden_types_from_defining_use: UnexpectedHiddenRegion for {:?}",
309+
this_use,
310+
);
311+
let guar = tcx.dcx().span_delayed_bug(
312+
hidden_type.span,
313+
"opaque type with non-universal region args",
314+
);
315+
ty::OpaqueHiddenType::new_error(tcx, guar)
316+
}
317+
};
309318

310319
// Now that we mapped the member regions to their final value,
311320
// map the arguments of the opaque type key back to the parameters

compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::constraints::ConstraintSccIndex;
1111
use crate::handle_placeholders::{SccAnnotations, region_definitions};
1212
use crate::region_infer::reverse_sccs::ReverseSccGraph;
1313
use crate::region_infer::values::RegionValues;
14-
use crate::region_infer::{ConstraintSccs, RegionDefinition, RegionTracker, Representative};
14+
use crate::region_infer::{OutlivesConstraintSet, ConstraintSccs, RegionDefinition, RegionTracker, Representative};
1515
use crate::type_check::MirTypeckRegionConstraints;
1616
use crate::type_check::free_region_relations::UniversalRegionRelations;
1717
use crate::universal_regions::UniversalRegions;
@@ -39,16 +39,36 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
3939
location_map: Rc<DenseLocationMap>,
4040
constraints: &MirTypeckRegionConstraints<'tcx>,
4141
) -> RegionCtxt<'a, 'tcx> {
42+
let mut outlives_constraints = constraints.outlives_constraints.clone();
4243
let universal_regions = &universal_region_relations.universal_regions;
4344
let (definitions, _has_placeholders) = region_definitions(infcx, universal_regions);
45+
46+
let compute_sccs =
47+
|outlives_constraints: &OutlivesConstraintSet<'tcx>,
48+
annotations: &mut SccAnnotations<'_, 'tcx, RegionTracker>| {
49+
ConstraintSccs::new_with_annotation(
50+
&outlives_constraints
51+
.graph(definitions.len())
52+
.region_graph(outlives_constraints, universal_regions.fr_static),
53+
annotations,
54+
)
55+
};
56+
4457
let mut scc_annotations = SccAnnotations::init(&definitions);
45-
let constraint_sccs = ConstraintSccs::new_with_annotation(
46-
&constraints
47-
.outlives_constraints
48-
.graph(definitions.len())
49-
.region_graph(&constraints.outlives_constraints, universal_regions.fr_static),
50-
&mut scc_annotations,
58+
let mut constraint_sccs = compute_sccs(&outlives_constraints, &mut scc_annotations);
59+
60+
let added_constraints = crate::handle_placeholders::rewrite_placeholder_outlives(
61+
&constraint_sccs,
62+
&scc_annotations,
63+
universal_regions.fr_static,
64+
&mut outlives_constraints,
5165
);
66+
67+
if added_constraints {
68+
scc_annotations = SccAnnotations::init(&definitions);
69+
constraint_sccs = compute_sccs(&outlives_constraints, &mut scc_annotations);
70+
}
71+
5272
let scc_annotations = scc_annotations.scc_to_annotation;
5373

5474
// Unlike the `RegionInferenceContext`, we only care about free regions
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ check-pass
2+
3+
// We have some `RPIT` with an item bound of `for<'a> Outlives<'a>`. We
4+
// infer a hidden type of `&'?x i32` where `'?x` is required to outlive
5+
// some placeholder `'!a` due to the `for<'a> Outlives<'a>` item bound.
6+
//
7+
// We previously did not write constraints of the form `'?x: '!a` into
8+
// `'?x: 'static`. This caused member constraints to bail and not consider
9+
// `'?x` to be constrained to an arg region.
10+
11+
pub trait Outlives<'a> {}
12+
impl<'a, T: 'a> Outlives<'a> for T {}
13+
14+
pub fn foo() -> impl for<'a> Outlives<'a> {
15+
let x: &'static i32 = &1;
16+
x
17+
}
18+
19+
fn main() {}

0 commit comments

Comments
 (0)