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)
|
hir::LifetimeName::Param(param)
|
||||||
}
|
}
|
||||||
LifetimeRes::Fresh { param, .. } => {
|
LifetimeRes::Fresh { param, .. } => {
|
||||||
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
|
|
||||||
let param = self.local_def_id(param);
|
let param = self.local_def_id(param);
|
||||||
hir::LifetimeName::Param(param)
|
hir::LifetimeName::Param(param)
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
let id = NodeId::from_u32(i);
|
let id = NodeId::from_u32(i);
|
||||||
let l = self.lower_lifetime(&Lifetime {
|
let l = self.lower_lifetime(&Lifetime {
|
||||||
id,
|
id,
|
||||||
ident: Ident::new(kw::UnderscoreLifetime, elided_lifetime_span),
|
ident: Ident::new(kw::Empty, elided_lifetime_span),
|
||||||
});
|
});
|
||||||
GenericArg::Lifetime(l)
|
GenericArg::Lifetime(l)
|
||||||
}),
|
}),
|
||||||
|
@ -29,14 +29,15 @@ use std::fmt;
|
|||||||
#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
|
#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
|
||||||
pub struct Lifetime {
|
pub struct Lifetime {
|
||||||
pub hir_id: HirId,
|
pub hir_id: HirId,
|
||||||
pub ident: Ident,
|
|
||||||
|
|
||||||
/// Either "`'a`", referring to a named lifetime definition,
|
/// 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
|
/// See `Lifetime::suggestion_position` for practical use.
|
||||||
/// refer to type definitions needing lifetime parameters,
|
pub ident: Ident,
|
||||||
/// `&T` and `&mut T`, and trait objects without `... + 'a`.
|
|
||||||
|
/// Semantics of this lifetime.
|
||||||
pub res: LifetimeName,
|
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 {
|
impl Lifetime {
|
||||||
pub fn is_elided(&self) -> bool {
|
pub fn is_elided(&self) -> bool {
|
||||||
self.res.is_elided()
|
self.res.is_elided()
|
||||||
@ -144,6 +158,22 @@ impl Lifetime {
|
|||||||
self.ident.name == kw::Empty || self.ident.name == kw::UnderscoreLifetime
|
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 {
|
pub fn is_static(&self) -> bool {
|
||||||
self.res == LifetimeName::Static
|
self.res == LifetimeName::Static
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ use rustc_middle::hir::nested_filter;
|
|||||||
use rustc_middle::middle::resolve_lifetime::*;
|
use rustc_middle::middle::resolve_lifetime::*;
|
||||||
use rustc_middle::ty::{self, DefIdTree, TyCtxt, TypeSuperVisitable, TypeVisitor};
|
use rustc_middle::ty::{self, DefIdTree, TyCtxt, TypeSuperVisitable, TypeVisitor};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
use rustc_span::symbol::{kw, sym, Ident};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
@ -1218,13 +1218,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||||||
(generics.span, "<'a>".to_owned())
|
(generics.span, "<'a>".to_owned())
|
||||||
};
|
};
|
||||||
|
|
||||||
let lifetime_sugg = match lifetime_ref.ident.name {
|
let lifetime_sugg = match lifetime_ref.suggestion_position() {
|
||||||
kw::Empty => "'a, ".to_owned(),
|
(hir::LifetimeSuggestionPosition::Normal, span) => (span, "'a".to_owned()),
|
||||||
kw::UnderscoreLifetime => "'a ".to_owned(),
|
(hir::LifetimeSuggestionPosition::Ampersand, span) => (span, "'a ".to_owned()),
|
||||||
_ => "'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![
|
let suggestions = vec![
|
||||||
(lifetime_ref.ident.span.shrink_to_hi(), lifetime_sugg),
|
lifetime_sugg,
|
||||||
new_param_sugg,
|
new_param_sugg,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ use crate::ty::{EarlyBinder, SubstsRef};
|
|||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::{kw, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use super::{EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, Predicate, TyCtxt};
|
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>(
|
pub fn default_value<'tcx>(
|
||||||
&self,
|
&self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
@ -530,7 +530,7 @@ impl ty::EarlyBoundRegion {
|
|||||||
/// Does this early bound region have a name? Early bound regions normally
|
/// Does this early bound region have a name? Early bound regions normally
|
||||||
/// always have names except when using anonymous lifetimes (`'_`).
|
/// always have names except when using anonymous lifetimes (`'_`).
|
||||||
pub fn has_name(&self) -> bool {
|
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;
|
let identify_regions = self.tcx.sess.opts.unstable_opts.identify_regions;
|
||||||
|
|
||||||
match *region {
|
match *region {
|
||||||
ty::ReEarlyBound(ref data) => {
|
ty::ReEarlyBound(ref data) => data.has_name(),
|
||||||
data.name != kw::Empty && data.name != kw::UnderscoreLifetime
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
|
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
|
||||||
| ty::ReFree(ty::FreeRegion { bound_region: br, .. })
|
| ty::ReFree(ty::FreeRegion { bound_region: br, .. })
|
||||||
| ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
| ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
||||||
if let ty::BrNamed(_, name) = br {
|
if br.is_named() {
|
||||||
if name != kw::Empty && name != kw::UnderscoreLifetime {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((region, _)) = highlight.highlight_bound_region {
|
if let Some((region, _)) = highlight.highlight_bound_region {
|
||||||
@ -2049,11 +2045,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
|
|||||||
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
|
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
|
||||||
| ty::ReFree(ty::FreeRegion { bound_region: br, .. })
|
| ty::ReFree(ty::FreeRegion { bound_region: br, .. })
|
||||||
| ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
| ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
||||||
if let ty::BrNamed(_, name) = br {
|
if let ty::BrNamed(_, name) = br && br.is_named() {
|
||||||
if name != kw::Empty && name != kw::UnderscoreLifetime {
|
p!(write("{}", name));
|
||||||
p!(write("{}", name));
|
return Ok(self);
|
||||||
return Ok(self);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((region, counter)) = highlight.highlight_bound_region {
|
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))
|
(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);
|
let name = next_name(&self);
|
||||||
|
|
||||||
if let Some(lt_idx) = lifetime_idx {
|
if let Some(lt_idx) = lifetime_idx {
|
||||||
|
@ -83,7 +83,9 @@ pub struct BoundRegion {
|
|||||||
impl BoundRegionKind {
|
impl BoundRegionKind {
|
||||||
pub fn is_named(&self) -> bool {
|
pub fn is_named(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
BoundRegionKind::BrNamed(_, name) => name != kw::UnderscoreLifetime,
|
BoundRegionKind::BrNamed(_, name) => {
|
||||||
|
name != kw::UnderscoreLifetime && name != kw::Empty
|
||||||
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,9 +182,7 @@ fn clean_poly_trait_ref_with_bindings<'tcx>(
|
|||||||
.collect_referenced_late_bound_regions(&poly_trait_ref)
|
.collect_referenced_late_bound_regions(&poly_trait_ref)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|br| match br {
|
.filter_map(|br| match br {
|
||||||
ty::BrNamed(_, name) if name != kw::UnderscoreLifetime => {
|
ty::BrNamed(_, name) if br.is_named() => Some(GenericParamDef::lifetime(name)),
|
||||||
Some(GenericParamDef::lifetime(name))
|
|
||||||
}
|
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect();
|
.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> {
|
pub(crate) fn clean_middle_region<'tcx>(region: ty::Region<'tcx>) -> Option<Lifetime> {
|
||||||
match *region {
|
match *region {
|
||||||
ty::ReStatic => Some(Lifetime::statik()),
|
ty::ReStatic => Some(Lifetime::statik()),
|
||||||
|
_ if !region.has_name() => None,
|
||||||
ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) => {
|
ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) => {
|
||||||
if name != kw::UnderscoreLifetime { Some(Lifetime(name)) } else { None }
|
Some(Lifetime(name))
|
||||||
}
|
|
||||||
ty::ReEarlyBound(ref data) => {
|
|
||||||
if data.name != kw::UnderscoreLifetime {
|
|
||||||
Some(Lifetime(data.name))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ty::ReEarlyBound(ref data) => Some(Lifetime(data.name)),
|
||||||
ty::ReLateBound(..)
|
ty::ReLateBound(..)
|
||||||
| ty::ReFree(..)
|
| ty::ReFree(..)
|
||||||
| ty::ReVar(..)
|
| ty::ReVar(..)
|
||||||
@ -396,7 +389,7 @@ fn clean_projection_predicate<'tcx>(
|
|||||||
.collect_referenced_late_bound_regions(&pred)
|
.collect_referenced_late_bound_regions(&pred)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|br| match br {
|
.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,
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@ -660,7 +653,7 @@ fn clean_ty_generics<'tcx>(
|
|||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|param| match param.kind {
|
.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::Lifetime => Some(clean_generic_param_def(param, cx)),
|
||||||
ty::GenericParamDefKind::Type { synthetic, .. } => {
|
ty::GenericParamDefKind::Type { synthetic, .. } => {
|
||||||
if param.name == kw::SelfUpper {
|
if param.name == kw::SelfUpper {
|
||||||
@ -1460,8 +1453,11 @@ fn maybe_expand_private_type_alias<'tcx>(
|
|||||||
});
|
});
|
||||||
if let Some(lt) = lifetime {
|
if let Some(lt) = lifetime {
|
||||||
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
|
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
|
||||||
let cleaned =
|
let cleaned = if !lt.is_anonymous() {
|
||||||
if !lt.is_elided() { clean_lifetime(lt, cx) } else { Lifetime::elided() };
|
clean_lifetime(lt, cx)
|
||||||
|
} else {
|
||||||
|
Lifetime::elided()
|
||||||
|
};
|
||||||
substs.insert(lt_def_id.to_def_id(), SubstParam::Lifetime(cleaned));
|
substs.insert(lt_def_id.to_def_id(), SubstParam::Lifetime(cleaned));
|
||||||
}
|
}
|
||||||
indices.lifetimes += 1;
|
indices.lifetimes += 1;
|
||||||
@ -1892,7 +1888,7 @@ fn clean_generic_args<'tcx>(
|
|||||||
.args
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arg| match arg {
|
.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))
|
GenericArg::Lifetime(clean_lifetime(*lt, cx))
|
||||||
}
|
}
|
||||||
hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
|
hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()),
|
||||||
|
@ -2,20 +2,62 @@
|
|||||||
// gate-test-anonymous_lifetime_in_impl_trait
|
// gate-test-anonymous_lifetime_in_impl_trait
|
||||||
// Verify the behaviour of `feature(anonymous_lifetime_in_impl_trait)`.
|
// Verify the behaviour of `feature(anonymous_lifetime_in_impl_trait)`.
|
||||||
|
|
||||||
fn f(_: impl Iterator<Item = &'_ ()>) {}
|
mod elided {
|
||||||
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
fn f(_: impl Iterator<Item = &()>) {}
|
||||||
|
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
||||||
|
|
||||||
fn g(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
|
fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
|
||||||
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
//~^ ERROR anonymous lifetimes in `impl Trait` are unstable
|
||||||
//~| ERROR missing lifetime specifier
|
//~| ERROR missing lifetime specifier
|
||||||
|
|
||||||
// Anonymous lifetimes in async fn are already allowed.
|
// Anonymous lifetimes in async fn are already allowed.
|
||||||
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
|
// This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
|
||||||
async fn h(_: impl Iterator<Item = &'_ ()>) {}
|
async fn h(_: impl Iterator<Item = &()>) {}
|
||||||
|
|
||||||
// Anonymous lifetimes in async fn are already allowed.
|
// Anonymous lifetimes in async fn are already allowed.
|
||||||
// But that lifetime does not participate in resolution.
|
// But that lifetime does not participate in resolution.
|
||||||
async fn i(x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
|
async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
|
||||||
//~^ ERROR missing lifetime specifier
|
//~^ 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() {}
|
fn main() {}
|
||||||
|
@ -1,52 +1,172 @@
|
|||||||
error[E0106]: missing lifetime specifier
|
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() }
|
LL | fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
|
||||||
| ^^ expected named lifetime parameter
|
| ^ 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: 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
|
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
|
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() }
|
LL | async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
|
||||||
| ^^ expected named lifetime parameter
|
| ^ 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: 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
|
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
|
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 = &'_ ()>) {}
|
LL | fn f(_: impl Iterator<Item = &()>) {}
|
||||||
| ^^ expected named lifetime parameter
|
| ^ expected named lifetime parameter
|
||||||
|
|
|
|
||||||
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
|
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
|
||||||
help: consider introducing a named lifetime parameter
|
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
|
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() }
|
LL | fn g(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
|
||||||
| ^^ expected named lifetime parameter
|
| ^ expected named lifetime parameter
|
||||||
|
|
|
|
||||||
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
|
= help: add `#![feature(anonymous_lifetime_in_impl_trait)]` to the crate attributes to enable
|
||||||
help: consider introducing a named lifetime parameter
|
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.
|
Some errors have detailed explanations: E0106, E0658.
|
||||||
For more information about an error, try `rustc --explain E0106`.
|
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::FnRetTy::Return;
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
|
BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
|
||||||
ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, PolyTraitRef, PredicateOrigin, TraitFn, TraitItem,
|
ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, PolyTraitRef, PredicateOrigin, TraitFn,
|
||||||
TraitItemKind, Ty, TyKind, WherePredicate,
|
TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::hir::nested_filter as middle_nested_filter;
|
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
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|par| match par.kind {
|
.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,
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@ -620,7 +622,9 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
|
|||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|par| match par.kind {
|
.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,
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@ -647,7 +651,7 @@ struct BodyLifetimeChecker {
|
|||||||
impl<'tcx> Visitor<'tcx> for BodyLifetimeChecker {
|
impl<'tcx> Visitor<'tcx> for BodyLifetimeChecker {
|
||||||
// for lifetimes as parameters of generics
|
// for lifetimes as parameters of generics
|
||||||
fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
|
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;
|
self.lifetimes_used_in_body = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user