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 8824994

Browse files
committedMar 7, 2023
Auto merge of #108691 - aliemjay:closure-subject, r=jackh726
fix multiple issues when promoting type-test subject Multiple interdependent fixes. See linked issues for a short description of each. When Promoting a type-test `T: 'a` from within the closure back to its parent function, there are a couple pre-existing bugs and limitations. They were exposed by the recent changes to opaque types because the type-test subject (`T`) is no longer a simple ParamTy. Commit 1: Fixes #108635 Fixes #107426 Commit 2: Fixes #108639 Commit 3: Fixes #107516
2 parents 81be7b8 + 427dc18 commit 8824994

12 files changed

+214
-154
lines changed
 

‎compiler/rustc_borrowck/src/nll.rs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ use rustc_middle::mir::{
1010
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
1111
Promoted,
1212
};
13-
use rustc_middle::ty::{self, OpaqueHiddenType, Region, RegionVid};
13+
use rustc_middle::ty::{self, OpaqueHiddenType, Region, RegionVid, TyCtxt};
1414
use rustc_span::symbol::sym;
1515
use std::env;
16-
use std::fmt::Debug;
1716
use std::io;
1817
use std::path::PathBuf;
1918
use std::rc::Rc;
@@ -325,7 +324,7 @@ pub(super) fn dump_mir_results<'tcx>(
325324
infcx: &BorrowckInferCtxt<'_, 'tcx>,
326325
body: &Body<'tcx>,
327326
regioncx: &RegionInferenceContext<'tcx>,
328-
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
327+
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
329328
) {
330329
if !dump_enabled(infcx.tcx, "nll", body.source.def_id()) {
331330
return;
@@ -340,9 +339,11 @@ pub(super) fn dump_mir_results<'tcx>(
340339

341340
if let Some(closure_region_requirements) = closure_region_requirements {
342341
writeln!(out, "| Free Region Constraints")?;
343-
for_each_region_constraint(closure_region_requirements, &mut |msg| {
344-
writeln!(out, "| {}", msg)
345-
})?;
342+
for_each_region_constraint(
343+
infcx.tcx,
344+
closure_region_requirements,
345+
&mut |msg| writeln!(out, "| {}", msg),
346+
)?;
346347
writeln!(out, "|")?;
347348
}
348349
}
@@ -375,7 +376,7 @@ pub(super) fn dump_annotation<'tcx>(
375376
infcx: &BorrowckInferCtxt<'_, 'tcx>,
376377
body: &Body<'tcx>,
377378
regioncx: &RegionInferenceContext<'tcx>,
378-
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
379+
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
379380
opaque_type_values: &VecMap<LocalDefId, OpaqueHiddenType<'tcx>>,
380381
errors: &mut crate::error::BorrowckErrors<'tcx>,
381382
) {
@@ -405,7 +406,7 @@ pub(super) fn dump_annotation<'tcx>(
405406

406407
// Dump the region constraints we are imposing *between* those
407408
// newly created variables.
408-
for_each_region_constraint(closure_region_requirements, &mut |msg| {
409+
for_each_region_constraint(tcx, closure_region_requirements, &mut |msg| {
409410
err.note(msg);
410411
Ok(())
411412
})
@@ -426,16 +427,19 @@ pub(super) fn dump_annotation<'tcx>(
426427
errors.buffer_non_error_diag(err);
427428
}
428429

429-
fn for_each_region_constraint(
430-
closure_region_requirements: &ClosureRegionRequirements<'_>,
430+
fn for_each_region_constraint<'tcx>(
431+
tcx: TyCtxt<'tcx>,
432+
closure_region_requirements: &ClosureRegionRequirements<'tcx>,
431433
with_msg: &mut dyn FnMut(&str) -> io::Result<()>,
432434
) -> io::Result<()> {
433435
for req in &closure_region_requirements.outlives_requirements {
434-
let subject: &dyn Debug = match &req.subject {
435-
ClosureOutlivesSubject::Region(subject) => subject,
436-
ClosureOutlivesSubject::Ty(ty) => ty,
436+
let subject = match req.subject {
437+
ClosureOutlivesSubject::Region(subject) => format!("{:?}", subject),
438+
ClosureOutlivesSubject::Ty(ty) => {
439+
format!("{:?}", ty.instantiate(tcx, |vid| tcx.mk_re_var(vid)))
440+
}
437441
};
438-
with_msg(&format!("where {:?}: {:?}", subject, req.outlived_free_region,))?;
442+
with_msg(&format!("where {}: {:?}", subject, req.outlived_free_region,))?;
439443
}
440444
Ok(())
441445
}

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

Lines changed: 51 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ use rustc_infer::infer::outlives::test_type_match;
1212
use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq};
1313
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin};
1414
use rustc_middle::mir::{
15-
Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements,
16-
ConstraintCategory, Local, Location, ReturnConstraint, TerminatorKind,
15+
Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureOutlivesSubjectTy,
16+
ClosureRegionRequirements, ConstraintCategory, Local, Location, ReturnConstraint,
17+
TerminatorKind,
1718
};
1819
use rustc_middle::traits::ObligationCause;
1920
use rustc_middle::traits::ObligationCauseCode;
@@ -1084,18 +1085,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
10841085
true
10851086
}
10861087

