diff options
| author | Maybe Waffle <waffle.lapkin@gmail.com> | 2022-06-30 13:06:19 +0400 |
|---|---|---|
| committer | Maybe Waffle <waffle.lapkin@gmail.com> | 2022-07-12 21:00:13 +0400 |
| commit | 0c284843ba23482a2263e1e60b595ead154baae1 (patch) | |
| tree | 36f544973905aabab11afbfdc6d91d9b9ced53cf | |
| parent | c2dbd62c7c60cd4017c9d499101e40c129e4bc61 (diff) | |
| download | rust-0c284843ba23482a2263e1e60b595ead154baae1.tar.gz rust-0c284843ba23482a2263e1e60b595ead154baae1.zip | |
make for<> in closures a possible place to suggest adding named lifetime
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/lifetimes.rs | 34 |
2 files changed, 36 insertions, 4 deletions
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 03cb1cfcfc9..d46f0319f2c 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -70,6 +70,8 @@ pub(crate) enum ForLifetimeSpanType { BoundTail, TypeEmpty, TypeTail, + ClosureEmpty, + ClosureTail, } impl ForLifetimeSpanType { @@ -77,13 +79,15 @@ impl ForLifetimeSpanType { match self { Self::BoundEmpty | Self::BoundTail => "bound", Self::TypeEmpty | Self::TypeTail => "type", + Self::ClosureEmpty | Self::ClosureTail => "closure", } } pub(crate) fn suggestion(&self, sugg: &str) -> String { match self { 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), } } } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 547255498a0..8763279a668 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -15,7 +15,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefIdMap, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; 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::nested_filter; use rustc_middle::middle::resolve_lifetime::*; @@ -629,8 +629,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }) .unzip(); - // FIXME: missing_named_lifetime_spots - self.map.late_bound_vars.insert(e.hir_id, binders); let scope = Scope::Binder { hir_id: e.hir_id, @@ -642,11 +640,41 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { allow_late_bound: true, 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| { // a closure has no bounds, so everything // contained within is scoped within its binder. intravisit::walk_expr(this, e) }); + + if let hir::ClosureBinder::For { .. } = binder { + self.missing_named_lifetime_spots.pop(); + } } else { intravisit::walk_expr(self, e) } |
