1
Fork 0

Lint elided lifetimes in path during lifetime resolution.

This commit is contained in:
Camille GILLOT 2021-07-11 15:04:57 +02:00
parent ac03470c3b
commit 5ea7ea8a57
13 changed files with 181 additions and 78 deletions

View file

@ -1928,6 +1928,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let param_name = match lt.name {
hir::LifetimeName::Param(param_name) => param_name,
hir::LifetimeName::Implicit
| hir::LifetimeName::ImplicitMissing
| hir::LifetimeName::Underscore
| hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
hir::LifetimeName::ImplicitObjectLifetimeDefault => {
@ -2322,11 +2323,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&'s mut self,
span: Span,
count: usize,
param_mode: ParamMode,
) -> impl Iterator<Item = hir::Lifetime> + Captures<'a> + Captures<'s> + Captures<'hir> {
(0..count).map(move |_| self.elided_path_lifetime(span))
(0..count).map(move |_| self.elided_path_lifetime(span, param_mode))
}
fn elided_path_lifetime(&mut self, span: Span) -> hir::Lifetime {
fn elided_path_lifetime(&mut self, span: Span, param_mode: ParamMode) -> hir::Lifetime {
match self.anonymous_lifetime_mode {
AnonymousLifetimeMode::CreateParameter => {
// We should have emitted E0726 when processing this path above
@ -2342,7 +2344,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// lifetime. Instead, we simply create an implicit lifetime, which will be checked
// later, at which point a suitable error will be emitted.
AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {
self.new_implicit_lifetime(span)
if param_mode == ParamMode::Explicit {
let id = self.resolver.next_node_id();
self.new_named_lifetime(id, span, hir::LifetimeName::ImplicitMissing)
} else {
self.new_implicit_lifetime(span)
}
}
}
}
@ -2536,7 +2543,9 @@ fn lifetimes_from_impl_trait_bounds(
fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
let name = match lifetime.name {
hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
hir::LifetimeName::Implicit
| hir::LifetimeName::ImplicitMissing
| hir::LifetimeName::Underscore => {
if self.collect_elided_lifetimes {
// Use `'_` for both implicit and underscore lifetimes in
// `type Foo<'_> = impl SomeTrait<'_>;`.

View file

@ -7,8 +7,6 @@ use rustc_hir as hir;
use rustc_hir::def::{DefKind, PartialRes, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::GenericArg;
use rustc_session::lint::builtin::ELIDED_LIFETIMES_IN_PATHS;
use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_span::symbol::Ident;
use rustc_span::{BytePos, Span, DUMMY_SP};
@ -275,7 +273,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label
let elided_lifetime_span = if generic_args.span.is_empty() {
// If there are no brackets, use the identifier span.
segment.ident.span
path_span
} else if generic_args.is_empty() {
// If there are brackets, but not generic arguments, then use the opening bracket
generic_args.span.with_hi(generic_args.span.lo() + BytePos(1))
@ -284,7 +282,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
generic_args.span.with_lo(generic_args.span.lo() + BytePos(1)).shrink_to_lo()
};
generic_args.args = self
.elided_path_lifetimes(elided_lifetime_span, expected_lifetimes)
.elided_path_lifetimes(elided_lifetime_span, expected_lifetimes, param_mode)
.map(GenericArg::Lifetime)
.chain(generic_args.args.into_iter())
.collect();
@ -329,21 +327,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
err.note("assuming a `'static` lifetime...");
err.emit();
}
AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {
self.resolver.lint_buffer().buffer_lint_with_diagnostic(
ELIDED_LIFETIMES_IN_PATHS,
CRATE_NODE_ID,
path_span,
"hidden lifetime parameters in types are deprecated",
BuiltinLintDiagnostics::ElidedLifetimesInPaths(
expected_lifetimes,
path_span,
incl_angl_brckt,
insertion_sp,
suggestion,
),
);
}
AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {}
}
}
}