1087-
/// When we promote a type test `T: 'r`, we have to convert the
1088-
/// type `T` into something we can store in a query result (so
1089-
/// something allocated for `'tcx`). This is problematic if `ty`
1090-
/// contains regions. During the course of NLL region checking, we
1091-
/// will have replaced all of those regions with fresh inference
1092-
/// variables. To create a test subject, we want to replace those
1093-
/// inference variables with some region from the closure
1094-
/// signature -- this is not always possible, so this is a
1095-
/// fallible process. Presuming we do find a suitable region, we
1096-
/// will use it's *external name*, which will be a `RegionKind`
1097-
/// variant that can be used in query responses such as
1098-
/// `ReEarlyBound`.
1088+
/// When we promote a type test `T: 'r`, we have to replace all region
1089+
/// variables in the type `T` with an equal universal region from the
1090+
/// closure signature.
1091+
/// This is not always possible, so this is a fallible process.
10991092
#[instrument(level = "debug", skip(self, infcx))]
11001093
fn try_promote_type_test_subject(
11011094
&self,
@@ -1104,91 +1097,63 @@ impl<'tcx> RegionInferenceContext<'tcx> {
11041097
) -> Option<ClosureOutlivesSubject<'tcx>> {
11051098
let tcx = infcx.tcx;
11061099

1100+
// Opaque types' substs may include useless lifetimes.
1101+
// We will replace them with ReStatic.
1102+
struct OpaqueFolder<'tcx> {
1103+
tcx: TyCtxt<'tcx>,
1104+
}
1105+
impl<'tcx> ty::TypeFolder<TyCtxt<'tcx>> for OpaqueFolder<'tcx> {
1106+
fn interner(&self) -> TyCtxt<'tcx> {
1107+
self.tcx
1108+
}
1109+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
1110+
use ty::TypeSuperFoldable as _;
1111+
let tcx = self.tcx;
1112+
let &ty::Alias(ty::Opaque, ty::AliasTy { substs, def_id, .. }) = t.kind() else {
1113+
return t.super_fold_with(self);
1114+
};
1115+
let substs =
1116+
std::iter::zip(substs, tcx.variances_of(def_id)).map(|(arg, v)| {
1117+
match (arg.unpack(), v) {
1118+
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => {
1119+
tcx.lifetimes.re_static.into()
1120+
}
1121+
_ => arg.fold_with(self),
1122+
}
1123+
});
1124+
tcx.mk_opaque(def_id, tcx.mk_substs_from_iter(substs))
1125+
}
1126+
}
1127+
1128+
let ty = ty.fold_with(&mut OpaqueFolder { tcx });
1129+
11071130
let ty = tcx.fold_regions(ty, |r, _depth| {
1108-
let region_vid = self.to_region_vid(r);
1131+
let r_vid = self.to_region_vid(r);
1132+
let r_scc = self.constraint_sccs.scc(r_vid);
11091133

11101134
// The challenge if this. We have some region variable `r`
11111135
// whose value is a set of CFG points and universal
11121136
// regions. We want to find if that set is *equivalent* to
11131137
// any of the named regions found in the closure.
1114-
//
1115-
// To do so, we compute the
1116-
// `non_local_universal_upper_bound`. This will be a
1117-
// non-local, universal region that is greater than `r`.
1118-
// However, it might not be *contained* within `r`, so
1119-
// then we further check whether this bound is contained
1120-
// in `r`. If so, we can say that `r` is equivalent to the
1121-
// bound.
1122-
//
1123-
// Let's work through a few examples. For these, imagine
1124-
// that we have 3 non-local regions (I'll denote them as
1125-
// `'static`, `'a`, and `'b`, though of course in the code
1126-
// they would be represented with indices) where:
1127-
//
1128-
// - `'static: 'a`
1129-
// - `'static: 'b`
1130-
//
1131-
// First, let's assume that `r` is some existential
1132-
// variable with an inferred value `{'a, 'static}` (plus
1133-
// some CFG nodes). In this case, the non-local upper
1134-
// bound is `'static`, since that outlives `'a`. `'static`
1135-
// is also a member of `r` and hence we consider `r`
1136-
// equivalent to `'static` (and replace it with
1137-
// `'static`).
1138-
//
1139-
// Now let's consider the inferred value `{'a, 'b}`. This
1140-
// means `r` is effectively `'a | 'b`. I'm not sure if
1141-
// this can come about, actually, but assuming it did, we
1142-
// would get a non-local upper bound of `'static`. Since
1143-
// `'static` is not contained in `r`, we would fail to
1144-
// find an equivalent.
1145-
let upper_bound = self.non_local_universal_upper_bound(region_vid);
1146-
if self.region_contains(region_vid, upper_bound) {
1147-
self.definitions[upper_bound].external_name.unwrap_or(r)
1148-
} else {
1149-
// In the case of a failure, use a `ReVar` result. This will
1150-
// cause the `needs_infer` later on to return `None`.
1151-
r
1152-
}
1138+
// To do so, we simply check every candidate `u_r` for equality.
1139+
self.scc_values
1140+
.universal_regions_outlived_by(r_scc)
1141+
.filter(|&u_r| !self.universal_regions.is_local_free_region(u_r))
1142+
.find(|&u_r| self.eval_equal(u_r, r_vid))
1143+
.map(|u_r| tcx.mk_re_var(u_r))
1144+
// In the case of a failure, use `ReErased`. We will eventually
1145+
// return `None` in this case.
1146+
.unwrap_or(tcx.lifetimes.re_erased)
11531147
});
11541148

