Lint elided lifetimes in path during lifetime resolution.
This commit is contained in:
parent
ac03470c3b
commit
5ea7ea8a57
13 changed files with 181 additions and 78 deletions
|
@ -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<'_>;`.
|
||||||
|
|
|
@ -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,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
//
|
//
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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"));
|
||||||
|
|
|
@ -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"));
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue