Skip to content

Commit 0c28484

Browse files
committed
make for<> in closures a possible place to suggest adding named lifetime
1 parent c2dbd62 commit 0c28484

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,24 @@ pub(crate) enum ForLifetimeSpanType {
7070
BoundTail,
7171
TypeEmpty,
7272
TypeTail,
73+
ClosureEmpty,
74+
ClosureTail,
7375
}
7476

7577
impl ForLifetimeSpanType {
7678
pub(crate) fn descr(&self) -> &'static str {
7779
match self {
7880
Self::BoundEmpty | Self::BoundTail => "bound",
7981
Self::TypeEmpty | Self::TypeTail => "type",
82+
Self::ClosureEmpty | Self::ClosureTail => "closure",
8083
}
8184
}
8285

8386
pub(crate) fn suggestion(&self, sugg: &str) -> String {
8487
match self {
8588
Self::BoundEmpty | Self::TypeEmpty => format!("for<{}> ", sugg),
86-
Self::BoundTail | Self::TypeTail => format!(", {}", sugg),
89+
Self::ClosureEmpty => format!("for<{}>", sugg),
90+
Self::BoundTail | Self::TypeTail | Self::ClosureTail => format!(", {}", sugg),
8791
}
8892
}
8993
}

compiler/rustc_resolve/src/late/lifetimes.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_hir::def::{DefKind, Res};
1515
use rustc_hir::def_id::{DefIdMap, LocalDefId};
1616
use rustc_hir::intravisit::{self, Visitor};
1717
use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node};
18-
use rustc_hir::{GenericParamKind, HirIdMap};
18+
use rustc_hir::{GenericParamKind, HirIdMap, LifetimeParamKind};
1919
use rustc_middle::hir::map::Map;
2020
use rustc_middle::hir::nested_filter;
2121
use rustc_middle::middle::resolve_lifetime::*;
@@ -629,8 +629,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
629629
})
630630
.unzip();
631631

632-
// FIXME: missing_named_lifetime_spots
633-
634632
self.map.late_bound_vars.insert(e.hir_id, binders);
635633
let scope = Scope::Binder {
636634
hir_id: e.hir_id,
@@ -642,11 +640,41 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
642640
allow_late_bound: true,
643641
where_bound_origin: None,
644642
};
643+
644+
if let &hir::ClosureBinder::For { span, .. } = binder {
645+
let last_lt = bound_generic_params
646+
.iter()
647+
.filter(|p| {
648+
matches!(
649+
p,
650+
GenericParam {
651+
kind: GenericParamKind::Lifetime {
652+
kind: LifetimeParamKind::Explicit
653+
},
654+
..
655+
}
656+
)
657+
})
658+
.last();
659+
let (span, span_type) = match last_lt {
660+
Some(GenericParam { span: last_sp, .. }) => {
661+
(last_sp.shrink_to_hi(), ForLifetimeSpanType::ClosureTail)
662+
}
663+
None => (span, ForLifetimeSpanType::ClosureEmpty),
664+
};
665+
self.missing_named_lifetime_spots
666+
.push(MissingLifetimeSpot::HigherRanked { span, span_type });
667+
}
668+
645669
self.with(scope, |this| {
646670
// a closure has no bounds, so everything
647671
// contained within is scoped within its binder.
648672
intravisit::walk_expr(this, e)
649673
});
674+
675+
if let hir::ClosureBinder::For { .. } = binder {
676+
self.missing_named_lifetime_spots.pop();
677+
}
650678
} else {
651679
intravisit::walk_expr(self, e)
652680
}

0 commit comments

Comments
 (0)