11551149
debug!("try_promote_type_test_subject: folded ty = {:?}", ty);
11561150

1157-
// `needs_infer` will only be true if we failed to promote some region.
1158-
if ty.needs_infer() {
1151+
// This will be true if we failed to promote some region.
1152+
if ty.has_erased_regions() {
11591153
return None;
11601154
}
11611155

1162-
Some(ClosureOutlivesSubject::Ty(ty))
1163-
}
1164-
1165-
/// Given some universal or existential region `r`, finds a
1166-
/// non-local, universal region `r+` that outlives `r` at entry to (and
1167-
/// exit from) the closure. In the worst case, this will be
1168-
/// `'static`.
1169-
///
1170-
/// This is used for two purposes. First, if we are propagated
1171-
/// some requirement `T: r`, we can use this method to enlarge `r`
1172-
/// to something we can encode for our creator (which only knows
1173-
/// about non-local, universal regions). It is also used when
1174-
/// encoding `T` as part of `try_promote_type_test_subject` (see
1175-
/// that fn for details).
1176-
///
1177-
/// This is based on the result `'y` of `universal_upper_bound`,
1178-
/// except that it converts further takes the non-local upper
1179-
/// bound of `'y`, so that the final result is non-local.
1180-
fn non_local_universal_upper_bound(&self, r: RegionVid) -> RegionVid {
1181-
debug!("non_local_universal_upper_bound(r={:?}={})", r, self.region_value_str(r));
1182-
1183-
let lub = self.universal_upper_bound(r);
1184-
1185-
// Grow further to get smallest universal region known to
1186-
// creator.
1187-
let non_local_lub = self.universal_region_relations.non_local_upper_bound(lub);
1188-
1189-
debug!("non_local_universal_upper_bound: non_local_lub={:?}", non_local_lub);
1190-
1191-
non_local_lub
1156+
Some(ClosureOutlivesSubject::Ty(ClosureOutlivesSubjectTy::bind(tcx, ty)))
11921157
}
11931158

11941159
/// Returns a universally quantified region that outlives the

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
116116
let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
117117
let subject = match outlives_requirement.subject {
118118
ClosureOutlivesSubject::Region(re) => closure_mapping[re].into(),
119-
ClosureOutlivesSubject::Ty(ty) => ty.into(),
119+
ClosureOutlivesSubject::Ty(subject_ty) => {
120+
subject_ty.instantiate(self.tcx, |vid| closure_mapping[vid]).into()
121+
}
120122
};
121123

122124
self.category = outlives_requirement.category;

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

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -93,31 +93,6 @@ impl UniversalRegionRelations<'_> {
9393
res
9494
}
9595

96-
/// Returns the "postdominating" bound of the set of
97-
/// `non_local_upper_bounds` for the given region.
98-
pub(crate) fn non_local_upper_bound(&self, fr: RegionVid) -> RegionVid {
99-
let upper_bounds = self.non_local_upper_bounds(fr);
100-
101-
// In case we find more than one, reduce to one for
102-
// convenience. This is to prevent us from generating more
103-
// complex constraints, but it will cause spurious errors.
104-
let post_dom = self.inverse_outlives.mutual_immediate_postdominator(upper_bounds);
105-
106-
debug!("non_local_bound: post_dom={:?}", post_dom);
107-
108-
post_dom
109-
.and_then(|post_dom| {
110-
// If the mutual immediate postdom is not local, then
111-
// there is no non-local result we can return.
112-
if !self.universal_regions.is_local_free_region(post_dom) {
113-
Some(post_dom)
114-
} else {
115-
None
116-
}
117-
})
118-
.unwrap_or(self.universal_regions.fr_static)
119-
}
120-
12196
/// Finds a "lower bound" for `fr` that is not local. In other
12297
/// words, returns the largest (*) known region `fr1` that (a) is
12398
/// outlived by `fr` and (b) is not local.

