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
This commit is contained in:
commit
8824994ccd
@ -10,10 +10,9 @@
|
||||
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
|
||||
Promoted,
|
||||
};
|
||||
use rustc_middle::ty::{self, OpaqueHiddenType, Region, RegionVid};
|
||||
use rustc_middle::ty::{self, OpaqueHiddenType, Region, RegionVid, TyCtxt};
|
||||
use rustc_span::symbol::sym;
|
||||
use std::env;
|
||||
use std::fmt::Debug;
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
@ -325,7 +324,7 @@ pub(super) fn dump_mir_results<'tcx>(
|
||||
infcx: &BorrowckInferCtxt<'_, 'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
regioncx: &RegionInferenceContext<'tcx>,
|
||||
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
|
||||
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
|
||||
) {
|
||||
if !dump_enabled(infcx.tcx, "nll", body.source.def_id()) {
|
||||
return;
|
||||
@ -340,9 +339,11 @@ pub(super) fn dump_mir_results<'tcx>(
|
||||
|
||||
if let Some(closure_region_requirements) = closure_region_requirements {
|
||||
writeln!(out, "| Free Region Constraints")?;
|
||||
for_each_region_constraint(closure_region_requirements, &mut |msg| {
|
||||
writeln!(out, "| {}", msg)
|
||||
})?;
|
||||
for_each_region_constraint(
|
||||
infcx.tcx,
|
||||
closure_region_requirements,
|
||||
&mut |msg| writeln!(out, "| {}", msg),
|
||||
)?;
|
||||
writeln!(out, "|")?;
|
||||
}
|
||||
}
|
||||
@ -375,7 +376,7 @@ pub(super) fn dump_annotation<'tcx>(
|
||||
infcx: &BorrowckInferCtxt<'_, 'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
regioncx: &RegionInferenceContext<'tcx>,
|
||||
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
|
||||
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
|
||||
opaque_type_values: &VecMap<LocalDefId, OpaqueHiddenType<'tcx>>,
|
||||
errors: &mut crate::error::BorrowckErrors<'tcx>,
|
||||
) {
|
||||
@ -405,7 +406,7 @@ pub(super) fn dump_annotation<'tcx>(
|
||||
|
||||
// Dump the region constraints we are imposing *between* those
|
||||
// newly created variables.
|
||||
for_each_region_constraint(closure_region_requirements, &mut |msg| {
|
||||
for_each_region_constraint(tcx, closure_region_requirements, &mut |msg| {
|
||||
err.note(msg);
|
||||
Ok(())
|
||||
})
|
||||
@ -426,16 +427,19 @@ pub(super) fn dump_annotation<'tcx>(
|
||||
errors.buffer_non_error_diag(err);
|
||||
}
|
||||
|
||||
fn for_each_region_constraint(
|
||||
closure_region_requirements: &ClosureRegionRequirements<'_>,
|
||||
fn for_each_region_constraint<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
closure_region_requirements: &ClosureRegionRequirements<'tcx>,
|
||||
with_msg: &mut dyn FnMut(&str) -> io::Result<()>,
|
||||
) -> io::Result<()> {
|
||||
for req in &closure_region_requirements.outlives_requirements {
|
||||
let subject: &dyn Debug = match &req.subject {
|
||||
ClosureOutlivesSubject::Region(subject) => subject,
|
||||
ClosureOutlivesSubject::Ty(ty) => ty,
|
||||
let subject = match req.subject {
|
||||
ClosureOutlivesSubject::Region(subject) => format!("{:?}", subject),
|
||||
ClosureOutlivesSubject::Ty(ty) => {
|
||||
format!("{:?}", ty.instantiate(tcx, |vid| tcx.mk_re_var(vid)))
|
||||
}
|
||||
};
|
||||
with_msg(&format!("where {:?}: {:?}", subject, req.outlived_free_region,))?;
|
||||
with_msg(&format!("where {}: {:?}", subject, req.outlived_free_region,))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -12,8 +12,9 @@
|
||||
use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq};
|
||||
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin};
|
||||
use rustc_middle::mir::{
|
||||
Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements,
|
||||
ConstraintCategory, Local, Location, ReturnConstraint, TerminatorKind,
|
||||
Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureOutlivesSubjectTy,
|
||||
ClosureRegionRequirements, ConstraintCategory, Local, Location, ReturnConstraint,
|
||||
TerminatorKind,
|
||||
};
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::traits::ObligationCauseCode;
|
||||
@ -1084,18 +1085,10 @@ fn try_promote_type_test(
|
||||
true
|
||||
}
|
||||
|
||||
/// When we promote a type test `T: 'r`, we have to convert the
|
||||
/// type `T` into something we can store in a query result (so
|
||||
/// something allocated for `'tcx`). This is problematic if `ty`
|
||||
/// contains regions. During the course of NLL region checking, we
|
||||
/// will have replaced all of those regions with fresh inference
|
||||
/// variables. To create a test subject, we want to replace those
|
||||
/// inference variables with some region from the closure
|
||||
/// signature -- this is not always possible, so this is a
|
||||
/// fallible process. Presuming we do find a suitable region, we
|
||||
/// will use it's *external name*, which will be a `RegionKind`
|
||||
/// variant that can be used in query responses such as
|
||||
/// `ReEarlyBound`.
|
||||
/// When we promote a type test `T: 'r`, we have to replace all region
|
||||
/// variables in the type `T` with an equal universal region from the
|
||||
/// closure signature.
|
||||
/// This is not always possible, so this is a fallible process.
|
||||
#[instrument(level = "debug", skip(self, infcx))]
|
||||
fn try_promote_type_test_subject(
|
||||
&self,
|
||||
@ -1104,91 +1097,63 @@ fn try_promote_type_test_subject(
|
||||
) -> Option<ClosureOutlivesSubject<'tcx>> {
|
||||
let tcx = infcx.tcx;
|
||||
|
||||
// Opaque types' substs may include useless lifetimes.
|
||||
// We will replace them with ReStatic.
|
||||
struct OpaqueFolder<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
impl<'tcx> ty::TypeFolder<TyCtxt<'tcx>> for OpaqueFolder<'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
use ty::TypeSuperFoldable as _;
|
||||
let tcx = self.tcx;
|
||||
let &ty::Alias(ty::Opaque, ty::AliasTy { substs, def_id, .. }) = t.kind() else {
|
||||
return t.super_fold_with(self);
|
||||
};
|
||||
let substs =
|
||||
std::iter::zip(substs, tcx.variances_of(def_id)).map(|(arg, v)| {
|
||||
match (arg.unpack(), v) {
|
||||
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => {
|
||||
tcx.lifetimes.re_static.into()
|
||||
}
|
||||
_ => arg.fold_with(self),
|
||||
}
|
||||
});
|
||||
tcx.mk_opaque(def_id, tcx.mk_substs_from_iter(substs))
|
||||
}
|
||||
}
|
||||
|
||||
let ty = ty.fold_with(&mut OpaqueFolder { tcx });
|
||||
|
||||
let ty = tcx.fold_regions(ty, |r, _depth| {
|
||||
let region_vid = self.to_region_vid(r);
|
||||
let r_vid = self.to_region_vid(r);
|
||||
let r_scc = self.constraint_sccs.scc(r_vid);
|
||||
|
||||
// The challenge if this. We have some region variable `r`
|
||||
// whose value is a set of CFG points and universal
|
||||
// regions. We want to find if that set is *equivalent* to
|
||||
// any of the named regions found in the closure.
|
||||
//
|
||||
// To do so, we compute the
|
||||
// `non_local_universal_upper_bound`. This will be a
|
||||
// non-local, universal region that is greater than `r`.
|
||||
// However, it might not be *contained* within `r`, so
|
||||
// then we further check whether this bound is contained
|
||||
// in `r`. If so, we can say that `r` is equivalent to the
|
||||
// bound.
|
||||
//
|
||||
// Let's work through a few examples. For these, imagine
|
||||
// that we have 3 non-local regions (I'll denote them as
|
||||
// `'static`, `'a`, and `'b`, though of course in the code
|
||||
// they would be represented with indices) where:
|
||||
//
|
||||
// - `'static: 'a`
|
||||
// - `'static: 'b`
|
||||
//
|
||||
// First, let's assume that `r` is some existential
|
||||
// variable with an inferred value `{'a, 'static}` (plus
|
||||
// some CFG nodes). In this case, the non-local upper
|
||||
// bound is `'static`, since that outlives `'a`. `'static`
|
||||
// is also a member of `r` and hence we consider `r`
|
||||
// equivalent to `'static` (and replace it with
|
||||
// `'static`).
|
||||
//
|
||||
// Now let's consider the inferred value `{'a, 'b}`. This
|
||||
// means `r` is effectively `'a | 'b`. I'm not sure if
|
||||
// this can come about, actually, but assuming it did, we
|
||||
// would get a non-local upper bound of `'static`. Since
|
||||
// `'static` is not contained in `r`, we would fail to
|
||||
// find an equivalent.
|
||||
let upper_bound = self.non_local_universal_upper_bound(region_vid);
|
||||
if self.region_contains(region_vid, upper_bound) {
|
||||
self.definitions[upper_bound].external_name.unwrap_or(r)
|
||||
} else {
|
||||
// In the case of a failure, use a `ReVar` result. This will
|
||||
// cause the `needs_infer` later on to return `None`.
|
||||
r
|
||||
}
|
||||
// To do so, we simply check every candidate `u_r` for equality.
|
||||
self.scc_values
|
||||
.universal_regions_outlived_by(r_scc)
|
||||
.filter(|&u_r| !self.universal_regions.is_local_free_region(u_r))
|
||||
.find(|&u_r| self.eval_equal(u_r, r_vid))
|
||||
.map(|u_r| tcx.mk_re_var(u_r))
|
||||
// In the case of a failure, use `ReErased`. We will eventually
|
||||
// return `None` in this case.
|
||||
.unwrap_or(tcx.lifetimes.re_erased)
|
||||
});
|
||||
|
||||
debug!("try_promote_type_test_subject: folded ty = {:?}", ty);
|
||||
|
||||
// `needs_infer` will only be true if we failed to promote some region.
|
||||
if ty.needs_infer() {
|
||||
// This will be true if we failed to promote some region.
|
||||
if ty.has_erased_regions() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(ClosureOutlivesSubject::Ty(ty))
|
||||
}
|
||||
|
||||
/// Given some universal or existential region `r`, finds a
|
||||
/// non-local, universal region `r+` that outlives `r` at entry to (and
|
||||
/// exit from) the closure. In the worst case, this will be
|
||||
/// `'static`.
|
||||
///
|
||||
/// This is used for two purposes. First, if we are propagated
|
||||
/// some requirement `T: r`, we can use this method to enlarge `r`
|
||||
/// to something we can encode for our creator (which only knows
|
||||
/// about non-local, universal regions). It is also used when
|
||||
/// encoding `T` as part of `try_promote_type_test_subject` (see
|
||||
/// that fn for details).
|
||||
///
|
||||
/// This is based on the result `'y` of `universal_upper_bound`,
|
||||
/// except that it converts further takes the non-local upper
|
||||
/// bound of `'y`, so that the final result is non-local.
|
||||
fn non_local_universal_upper_bound(&self, r: RegionVid) -> RegionVid {
|
||||
debug!("non_local_universal_upper_bound(r={:?}={})", r, self.region_value_str(r));
|
||||
|
||||
let lub = self.universal_upper_bound(r);
|
||||
|
||||
// Grow further to get smallest universal region known to
|
||||
// creator.
|
||||
let non_local_lub = self.universal_region_relations.non_local_upper_bound(lub);
|
||||
|
||||
debug!("non_local_universal_upper_bound: non_local_lub={:?}", non_local_lub);
|
||||
|
||||
non_local_lub
|
||||
Some(ClosureOutlivesSubject::Ty(ClosureOutlivesSubjectTy::bind(tcx, ty)))
|
||||
}
|
||||
|
||||
/// Returns a universally quantified region that outlives the
|
||||
|
@ -116,7 +116,9 @@ pub fn apply_closure_requirements(
|
||||
let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
|
||||
let subject = match outlives_requirement.subject {
|
||||
ClosureOutlivesSubject::Region(re) => closure_mapping[re].into(),
|
||||
ClosureOutlivesSubject::Ty(ty) => ty.into(),
|
||||
ClosureOutlivesSubject::Ty(subject_ty) => {
|
||||
subject_ty.instantiate(self.tcx, |vid| closure_mapping[vid]).into()
|
||||
}
|
||||
};
|
||||
|
||||
self.category = outlives_requirement.category;
|
||||
|
@ -93,31 +93,6 @@ pub(crate) fn non_local_upper_bounds(&self, fr: RegionVid) -> Vec<RegionVid> {
|
||||
res
|
||||
}
|
||||
|
||||
/// Returns the "postdominating" bound of the set of
|
||||
/// `non_local_upper_bounds` for the given region.
|
||||
pub(crate) fn non_local_upper_bound(&self, fr: RegionVid) -> RegionVid {
|
||||
let upper_bounds = self.non_local_upper_bounds(fr);
|
||||
|
||||
// In case we find more than one, reduce to one for
|
||||
// convenience. This is to prevent us from generating more
|
||||
// complex constraints, but it will cause spurious errors.
|
||||
let post_dom = self.inverse_outlives.mutual_immediate_postdominator(upper_bounds);
|
||||
|
||||
debug!("non_local_bound: post_dom={:?}", post_dom);
|
||||
|
||||
post_dom
|
||||
.and_then(|post_dom| {
|
||||
// If the mutual immediate postdom is not local, then
|
||||
// there is no non-local result we can return.
|
||||
if !self.universal_regions.is_local_free_region(post_dom) {
|
||||
Some(post_dom)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.unwrap_or(self.universal_regions.fr_static)
|
||||
}
|
||||
|
||||
/// Finds a "lower bound" for `fr` that is not local. In other
|
||||
/// words, returns the largest (*) known region `fr1` that (a) is
|
||||
/// outlived by `fr` and (b) is not local.
|
||||
|
@ -8,7 +8,7 @@
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_index::bit_set::BitMatrix;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use smallvec::SmallVec;
|
||||
@ -289,13 +289,6 @@ pub struct ConstQualifs {
|
||||
/// instance of the closure is created, the corresponding free regions
|
||||
/// can be extracted from its type and constrained to have the given
|
||||
/// outlives relationship.
|
||||
///
|
||||
/// In some cases, we have to record outlives requirements between types and
|
||||
/// regions as well. In that case, if those types include any regions, those
|
||||
/// regions are recorded using their external names (`ReStatic`,
|
||||
/// `ReEarlyBound`, `ReFree`). We use these because in a query response we
|
||||
/// cannot use `ReVar` (which is what we use internally within the rest of the
|
||||
/// NLL code).
|
||||
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||
pub struct ClosureRegionRequirements<'tcx> {
|
||||
/// The number of external regions defined on the closure. In our
|
||||
@ -392,16 +385,59 @@ pub enum ClosureOutlivesSubject<'tcx> {
|
||||
/// Subject is a type, typically a type parameter, but could also
|
||||
/// be a projection. Indicates a requirement like `T: 'a` being
|
||||
/// passed to the caller, where the type here is `T`.
|
||||
///
|
||||
/// The type here is guaranteed not to contain any free regions at
|
||||
/// present.
|
||||
Ty(Ty<'tcx>),
|
||||
Ty(ClosureOutlivesSubjectTy<'tcx>),
|
||||
|
||||
/// Subject is a free region from the closure. Indicates a requirement
|
||||
/// like `'a: 'b` being passed to the caller; the region here is `'a`.
|
||||
Region(ty::RegionVid),
|
||||
}
|
||||
|
||||
/// Represents a `ty::Ty` for use in [`ClosureOutlivesSubject`].
|
||||
///
|
||||
/// This abstraction is necessary because the type may include `ReVar` regions,
|
||||
/// which is what we use internally within NLL code, and they can't be used in
|
||||
/// a query response.
|
||||
///
|
||||
/// DO NOT implement `TypeVisitable` or `TypeFoldable` traits, because this
|
||||
/// type is not recognized as a binder for late-bound region.
|
||||
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||
pub struct ClosureOutlivesSubjectTy<'tcx> {
|
||||
inner: Ty<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
|
||||
/// All regions of `ty` must be of kind `ReVar` and must represent
|
||||
/// universal regions *external* to the closure.
|
||||
pub fn bind(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
|
||||
let inner = tcx.fold_regions(ty, |r, depth| match r.kind() {
|
||||
ty::ReVar(vid) => {
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::new(vid.index()),
|
||||
kind: ty::BrAnon(vid.as_u32(), None),
|
||||
};
|
||||
tcx.mk_re_late_bound(depth, br)
|
||||
}
|
||||
_ => bug!("unexpected region in ClosureOutlivesSubjectTy: {r:?}"),
|
||||
});
|
||||
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub fn instantiate(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
tcx.fold_regions(self.inner, |r, depth| match r.kind() {
|
||||
ty::ReLateBound(debruijn, br) => {
|
||||
debug_assert_eq!(debruijn, depth);
|
||||
map(ty::RegionVid::new(br.var.index()))
|
||||
}
|
||||
_ => bug!("unexpected region {r:?}"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// The constituent parts of a mir constant of kind ADT or array.
|
||||
#[derive(Copy, Clone, Debug, HashStable)]
|
||||
pub struct DestructuredConstant<'tcx> {
|
||||
|
@ -0,0 +1,19 @@
|
||||
// See #108639 for description.
|
||||
// check-pass
|
||||
|
||||
trait Trait {
|
||||
type Item<'a>: 'a;
|
||||
}
|
||||
|
||||
fn assert_static<T: 'static>(_: T) {}
|
||||
fn relate<T>(_: T, _: T) {}
|
||||
|
||||
fn test_args<I: Trait>() {
|
||||
let closure = |a, b| {
|
||||
relate(&a, b);
|
||||
assert_static(a);
|
||||
};
|
||||
closure(None::<I::Item<'_>>, &None::<I::Item<'_>>);
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,18 @@
|
||||
// Regression test for #107426.
|
||||
// check-pass
|
||||
|
||||
use std::marker::PhantomData;
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Scope<'a>(&'a PhantomData<&'a mut &'a ()>);
|
||||
fn event<'a, F: FnMut() + 'a>(_: Scope<'a>, _: F) {}
|
||||
fn make_fn<'a>(_: Scope<'a>) -> impl Fn() + Copy + 'a {
|
||||
|| {}
|
||||
}
|
||||
|
||||
fn foo(cx: Scope) {
|
||||
let open_toggle = make_fn(cx);
|
||||
|
||||
|| event(cx, open_toggle);
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,17 @@
|
||||
// Resgression test for #107516.
|
||||
// check-pass
|
||||
|
||||
fn iter1<'a: 'a>() -> impl Iterator<Item = &'static str> {
|
||||
None.into_iter()
|
||||
}
|
||||
|
||||
fn iter2<'a>() -> impl Iterator<Item = &'a str> {
|
||||
None.into_iter()
|
||||
}
|
||||
|
||||
struct Bivar<'a, I: Iterator<Item = &'a str> + 'a>(I);
|
||||
|
||||
fn main() {
|
||||
let _ = || Bivar(iter1());
|
||||
let _ = || Bivar(iter2());
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
// See #108635 for description.
|
||||
// check-pass
|
||||
|
||||
trait Trait {
|
||||
type Item<'a>: 'a;
|
||||
}
|
||||
|
||||
fn assert_static<T: 'static>(_: T) {}
|
||||
|
||||
fn test_args<I: Trait>() {
|
||||
let closure = |a, _b| assert_static(a);
|
||||
|
||||
closure(None::<I::Item<'_>>, &None::<I::Item<'_>>);
|
||||
}
|
||||
|
||||
fn test_upvars<I: Trait>() {
|
||||
let upvars = (None::<I::Item<'_>>, &None::<I::Item<'_>>);
|
||||
let _closure = || {
|
||||
let (a, _b) = upvars;
|
||||
assert_static(a);
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -110,7 +110,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
(),
|
||||
]
|
||||
= note: number of external vids: 4
|
||||
= note: where <T as Anything<ReEarlyBound(1, 'b)>>::AssocType: '_#3r
|
||||
= note: where <T as Anything<'_#2r>>::AssocType: '_#3r
|
||||
|
||||
note: no external requirements
|
||||
--> $DIR/projection-one-region-closure.rs:62:1
|
||||
|
@ -86,7 +86,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
(),
|
||||
]
|
||||
= note: number of external vids: 4
|
||||
= note: where <T as Anything<ReEarlyBound(1, 'b)>>::AssocType: '_#3r
|
||||
= note: where <T as Anything<'_#2r>>::AssocType: '_#3r
|
||||
|
||||
note: no external requirements
|
||||
--> $DIR/projection-one-region-trait-bound-closure.rs:52:1
|
||||
|
@ -11,7 +11,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
]
|
||||
= note: late-bound region is '_#4r
|
||||
= note: number of external vids: 5
|
||||
= note: where <T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType: '_#3r
|
||||
= note: where <T as Anything<'_#1r, '_#2r>>::AssocType: '_#3r
|
||||
|
||||
note: no external requirements
|
||||
--> $DIR/projection-two-region-trait-bound-closure.rs:34:1
|
||||
@ -23,14 +23,14 @@ LL | | T: Anything<'b, 'c>,
|
||||
|
|
||||
= note: defining type: no_relationships_late::<'_#1r, '_#2r, T>
|
||||
|
||||
error[E0309]: the associated type `<T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType` may not live long enough
|
||||
error[E0309]: the associated type `<T as Anything<'_#5r, '_#6r>>::AssocType` may not live long enough
|
||||
--> $DIR/projection-two-region-trait-bound-closure.rs:38:39
|
||||
|
|
||||
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding an explicit lifetime bound `<T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType: 'a`...
|
||||
= note: ...so that the type `<T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType` will meet its required lifetime bounds
|
||||
= help: consider adding an explicit lifetime bound `<T as Anything<'_#5r, '_#6r>>::AssocType: 'a`...
|
||||
= note: ...so that the type `<T as Anything<'_#5r, '_#6r>>::AssocType` will meet its required lifetime bounds
|
||||
|
||||
note: external requirements
|
||||
--> $DIR/projection-two-region-trait-bound-closure.rs:48:29
|
||||
@ -44,7 +44,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
(),
|
||||
]
|
||||
= note: number of external vids: 5
|
||||
= note: where <T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType: '_#4r
|
||||
= note: where <T as Anything<'_#2r, '_#3r>>::AssocType: '_#4r
|
||||
|
||||
note: no external requirements
|
||||
--> $DIR/projection-two-region-trait-bound-closure.rs:43:1
|
||||
@ -57,14 +57,14 @@ LL | | 'a: 'a,
|
||||
|
|
||||
= note: defining type: no_relationships_early::<'_#1r, '_#2r, '_#3r, T>
|
||||
|
||||
error[E0309]: the associated type `<T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType` may not live long enough
|
||||
error[E0309]: the associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
|
||||
--> $DIR/projection-two-region-trait-bound-closure.rs:48:39
|
||||
|
|
||||
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding an explicit lifetime bound `<T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType: 'a`...
|
||||
= note: ...so that the type `<T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType` will meet its required lifetime bounds
|
||||
= help: consider adding an explicit lifetime bound `<T as Anything<'_#6r, '_#7r>>::AssocType: 'a`...
|
||||
= note: ...so that the type `<T as Anything<'_#6r, '_#7r>>::AssocType` will meet its required lifetime bounds
|
||||
|
||||
note: external requirements
|
||||
--> $DIR/projection-two-region-trait-bound-closure.rs:61:29
|
||||
@ -78,7 +78,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
(),
|
||||
]
|
||||
= note: number of external vids: 5
|
||||
= note: where <T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType: '_#4r
|
||||
= note: where <T as Anything<'_#2r, '_#3r>>::AssocType: '_#4r
|
||||
|
||||
note: no external requirements
|
||||
--> $DIR/projection-two-region-trait-bound-closure.rs:53:1
|
||||
@ -103,7 +103,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
(),
|
||||
]
|
||||
= note: number of external vids: 5
|
||||
= note: where <T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType: '_#4r
|
||||
= note: where <T as Anything<'_#2r, '_#3r>>::AssocType: '_#4r
|
||||
|
||||
note: no external requirements
|
||||
--> $DIR/projection-two-region-trait-bound-closure.rs:65:1
|
||||
@ -128,7 +128,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
(),
|
||||
]
|
||||
= note: number of external vids: 5
|
||||
= note: where <T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType: '_#4r
|
||||
= note: where <T as Anything<'_#2r, '_#3r>>::AssocType: '_#4r
|
||||
|
||||
note: no external requirements
|
||||
--> $DIR/projection-two-region-trait-bound-closure.rs:74:1
|
||||
@ -154,7 +154,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
]
|
||||
= note: late-bound region is '_#3r
|
||||
= note: number of external vids: 4
|
||||
= note: where <T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(0, 'b)>>::AssocType: '_#2r
|
||||
= note: where <T as Anything<'_#1r, '_#1r>>::AssocType: '_#2r
|
||||
|
||||
note: no external requirements
|
||||
--> $DIR/projection-two-region-trait-bound-closure.rs:83:1
|
||||
@ -194,7 +194,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
(),
|
||||
]
|
||||
= note: number of external vids: 4
|
||||
= note: where <T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(1, 'b)>>::AssocType: '_#3r
|
||||
= note: where <T as Anything<'_#2r, '_#2r>>::AssocType: '_#3r
|
||||
|
||||
note: no external requirements
|
||||
--> $DIR/projection-two-region-trait-bound-closure.rs:92:1
|
||||
@ -219,7 +219,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
(),
|
||||
]
|
||||
= note: number of external vids: 3
|
||||
= note: where <T as Anything<ReEarlyBound(0, 'a), ReEarlyBound(0, 'a)>>::AssocType: '_#2r
|
||||
= note: where <T as Anything<'_#1r, '_#1r>>::AssocType: '_#2r
|
||||
|
||||
note: no external requirements
|
||||
--> $DIR/projection-two-region-trait-bound-closure.rs:101:1
|
||||
|
Loading…
Reference in New Issue
Block a user