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 { let param_name = match lt.name {
hir::LifetimeName::Param(param_name) => param_name, hir::LifetimeName::Param(param_name) => param_name,
hir::LifetimeName::Implicit hir::LifetimeName::Implicit
| hir::LifetimeName::ImplicitMissing
| hir::LifetimeName::Underscore | hir::LifetimeName::Underscore
| hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()), | hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
hir::LifetimeName::ImplicitObjectLifetimeDefault => { hir::LifetimeName::ImplicitObjectLifetimeDefault => {
@ -2322,11 +2323,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&'s mut self, &'s mut self,
span: Span, span: Span,
count: usize, count: usize,
param_mode: ParamMode,
) -> impl Iterator<Item = hir::Lifetime> + Captures<'a> + Captures<'s> + Captures<'hir> { ) -> 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 { match self.anonymous_lifetime_mode {
AnonymousLifetimeMode::CreateParameter => { AnonymousLifetimeMode::CreateParameter => {
// We should have emitted E0726 when processing this path above // We should have emitted E0726 when processing this path above
@ -2342,10 +2344,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// lifetime. Instead, we simply create an implicit lifetime, which will be checked // lifetime. Instead, we simply create an implicit lifetime, which will be checked
// later, at which point a suitable error will be emitted. // later, at which point a suitable error will be emitted.
AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => { AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {
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) self.new_implicit_lifetime(span)
} }
} }
} }
}
/// Invoked to create the lifetime argument(s) for an elided trait object /// Invoked to create the lifetime argument(s) for an elided trait object
/// bound, like the bound in `Box<dyn Debug>`. This method is not invoked /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
@ -2536,7 +2543,9 @@ fn lifetimes_from_impl_trait_bounds(
fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) { fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
let name = match lifetime.name { 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 { if self.collect_elided_lifetimes {
// Use `'_` for both implicit and underscore lifetimes in // Use `'_` for both implicit and underscore lifetimes in
// `type Foo<'_> = impl SomeTrait<'_>;`. // `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::{DefKind, PartialRes, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::GenericArg; 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::symbol::Ident;
use rustc_span::{BytePos, Span, DUMMY_SP}; 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 // See rustc_resolve::late::lifetimes::LifetimeContext::add_missing_lifetime_specifiers_label
let elided_lifetime_span = if generic_args.span.is_empty() { let elided_lifetime_span = if generic_args.span.is_empty() {
// If there are no brackets, use the identifier span. // If there are no brackets, use the identifier span.
segment.ident.span path_span
} else if generic_args.is_empty() { } else if generic_args.is_empty() {
// If there are brackets, but not generic arguments, then use the opening bracket // If there are brackets, but not generic arguments, then use the opening bracket
generic_args.span.with_hi(generic_args.span.lo() + BytePos(1)) 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.span.with_lo(generic_args.span.lo() + BytePos(1)).shrink_to_lo()
}; };
generic_args.args = self 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) .map(GenericArg::Lifetime)
.chain(generic_args.args.into_iter()) .chain(generic_args.args.into_iter())
.collect(); .collect();
@ -329,21 +327,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
err.note("assuming a `'static` lifetime..."); err.note("assuming a `'static` lifetime...");
err.emit(); err.emit();
} }
AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => { 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,
),
);
}
} }
} }
} }

View file