‎compiler/rustc_middle/src/mir/query.rs

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_errors::ErrorGuaranteed;
88
use rustc_hir as hir;
99
use rustc_hir::def_id::{DefId, LocalDefId};
1010
use rustc_index::bit_set::BitMatrix;
11-
use rustc_index::vec::IndexVec;
11+
use rustc_index::vec::{Idx, IndexVec};
1212
use rustc_span::Span;
1313
use rustc_target::abi::VariantIdx;
1414
use smallvec::SmallVec;
@@ -289,13 +289,6 @@ pub struct ConstQualifs {
289289
/// instance of the closure is created, the corresponding free regions
290290
/// can be extracted from its type and constrained to have the given
291291
/// outlives relationship.
292-
///
293-
/// In some cases, we have to record outlives requirements between types and
294-
/// regions as well. In that case, if those types include any regions, those
295-
/// regions are recorded using their external names (`ReStatic`,
296-
/// `ReEarlyBound`, `ReFree`). We use these because in a query response we
297-
/// cannot use `ReVar` (which is what we use internally within the rest of the
298-
/// NLL code).
299292
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
300293
pub struct ClosureRegionRequirements<'tcx> {
301294
/// The number of external regions defined on the closure. In our
@@ -392,16 +385,59 @@ pub enum ClosureOutlivesSubject<'tcx> {
392385
/// Subject is a type, typically a type parameter, but could also
393386
/// be a projection. Indicates a requirement like `T: 'a` being
394387
/// passed to the caller, where the type here is `T`.
395-
///
396-
/// The type here is guaranteed not to contain any free regions at
397-
/// present.
398-
Ty(Ty<'tcx>),
388+
Ty(ClosureOutlivesSubjectTy<'tcx>),
399389

400390
/// Subject is a free region from the closure. Indicates a requirement
401391
/// like `'a: 'b` being passed to the caller; the region here is `'a`.
402392
Region(ty::RegionVid),
403393
}
404394

395+
/// Represents a `ty::Ty` for use in [`ClosureOutlivesSubject`].
396+
///
397+
/// This abstraction is necessary because the type may include `ReVar` regions,
398+
/// which is what we use internally within NLL code, and they can't be used in
399+
/// a query response.
400+
///
401+
/// DO NOT implement `TypeVisitable` or `TypeFoldable` traits, because this
402+
/// type is not recognized as a binder for late-bound region.
403+
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
404+
pub struct ClosureOutlivesSubjectTy<'tcx> {
405+
inner: Ty<'tcx>,
406+
}
407+
408+
impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
409+
/// All regions of `ty` must be of kind `ReVar` and must represent
410+
/// universal regions *external* to the closure.
411+
pub fn bind(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
412+
let inner = tcx.fold_regions(ty, |r, depth| match r.kind() {
413+
ty::ReVar(vid) => {
414+
let br = ty::BoundRegion {
415+
var: ty::BoundVar::new(vid.index()),
416+
kind: ty::BrAnon(vid.as_u32(), None),
417+
};
418+
tcx.mk_re_late_bound(depth, br)
419+
}
420+
_ => bug!("unexpected region in ClosureOutlivesSubjectTy: {r:?}"),
421+
});
422+
423+
Self { inner }
424+
}
425+
426+
pub fn instantiate(
427+
self,
428+
tcx: TyCtxt<'tcx>,
429+
mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>,
430+
) -> Ty<'tcx> {
431+
tcx.fold_regions(self.inner, |r, depth| match r.kind() {
432+
ty::ReLateBound(debruijn, br) => {
433+
debug_assert_eq!(debruijn, depth);
434+
map(ty::RegionVid::new(br.var.index()))
435+
}
436+
_ => bug!("unexpected region {r:?}"),
437+
})
438+
}
439+
}
440+
405441
/// The constituent parts of a mir constant of kind ADT or array.
406442
#[derive(Copy, Clone, Debug, HashStable)]
407443
pub struct DestructuredConstant<'tcx> {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// See #108639 for description.
2+
// check-pass
3+
4+
trait Trait {
5+
type Item<'a>: 'a;
6+
}
7+
8+
fn assert_static<T: 'static>(_: T) {}
9+
fn relate<T>(_: T, _: T) {}
10+
11+
fn test_args<I: Trait>() {
12+
let closure = |a, b| {
13+
relate(&a, b);
14+
assert_static(a);
15+
};
16+
closure(None::<I::Item<'_>>, &None::<I::Item<'_>>);
17+
}
18+
19+
fn main() {}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Regression test for #107426.
2+
// check-pass
3+
4+
use std::marker::PhantomData;
5+
#[derive(Clone, Copy)]
6+
pub struct Scope<'a>(&'a PhantomData<&'a mut &'a ()>);
7+
fn event<'a, F: FnMut() + 'a>(_: Scope<'a>, _: F) {}
8+
fn make_fn<'a>(_: Scope<'a>) -> impl Fn() + Copy + 'a {
9+
|| {}
10+
}
11+
12+
fn foo(cx: Scope) {
13+
let open_toggle = make_fn(cx);
14+
15+
|| event(cx, open_toggle);
16+
}
17+
18+
fn main() {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Resgression test for #107516.
2+
// check-pass
3+
4+
fn iter1<'a: 'a>() -> impl Iterator<Item = &'static str> {
5+
None.into_iter()
6+
}
7+
8+
fn iter2<'a>() -> impl Iterator<Item = &'a str> {
9+
None.into_iter()
10+
}
11+
12+
struct Bivar<'a, I: Iterator<Item = &'a str> + 'a>(I);
13+
14+
fn main() {
15+
let _ = || Bivar(iter1());
16+
let _ = || Bivar(iter2());
17+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// See #108635 for description.
2+
// check-pass
3+
4+
trait Trait {
5+
type Item<'a>: 'a;
6+
}
7+
8+
fn assert_static<T: 'static>(_: T) {}
9+
10+
fn test_args<I: Trait>() {
11+
let closure = |a, _b| assert_static(a);
12+
13+
closure(None::<I::Item<'_>>, &None::<I::Item<'_>>);
14+
}
15+
16+
fn test_upvars<I: Trait>() {
17+
let upvars = (None::<I::Item<'_>>, &None::<I::Item<'_>>);
18+
let _closure = || {
19+
let (a, _b) = upvars;
20+
assert_static(a);
21+
};
22+
}
23+
24+
fn main() {}

‎tests/ui/nll/ty-outlives/projection-one-region-closure.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
110110
(),
111111
]
112112
= note: number of external vids: 4
113-
= note: where <T as Anything<ReEarlyBound(1, 'b)>>::AssocType: '_#3r
113+
= note: where <T as Anything<'_#2r>>::AssocType: '_#3r
114114

115115
note: no external requirements
116116
--> $DIR/projection-one-region-closure.rs:62:1

‎tests/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
8686
(),
8787
]
8888
= note: number of external vids: 4
89-
= note: where <T as Anything<ReEarlyBound(1, 'b)>>::AssocType: '_#3r
89+
= note: where <T as Anything<'_#2r>>::AssocType: '_#3r
9090

9191
note: no external requirements
9292
--> $DIR/projection-one-region-trait-bound-closure.rs:52:1

‎tests/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
1111
]
1212
= note: late-bound region is '_#4r
1313
= note: number of external vids: 5
14-
= note: where <T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType: '_#3r
14+
= note: where <T as Anything<'_#1r, '_#2r>>::AssocType: '_#3r
1515

