mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-10 00:47:45 +00:00
Don't ICE on regions from anonymous_lifetime_in_impl_trait
This commit is contained in:
parent
0940040c04
commit
e025306fa0
@ -251,7 +251,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||||||
.or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr))
|
.or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr))
|
||||||
.or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr))
|
.or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr))
|
||||||
.or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr))
|
.or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr))
|
||||||
.or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr));
|
.or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr))
|
||||||
|
.or_else(|| self.give_name_if_anonymous_region_appears_in_arg_position_impl_trait(fr));
|
||||||
|
|
||||||
if let Some(ref value) = value {
|
if let Some(ref value) = value {
|
||||||
self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone());
|
self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone());
|
||||||
@ -869,13 +870,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut found = false;
|
let found = tcx
|
||||||
tcx.fold_regions(tcx.type_of(region_parent), |r: ty::Region<'tcx>, _| {
|
.any_free_region_meets(&tcx.type_of(region_parent), |r| *r == ty::ReEarlyBound(region));
|
||||||
if *r == ty::ReEarlyBound(region) {
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
r
|
|
||||||
});
|
|
||||||
|
|
||||||
Some(RegionName {
|
Some(RegionName {
|
||||||
name: self.synthesize_region_name(),
|
name: self.synthesize_region_name(),
|
||||||
@ -888,4 +884,92 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||||||
),
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn give_name_if_anonymous_region_appears_in_arg_position_impl_trait(
|
||||||
|
&self,
|
||||||
|
fr: RegionVid,
|
||||||
|
) -> Option<RegionName> {
|
||||||
|
let ty::ReEarlyBound(region) = *self.to_error_region(fr)? else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
if region.has_name() {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
let predicates = self
|
||||||
|
.infcx
|
||||||
|
.tcx
|
||||||
|
.predicates_of(self.body.source.def_id())
|
||||||
|
.instantiate_identity(self.infcx.tcx)
|
||||||
|
.predicates;
|
||||||
|
|
||||||
|
if let Some(upvar_index) = self
|
||||||
|
.regioncx
|
||||||
|
.universal_regions()
|
||||||
|
.defining_ty
|
||||||
|
.upvar_tys()
|
||||||
|
.position(|ty| self.any_param_predicate_mentions(&predicates, ty, region))
|
||||||
|
{
|
||||||
|
let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region(
|
||||||
|
self.infcx.tcx,
|
||||||
|
&self.upvars,
|
||||||
|
upvar_index,
|
||||||
|
);
|
||||||
|
let region_name = self.synthesize_region_name();
|
||||||
|
|
||||||
|
Some(RegionName {
|
||||||
|
name: region_name,
|
||||||
|
source: RegionNameSource::AnonRegionFromUpvar(upvar_span, upvar_name),
|
||||||
|
})
|
||||||
|
} else if let Some(arg_index) = self
|
||||||
|
.regioncx
|
||||||
|
.universal_regions()
|
||||||
|
.unnormalized_input_tys
|
||||||
|
.iter()
|
||||||
|
.position(|ty| self.any_param_predicate_mentions(&predicates, *ty, region))
|
||||||
|
{
|
||||||
|
let (arg_name, arg_span) = self.regioncx.get_argument_name_and_span_for_region(
|
||||||
|
self.body,
|
||||||
|
&self.local_names,
|
||||||
|
arg_index,
|
||||||
|
);
|
||||||
|
let region_name = self.synthesize_region_name();
|
||||||
|
|
||||||
|
Some(RegionName {
|
||||||
|
name: region_name,
|
||||||
|
source: RegionNameSource::AnonRegionFromArgument(
|
||||||
|
RegionNameHighlight::CannotMatchHirTy(arg_span, arg_name?.to_string()),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn any_param_predicate_mentions(
|
||||||
|
&self,
|
||||||
|
predicates: &[ty::Predicate<'tcx>],
|
||||||
|
ty: Ty<'tcx>,
|
||||||
|
region: ty::EarlyBoundRegion,
|
||||||
|
) -> bool {
|
||||||
|
let tcx = self.infcx.tcx;
|
||||||
|
ty.walk().any(|arg| {
|
||||||
|
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||||
|
&& let ty::Param(_) = ty.kind()
|
||||||
|
{
|
||||||
|
predicates.iter().any(|pred| {
|
||||||
|
match pred.kind().skip_binder() {
|
||||||
|
ty::PredicateKind::Trait(data) if data.self_ty() == ty => {}
|
||||||
|
ty::PredicateKind::Projection(data) if data.projection_ty.self_ty() == ty => {}
|
||||||
|
_ => return false,
|
||||||
|
}
|
||||||
|
tcx.any_free_region_meets(pred, |r| {
|
||||||
|
*r == ty::ReEarlyBound(region)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
12
src/test/ui/borrowck/anonymous-region-in-apit.rs
Normal file
12
src/test/ui/borrowck/anonymous-region-in-apit.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#![feature(anonymous_lifetime_in_impl_trait)]
|
||||||
|
|
||||||
|
trait Foo<T> {
|
||||||
|
fn bar(self, baz: T);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn qux(foo: impl Foo<&str>) {
|
||||||
|
|baz: &str| foo.bar(baz);
|
||||||
|
//~^ ERROR borrowed data escapes outside of closure
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
16
src/test/ui/borrowck/anonymous-region-in-apit.stderr
Normal file
16
src/test/ui/borrowck/anonymous-region-in-apit.stderr
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
error[E0521]: borrowed data escapes outside of closure
|
||||||
|
--> $DIR/anonymous-region-in-apit.rs:8:17
|
||||||
|
|
|
||||||
|
LL | fn qux(foo: impl Foo<&str>) {
|
||||||
|
| --- lifetime `'2` appears in the type of `foo`
|
||||||
|
LL | |baz: &str| foo.bar(baz);
|
||||||
|
| --- - ^^^^^^^^^^^^
|
||||||
|
| | | |
|
||||||
|
| | | `baz` escapes the closure body here
|
||||||
|
| | | argument requires that `'1` must outlive `'2`
|
||||||
|
| | let's call the lifetime of this reference `'1`
|
||||||
|
| `baz` is a reference that is only valid in the closure body
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0521`.
|
Loading…
Reference in New Issue
Block a user