@ -584,7 +584,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span)) Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span))
} }
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Implicit => { hir::LifetimeName::ImplicitObjectLifetimeDefault
| hir::LifetimeName::Implicit
| hir::LifetimeName::ImplicitMissing => {
// In this case, the user left off the lifetime; so // In this case, the user left off the lifetime; so
// they wrote something like: // they wrote something like:
// //

View file

@ -94,6 +94,9 @@ pub enum LifetimeName {
/// User wrote nothing (e.g., the lifetime in `&u32`). /// User wrote nothing (e.g., the lifetime in `&u32`).
Implicit, Implicit,
/// User wrote nothing, but should have provided something.
ImplicitMissing,
/// Implicit lifetime in a context like `dyn Foo`. This is /// Implicit lifetime in a context like `dyn Foo`. This is
/// distinguished from implicit lifetimes elsewhere because the /// distinguished from implicit lifetimes elsewhere because the
/// lifetime that they default to must appear elsewhere within the /// lifetime that they default to must appear elsewhere within the
@ -123,6 +126,7 @@ impl LifetimeName {
match *self { match *self {
LifetimeName::ImplicitObjectLifetimeDefault LifetimeName::ImplicitObjectLifetimeDefault
| LifetimeName::Implicit | LifetimeName::Implicit
| LifetimeName::ImplicitMissing
| LifetimeName::Error => Ident::empty(), | LifetimeName::Error => Ident::empty(),
LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime), LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime),
LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime), LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
@ -134,6 +138,7 @@ impl LifetimeName {
match self { match self {
LifetimeName::ImplicitObjectLifetimeDefault LifetimeName::ImplicitObjectLifetimeDefault
| LifetimeName::Implicit | LifetimeName::Implicit
| LifetimeName::ImplicitMissing
| LifetimeName::Underscore => true, | LifetimeName::Underscore => true,
// It might seem surprising that `Fresh(_)` counts as // It might seem surprising that `Fresh(_)` counts as

View file

@ -546,6 +546,7 @@ pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime
| LifetimeName::Static | LifetimeName::Static
| LifetimeName::Error | LifetimeName::Error
| LifetimeName::Implicit | LifetimeName::Implicit
| LifetimeName::ImplicitMissing
| LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::ImplicitObjectLifetimeDefault
| LifetimeName::Underscore => {} | LifetimeName::Underscore => {}
} }

View file

@ -1950,6 +1950,41 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
} }
} }
crate fn report_elided_lifetime_in_ty(&self, lifetime_refs: &[&hir::Lifetime]) {
let missing_lifetimes = lifetime_refs
.iter()
.filter(|a| matches!(a, hir::Lifetime { name: hir::LifetimeName::ImplicitMissing, .. }))
.count();
if missing_lifetimes > 0 {
let mut spans: Vec<_> = lifetime_refs.iter().map(|lt| lt.span).collect();
spans.sort();
let mut spans_dedup = spans.clone();
spans_dedup.dedup();
let spans_with_counts: Vec<_> = spans_dedup
.into_iter()
.map(|sp| (sp, spans.iter().filter(|nsp| *nsp == &sp).count()))
.collect();
self.tcx.struct_span_lint_hir(
rustc_session::lint::builtin::ELIDED_LIFETIMES_IN_PATHS,
hir::CRATE_HIR_ID,
spans,
|lint| {
let mut db = lint.build("hidden lifetime parameters in types are deprecated");
self.add_missing_lifetime_specifiers_label(
&mut db,
spans_with_counts,
&FxHashSet::from_iter([kw::UnderscoreLifetime]),
Vec::new(),
&[],
);
db.emit()
},
);
}
}
// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const // FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const
// generics. We are disallowing this until we can decide on how we want to handle non-'static // generics. We are disallowing this until we can decide on how we want to handle non-'static
// lifetimes in const generics. See issue #74052 for discussion. // lifetimes in const generics. See issue #74052 for discussion.
@ -2376,7 +2411,10 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
); );
let is_allowed_lifetime = matches!( let is_allowed_lifetime = matches!(
lifetime_ref.name, lifetime_ref.name,
hir::LifetimeName::Implicit | hir::LifetimeName::Static | hir::LifetimeName::Underscore hir::LifetimeName::Implicit
| hir::LifetimeName::ImplicitMissing
| hir::LifetimeName::Static
| hir::LifetimeName::Underscore
); );
if !self.tcx.lazy_normalization() && is_anon_const && !is_allowed_lifetime { if !self.tcx.lazy_normalization() && is_anon_const && !is_allowed_lifetime {

View file

@ -923,7 +923,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
} }
}); });
match lifetime.name { match lifetime.name {
LifetimeName::Implicit => { LifetimeName::Implicit | hir::LifetimeName::ImplicitMissing => {
// For types like `dyn Foo`, we should // For types like `dyn Foo`, we should
// generate a special form of elided. // generate a special form of elided.
span_bug!(ty.span, "object-lifetime-default expected, not implicit",); span_bug!(ty.span, "object-lifetime-default expected, not implicit",);
@ -3057,9 +3057,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
let error = loop { let error = loop {
match *scope { match *scope {
// Do not assign any resolution, it will be inferred. // Do not assign any resolution, it will be inferred.
Scope::Body { .. } => return, Scope::Body { .. } => break Ok(()),
Scope::Root => break None, Scope::Root => break Err(None),
Scope::Binder { s, ref lifetimes, scope_type, .. } => { Scope::Binder { s, ref lifetimes, scope_type, .. } => {
// collect named lifetimes for suggestions // collect named lifetimes for suggestions
@ -3086,7 +3086,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
self.insert_lifetime(lifetime_ref, lifetime); self.insert_lifetime(lifetime_ref, lifetime);
} }
return; break Ok(());
} }
Scope::Elision { elide: Elide::Exact(l), .. } => { Scope::Elision { elide: Elide::Exact(l), .. } => {
@ -3094,7 +3094,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
for lifetime_ref in lifetime_refs { for lifetime_ref in lifetime_refs {
self.insert_lifetime(lifetime_ref, lifetime); self.insert_lifetime(lifetime_ref, lifetime);
} }
return; break Ok(());
} }
Scope::Elision { elide: Elide::Error(ref e), ref s, .. } => { Scope::Elision { elide: Elide::Error(ref e), ref s, .. } => {
@ -3119,10 +3119,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
_ => break, _ => break,
} }
} }
break Some(&e[..]); break Err(Some(&e[..]));
} }
Scope::Elision { elide: Elide::Forbid, .. } => break None, Scope::Elision { elide: Elide::Forbid, .. } => break Err(None),
Scope::ObjectLifetimeDefault { s, .. } Scope::ObjectLifetimeDefault { s, .. }
| Scope::Supertrait { s, .. } | Scope::Supertrait { s, .. }
@ -3132,6 +3132,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
} }
}; };
let error = match error {
Ok(()) => {
self.report_elided_lifetime_in_ty(lifetime_refs);
return;
}
Err(error) => error,
};
// If we specifically need the `scope_for_path` map, then we're in the // If we specifically need the `scope_for_path` map, then we're in the
// diagnostic pass and we don't want to emit more errors. // diagnostic pass and we don't want to emit more errors.
if self.map.scope_for_path.is_some() { if self.map.scope_for_path.is_some() {
@ -3274,7 +3282,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
)) ))
.emit(); .emit();
} }
hir::LifetimeName::Param(_) | hir::LifetimeName::Implicit => { hir::LifetimeName::Param(_)
| hir::LifetimeName::Implicit
| hir::LifetimeName::ImplicitMissing => {
self.resolve_lifetime_ref(lt); self.resolve_lifetime_ref(lt);
} }
hir::LifetimeName::ImplicitObjectLifetimeDefault => { hir::LifetimeName::ImplicitObjectLifetimeDefault => {

View file

@ -5,23 +5,24 @@
#![deny(elided_lifetimes_in_paths)] #![deny(elided_lifetimes_in_paths)]
//~^ NOTE the lint level is defined here //~^ NOTE the lint level is defined here
use std::cell::{RefCell, Ref}; use std::cell::{Ref, RefCell};
struct Foo<'a> {
struct Foo<'a> { x: &'a u32 } x: &'a u32,
}
fn foo(x: &Foo<'_>) { fn foo(x: &Foo<'_>) {
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected named lifetime parameter
//~| HELP consider using the `'_` lifetime
} }
fn bar(x: &Foo<'_>) {} fn bar(x: &Foo<'_>) {}
struct Wrapped<'a>(&'a str); struct Wrapped<'a>(&'a str);
struct WrappedWithBow<'a> { struct WrappedWithBow<'a> {
gift: &'a str gift: &'a str,
} }
struct MatchedSet<'a, 'b> { struct MatchedSet<'a, 'b> {
@ -31,19 +32,22 @@ struct MatchedSet<'a, 'b> {
fn wrap_gift(gift: &str) -> Wrapped<'_> { fn wrap_gift(gift: &str) -> Wrapped<'_> {
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected named lifetime parameter
//~| HELP consider using the `'_` lifetime
Wrapped(gift) Wrapped(gift)
} }
fn wrap_gift_with_bow(gift: &str) -> WrappedWithBow<'_> { fn wrap_gift_with_bow(gift: &str) -> WrappedWithBow<'_> {
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected named lifetime parameter
//~| HELP consider using the `'_` lifetime
WrappedWithBow { gift } WrappedWithBow { gift }
} }
fn inspect_matched_set(set: MatchedSet<'_, '_>) { fn inspect_matched_set(set: MatchedSet<'_, '_>) {
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected 2 lifetime parameters
//~| HELP consider using the `'_` lifetime
println!("{} {}", set.one, set.another); println!("{} {}", set.one, set.another);
} }
@ -55,7 +59,8 @@ macro_rules! autowrapper {
fn $fn_name(gift: &str) -> $type_name<'_> { fn $fn_name(gift: &str) -> $type_name<'_> {
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected named lifetime parameter
//~| HELP consider using the `'_` lifetime
$type_name { gift } $type_name { gift }
} }
} }
@ -69,7 +74,8 @@ macro_rules! anytuple_ref_ty {
($($types:ty),*) => { ($($types:ty),*) => {
Ref<'_, ($($types),*)> Ref<'_, ($($types),*)>
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected named lifetime parameter
//~| HELP consider using the `'_` lifetime
} }
} }
@ -77,7 +83,8 @@ fn main() {
let honesty = RefCell::new((4, 'e')); let honesty = RefCell::new((4, 'e'));
let loyalty: Ref<'_, (u32, char)> = honesty.borrow(); let loyalty: Ref<'_, (u32, char)> = honesty.borrow();
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected named lifetime parameter
//~| HELP consider using the `'_` lifetime
let generosity = Ref::map(loyalty, |t| &t.0); let generosity = Ref::map(loyalty, |t| &t.0);
let laughter = RefCell::new((true, "magic")); let laughter = RefCell::new((true, "magic"));

View file

@ -5,23 +5,24 @@
#![deny(elided_lifetimes_in_paths)] #![deny(elided_lifetimes_in_paths)]
//~^ NOTE the lint level is defined here //~^ NOTE the lint level is defined here
use std::cell::{RefCell, Ref}; use std::cell::{Ref, RefCell};
struct Foo<'a> {
struct Foo<'a> { x: &'a u32 } x: &'a u32,
}
fn foo(x: &Foo) { fn foo(x: &Foo) {
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected named lifetime parameter
//~| HELP consider using the `'_` lifetime
} }
fn bar(x: &Foo<'_>) {} fn bar(x: &Foo<'_>) {}
struct Wrapped<'a>(&'a str); struct Wrapped<'a>(&'a str);
struct WrappedWithBow<'a> { struct WrappedWithBow<'a> {
gift: &'a str gift: &'a str,
} }
struct MatchedSet<'a, 'b> { struct MatchedSet<'a, 'b> {
@ -31,19 +32,22 @@ struct MatchedSet<'a, 'b> {
fn wrap_gift(gift: &str) -> Wrapped { fn wrap_gift(gift: &str) -> Wrapped {
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected named lifetime parameter
//~| HELP consider using the `'_` lifetime
Wrapped(gift) Wrapped(gift)
} }
fn wrap_gift_with_bow(gift: &str) -> WrappedWithBow { fn wrap_gift_with_bow(gift: &str) -> WrappedWithBow {
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected named lifetime parameter
//~| HELP consider using the `'_` lifetime
WrappedWithBow { gift } WrappedWithBow { gift }
} }
fn inspect_matched_set(set: MatchedSet) { fn inspect_matched_set(set: MatchedSet) {
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected 2 lifetime parameters
//~| HELP consider using the `'_` lifetime
println!("{} {}", set.one, set.another); println!("{} {}", set.one, set.another);
} }
@ -55,7 +59,8 @@ macro_rules! autowrapper {
fn $fn_name(gift: &str) -> $type_name { fn $fn_name(gift: &str) -> $type_name {
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected named lifetime parameter
//~| HELP consider using the `'_` lifetime
$type_name { gift } $type_name { gift }
} }
} }
@ -69,7 +74,8 @@ macro_rules! anytuple_ref_ty {
($($types:ty),*) => { ($($types:ty),*) => {
Ref<($($types),*)> Ref<($($types),*)>
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected named lifetime parameter
//~| HELP consider using the `'_` lifetime
} }
} }
@ -77,7 +83,8 @@ fn main() {
let honesty = RefCell::new((4, 'e')); let honesty = RefCell::new((4, 'e'));
let loyalty: Ref<(u32, char)> = honesty.borrow(); let loyalty: Ref<(u32, char)> = honesty.borrow();
//~^ ERROR hidden lifetime parameters in types are deprecated //~^ ERROR hidden lifetime parameters in types are deprecated
//~| HELP indicate the anonymous lifetime //~| NOTE expected named lifetime parameter
//~| HELP consider using the `'_` lifetime
let generosity = Ref::map(loyalty, |t| &t.0); let generosity = Ref::map(loyalty, |t| &t.0);
let laughter = RefCell::new((true, "magic")); let laughter = RefCell::new((true, "magic"));

View file

@ -1,60 +1,92 @@
error: hidden lifetime parameters in types are deprecated error: hidden lifetime parameters in types are deprecated
--> $DIR/elided-lifetimes.rs:13:12 --> $DIR/elided-lifetimes.rs:14:12
| |
LL | fn foo(x: &Foo) { LL | fn foo(x: &Foo) {
| ^^^- help: indicate the anonymous lifetime: `<'_>` | ^^^ expected named lifetime parameter
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/elided-lifetimes.rs:5:9 --> $DIR/elided-lifetimes.rs:5:9
| |
LL | #![deny(elided_lifetimes_in_paths)] LL | #![deny(elided_lifetimes_in_paths)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider using the `'_` lifetime
|
LL | fn foo(x: &Foo<'_>) {
| ~~~~~~~
error: hidden lifetime parameters in types are deprecated error: hidden lifetime parameters in types are deprecated
--> $DIR/elided-lifetimes.rs:32:29 --> $DIR/elided-lifetimes.rs:33:29
| |
LL | fn wrap_gift(gift: &str) -> Wrapped { LL | fn wrap_gift(gift: &str) -> Wrapped {
| ^^^^^^^- help: indicate the anonymous lifetime: `<'_>` | ^^^^^^^ expected named lifetime parameter
|
help: consider using the `'_` lifetime
|
LL | fn wrap_gift(gift: &str) -> Wrapped<'_> {
| ~~~~~~~~~~~
error: hidden lifetime parameters in types are deprecated error: hidden lifetime parameters in types are deprecated
--> $DIR/elided-lifetimes.rs:38:38 --> $DIR/elided-lifetimes.rs:40:38
| |
LL | fn wrap_gift_with_bow(gift: &str) -> WrappedWithBow { LL | fn wrap_gift_with_bow(gift: &str) -> WrappedWithBow {
| ^^^^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>` | ^^^^^^^^^^^^^^ expected named lifetime parameter
|
help: consider using the `'_` lifetime
|
LL | fn wrap_gift_with_bow(gift: &str) -> WrappedWithBow<'_> {
| ~~~~~~~~~~~~~~~~~~
error: hidden lifetime parameters in types are deprecated error: hidden lifetime parameters in types are deprecated
--> $DIR/elided-lifetimes.rs:44:29 --> $DIR/elided-lifetimes.rs:47:29
| |
LL | fn inspect_matched_set(set: MatchedSet) { LL | fn inspect_matched_set(set: MatchedSet) {
| ^^^^^^^^^^- help: indicate the anonymous lifetimes: `<'_, '_>` | ^^^^^^^^^^ expected 2 lifetime parameters
|
help: consider using the `'_` lifetime
|
LL | fn inspect_matched_set(set: MatchedSet<'_, '_>) {
| ~~~~~~~~~~~~~~~~~~
error: hidden lifetime parameters in types are deprecated error: hidden lifetime parameters in types are deprecated
--> $DIR/elided-lifetimes.rs:56:36 --> $DIR/elided-lifetimes.rs:60:36
| |
LL | fn $fn_name(gift: &str) -> $type_name { LL | fn $fn_name(gift: &str) -> $type_name {
| ^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>` | ^^^^^^^^^^ expected named lifetime parameter
... ...
LL | autowrapper!(Autowrapped, autowrap_gift, 'a); LL | autowrapper!(Autowrapped, autowrap_gift, 'a);
| -------------------------------------------- in this macro invocation | -------------------------------------------- in this macro invocation
| |
= note: this error originates in the macro `autowrapper` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `autowrapper` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider using the `'_` lifetime
|
LL | fn $fn_name(gift: &str) -> $type_name<'_> {
| ~~~~~~~~~~~~~~
error: hidden lifetime parameters in types are deprecated error: hidden lifetime parameters in types are deprecated
--> $DIR/elided-lifetimes.rs:78:18 --> $DIR/elided-lifetimes.rs:84:22
| |
LL | let loyalty: Ref<(u32, char)> = honesty.borrow(); LL | let loyalty: Ref<(u32, char)> = honesty.borrow();
| ^^^^^^^^^^^^^^^^ help: indicate the anonymous lifetime: `Ref<'_, (u32, char)>` | ^ expected named lifetime parameter
|
help: consider using the `'_` lifetime
|
LL | let loyalty: Ref<'_, (u32, char)> = honesty.borrow();
| +++
error: hidden lifetime parameters in types are deprecated error: hidden lifetime parameters in types are deprecated
--> $DIR/elided-lifetimes.rs:70:9 --> $DIR/elided-lifetimes.rs:75:13
| |
LL | Ref<($($types),*)> LL | Ref<($($types),*)>
| ^^^^^^^^^^^^^^^^^^ help: indicate the anonymous lifetime: `Ref<'_, ($($types),*)>` | ^ expected named lifetime parameter
... ...
LL | let yellow: anytuple_ref_ty!(bool, &str) = laughter.borrow(); LL | let yellow: anytuple_ref_ty!(bool, &str) = laughter.borrow();
| ---------------------------- in this macro invocation | ---------------------------- in this macro invocation
| |
= note: this error originates in the macro `anytuple_ref_ty` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `anytuple_ref_ty` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider using the `'_` lifetime
|
LL | Ref<'_, ($($types),*)>
| +++
error: aborting due to 7 previous errors error: aborting due to 7 previous errors

View file

@ -2,9 +2,13 @@ warning: hidden lifetime parameters in types are deprecated
--> $DIR/allowed-by-default-lint.rs:9:12 --> $DIR/allowed-by-default-lint.rs:9:12
| |
LL | fn foo(x: &Foo) {} LL | fn foo(x: &Foo) {}
| ^^^- help: indicate the anonymous lifetime: `<'_>` | ^^^ expected named lifetime parameter
| |
= note: requested on the command line with `--force-warn elided-lifetimes-in-paths` = note: requested on the command line with `--force-warn elided-lifetimes-in-paths`
help: consider using the `'_` lifetime
|
LL | fn foo(x: &Foo<'_>) {}
| ~~~~~~~
warning: 1 warning emitted warning: 1 warning emitted

View file

@ -1,7 +1,6 @@
// check-pass // check-pass
#![feature(lint_reasons)] #![feature(lint_reasons)]
#![warn(elided_lifetimes_in_paths, #![warn(elided_lifetimes_in_paths,
//~^ NOTE the lint level is defined here //~^ NOTE the lint level is defined here
reason = "explicit anonymous lifetimes aid reasoning about ownership")] reason = "explicit anonymous lifetimes aid reasoning about ownership")]
@ -20,8 +19,9 @@ pub struct CheaterDetectionMechanism {}
impl fmt::Debug for CheaterDetectionMechanism { impl fmt::Debug for CheaterDetectionMechanism {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
//~^ WARN hidden lifetime parameters in types are deprecated //~^ WARN hidden lifetime parameters in types are deprecated
//~| NOTE expected named lifetime parameter
//~| NOTE explicit anonymous lifetimes aid //~| NOTE explicit anonymous lifetimes aid
//~| HELP indicate the anonymous lifetime //~| HELP consider using the `'_` lifetime
fmt.debug_struct("CheaterDetectionMechanism").finish() fmt.debug_struct("CheaterDetectionMechanism").finish()
} }
} }

View file

@ -1,15 +1,19 @@
warning: hidden lifetime parameters in types are deprecated warning: hidden lifetime parameters in types are deprecated
--> $DIR/reasons.rs:21:29 --> $DIR/reasons.rs:20:29
| |
LL | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { LL | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
| ^^^^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>` | ^^^^^^^^^^^^^^ expected named lifetime parameter
| |
= note: explicit anonymous lifetimes aid reasoning about ownership = note: explicit anonymous lifetimes aid reasoning about ownership
note: the lint level is defined here note: the lint level is defined here
--> $DIR/reasons.rs:5:9 --> $DIR/reasons.rs:4:9
| |
LL | #![warn(elided_lifetimes_in_paths, LL | #![warn(elided_lifetimes_in_paths,
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider using the `'_` lifetime
|
LL | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
| ~~~~~~~~~~~~~~~~~~
warning: variable `Social_exchange_psychology` should have a snake case name warning: variable `Social_exchange_psychology` should have a snake case name
--> $DIR/reasons.rs:30:9 --> $DIR/reasons.rs:30:9
@ -20,7 +24,7 @@ LL | let Social_exchange_psychology = CheaterDetectionMechanism {};
= note: people shouldn't have to change their usual style habits = note: people shouldn't have to change their usual style habits
to contribute to our project to contribute to our project
note: the lint level is defined here note: the lint level is defined here
--> $DIR/reasons.rs:9:5 --> $DIR/reasons.rs:8:5
| |
LL | nonstandard_style, LL | nonstandard_style,
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^