1616
note: no external requirements
1717
--> $DIR/projection-two-region-trait-bound-closure.rs:34:1
@@ -23,14 +23,14 @@ LL | | T: Anything<'b, 'c>,
2323
|
2424
= note: defining type: no_relationships_late::<'_#1r, '_#2r, T>
2525

26-
error[E0309]: the associated type `<T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType` may not live long enough
26+
error[E0309]: the associated type `<T as Anything<'_#5r, '_#6r>>::AssocType` may not live long enough
2727
--> $DIR/projection-two-region-trait-bound-closure.rs:38:39
2828
|
2929
LL | with_signature(cell, t, |cell, t| require(cell, t));
3030
| ^^^^^^^^^^^^^^^^
3131
|
32-
= help: consider adding an explicit lifetime bound `<T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType: 'a`...
33-
= note: ...so that the type `<T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType` will meet its required lifetime bounds
32+
= help: consider adding an explicit lifetime bound `<T as Anything<'_#5r, '_#6r>>::AssocType: 'a`...
33+
= note: ...so that the type `<T as Anything<'_#5r, '_#6r>>::AssocType` will meet its required lifetime bounds
3434

3535
note: external requirements
3636
--> $DIR/projection-two-region-trait-bound-closure.rs:48:29
@@ -44,7 +44,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
4444
(),
4545
]
4646
= note: number of external vids: 5
47-
= note: where <T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType: '_#4r
47+
= note: where <T as Anything<'_#2r, '_#3r>>::AssocType: '_#4r
4848

