Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/handle_placeholders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>(
}
}

fn rewrite_placeholder_outlives<'tcx>(
pub(crate) fn rewrite_placeholder_outlives<'tcx>(
sccs: &Sccs<RegionVid, ConstraintSccIndex>,
annotations: &SccAnnotations<'_, '_, RegionTracker>,
fr_static: RegionVid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub(super) fn apply_member_constraints<'tcx>(
debug!(?member_constraints);
for scc_a in rcx.constraint_sccs.all_sccs() {
debug!(?scc_a);
// Start by adding the region values required by outlives constraints. This
// Start by adding the region values required by outlives constraints. This
// matches how we compute the final region values in `fn compute_regions`.
//
// We need to do this here to get a lower bound when applying member constraints.
Expand All @@ -64,6 +64,7 @@ fn apply_member_constraint<'tcx>(
// If the member region lives in a higher universe, we currently choose
// the most conservative option by leaving it unchanged.
if !rcx.max_placeholder_universe_reached(member).is_root() {
debug!("member region reached non root universe, bailing");
return;
}

Expand Down
43 changes: 26 additions & 17 deletions compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,10 @@ fn collect_defining_uses<'tcx>(
}
} else {
errors.push(DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err));
debug!(
"collect_defining_uses: InvalidOpaqueTypeArgs for {:?} := {:?}",
non_nll_opaque_type_key, hidden_type
);
}
continue;
}
Expand Down Expand Up @@ -286,26 +290,31 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
let tcx = infcx.tcx;
let mut decls_modulo_regions: FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueTypeKey<'tcx>, Span)> =
FxIndexMap::default();
for &DefiningUse { opaque_type_key, ref arg_regions, hidden_type } in defining_uses {
for this_use @ &DefiningUse { opaque_type_key, ref arg_regions, hidden_type } in defining_uses {
// After applying member constraints, we now map all regions in the hidden type
// to the `arg_regions` of this defining use. In case a region in the hidden type
// ended up not being equal to any such region, we error.
let hidden_type =
match hidden_type.try_fold_with(&mut ToArgRegionsFolder::new(rcx, arg_regions)) {
Ok(hidden_type) => hidden_type,
Err(r) => {
errors.push(DeferredOpaqueTypeError::UnexpectedHiddenRegion {
hidden_type,
opaque_type_key,
member_region: ty::Region::new_var(tcx, r),
});
let guar = tcx.dcx().span_delayed_bug(
hidden_type.span,
"opaque type with non-universal region args",
);
ty::OpaqueHiddenType::new_error(tcx, guar)
}
};
let hidden_type = match hidden_type
.try_fold_with(&mut ToArgRegionsFolder::new(rcx, arg_regions))
{
Ok(hidden_type) => hidden_type,
Err(r) => {
errors.push(DeferredOpaqueTypeError::UnexpectedHiddenRegion {
hidden_type,
opaque_type_key,
member_region: ty::Region::new_var(tcx, r),
});
debug!(
"compute_definition_site_hidden_types_from_defining_use: UnexpectedHiddenRegion for {:?}",
this_use,
);
Comment on lines +307 to +310
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to have caused the entire match to have gotten reflowed :/

let guar = tcx.dcx().span_delayed_bug(
hidden_type.span,
"opaque type with non-universal region args",
);
ty::OpaqueHiddenType::new_error(tcx, guar)
}
};

// Now that we mapped the member regions to their final value,
// map the arguments of the opaque type key back to the parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use crate::constraints::ConstraintSccIndex;
use crate::handle_placeholders::{SccAnnotations, region_definitions};
use crate::region_infer::reverse_sccs::ReverseSccGraph;
use crate::region_infer::values::RegionValues;
use crate::region_infer::{ConstraintSccs, RegionDefinition, RegionTracker, Representative};
use crate::region_infer::{
ConstraintSccs, OutlivesConstraintSet, RegionDefinition, RegionTracker, Representative,
};
use crate::type_check::MirTypeckRegionConstraints;
use crate::type_check::free_region_relations::UniversalRegionRelations;
use crate::universal_regions::UniversalRegions;
Expand Down Expand Up @@ -39,16 +41,36 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
location_map: Rc<DenseLocationMap>,
constraints: &MirTypeckRegionConstraints<'tcx>,
) -> RegionCtxt<'a, 'tcx> {
let mut outlives_constraints = constraints.outlives_constraints.clone();
let universal_regions = &universal_region_relations.universal_regions;
let (definitions, _has_placeholders) = region_definitions(infcx, universal_regions);

let compute_sccs =
|outlives_constraints: &OutlivesConstraintSet<'tcx>,
annotations: &mut SccAnnotations<'_, 'tcx, RegionTracker>| {
ConstraintSccs::new_with_annotation(
&outlives_constraints
.graph(definitions.len())
.region_graph(outlives_constraints, universal_regions.fr_static),
annotations,
)
};

let mut scc_annotations = SccAnnotations::init(&definitions);
let constraint_sccs = ConstraintSccs::new_with_annotation(
&constraints
.outlives_constraints
.graph(definitions.len())
.region_graph(&constraints.outlives_constraints, universal_regions.fr_static),
&mut scc_annotations,
let mut constraint_sccs = compute_sccs(&outlives_constraints, &mut scc_annotations);

let added_constraints = crate::handle_placeholders::rewrite_placeholder_outlives(
&constraint_sccs,
&scc_annotations,
universal_regions.fr_static,
&mut outlives_constraints,
);

if added_constraints {
scc_annotations = SccAnnotations::init(&definitions);
constraint_sccs = compute_sccs(&outlives_constraints, &mut scc_annotations);
}

let scc_annotations = scc_annotations.scc_to_annotation;

// Unlike the `RegionInferenceContext`, we only care about free regions
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//@ check-pass

// We have some `RPIT` with an item bound of `for<'a> Outlives<'a>`. We
// infer a hidden type of `&'?x i32` where `'?x` is required to outlive
// some placeholder `'!a` due to the `for<'a> Outlives<'a>` item bound.
//
// We previously did not write constraints of the form `'?x: '!a` into
// `'?x: 'static`. This caused member constraints to bail and not consider
// `'?x` to be constrained to an arg region.

pub trait Outlives<'a> {}
impl<'a, T: 'a> Outlives<'a> for T {}

pub fn foo() -> impl for<'a> Outlives<'a> {
let x: &'static i32 = &1;
x
}

fn main() {}
1 change: 0 additions & 1 deletion tests/ui/impl-trait/nested-rpit-hrtb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = im
// This should resolve.
fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {}
//~^ ERROR implementation of `Bar` is not general enough
//~| ERROR lifetime may not live long enough

// This should resolve.
fn two_htrb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Qux<'b>> {}
Expand Down
14 changes: 4 additions & 10 deletions tests/ui/impl-trait/nested-rpit-hrtb.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/nested-rpit-hrtb.rs:57:77
--> $DIR/nested-rpit-hrtb.rs:56:77
|
LL | fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {}
| ^^ undeclared lifetime
Expand All @@ -15,7 +15,7 @@ LL | fn two_htrb_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Siz
| ++++

error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/nested-rpit-hrtb.rs:65:82
--> $DIR/nested-rpit-hrtb.rs:64:82
|
LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {}
| ^^ undeclared lifetime
Expand Down Expand Up @@ -87,12 +87,6 @@ LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc
but trait `Qux<'_>` is implemented for `()`
= help: for that trait implementation, expected `()`, found `&'a ()`

error: lifetime may not live long enough
--> $DIR/nested-rpit-hrtb.rs:49:93
|
LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {}
| -- lifetime `'b` defined here ^^ opaque type requires that `'b` must outlive `'static`

error: implementation of `Bar` is not general enough
--> $DIR/nested-rpit-hrtb.rs:49:93
|
Expand All @@ -103,7 +97,7 @@ LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc =
= note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0`

error[E0277]: the trait bound `for<'a, 'b> &'a (): Qux<'b>` is not satisfied
--> $DIR/nested-rpit-hrtb.rs:61:64
--> $DIR/nested-rpit-hrtb.rs:60:64
|
LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {}
| ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Qux<'b>` is not implemented for `&'a ()`
Expand All @@ -112,7 +106,7 @@ LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b>
but trait `Qux<'_>` is implemented for `()`
= help: for that trait implementation, expected `()`, found `&'a ()`

error: aborting due to 10 previous errors
error: aborting due to 9 previous errors

Some errors have detailed explanations: E0261, E0277, E0657.
For more information about an error, try `rustc --explain E0261`.
26 changes: 14 additions & 12 deletions tests/ui/nll/ice-106874.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ LL | A(B(C::new(D::new(move |st| f(st)))))
= note: ...but it actually implements `FnOnce<(&'1 mut V,)>`, for some specific lifetime `'1`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: higher-ranked subtype error
--> $DIR/ice-106874.rs:8:5
|
LL | A(B(C::new(D::new(move |st| f(st)))))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: higher-ranked subtype error
--> $DIR/ice-106874.rs:8:5
|
LL | A(B(C::new(D::new(move |st| f(st)))))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: implementation of `FnOnce` is not general enough
--> $DIR/ice-106874.rs:8:7
|
Expand Down Expand Up @@ -75,17 +89,5 @@ LL | A(B(C::new(D::new(move |st| f(st)))))
= note: ...but it actually implements `Fn<(&'2 mut V,)>`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: higher-ranked subtype error
--> $DIR/ice-106874.rs:8:7
|
LL | A(B(C::new(D::new(move |st| f(st)))))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: higher-ranked subtype error
--> $DIR/ice-106874.rs:8:41
|
LL | A(B(C::new(D::new(move |st| f(st)))))
| ^

error: aborting due to 10 previous errors

Loading