make for<> in closures a possible place to suggest adding named lifetime
This commit is contained in:
parent
c2dbd62c7c
commit
0c284843ba
2 changed files with 36 additions and 4 deletions
|
@ -70,6 +70,8 @@ pub(crate) enum ForLifetimeSpanType {
|
||||||
BoundTail,
|
BoundTail,
|
||||||
TypeEmpty,
|
TypeEmpty,
|
||||||
TypeTail,
|
TypeTail,
|
||||||
|
ClosureEmpty,
|
||||||
|
ClosureTail,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ForLifetimeSpanType {
|
impl ForLifetimeSpanType {
|
||||||
|
@ -77,13 +79,15 @@ impl ForLifetimeSpanType {
|
||||||
match self {
|
match self {
|
||||||
Self::BoundEmpty | Self::BoundTail => "bound",
|
Self::BoundEmpty | Self::BoundTail => "bound",
|
||||||
Self::TypeEmpty | Self::TypeTail => "type",
|
Self::TypeEmpty | Self::TypeTail => "type",
|
||||||
|
Self::ClosureEmpty | Self::ClosureTail => "closure",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn suggestion(&self, sugg: &str) -> String {
|
pub(crate) fn suggestion(&self, sugg: &str) -> String {
|
||||||
match self {
|
match self {
|
||||||
Self::BoundEmpty | Self::TypeEmpty => format!("for<{}> ", sugg),
|
Self::BoundEmpty | Self::TypeEmpty => format!("for<{}> ", sugg),
|
||||||
Self::BoundTail | Self::TypeTail => format!(", {}", sugg),
|
Self::ClosureEmpty => format!("for<{}>", sugg),
|
||||||
|
Self::BoundTail | Self::TypeTail | Self::ClosureTail => format!(", {}", sugg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::{DefIdMap, LocalDefId};
|
use rustc_hir::def_id::{DefIdMap, LocalDefId};
|
||||||
use rustc_hir::intravisit::{self, Visitor};
|
use rustc_hir::intravisit::{self, Visitor};
|
||||||
use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node};
|
use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node};
|
||||||
use rustc_hir::{GenericParamKind, HirIdMap};
|
use rustc_hir::{GenericParamKind, HirIdMap, LifetimeParamKind};
|
||||||
use rustc_middle::hir::map::Map;
|
use rustc_middle::hir::map::Map;
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::middle::resolve_lifetime::*;
|
use rustc_middle::middle::resolve_lifetime::*;
|
||||||
|
@ -629,8 +629,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
// FIXME: missing_named_lifetime_spots
|
|
||||||
|
|
||||||
self.map.late_bound_vars.insert(e.hir_id, binders);
|
self.map.late_bound_vars.insert(e.hir_id, binders);
|
||||||
let scope = Scope::Binder {
|
let scope = Scope::Binder {
|
||||||
hir_id: e.hir_id,
|
hir_id: e.hir_id,
|
||||||
|
@ -642,11 +640,41 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
allow_late_bound: true,
|
allow_late_bound: true,
|
||||||
where_bound_origin: None,
|
where_bound_origin: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let &hir::ClosureBinder::For { span, .. } = binder {
|
||||||
|
let last_lt = bound_generic_params
|
||||||
|
.iter()
|
||||||
|
.filter(|p| {
|
||||||
|
matches!(
|
||||||
|
p,
|
||||||
|
GenericParam {
|
||||||
|
kind: GenericParamKind::Lifetime {
|
||||||
|
kind: LifetimeParamKind::Explicit
|
||||||
|
},
|
||||||
|
..
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.last();
|
||||||
|
let (span, span_type) = match last_lt {
|
||||||
|
Some(GenericParam { span: last_sp, .. }) => {
|
||||||
|
(last_sp.shrink_to_hi(), ForLifetimeSpanType::ClosureTail)
|
||||||
|
}
|
||||||
|
None => (span, ForLifetimeSpanType::ClosureEmpty),
|
||||||
|
};
|
||||||
|
self.missing_named_lifetime_spots
|
||||||
|
.push(MissingLifetimeSpot::HigherRanked { span, span_type });
|
||||||
|
}
|
||||||
|
|
||||||
self.with(scope, |this| {
|
self.with(scope, |this| {
|
||||||
// a closure has no bounds, so everything
|
// a closure has no bounds, so everything
|
||||||
// contained within is scoped within its binder.
|
// contained within is scoped within its binder.
|
||||||
intravisit::walk_expr(this, e)
|
intravisit::walk_expr(this, e)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if let hir::ClosureBinder::For { .. } = binder {
|
||||||
|
self.missing_named_lifetime_spots.pop();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
intravisit::walk_expr(self, e)
|
intravisit::walk_expr(self, e)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue