Use kw::Empty for elided lifetimes in path.
This commit is contained in:
parent
41090346d8
commit
1c737d6997
@ -2101,7 +2101,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
hir::LifetimeName::Param(param)
|
||||
}
|
||||
LifetimeRes::Fresh { param, .. } => {
|
||||
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
|
||||
let param = self.local_def_id(param);
|
||||
hir::LifetimeName::Param(param)
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let id = NodeId::from_u32(i);
|
||||
let l = self.lower_lifetime(&Lifetime {
|
||||
id,
|
||||
ident: Ident::new(kw::UnderscoreLifetime, elided_lifetime_span),
|
||||
ident: Ident::new(kw::Empty, elided_lifetime_span),
|
||||
});
|
||||
GenericArg::Lifetime(l)
|
||||
}),
|
||||
|
@ -29,14 +29,15 @@ use std::fmt;
|
||||
#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
|
||||
pub struct Lifetime {
|
||||
pub hir_id: HirId,
|
||||
pub ident: Ident,
|
||||
|
||||
/// Either "`'a`", referring to a named lifetime definition,
|
||||
/// or "``" (i.e., `kw::Empty`), for elision placeholders.
|
||||
/// `'_` referring to an anonymous lifetime (either explicitly `'_` or `&type`),
|
||||
/// or "``" (i.e., `kw::Empty`) when appearing in path.
|
||||
///
|
||||
/// HIR lowering inserts these placeholders in type paths that
|
||||
/// refer to type definitions needing lifetime parameters,
|
||||
/// `&T` and `&mut T`, and trait objects without `... + 'a`.
|
||||
/// See `Lifetime::suggestion_position` for practical use.
|
||||
pub ident: Ident,
|
||||
|
||||
/// Semantics of this lifetime.
|
||||
pub res: LifetimeName,
|
||||
}
|
||||
|
||||
@ -135,6 +136,19 @@ impl fmt::Display for Lifetime {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum LifetimeSuggestionPosition {
|
||||
/// The user wrote `'a` or `'_`.
|
||||
Normal,
|
||||
/// The user wrote `&type` or `&mut type`.
|
||||
Ampersand,
|
||||
/// The user wrote `Path` and omitted the `<'_>`.
|
||||
ElidedPath,
|
||||
/// The user wrote `Path<T>`, and omitted the `'_,`.
|
||||
ElidedPathArgument,
|
||||
/// The user wrote `dyn Trait` and omitted the `+ '_`.
|
||||
ObjectDefault,
|
||||
}
|
||||
|
||||
impl Lifetime {
|
||||
pub fn is_elided(&self) -> bool {
|
||||
self.res.is_elided()
|
||||
@ -144,6 +158,22 @@ impl Lifetime {
|
||||
self.ident.name == kw::Empty || self.ident.name == kw::UnderscoreLifetime
|
||||
}
|
||||
|
||||
pub fn suggestion_position(&self) -> (LifetimeSuggestionPosition, Span) {
|
||||
if self.ident.name == kw::Empty {
|
||||
if self.ident.span.is_empty() {
|
||||
(LifetimeSuggestionPosition::ElidedPathArgument, self.ident.span)
|
||||
} else {
|
||||
(LifetimeSuggestionPosition::ElidedPath, self.ident.span.shrink_to_hi())
|
||||
}
|
||||
} else if self.res == LifetimeName::ImplicitObjectLifetimeDefault {
|
||||
(LifetimeSuggestionPosition::ObjectDefault, self.ident.span)
|
||||
} else if self.ident.span.is_empty() {
|
||||
(LifetimeSuggestionPosition::Ampersand, self.ident.span)
|
||||
} else {
|
||||
(LifetimeSuggestionPosition::Normal, self.ident.span)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_static(&self) -> bool {
|
||||
self.res == LifetimeName::Static
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::middle::resolve_lifetime::*;
|
||||
use rustc_middle::ty::{self, DefIdTree, TyCtxt, TypeSuperVisitable, TypeVisitor};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::Span;
|
||||
use std::fmt;
|
||||
|
||||
@ -1218,13 +1218,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
(generics.span, "<'a>".to_owned())
|
||||
};
|
||||
|
||||
let lifetime_sugg = match lifetime_ref.ident.name {
|
||||
kw::Empty => "'a, ".to_owned(),
|
||||
kw::UnderscoreLifetime => "'a ".to_owned(),
|
||||
_ => "'a ".to_owned(),
|
||||
let lifetime_sugg = match lifetime_ref.suggestion_position() {
|
||||
(hir::LifetimeSuggestionPosition::Normal, span) => (span, "'a".to_owned()),
|
||||
(hir::LifetimeSuggestionPosition::Ampersand, span) => (span, "'a ".to_owned()),
|
||||
(hir::LifetimeSuggestionPosition::ElidedPath, span) => (span, "<'a>".to_owned()),
|
||||
(hir::LifetimeSuggestionPosition::ElidedPathArgument, span) => (span, "'a, ".to_owned()),
|
||||
(hir::LifetimeSuggestionPosition::ObjectDefault, span) => (span, "+ 'a".to_owned()),
|
||||
};
|
||||
let suggestions = vec![
|
||||
(lifetime_ref.ident.span.shrink_to_hi(), lifetime_sugg),
|
||||
lifetime_sugg,
|
||||
new_param_sugg,
|
||||
];
|
||||
|
||||
|
@ -3,7 +3,7 @@ use crate::ty::{EarlyBinder, SubstsRef};
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::symbol::{kw, Symbol};
|
||||
use rustc_span::Span;
|
||||
|
||||
use super::{EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, Predicate, TyCtxt};
|
||||
@ -78,6 +78,15 @@ impl GenericParamDef {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_anonymous_lifetime(&self) -> bool {
|
||||
match self.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
self.name == kw::UnderscoreLifetime || self.name == kw::Empty
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_value<'tcx>(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -530,7 +530,7 @@ impl ty::EarlyBoundRegion {
|
||||
/// Does this early bound region have a name? Early bound regions normally
|
||||
/// always have names except when using anonymous lifetimes (`'_`).
|
||||
pub fn has_name(&self) -> bool {
|
||||
self.name != kw::UnderscoreLifetime
|
||||
self.name != kw::UnderscoreLifetime && self.name != kw::Empty
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1963,17 +1963,13 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
|
||||
let identify_regions = self.tcx.sess.opts.unstable_opts.identify_regions;
|
||||
|
||||
match *region {
|
||||
ty::ReEarlyBound(ref data) => {
|
||||
data.name != kw::Empty && data.name != kw::UnderscoreLifetime
|
||||
}
|
||||
ty::ReEarlyBound(ref data) => data.has_name(),
|
||||
|
||||
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
|
||||
| ty::ReFree(ty::FreeRegion { bound_region: br, .. })
|
||||
| ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
||||
if let ty::BrNamed(_, name) = br {
|
||||
if name != kw::Empty && name != kw::UnderscoreLifetime {
|
||||
return true;
|
||||
}
|
||||
if br.is_named() {
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Some((region, _)) = highlight.highlight_bound_region {
|
||||
@ -2049,11 +2045,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
|
||||
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
|
||||
| ty::ReFree(ty::FreeRegion { bound_region: br, .. })
|
||||
| ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
||||
if let ty::BrNamed(_, name) = br {
|
||||
if name != kw::Empty && name != kw::UnderscoreLifetime {
|
||||
p!(write("{}", name));
|
||||
return Ok(self);
|
||||
}
|
||||
if let ty::BrNamed(_, name) = br && br.is_named() {
|
||||
p!(write("{}", name));
|
||||
return Ok(self);
|
||||
}
|
||||
|
||||
if let Some((region, counter)) = highlight.highlight_bound_region {
|
||||
@ -2266,7 +2260,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
|
||||
|
||||
(name, ty::BrNamed(CRATE_DEF_ID.to_def_id(), name))
|
||||
}
|
||||
ty::BrNamed(def_id, kw::UnderscoreLifetime) => {
|
||||
ty::BrNamed(def_id, kw::UnderscoreLifetime | kw::Empty) => {
|
||||
let name = next_name(&self);
|
||||
|
||||
if let Some(lt_idx) = lifetime_idx {
|
||||
|
@ -83,7 +83,9 @@ pub struct BoundRegion {
|
||||
impl BoundRegionKind {
|
||||
pub fn is_named(&self) -> bool {
|
||||
match *self {
|
||||
BoundRegionKind::BrNamed(_, name) => name != kw::UnderscoreLifetime,
|
||||
BoundRegionKind::BrNamed(_, name) => {
|
||||
name != kw::UnderscoreLifetime && name != kw::Empty
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -182,9 +182,7 @@ fn clean_poly_trait_ref_with_bindings<'tcx>(
|
||||
.collect_referenced_late_bound_regions(&poly_trait_ref)
|
||||
.into_iter()
|
||||
.filter_map(|br| match br {
|
||||
ty::BrNamed(_, name) if name != kw::UnderscoreLifetime => {
|
||||
Some(GenericParamDef::lifetime(name))
|
||||
}
|
||||
ty::BrNamed(_, name) if br.is_named() => Some(GenericParamDef::lifetime(name)),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
@ -233,16 +231,11 @@ pub(crate) fn clean_middle_const<'tcx>(
|
||||
pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option<Lifetime> {
|
||||
match *region {
|
||||
ty::ReStatic => Some(Lifetime::statik()),
|
||||
_ if !region.has_name() => None,
|
||||
ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) => {
|
||||
if name != kw::UnderscoreLifetime { Some(Lifetime(name)) } else { None }
|
||||
}
|
||||
ty::ReEarlyBound(ref data) => {
|
||||
if data.name != kw::UnderscoreLifetime {
|
||||
Some(Lifetime(data.name))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
Some(Lifetime(name))
|
||||
}
|
||||
ty::ReEarlyBound(ref data) => Some(Lifetime(data.name)),
|
||||
ty::ReLateBound(..)
|
||||
| ty::ReFree(..)
|
||||
| ty::ReVar(..)
|
||||
@ -396,7 +389,7 @@ fn clean_projection_predicate<'tcx>(
|
||||
.collect_referenced_late_bound_regions(&pred)
|
||||
.into_iter()
|
||||
.filter_map(|br| match br {
|
||||
ty::BrNamed(_, name) if name != kw::UnderscoreLifetime => Some(Lifetime(name)),
|
||||
ty::BrNamed(_, name) if br.is_named() => Some(Lifetime(name)),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
@ -660,7 +653,7 @@ fn clean_ty_generics<'tcx>(
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
ty::GenericParamDefKind::Lifetime if param.name == kw::UnderscoreLifetime => None,
|
||||
ty::GenericParamDefKind::Lifetime if param.is_anonymous_lifetime() => None,
|
||||
ty::GenericParamDefKind::Lifetime => Some(clean_generic_param_def(param, cx)),
|
||||
ty::GenericParamDefKind::Type { synthetic, .. } => {
|
||||
if param.name == kw::SelfUpper {
|
||||
@ -1460,8 +1453,11 @@ fn maybe_expand_private_type_alias<'tcx>(
|
||||
});
|
||||
if let Some(lt) = lifetime {
|
||||
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
|
||||
let cleaned =
|
||||
if !lt.is_elided() { clean_lifetime(lt, cx) } else { Lifetime::elided() };
|
||||
let cleaned = if !lt.is_anonymous() {
|
||||
clean_lifetime(lt, cx)
|
||||
} else {
|
||||
Lifetime::elided()
|
||||
};
|
||||
substs.insert(lt_def_id.to_def_id(), SubstParam::Lifetime(cleaned));
|
||||
}
|
||||
indices.lifetimes += 1;
|
||||
@ -1892,7 +1888,7 @@ fn clean_generic_args<'tcx>(
|
||||
.args
|
||||
.iter()
|
||||
.map(|arg| match arg {
|
||||
hir::GenericArg::Lifetime(lt) if !lt.is_elided() => {
|
||||
hir::GenericArg::Lifetime(lt) if !lt.is_anonymous() => {
|
||||
GenericArg::Lifetime(clean_lifetime(*lt, cx))
|
||||
}
|
||||
hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
|
||||
|
@ -2,20 +2,62 @@
|
||||
// gate-test-anonymous_lifetime_in_impl_trait
|
||||
// Verify the behaviour of `feature(anonymous_lifetime_in_impl_trait)`.
|
||||
|
||||
fn f(_: impl Iterator<Item = &'_ ()>) {}
|
||||
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
||||
mod elided {
|
||||
fn f(_: impl Iterator<Item = &()>) {}
|
||||
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
||||
|
||||
fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
|
||||
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
||||
//~| ERROR missing lifetime specifier
|
||||
fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
|
||||
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
||||
//~| ERROR missing lifetime specifier
|
||||
|
||||
// Anonymous lifetimes in async fn are already allowed.
|
||||
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
|
||||
async fn h(_: impl Iterator<Item = &'_ ()>) {}
|
||||
// Anonymous lifetimes in async fn are already allowed.
|
||||
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
|
||||
async fn h(_: impl Iterator<Item = &()>) {}
|
||||
|
||||
// Anonymous lifetimes in async fn are already allowed.
|
||||
// But that lifetime does not participate in resolution.
|
||||
async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
|
||||
//~^ ERROR missing lifetime specifier
|
||||
// Anonymous lifetimes in async fn are already allowed.
|
||||
// But that lifetime does not participate in resolution.
|
||||
async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
|
||||
//~^ ERROR missing lifetime specifier
|
||||
}
|
||||
|
||||
mod underscore {
|
||||
fn f(_: impl Iterator<Item = &'_ ()>) {}
|
||||
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
||||
|
||||
fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
|
||||
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
||||
//~| ERROR missing lifetime specifier
|
||||
|
||||
// Anonymous lifetimes in async fn are already allowed.
|
||||
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
|
||||
async fn h(_: impl Iterator<Item = &'_ ()>) {}
|
||||
|
||||
// Anonymous lifetimes in async fn are already allowed.
|
||||
// But that lifetime does not participate in resolution.
|
||||
async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
|
||||
//~^ ERROR missing lifetime specifier
|
||||
}
|
||||
|
||||
mod alone_in_path {
|
||||
trait Foo<'a> { fn next(&mut self) -> Option<&'a ()>; }
|
||||
|
||||
fn f(_: impl Foo) {}
|
||||
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
||||
|
||||
fn g(mut x: impl Foo) -> Option<&()> { x.next() }
|
||||
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
||||
//~| ERROR missing lifetime specifier
|
||||
}
|
||||
|
||||
mod in_path {
|
||||
trait Foo<'a, T> { fn next(&mut self) -> Option<&'a T>; }
|
||||
|
||||
fn f(_: impl Foo<()>) {}
|
||||
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
||||
|
||||
fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
|
||||
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
||||
//~| ERROR missing lifetime specifier
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,52 +1,172 @@
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:8:50
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:9:54
|
||||
|
|
||||
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
|
||||
| ^^ expected named lifetime parameter
|
||||
LL | fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
|
||||
| ~~~~~~~
|
||||
LL | fn g(mut x: impl Iterator<Item = &()>) -> Option<&'static ()> { x.next() }
|
||||
| +++++++
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:18:56
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:19:60
|
||||
|
|
||||
LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
|
||||
| ^^ expected named lifetime parameter
|
||||
LL | async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
|
||||
| ~~~~~~~
|
||||
LL | async fn i(mut x: impl Iterator<Item = &()>) -> Option<&'static ()> { x.next() }
|
||||
| +++++++
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:27:58
|
||||
|
|
||||
LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
|
||||
| ^^ expected named lifetime parameter
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
|
||||
| ~~~~~~~
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:37:64
|
||||
|
|
||||
LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
|
||||
| ^^ expected named lifetime parameter
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'static ()> { x.next() }
|
||||
| ~~~~~~~
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:47:37
|
||||
|
|
||||
LL | fn g(mut x: impl Foo) -> Option<&()> { x.next() }
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | fn g(mut x: impl Foo) -> Option<&'static ()> { x.next() }
|
||||
| +++++++
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:58:41
|
||||
|
|
||||
LL | fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | fn g(mut x: impl Foo<()>) -> Option<&'static ()> { x.next() }
|
||||
| +++++++
|
||||
|
||||
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:5:31
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:6:35
|
||||
|
|
||||
LL | fn f(_: impl Iterator<Item = &'_ ()>) {}
|
||||
| ^^ expected named lifetime parameter
|
||||
LL | fn f(_: impl Iterator<Item = &()>) {}
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn f<'a>(_: impl Iterator<Item = &'_'a ()>) {}
|
||||
| ++++ ++
|
||||
LL | fn f<'a>(_: impl Iterator<Item = &'a ()>) {}
|
||||
| ++++ ++
|
||||
|
||||
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:8:31
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:9:39
|
||||
|
|
||||
LL | fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
|
||||
| ^^ expected named lifetime parameter
|
||||
LL | fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn g<'a>(x: impl Iterator<Item = &'_'a ()>) -> Option<&'_ ()> { x.next() }
|
||||
| ++++ ++
|
||||
LL | fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&()> { x.next() }
|
||||
| ++++ ++
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:24:35
|
||||
|
|
||||
LL | fn f(_: impl Iterator<Item = &'_ ()>) {}
|
||||
| ^^ expected named lifetime parameter
|
||||
|
|
||||
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn f<'a>(_: impl Iterator<Item = &'a ()>) {}
|
||||
| ++++ ~~
|
||||
|
||||
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:27:39
|
||||
|
|
||||
LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
|
||||
| ^^ expected named lifetime parameter
|
||||
|
|
||||
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'_ ()> { x.next() }
|
||||
| ++++ ~~
|
||||
|
||||
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:44:18
|
||||
|
|
||||
LL | fn f(_: impl Foo) {}
|
||||
| ^^^ expected named lifetime parameter
|
||||
|
|
||||
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn f<'a>(_: impl Foo<'a>) {}
|
||||
| ++++ ++++
|
||||
|
||||
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:47:22
|
||||
|
|
||||
LL | fn g(mut x: impl Foo) -> Option<&()> { x.next() }
|
||||
| ^^^ expected named lifetime parameter
|
||||
|
|
||||
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn g<'a>(mut x: impl Foo<'a>) -> Option<&()> { x.next() }
|
||||
| ++++ ++++
|
||||
|
||||
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:55:22
|
||||
|
|
||||
LL | fn f(_: impl Foo<()>) {}
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn f<'a>(_: impl Foo<'a, ()>) {}
|
||||
| ++++ +++
|
||||
|
||||
error[E0658]: anonymous lifetimes in `impl Trait` are unstable
|
||||
--> $DIR/impl-trait-missing-lifetime-gated.rs:58:26
|
||||
|
|
||||
LL | fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn g<'a>(mut x: impl Foo<'a, ()>) -> Option<&()> { x.next() }
|
||||
| ++++ +++
|
||||
|
||||
error: aborting due to 14 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0106, E0658.
|
||||
For more information about an error, try `rustc --explain E0106`.
|
||||
|
@ -10,8 +10,8 @@ use rustc_hir::lang_items;
|
||||
use rustc_hir::FnRetTy::Return;
|
||||
use rustc_hir::{
|
||||
BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
|
||||
ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, PolyTraitRef, PredicateOrigin, TraitFn, TraitItem,
|
||||
TraitItemKind, Ty, TyKind, WherePredicate,
|
||||
ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, PolyTraitRef, PredicateOrigin, TraitFn,
|
||||
TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter as middle_nested_filter;
|
||||
@ -595,7 +595,9 @@ fn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>,
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|par| match par.kind {
|
||||
GenericParamKind::Lifetime { .. } => Some((par.name.ident().name, par.span)),
|
||||
GenericParamKind::Lifetime {
|
||||
kind: LifetimeParamKind::Explicit,
|
||||
} => Some((par.name.ident().name, par.span)),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
@ -620,7 +622,9 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|par| match par.kind {
|
||||
GenericParamKind::Lifetime { .. } => Some((par.name.ident().name, par.span)),
|
||||
GenericParamKind::Lifetime {
|
||||
kind: LifetimeParamKind::Explicit,
|
||||
} => Some((par.name.ident().name, par.span)),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
@ -647,7 +651,7 @@ struct BodyLifetimeChecker {
|
||||
impl<'tcx> Visitor<'tcx> for BodyLifetimeChecker {
|
||||
// for lifetimes as parameters of generics
|
||||
fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
|
||||
if lifetime.ident.name != kw::UnderscoreLifetime && lifetime.ident.name != kw::StaticLifetime {
|
||||
if !lifetime.is_anonymous() && lifetime.ident.name != kw::StaticLifetime {
|
||||
self.lifetimes_used_in_body = true;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user