1
Fork 0

Add filtering based on involved required lifetime

More accurate filtering still needed.
This commit is contained in:
Esteban Kuber 2021-10-12 09:19:14 +00:00
parent ab45ab83ac
commit 09dbf37213
3 changed files with 21 additions and 23 deletions

View file

@ -156,11 +156,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
spans.dedup_by_key(|span| (span.lo(), span.hi())); spans.dedup_by_key(|span| (span.lo(), span.hi()));
// We try to make the output have fewer overlapping spans if possible. // We try to make the output have fewer overlapping spans if possible.
let (require_msg, require_span) = if sup_origin.span().overlaps(return_sp) { let require_msg = if spans.is_empty() {
("...is captured and required to live as long as `'static` here", sup_origin.span()) "...is captured and required to live as long as `'static` here"
} else { } else {
("...and is required to live as long as `'static` here", return_sp) "...and is required to live as long as `'static` here"
}; };
let require_span =
if sup_origin.span().overlaps(return_sp) { sup_origin.span() } else { return_sp };
for span in &spans { for span in &spans {
err.span_label(*span, "...is captured here..."); err.span_label(*span, "...is captured here...");

View file

@ -48,7 +48,7 @@ pub fn resolve<'tcx>(
values.values.iter_mut().for_each(|v| match *v { values.values.iter_mut().for_each(|v| match *v {
VarValue::Value(ref mut r) => *r = re_erased, VarValue::Value(ref mut r) => *r = re_erased,
VarValue::ErrorValue => {} VarValue::ErrorValue(_) => {}
}); });
(values, errors) (values, errors)
} }
@ -69,7 +69,7 @@ pub struct LexicalRegionResolutions<'tcx> {
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
enum VarValue<'tcx> { enum VarValue<'tcx> {
Value(Region<'tcx>), Value(Region<'tcx>),
ErrorValue, ErrorValue(RegionVid),
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -233,7 +233,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
(None, a_region, b_vid, b_data) (None, a_region, b_vid, b_data)
} }
Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) { Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) {
VarValue::ErrorValue => continue, VarValue::ErrorValue(_) => continue,
VarValue::Value(a_region) => { VarValue::Value(a_region) => {
let b_data = var_values.value_mut(b_vid); let b_data = var_values.value_mut(b_vid);
(Some(a_vid), a_region, b_vid, b_data) (Some(a_vid), a_region, b_vid, b_data)
@ -250,7 +250,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
} }
if let Some(a_vid) = a_vid { if let Some(a_vid) = a_vid {
match *b_data { match *b_data {
VarValue::Value(ReStatic) | VarValue::ErrorValue => (), VarValue::Value(ReStatic) | VarValue::ErrorValue(_) => (),
_ => { _ => {
constraints[a_vid].push((a_vid, b_vid)); constraints[a_vid].push((a_vid, b_vid));
constraints[b_vid].push((a_vid, b_vid)); constraints[b_vid].push((a_vid, b_vid));
@ -262,14 +262,14 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
while let Some(vid) = changes.pop() { while let Some(vid) = changes.pop() {
constraints[vid].retain(|&(a_vid, b_vid)| { constraints[vid].retain(|&(a_vid, b_vid)| {
let a_region = match *var_values.value(a_vid) { let a_region = match *var_values.value(a_vid) {
VarValue::ErrorValue => return false, VarValue::ErrorValue(_) => return false,
VarValue::Value(a_region) => a_region, VarValue::Value(a_region) => a_region,
}; };
let b_data = var_values.value_mut(b_vid); let b_data = var_values.value_mut(b_vid);
if self.expand_node(a_region, b_vid, b_data) { if self.expand_node(a_region, b_vid, b_data) {
changes.push(b_vid); changes.push(b_vid);
} }
!matches!(b_data, VarValue::Value(ReStatic) | VarValue::ErrorValue) !matches!(b_data, VarValue::Value(ReStatic) | VarValue::ErrorValue(_))
}); });
} }
} }
@ -332,7 +332,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
true true
} }
VarValue::ErrorValue => false, VarValue::ErrorValue(_) => false,
} }
} }
@ -476,7 +476,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
debug!("contraction: {:?} == {:?}, {:?}", a_vid, a_data, b_region); debug!("contraction: {:?} == {:?}, {:?}", a_vid, a_data, b_region);
let a_region = match *a_data { let a_region = match *a_data {
VarValue::ErrorValue => continue, VarValue::ErrorValue(_) => continue,
VarValue::Value(a_region) => a_region, VarValue::Value(a_region) => a_region,
}; };
@ -489,7 +489,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
cannot verify that {:?}={:?} <= {:?}", cannot verify that {:?}={:?} <= {:?}",
origin, a_vid, a_region, b_region origin, a_vid, a_region, b_region
); );
*a_data = VarValue::ErrorValue; *a_data = VarValue::ErrorValue(a_vid);
} }
} }
} }
@ -545,7 +545,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
for (node_vid, value) in var_data.values.iter_enumerated() { for (node_vid, value) in var_data.values.iter_enumerated() {
match *value { match *value {
VarValue::Value(_) => { /* Inference successful */ } VarValue::Value(_) => { /* Inference successful */ }
VarValue::ErrorValue => { VarValue::ErrorValue(reg) => {
// Inference impossible: this value contains // Inference impossible: this value contains
// inconsistent constraints. // inconsistent constraints.
// //
@ -577,9 +577,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
.constraints .constraints
.iter() .iter()
.filter_map(|(constraint, origin)| match (constraint, origin) { .filter_map(|(constraint, origin)| match (constraint, origin) {
(Constraint::VarSubVar(_, _), SubregionOrigin::DataBorrowed(_, sp)) => { (
Some(*sp) Constraint::VarSubVar(_, sup),
} SubregionOrigin::DataBorrowed(_, sp),
) if sup == &reg => Some(*sp),
_ => None, _ => None,
}) })
.collect(); .collect();
@ -898,7 +899,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> {
pub fn resolve_var(&self, rid: RegionVid) -> ty::Region<'tcx> { pub fn resolve_var(&self, rid: RegionVid) -> ty::Region<'tcx> {
let result = match self.values[rid] { let result = match self.values[rid] {
VarValue::Value(r) => r, VarValue::Value(r) => r,
VarValue::ErrorValue => self.error_region, VarValue::ErrorValue(_) => self.error_region,
}; };
debug!("resolve_var({:?}) = {:?}", rid, result); debug!("resolve_var({:?}) = {:?}", rid, result);
result result

View file

@ -4,13 +4,8 @@ error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'
LL | pub async fn run_dummy_fn(&self) { LL | pub async fn run_dummy_fn(&self) {
| ^^^^^ this data with an anonymous lifetime `'_`... | ^^^^^ this data with an anonymous lifetime `'_`...
LL | foo(|| self.bar()).await; LL | foo(|| self.bar()).await;
| ------------------------ ...is captured here... | --- ...is captured and required to live as long as `'static` here
| |
note: ...and is required to live as long as `'static` here
--> $DIR/issue-62097.rs:13:9
|
LL | foo(|| self.bar()).await;
| ^^^
note: `'static` lifetime requirement introduced by this bound note: `'static` lifetime requirement introduced by this bound
--> $DIR/issue-62097.rs:4:19 --> $DIR/issue-62097.rs:4:19
| |