4949
note: no external requirements
5050
--> $DIR/projection-two-region-trait-bound-closure.rs:43:1
@@ -57,14 +57,14 @@ LL | | 'a: 'a,
5757
|
5858
= note: defining type: no_relationships_early::<'_#1r, '_#2r, '_#3r, T>
5959

60-
error[E0309]: the associated type `<T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType` may not live long enough
60+
error[E0309]: the associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
6161
--> $DIR/projection-two-region-trait-bound-closure.rs:48:39
6262
|
6363
LL | with_signature(cell, t, |cell, t| require(cell, t));
6464
| ^^^^^^^^^^^^^^^^
6565
|
66-
= help: consider adding an explicit lifetime bound `<T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType: 'a`...
67-
= note: ...so that the type `<T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType` will meet its required lifetime bounds
66+
= help: consider adding an explicit lifetime bound `<T as Anything<'_#6r, '_#7r>>::AssocType: 'a`...
67+
= note: ...so that the type `<T as Anything<'_#6r, '_#7r>>::AssocType` will meet its required lifetime bounds
6868

6969
note: external requirements
7070
--> $DIR/projection-two-region-trait-bound-closure.rs:61:29
@@ -78,7 +78,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
7878
(),
7979
]
8080
= note: number of external vids: 5
81-
= note: where <T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType: '_#4r
81+
= note: where <T as Anything<'_#2r, '_#3r>>::AssocType: '_#4r
8282

8383
note: no external requirements
8484
--> $DIR/projection-two-region-trait-bound-closure.rs:53:1
@@ -103,7 +103,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
103103
(),
104104
]
105105
= note: number of external vids: 5
106-
= note: where <T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType: '_#4r
106+
= note: where <T as Anything<'_#2r, '_#3r>>::AssocType: '_#4r
107107

108108
note: no external requirements
109109
--> $DIR/projection-two-region-trait-bound-closure.rs:65:1
@@ -128,7 +128,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
128128
(),
129129
]
130130
= note: number of external vids: 5
131-
= note: where <T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType: '_#4r
131+
= note: where <T as Anything<'_#2r, '_#3r>>::AssocType: '_#4r
132132

133133
note: no external requirements
134134
--> $DIR/projection-two-region-trait-bound-closure.rs:74:1
@@ -154,7 +154,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
154154
]
155155
= note: late-bound region is '_#3r
156156
= note: number of external vids: 4
157-
= note: where <T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(0, 'b)>>::AssocType: '_#2r
157+
= note: where <T as Anything<'_#1r, '_#1r>>::AssocType: '_#2r
158158

159159
note: no external requirements
160160
--> $DIR/projection-two-region-trait-bound-closure.rs:83:1
@@ -194,7 +194,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
194194
(),
195195
]
196196
= note: number of external vids: 4
197-
= note: where <T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(1, 'b)>>::AssocType: '_#3r
197+
= note: where <T as Anything<'_#2r, '_#2r>>::AssocType: '_#3r
198198

199199
note: no external requirements
200200
--> $DIR/projection-two-region-trait-bound-closure.rs:92:1
@@ -219,7 +219,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
219219
(),
220220
]
221221
= note: number of external vids: 3
222-
= note: where <T as Anything<ReEarlyBound(0, 'a), ReEarlyBound(0, 'a)>>::AssocType: '_#2r
222+
= note: where <T as Anything<'_#1r, '_#1r>>::AssocType: '_#2r
223223

224224
note: no external requirements
225225
--> $DIR/projection-two-region-trait-bound-closure.rs:101:1

0 commit comments

Comments
 (0)
Please sign in to comment.