mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Auto merge of #95779 - cjgillot:ast-lifetimes-undeclared, r=petrochenkov
Report undeclared lifetimes during late resolution. First step in https://github.com/rust-lang/rust/pull/91557 We reuse the rib design of the current resolution framework. Specific `LifetimeRib` and `LifetimeRibKind` types are introduced. The most important variant is `LifetimeRibKind::Generics`, which happens each time we encounter something which may introduce generic lifetime parameters. It can be an item or a `for<...>` binder. The `LifetimeBinderKind` specifies how this rib behaves with respect to in-band lifetimes. r? `@petrochenkov`
This commit is contained in:
commit
1ec2c136b3
@ -35,7 +35,7 @@ pub enum FnCtxt {
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum FnKind<'a> {
|
||||
/// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
|
||||
Fn(FnCtxt, Ident, &'a FnSig, &'a Visibility, Option<&'a Block>),
|
||||
Fn(FnCtxt, Ident, &'a FnSig, &'a Visibility, &'a Generics, Option<&'a Block>),
|
||||
|
||||
/// E.g., `|x, y| body`.
|
||||
Closure(&'a FnDecl, &'a Expr),
|
||||
@ -44,7 +44,7 @@ pub enum FnKind<'a> {
|
||||
impl<'a> FnKind<'a> {
|
||||
pub fn header(&self) -> Option<&'a FnHeader> {
|
||||
match *self {
|
||||
FnKind::Fn(_, _, sig, _, _) => Some(&sig.header),
|
||||
FnKind::Fn(_, _, sig, _, _, _) => Some(&sig.header),
|
||||
FnKind::Closure(_, _) => None,
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,7 @@ impl<'a> FnKind<'a> {
|
||||
|
||||
pub fn decl(&self) -> &'a FnDecl {
|
||||
match self {
|
||||
FnKind::Fn(_, _, sig, _, _) => &sig.decl,
|
||||
FnKind::Fn(_, _, sig, _, _, _) => &sig.decl,
|
||||
FnKind::Closure(decl, _) => decl,
|
||||
}
|
||||
}
|
||||
@ -295,8 +295,8 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
|
||||
walk_list!(visitor, visit_expr, expr);
|
||||
}
|
||||
ItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => {
|
||||
visitor.visit_generics(generics);
|
||||
let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref());
|
||||
let kind =
|
||||
FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref());
|
||||
visitor.visit_fn(kind, item.span, item.id)
|
||||
}
|
||||
ItemKind::Mod(_unsafety, ref mod_kind) => match mod_kind {
|
||||
@ -561,8 +561,7 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI
|
||||
walk_list!(visitor, visit_expr, expr);
|
||||
}
|
||||
ForeignItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => {
|
||||
visitor.visit_generics(generics);
|
||||
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, body.as_deref());
|
||||
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref());
|
||||
visitor.visit_fn(kind, span, id);
|
||||
}
|
||||
ForeignItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
|
||||
@ -644,7 +643,8 @@ pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: &
|
||||
|
||||
pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>, _span: Span) {
|
||||
match kind {
|
||||
FnKind::Fn(_, _, sig, _, body) => {
|
||||
FnKind::Fn(_, _, sig, _, generics, body) => {
|
||||
visitor.visit_generics(generics);
|
||||
visitor.visit_fn_header(&sig.header);
|
||||
walk_fn_decl(visitor, &sig.decl);
|
||||
walk_list!(visitor, visit_block, body);
|
||||
@ -667,8 +667,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem,
|
||||
walk_list!(visitor, visit_expr, expr);
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => {
|
||||
visitor.visit_generics(generics);
|
||||
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, body.as_deref());
|
||||
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref());
|
||||
visitor.visit_fn(kind, span, id);
|
||||
}
|
||||
AssocItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => {
|
||||
|
@ -484,7 +484,7 @@ enum ParenthesizedGenericArgs {
|
||||
/// an "elided" or "underscore" lifetime name. In the future, we probably want to move
|
||||
/// everything into HIR lowering.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum AnonymousLifetimeMode {
|
||||
pub enum AnonymousLifetimeMode {
|
||||
/// For **Modern** cases, create a new anonymous region parameter
|
||||
/// and reference that.
|
||||
///
|
||||
@ -1835,7 +1835,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// Output lifetime like `'_`:
|
||||
for (span, node_id) in lifetimes_to_define {
|
||||
let param = this.fresh_lifetime_to_generic_param(span, node_id);
|
||||
lifetime_params.push((span, hir::LifetimeName::Implicit(false)));
|
||||
lifetime_params.push((span, hir::LifetimeName::Implicit));
|
||||
generic_params.push(param);
|
||||
}
|
||||
let generic_params = this.arena.alloc_from_iter(generic_params);
|
||||
@ -2017,16 +2017,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
});
|
||||
let param_name = match lt.name {
|
||||
hir::LifetimeName::Param(param_name) => param_name,
|
||||
hir::LifetimeName::Implicit(_)
|
||||
| hir::LifetimeName::Underscore
|
||||
| hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
|
||||
hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
|
||||
hir::ParamName::Plain(lt.name.ident())
|
||||
}
|
||||
hir::LifetimeName::ImplicitObjectLifetimeDefault => {
|
||||
self.sess.diagnostic().span_bug(
|
||||
param.ident.span,
|
||||
"object-lifetime-default should not occur here",
|
||||
);
|
||||
}
|
||||
hir::LifetimeName::Error => ParamName::Error,
|
||||
hir::LifetimeName::Static | hir::LifetimeName::Error => ParamName::Error,
|
||||
};
|
||||
|
||||
let kind =
|
||||
@ -2397,27 +2397,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span),
|
||||
|
||||
AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span, false),
|
||||
AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
|
||||
}
|
||||
}
|
||||
|
||||
/// Report an error on illegal use of `'_` or a `&T` with no explicit lifetime;
|
||||
/// return an "error lifetime".
|
||||
fn new_error_lifetime(&mut self, id: Option<NodeId>, span: Span) -> hir::Lifetime {
|
||||
let (id, msg, label) = match id {
|
||||
Some(id) => (id, "`'_` cannot be used here", "`'_` is a reserved lifetime name"),
|
||||
|
||||
None => (
|
||||
self.resolver.next_node_id(),
|
||||
"`&` without an explicit lifetime name cannot be used here",
|
||||
"explicit lifetime name needed here",
|
||||
),
|
||||
};
|
||||
|
||||
let mut err = struct_span_err!(self.sess, span, E0637, "{}", msg,);
|
||||
err.span_label(span, label);
|
||||
err.emit();
|
||||
|
||||
let id = id.unwrap_or_else(|| self.resolver.next_node_id());
|
||||
self.new_named_lifetime(id, span, hir::LifetimeName::Error)
|
||||
}
|
||||
|
||||
@ -2429,12 +2416,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
&'s mut self,
|
||||
span: Span,
|
||||
count: usize,
|
||||
param_mode: ParamMode,
|
||||
) -> impl Iterator<Item = hir::Lifetime> + Captures<'a> + Captures<'s> + Captures<'hir> {
|
||||
(0..count).map(move |_| self.elided_path_lifetime(span, param_mode))
|
||||
(0..count).map(move |_| self.elided_path_lifetime(span))
|
||||
}
|
||||
|
||||
fn elided_path_lifetime(&mut self, span: Span, param_mode: ParamMode) -> hir::Lifetime {
|
||||
fn elided_path_lifetime(&mut self, span: Span) -> hir::Lifetime {
|
||||
match self.anonymous_lifetime_mode {
|
||||
AnonymousLifetimeMode::CreateParameter => {
|
||||
// We should have emitted E0726 when processing this path above
|
||||
@ -2450,7 +2436,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// lifetime. Instead, we simply create an implicit lifetime, which will be checked
|
||||
// later, at which point a suitable error will be emitted.
|
||||
AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {
|
||||
self.new_implicit_lifetime(span, param_mode == ParamMode::Explicit)
|
||||
self.new_implicit_lifetime(span)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2493,11 +2479,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
r
|
||||
}
|
||||
|
||||
fn new_implicit_lifetime(&mut self, span: Span, missing: bool) -> hir::Lifetime {
|
||||
fn new_implicit_lifetime(&mut self, span: Span) -> hir::Lifetime {
|
||||
hir::Lifetime {
|
||||
hir_id: self.next_id(),
|
||||
span: self.lower_span(span),
|
||||
name: hir::LifetimeName::Implicit(missing),
|
||||
name: hir::LifetimeName::Implicit,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2600,7 +2586,7 @@ fn lifetimes_from_impl_trait_bounds(
|
||||
|
||||
fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
|
||||
let name = match lifetime.name {
|
||||
hir::LifetimeName::Implicit(_) | hir::LifetimeName::Underscore => {
|
||||
hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
|
||||
if self.collect_elided_lifetimes {
|
||||
// Use `'_` for both implicit and underscore lifetimes in
|
||||
// `type Foo<'_> = impl SomeTrait<'_>;`.
|
||||
|
@ -290,47 +290,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
generic_args.span.with_lo(generic_args.span.lo() + BytePos(1)).shrink_to_lo()
|
||||
};
|
||||
generic_args.args = self
|
||||
.elided_path_lifetimes(elided_lifetime_span, expected_lifetimes, param_mode)
|
||||
.elided_path_lifetimes(elided_lifetime_span, expected_lifetimes)
|
||||
.map(GenericArg::Lifetime)
|
||||
.chain(generic_args.args.into_iter())
|
||||
.collect();
|
||||
// In create-parameter mode we error here because we don't want to support
|
||||
// deprecated impl elision in new features like impl elision and `async fn`,
|
||||
// both of which work using the `CreateParameter` mode:
|
||||
//
|
||||
// impl Foo for std::cell::Ref<u32> // note lack of '_
|
||||
// async fn foo(_: std::cell::Ref<u32>) { ... }
|
||||
if let (ParamMode::Explicit, AnonymousLifetimeMode::CreateParameter) =
|
||||
(param_mode, self.anonymous_lifetime_mode)
|
||||
{
|
||||
let anon_lt_suggestion = vec!["'_"; expected_lifetimes].join(", ");
|
||||
let no_non_lt_args = generic_args.args.len() == expected_lifetimes;
|
||||
let no_bindings = generic_args.bindings.is_empty();
|
||||
let (incl_angl_brckt, suggestion) = if no_non_lt_args && no_bindings {
|
||||
// If there are no generic args, our suggestion can include the angle brackets.
|
||||
(true, format!("<{}>", anon_lt_suggestion))
|
||||
} else {
|
||||
// Otherwise we'll insert a `'_, ` right after the opening bracket.
|
||||
(false, format!("{}, ", anon_lt_suggestion))
|
||||
};
|
||||
let insertion_sp = elided_lifetime_span.shrink_to_hi();
|
||||
let mut err = struct_span_err!(
|
||||
self.sess,
|
||||
path_span,
|
||||
E0726,
|
||||
"implicit elided lifetime not allowed here"
|
||||
);
|
||||
rustc_errors::add_elided_lifetime_in_path_suggestion(
|
||||
&self.sess.source_map(),
|
||||
&mut err,
|
||||
expected_lifetimes,
|
||||
path_span,
|
||||
incl_angl_brckt,
|
||||
insertion_sp,
|
||||
suggestion,
|
||||
);
|
||||
err.note("assuming a `'static` lifetime...");
|
||||
err.emit();
|
||||
// Late resolver should have issued the error.
|
||||
self.sess
|
||||
.delay_span_bug(elided_lifetime_span, "implicit lifetime not allowed here");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,16 +91,18 @@ impl<'a> AstValidator<'a> {
|
||||
self.is_impl_trait_banned = old;
|
||||
}
|
||||
|
||||
fn with_tilde_const_allowed(&mut self, f: impl FnOnce(&mut Self)) {
|
||||
let old = mem::replace(&mut self.is_tilde_const_allowed, true);
|
||||
fn with_tilde_const(&mut self, allowed: bool, f: impl FnOnce(&mut Self)) {
|
||||
let old = mem::replace(&mut self.is_tilde_const_allowed, allowed);
|
||||
f(self);
|
||||
self.is_tilde_const_allowed = old;
|
||||
}
|
||||
|
||||
fn with_tilde_const_allowed(&mut self, f: impl FnOnce(&mut Self)) {
|
||||
self.with_tilde_const(true, f)
|
||||
}
|
||||
|
||||
fn with_banned_tilde_const(&mut self, f: impl FnOnce(&mut Self)) {
|
||||
let old = mem::replace(&mut self.is_tilde_const_allowed, false);
|
||||
f(self);
|
||||
self.is_tilde_const_allowed = old;
|
||||
self.with_tilde_const(false, f)
|
||||
}
|
||||
|
||||
fn with_let_management(
|
||||
@ -1202,12 +1204,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
self.visit_vis(&item.vis);
|
||||
self.visit_ident(item.ident);
|
||||
if let Const::Yes(_) = sig.header.constness {
|
||||
self.with_tilde_const_allowed(|this| this.visit_generics(generics));
|
||||
} else {
|
||||
self.visit_generics(generics);
|
||||
}
|
||||
let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref());
|
||||
let kind =
|
||||
FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref());
|
||||
self.visit_fn(kind, item.span, item.id);
|
||||
walk_list!(self, visit_attribute, &item.attrs);
|
||||
return; // Avoid visiting again.
|
||||
@ -1555,13 +1553,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
FnSig { span: sig_span, header: FnHeader { ext: Extern::Implicit, .. }, .. },
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
) = fk
|
||||
{
|
||||
self.maybe_lint_missing_abi(*sig_span, id);
|
||||
}
|
||||
|
||||
// Functions without bodies cannot have patterns.
|
||||
if let FnKind::Fn(ctxt, _, sig, _, None) = fk {
|
||||
if let FnKind::Fn(ctxt, _, sig, _, _, None) = fk {
|
||||
Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| {
|
||||
let (code, msg, label) = match ctxt {
|
||||
FnCtxt::Foreign => (
|
||||
@ -1596,7 +1595,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
});
|
||||
}
|
||||
|
||||
visit::walk_fn(self, fk, span);
|
||||
let tilde_const_allowed =
|
||||
matches!(fk.header(), Some(FnHeader { constness: Const::Yes(_), .. }))
|
||||
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
|
||||
|
||||
self.with_tilde_const(tilde_const_allowed, |this| visit::walk_fn(this, fk, span));
|
||||
}
|
||||
|
||||
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
|
||||
@ -1670,9 +1673,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
{
|
||||
self.visit_vis(&item.vis);
|
||||
self.visit_ident(item.ident);
|
||||
self.with_tilde_const_allowed(|this| this.visit_generics(generics));
|
||||
let kind =
|
||||
FnKind::Fn(FnCtxt::Assoc(ctxt), item.ident, sig, &item.vis, body.as_deref());
|
||||
let kind = FnKind::Fn(
|
||||
FnCtxt::Assoc(ctxt),
|
||||
item.ident,
|
||||
sig,
|
||||
&item.vis,
|
||||
generics,
|
||||
body.as_deref(),
|
||||
);
|
||||
self.visit_fn(kind, item.span, item.id);
|
||||
}
|
||||
_ => self
|
||||
|
@ -575,7 +575,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span))
|
||||
}
|
||||
|
||||
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Implicit(_) => {
|
||||
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Implicit => {
|
||||
// In this case, the user left off the lifetime; so
|
||||
// they wrote something like:
|
||||
//
|
||||
|
@ -1511,35 +1511,17 @@ pub fn add_elided_lifetime_in_path_suggestion(
|
||||
path_span: Span,
|
||||
incl_angl_brckt: bool,
|
||||
insertion_span: Span,
|
||||
anon_lts: String,
|
||||
) {
|
||||
let (replace_span, suggestion) = if incl_angl_brckt {
|
||||
(insertion_span, anon_lts)
|
||||
} else {
|
||||
// When possible, prefer a suggestion that replaces the whole
|
||||
// `Path<T>` expression with `Path<'_, T>`, rather than inserting `'_, `
|
||||
// at a point (which makes for an ugly/confusing label)
|
||||
if let Ok(snippet) = source_map.span_to_snippet(path_span) {
|
||||
// But our spans can get out of whack due to macros; if the place we think
|
||||
// we want to insert `'_` isn't even within the path expression's span, we
|
||||
// should bail out of making any suggestion rather than panicking on a
|
||||
// subtract-with-overflow or string-slice-out-out-bounds (!)
|
||||
// FIXME: can we do better?
|
||||
if insertion_span.lo().0 < path_span.lo().0 {
|
||||
diag.span_label(path_span, format!("expected lifetime parameter{}", pluralize!(n)));
|
||||
if source_map.span_to_snippet(insertion_span).is_err() {
|
||||
// Do not try to suggest anything if generated by a proc-macro.
|
||||
return;
|
||||
}
|
||||
let insertion_index = (insertion_span.lo().0 - path_span.lo().0) as usize;
|
||||
if insertion_index > snippet.len() {
|
||||
return;
|
||||
}
|
||||
let (before, after) = snippet.split_at(insertion_index);
|
||||
(path_span, format!("{}{}{}", before, anon_lts, after))
|
||||
} else {
|
||||
(insertion_span, anon_lts)
|
||||
}
|
||||
};
|
||||
diag.span_suggestion(
|
||||
replace_span,
|
||||
let anon_lts = vec!["'_"; n].join(", ");
|
||||
let suggestion =
|
||||
if incl_angl_brckt { format!("<{}>", anon_lts) } else { format!("{}, ", anon_lts) };
|
||||
diag.span_suggestion_verbose(
|
||||
insertion_span.shrink_to_hi(),
|
||||
&format!("indicate the anonymous lifetime{}", pluralize!(n)),
|
||||
suggestion,
|
||||
Applicability::MachineApplicable,
|
||||
|
@ -95,7 +95,7 @@ pub enum LifetimeName {
|
||||
/// User wrote nothing (e.g., the lifetime in `&u32`).
|
||||
///
|
||||
/// The bool indicates whether the user should have written something.
|
||||
Implicit(bool),
|
||||
Implicit,
|
||||
|
||||
/// Implicit lifetime in a context like `dyn Foo`. This is
|
||||
/// distinguished from implicit lifetimes elsewhere because the
|
||||
@ -125,7 +125,7 @@ impl LifetimeName {
|
||||
pub fn ident(&self) -> Ident {
|
||||
match *self {
|
||||
LifetimeName::ImplicitObjectLifetimeDefault
|
||||
| LifetimeName::Implicit(_)
|
||||
| LifetimeName::Implicit
|
||||
| LifetimeName::Error => Ident::empty(),
|
||||
LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime),
|
||||
LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
|
||||
@ -136,7 +136,7 @@ impl LifetimeName {
|
||||
pub fn is_elided(&self) -> bool {
|
||||
match self {
|
||||
LifetimeName::ImplicitObjectLifetimeDefault
|
||||
| LifetimeName::Implicit(_)
|
||||
| LifetimeName::Implicit
|
||||
| LifetimeName::Underscore => true,
|
||||
|
||||
// It might seem surprising that `Fresh(_)` counts as
|
||||
|
@ -528,7 +528,7 @@ pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime
|
||||
| LifetimeName::Param(ParamName::Error)
|
||||
| LifetimeName::Static
|
||||
| LifetimeName::Error
|
||||
| LifetimeName::Implicit(_)
|
||||
| LifetimeName::Implicit
|
||||
| LifetimeName::ImplicitObjectLifetimeDefault
|
||||
| LifetimeName::Underscore => {}
|
||||
}
|
||||
|
@ -441,6 +441,7 @@ impl EarlyLintPass for UnsafeCode {
|
||||
_,
|
||||
ast::FnSig { header: ast::FnHeader { unsafety: ast::Unsafe::Yes(_), .. }, .. },
|
||||
_,
|
||||
_,
|
||||
body,
|
||||
) = fk
|
||||
{
|
||||
|
@ -21,7 +21,8 @@ use crate::passes::{EarlyLintPassObject, LateLintPassObject};
|
||||
use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync;
|
||||
use rustc_errors::{struct_span_err, Applicability, MultiSpan, SuggestionStyle};
|
||||
use rustc_errors::{add_elided_lifetime_in_path_suggestion, struct_span_err};
|
||||
use rustc_errors::{Applicability, MultiSpan, SuggestionStyle};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def_id::{CrateNum, DefId};
|
||||
@ -665,6 +666,21 @@ pub trait LintContext: Sized {
|
||||
) => {
|
||||
db.span_note(span_def, "the macro is defined here");
|
||||
}
|
||||
BuiltinLintDiagnostics::ElidedLifetimesInPaths(
|
||||
n,
|
||||
path_span,
|
||||
incl_angl_brckt,
|
||||
insertion_span,
|
||||
) => {
|
||||
add_elided_lifetime_in_path_suggestion(
|
||||
sess.source_map(),
|
||||
&mut db,
|
||||
n,
|
||||
path_span,
|
||||
incl_angl_brckt,
|
||||
insertion_span,
|
||||
);
|
||||
}
|
||||
BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
|
||||
db.span_suggestion(span, ¬e, sugg, Applicability::MaybeIncorrect);
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
|
||||
|
||||
// Explicitly check for lints associated with 'closure_id', since
|
||||
// it does not have a corresponding AST node
|
||||
if let ast_visit::FnKind::Fn(_, _, sig, _, _) = fk {
|
||||
if let ast_visit::FnKind::Fn(_, _, sig, _, _, _) = fk {
|
||||
if let ast::Async::Yes { closure_id, .. } = sig.header.asyncness {
|
||||
self.check_id(closure_id);
|
||||
}
|
||||
@ -284,6 +284,11 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
|
||||
ast_visit::walk_path(self, p);
|
||||
}
|
||||
|
||||
fn visit_path_segment(&mut self, path_span: Span, s: &'a ast::PathSegment) {
|
||||
self.check_id(s.id);
|
||||
ast_visit::walk_path_segment(self, path_span, s);
|
||||
}
|
||||
|
||||
fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
|
||||
run_early_pass!(self, check_attribute, attr);
|
||||
}
|
||||
|
@ -418,6 +418,7 @@ pub enum BuiltinLintDiagnostics {
|
||||
AbsPathWithModule(Span),
|
||||
ProcMacroDeriveResolutionFallback(Span),
|
||||
MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
|
||||
ElidedLifetimesInPaths(usize, Span, bool, Span),
|
||||
UnknownCrateTypes(Span, String, String),
|
||||
UnusedImports(String, Vec<(Span, String)>, Option<Span>),
|
||||
RedundantImport(Vec<(Span, bool)>, Ident),
|
||||
|
@ -521,11 +521,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||
// while the current crate doesn't have a valid `crate_name`.
|
||||
if crate_name != kw::Empty {
|
||||
// `crate_name` should not be interpreted as relative.
|
||||
module_path.push(Segment {
|
||||
ident: Ident { name: kw::PathRoot, span: source.ident.span },
|
||||
id: Some(self.r.next_node_id()),
|
||||
has_generic_args: false,
|
||||
});
|
||||
module_path.push(Segment::from_ident_and_id(
|
||||
Ident { name: kw::PathRoot, span: source.ident.span },
|
||||
self.r.next_node_id(),
|
||||
));
|
||||
source.ident.name = crate_name;
|
||||
}
|
||||
if rename.is_none() {
|
||||
|
@ -133,8 +133,10 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
|
||||
if let FnKind::Fn(_, _, sig, _, body) = fn_kind {
|
||||
if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind {
|
||||
if let Async::Yes { closure_id, return_impl_trait_id, .. } = sig.header.asyncness {
|
||||
self.visit_generics(generics);
|
||||
|
||||
let return_impl_trait_id =
|
||||
self.create_def(return_impl_trait_id, DefPathData::ImplTrait, span);
|
||||
|
||||
|
@ -1402,7 +1402,7 @@ impl<'a> Resolver<'a> {
|
||||
let mut allow_super = true;
|
||||
let mut second_binding = None;
|
||||
|
||||
for (i, &Segment { ident, id, has_generic_args: _ }) in path.iter().enumerate() {
|
||||
for (i, &Segment { ident, id, .. }) in path.iter().enumerate() {
|
||||
debug!("resolve_path ident {} {:?} {:?}", i, ident, id);
|
||||
let record_segment_res = |this: &mut Self, res| {
|
||||
if finalize.is_some() {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion};
|
||||
use crate::late::lifetimes::{ElisionFailureInfo, LifetimeContext};
|
||||
use crate::late::{AliasPossibility, LateResolutionVisitor, RibKind};
|
||||
use crate::late::{LifetimeBinderKind, LifetimeRibKind};
|
||||
use crate::path_names_to_string;
|
||||
use crate::{Finalize, Module, ModuleKind, ModuleOrUniformRoot};
|
||||
use crate::{PathResult, PathSource, Segment};
|
||||
@ -1793,6 +1794,102 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||
(*ident, within_scope)
|
||||
})
|
||||
}
|
||||
|
||||
crate fn emit_undeclared_lifetime_error(
|
||||
&self,
|
||||
lifetime_ref: &ast::Lifetime,
|
||||
outer_lifetime_ref: Option<Ident>,
|
||||
) {
|
||||
debug_assert_ne!(lifetime_ref.ident.name, kw::UnderscoreLifetime);
|
||||
let mut err = if let Some(outer) = outer_lifetime_ref {
|
||||
let mut err = struct_span_err!(
|
||||
self.r.session,
|
||||
lifetime_ref.ident.span,
|
||||
E0401,
|
||||
"can't use generic parameters from outer item",
|
||||
);
|
||||
err.span_label(lifetime_ref.ident.span, "use of generic parameter from outer item");
|
||||
err.span_label(outer.span, "lifetime parameter from outer item");
|
||||
err
|
||||
} else {
|
||||
let mut err = struct_span_err!(
|
||||
self.r.session,
|
||||
lifetime_ref.ident.span,
|
||||
E0261,
|
||||
"use of undeclared lifetime name `{}`",
|
||||
lifetime_ref.ident
|
||||
);
|
||||
err.span_label(lifetime_ref.ident.span, "undeclared lifetime");
|
||||
err
|
||||
};
|
||||
let mut suggest_note = true;
|
||||
|
||||
for rib in self.lifetime_ribs.iter().rev() {
|
||||
match rib.kind {
|
||||
LifetimeRibKind::Generics { span, kind } => {
|
||||
if !span.can_be_used_for_suggestions() && suggest_note {
|
||||
suggest_note = false; // Avoid displaying the same help multiple times.
|
||||
err.span_label(
|
||||
span,
|
||||
&format!(
|
||||
"lifetime `{}` is missing in item created through this procedural macro",
|
||||
lifetime_ref.ident,
|
||||
),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
let higher_ranked = matches!(
|
||||
kind,
|
||||
LifetimeBinderKind::BareFnType
|
||||
| LifetimeBinderKind::PolyTrait
|
||||
| LifetimeBinderKind::WhereBound
|
||||
);
|
||||
let (span, sugg) = if span.is_empty() {
|
||||
let sugg = format!(
|
||||
"{}<{}>{}",
|
||||
if higher_ranked { "for" } else { "" },
|
||||
lifetime_ref.ident,
|
||||
if higher_ranked { " " } else { "" },
|
||||
);
|
||||
(span, sugg)
|
||||
} else {
|
||||
let span =
|
||||
self.r.session.source_map().span_through_char(span, '<').shrink_to_hi();
|
||||
let sugg = format!("{}, ", lifetime_ref.ident);
|
||||
(span, sugg)
|
||||
};
|
||||
if higher_ranked {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
&format!(
|
||||
"consider making the {} lifetime-generic with a new `{}` lifetime",
|
||||
kind.descr(),
|
||||
lifetime_ref
|
||||
),
|
||||
sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.note_once(
|
||||
"for more information on higher-ranked polymorphism, visit \
|
||||
https://doc.rust-lang.org/nomicon/hrtb.html",
|
||||
);
|
||||
} else {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
&format!("consider introducing lifetime `{}` here", lifetime_ref.ident),
|
||||
sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
LifetimeRibKind::Item => break,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> LifetimeContext<'_, 'tcx> {
|
||||
@ -1810,67 +1907,6 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
|
||||
)
|
||||
}
|
||||
|
||||
crate fn emit_undeclared_lifetime_error(&self, lifetime_ref: &hir::Lifetime) {
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
lifetime_ref.span,
|
||||
E0261,
|
||||
"use of undeclared lifetime name `{}`",
|
||||
lifetime_ref
|
||||
);
|
||||
err.span_label(lifetime_ref.span, "undeclared lifetime");
|
||||
let mut suggested_spans = vec![];
|
||||
for missing in &self.missing_named_lifetime_spots {
|
||||
match missing {
|
||||
MissingLifetimeSpot::Generics(generics) => {
|
||||
let (span, sugg) = if let Some(param) = generics.params.iter().find(|p| {
|
||||
!matches!(
|
||||
p.kind,
|
||||
hir::GenericParamKind::Type { synthetic: true, .. }
|
||||
| hir::GenericParamKind::Lifetime {
|
||||
kind: hir::LifetimeParamKind::Elided,
|
||||
}
|
||||
)
|
||||
}) {
|
||||
(param.span.shrink_to_lo(), format!("{}, ", lifetime_ref))
|
||||
} else {
|
||||
(generics.span, format!("<{}>", lifetime_ref))
|
||||
};
|
||||
if suggested_spans.contains(&span) {
|
||||
continue;
|
||||
}
|
||||
suggested_spans.push(span);
|
||||
if span.can_be_used_for_suggestions() {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
&format!("consider introducing lifetime `{}` here", lifetime_ref),
|
||||
sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
MissingLifetimeSpot::HigherRanked { span, span_type } => {
|
||||
err.span_suggestion(
|
||||
*span,
|
||||
&format!(
|
||||
"consider making the {} lifetime-generic with a new `{}` lifetime",
|
||||
span_type.descr(),
|
||||
lifetime_ref
|
||||
),
|
||||
span_type.suggestion(&lifetime_ref.to_string()),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.note(
|
||||
"for more information on higher-ranked polymorphism, visit \
|
||||
https://doc.rust-lang.org/nomicon/hrtb.html",
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
||||
/// Returns whether to add `'static` lifetime to the suggested lifetime list.
|
||||
crate fn report_elision_failure(
|
||||
&mut self,
|
||||
@ -1950,38 +1986,6 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
crate fn report_elided_lifetime_in_ty(&self, lifetime_refs: &[&hir::Lifetime]) {
|
||||
let Some(missing_lifetime) = lifetime_refs.iter().find(|lt| {
|
||||
lt.name == hir::LifetimeName::Implicit(true)
|
||||
}) else { return };
|
||||
|
||||
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,
|
||||
missing_lifetime.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
|
||||
// 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.
|
||||
@ -2416,9 +2420,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
|
||||
);
|
||||
let is_allowed_lifetime = matches!(
|
||||
lifetime_ref.name,
|
||||
hir::LifetimeName::Implicit(_)
|
||||
| hir::LifetimeName::Static
|
||||
| hir::LifetimeName::Underscore
|
||||
hir::LifetimeName::Implicit | hir::LifetimeName::Static | hir::LifetimeName::Underscore
|
||||
);
|
||||
|
||||
if !self.tcx.lazy_normalization() && is_anon_const && !is_allowed_lifetime {
|
||||
|
@ -164,9 +164,6 @@ crate struct LifetimeContext<'a, 'tcx> {
|
||||
map: &'a mut NamedRegionMap,
|
||||
scope: ScopeRef<'a>,
|
||||
|
||||
/// Used to disallow the use of in-band lifetimes in `fn` or `Fn` syntax.
|
||||
is_in_fn_syntax: bool,
|
||||
|
||||
is_in_const_generic: bool,
|
||||
|
||||
/// Indicates that we only care about the definition of a trait. This should
|
||||
@ -455,7 +452,6 @@ fn do_resolve(
|
||||
tcx,
|
||||
map: &mut named_region_map,
|
||||
scope: ROOT_SCOPE,
|
||||
is_in_fn_syntax: false,
|
||||
is_in_const_generic: false,
|
||||
trait_definition_only,
|
||||
labels_in_fn: vec![],
|
||||
@ -874,8 +870,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
match ty.kind {
|
||||
hir::TyKind::BareFn(ref c) => {
|
||||
let next_early_index = self.next_early_index();
|
||||
let was_in_fn_syntax = self.is_in_fn_syntax;
|
||||
self.is_in_fn_syntax = true;
|
||||
let lifetime_span: Option<Span> =
|
||||
c.generic_params.iter().rev().find_map(|param| match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => Some(param.span),
|
||||
@ -917,7 +911,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
intravisit::walk_ty(this, ty);
|
||||
});
|
||||
self.missing_named_lifetime_spots.pop();
|
||||
self.is_in_fn_syntax = was_in_fn_syntax;
|
||||
}
|
||||
hir::TyKind::TraitObject(bounds, ref lifetime, _) => {
|
||||
debug!(?bounds, ?lifetime, "TraitObject");
|
||||
@ -928,7 +921,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
});
|
||||
match lifetime.name {
|
||||
LifetimeName::Implicit(_) => {
|
||||
LifetimeName::Implicit => {
|
||||
// For types like `dyn Foo`, we should
|
||||
// generate a special form of elided.
|
||||
span_bug!(ty.span, "object-lifetime-default expected, not implicit",);
|
||||
@ -1805,7 +1798,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
tcx: *tcx,
|
||||
map,
|
||||
scope: &wrap_scope,
|
||||
is_in_fn_syntax: self.is_in_fn_syntax,
|
||||
is_in_const_generic: self.is_in_const_generic,
|
||||
trait_definition_only: self.trait_definition_only,
|
||||
labels_in_fn,
|
||||
@ -2320,7 +2312,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
|
||||
self.insert_lifetime(lifetime_ref, def);
|
||||
} else {
|
||||
self.emit_undeclared_lifetime_error(lifetime_ref);
|
||||
self.tcx.sess.delay_span_bug(
|
||||
lifetime_ref.span,
|
||||
&format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2336,10 +2331,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
);
|
||||
|
||||
if generic_args.parenthesized {
|
||||
let was_in_fn_syntax = self.is_in_fn_syntax;
|
||||
self.is_in_fn_syntax = true;
|
||||
self.visit_fn_like_elision(generic_args.inputs(), Some(generic_args.bindings[0].ty()));
|
||||
self.is_in_fn_syntax = was_in_fn_syntax;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2963,9 +2955,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
let error = loop {
|
||||
match *scope {
|
||||
// Do not assign any resolution, it will be inferred.
|
||||
Scope::Body { .. } => break Ok(()),
|
||||
Scope::Body { .. } => return,
|
||||
|
||||
Scope::Root => break Err(None),
|
||||
Scope::Root => break None,
|
||||
|
||||
Scope::Binder { s, ref lifetimes, scope_type, .. } => {
|
||||
// collect named lifetimes for suggestions
|
||||
@ -2992,7 +2984,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
|
||||
self.insert_lifetime(lifetime_ref, lifetime);
|
||||
}
|
||||
break Ok(());
|
||||
return;
|
||||
}
|
||||
|
||||
Scope::Elision { elide: Elide::Exact(l), .. } => {
|
||||
@ -3000,7 +2992,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
for lifetime_ref in lifetime_refs {
|
||||
self.insert_lifetime(lifetime_ref, lifetime);
|
||||
}
|
||||
break Ok(());
|
||||
return;
|
||||
}
|
||||
|
||||
Scope::Elision { elide: Elide::Error(ref e), ref s, .. } => {
|
||||
@ -3025,10 +3017,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
break Err(Some(&e[..]));
|
||||
break Some(&e[..]);
|
||||
}
|
||||
|
||||
Scope::Elision { elide: Elide::Forbid, .. } => break Err(None),
|
||||
Scope::Elision { elide: Elide::Forbid, .. } => break None,
|
||||
|
||||
Scope::ObjectLifetimeDefault { s, .. }
|
||||
| Scope::Supertrait { s, .. }
|
||||
@ -3038,14 +3030,6 @@ 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
|
||||
// diagnostic pass and we don't want to emit more errors.
|
||||
if self.map.scope_for_path.is_some() {
|
||||
@ -3130,18 +3114,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
if let hir::ParamName::Plain(_) = lifetime_i_name {
|
||||
let name = lifetime_i_name.ident().name;
|
||||
if name == kw::UnderscoreLifetime || name == kw::StaticLifetime {
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
self.tcx.sess.delay_span_bug(
|
||||
lifetime_i.span,
|
||||
E0262,
|
||||
"invalid lifetime parameter name: `{}`",
|
||||
lifetime_i.name.ident(),
|
||||
&format!("invalid lifetime parameter name: `{}`", lifetime_i.name.ident()),
|
||||
);
|
||||
err.span_label(
|
||||
lifetime_i.span,
|
||||
format!("{} is a reserved lifetime name", name),
|
||||
);
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3190,7 +3166,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
))
|
||||
.emit();
|
||||
}
|
||||
hir::LifetimeName::Param(_) | hir::LifetimeName::Implicit(_) => {
|
||||
hir::LifetimeName::Param(_) | hir::LifetimeName::Implicit => {
|
||||
self.resolve_lifetime_ref(lt);
|
||||
}
|
||||
hir::LifetimeName::ImplicitObjectLifetimeDefault => {
|
||||
|
@ -11,6 +11,7 @@
|
||||
#![feature(drain_filter)]
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(let_else)]
|
||||
#![feature(never_type)]
|
||||
@ -27,7 +28,7 @@ pub use rustc_hir::def::{Namespace, PerNS};
|
||||
use rustc_arena::{DroplessArena, TypedArena};
|
||||
use rustc_ast::node_id::NodeMap;
|
||||
use rustc_ast::{self as ast, NodeId, CRATE_NODE_ID};
|
||||
use rustc_ast::{Crate, Expr, ExprKind, LitKind, Path};
|
||||
use rustc_ast::{AngleBracketedArg, Crate, Expr, ExprKind, GenericArg, GenericArgs, LitKind, Path};
|
||||
use rustc_ast_lowering::ResolverAstLowering;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||
use rustc_data_structures::intern::Interned;
|
||||
@ -282,6 +283,9 @@ pub struct Segment {
|
||||
/// Signals whether this `PathSegment` has generic arguments. Used to avoid providing
|
||||
/// nonsensical suggestions.
|
||||
has_generic_args: bool,
|
||||
/// Signals whether this `PathSegment` has lifetime arguments.
|
||||
has_lifetime_args: bool,
|
||||
args_span: Span,
|
||||
}
|
||||
|
||||
impl Segment {
|
||||
@ -290,7 +294,23 @@ impl Segment {
|
||||
}
|
||||
|
||||
fn from_ident(ident: Ident) -> Segment {
|
||||
Segment { ident, id: None, has_generic_args: false }
|
||||
Segment {
|
||||
ident,
|
||||
id: None,
|
||||
has_generic_args: false,
|
||||
has_lifetime_args: false,
|
||||
args_span: DUMMY_SP,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_ident_and_id(ident: Ident, id: NodeId) -> Segment {
|
||||
Segment {
|
||||
ident,
|
||||
id: Some(id),
|
||||
has_generic_args: false,
|
||||
has_lifetime_args: false,
|
||||
args_span: DUMMY_SP,
|
||||
}
|
||||
}
|
||||
|
||||
fn names_to_string(segments: &[Segment]) -> String {
|
||||
@ -300,7 +320,28 @@ impl Segment {
|
||||
|
||||
impl<'a> From<&'a ast::PathSegment> for Segment {
|
||||
fn from(seg: &'a ast::PathSegment) -> Segment {
|
||||
Segment { ident: seg.ident, id: Some(seg.id), has_generic_args: seg.args.is_some() }
|
||||
let has_generic_args = seg.args.is_some();
|
||||
let (args_span, has_lifetime_args) = if let Some(args) = seg.args.as_deref() {
|
||||
match args {
|
||||
GenericArgs::AngleBracketed(args) => {
|
||||
let found_lifetimes = args
|
||||
.args
|
||||
.iter()
|
||||
.any(|arg| matches!(arg, AngleBracketedArg::Arg(GenericArg::Lifetime(_))));
|
||||
(args.span, found_lifetimes)
|
||||
}
|
||||
GenericArgs::Parenthesized(args) => (args.span, true),
|
||||
}
|
||||
} else {
|
||||
(DUMMY_SP, false)
|
||||
};
|
||||
Segment {
|
||||
ident: seg.ident,
|
||||
id: Some(seg.id),
|
||||
has_generic_args,
|
||||
has_lifetime_args,
|
||||
args_span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1358,9 +1399,17 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
pub fn next_node_id(&mut self) -> NodeId {
|
||||
let next =
|
||||
self.next_node_id.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
|
||||
mem::replace(&mut self.next_node_id, ast::NodeId::from_u32(next))
|
||||
let start = self.next_node_id;
|
||||
let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
|
||||
self.next_node_id = ast::NodeId::from_u32(next);
|
||||
start
|
||||
}
|
||||
|
||||
pub fn next_node_ids(&mut self, count: usize) -> std::ops::Range<NodeId> {
|
||||
let start = self.next_node_id;
|
||||
let end = start.as_usize().checked_add(count).expect("input too large; ran out of NodeIds");
|
||||
self.next_node_id = ast::NodeId::from_usize(end);
|
||||
start..self.next_node_id
|
||||
}
|
||||
|
||||
pub fn lint_buffer(&mut self) -> &mut LintBuffer {
|
||||
|
@ -2,9 +2,13 @@ error[E0726]: implicit elided lifetime not allowed here
|
||||
--> $DIR/async-fn-path-elision.rs:5:20
|
||||
|
|
||||
LL | async fn error(lt: HasLifetime) {
|
||||
| ^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
|
||||
| ^^^^^^^^^^^ expected lifetime parameter
|
||||
|
|
||||
= note: assuming a `'static` lifetime...
|
||||
help: indicate the anonymous lifetime
|
||||
|
|
||||
LL | async fn error(lt: HasLifetime<'_>) {
|
||||
| ++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,9 +2,17 @@ error[E0261]: use of undeclared lifetime name `'x`
|
||||
--> $DIR/gat-in-trait-path-undeclared-lifetime.rs:8:35
|
||||
|
|
||||
LL | fn _f(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'x` here: `<'x>`
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||
help: consider making the bound lifetime-generic with a new `'x` lifetime
|
||||
|
|
||||
LL | fn _f(arg : Box<dyn for<'x, 'a> X<Y<'x> = &'a [u32]>>) {}
|
||||
| +++
|
||||
help: consider introducing lifetime `'x` here
|
||||
|
|
||||
LL | fn _f<'x>(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
|
||||
| ++++
|
||||
|
||||
error[E0582]: binding for associated type `Y` references lifetime `'a`, which does not appear in the trait input types
|
||||
--> $DIR/gat-in-trait-path-undeclared-lifetime.rs:8:33
|
||||
|
@ -4,14 +4,19 @@ error[E0261]: use of undeclared lifetime name `'b`
|
||||
LL | + Deref<Target = Self::Item<'b>>;
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
help: consider introducing lifetime `'b` here
|
||||
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||
help: consider making the bound lifetime-generic with a new `'b` lifetime
|
||||
|
|
||||
LL | trait Iterable<'b> {
|
||||
| ++++
|
||||
LL | + for<'b> Deref<Target = Self::Item<'b>>;
|
||||
| +++++++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | type Iter<'b, 'a>: Iterator<Item = Self::Item<'a>>
|
||||
| +++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | trait Iterable<'b> {
|
||||
| ++++
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'undeclared`
|
||||
--> $DIR/generic_associated_type_undeclared_lifetimes.rs:11:41
|
||||
@ -21,12 +26,12 @@ LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>;
|
||||
|
|
||||
help: consider introducing lifetime `'undeclared` here
|
||||
|
|
||||
LL | trait Iterable<'undeclared> {
|
||||
| +++++++++++++
|
||||
help: consider introducing lifetime `'undeclared` here
|
||||
|
|
||||
LL | fn iter<'undeclared, 'a>(&'a self) -> Self::Iter<'undeclared>;
|
||||
| ++++++++++++
|
||||
help: consider introducing lifetime `'undeclared` here
|
||||
|
|
||||
LL | trait Iterable<'undeclared> {
|
||||
| +++++++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -4,9 +4,9 @@ trait X {
|
||||
type Y<'a>;
|
||||
}
|
||||
|
||||
fn f(x: Box<dyn X<Y<'a>=&'a ()>>) {}
|
||||
//~^ ERROR: use of undeclared lifetime name `'a`
|
||||
//~| ERROR: use of undeclared lifetime name `'a`
|
||||
|
||||
fn f(x: Box<dyn X<Y<'a> = &'a ()>>) {}
|
||||
//~^ ERROR: use of undeclared lifetime name `'a`
|
||||
//~| ERROR: use of undeclared lifetime name `'a`
|
||||
//~| ERROR: the trait `X` cannot be made into an object [E0038]
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,19 +1,50 @@
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/issue-67510.rs:7:21
|
||||
|
|
||||
LL | fn f(x: Box<dyn X<Y<'a>=&'a ()>>) {}
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `<'a>`
|
||||
LL | fn f(x: Box<dyn X<Y<'a> = &'a ()>>) {}
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||
help: consider making the bound lifetime-generic with a new `'a` lifetime
|
||||
|
|
||||
LL | fn f(x: Box<dyn for<'a> X<Y<'a> = &'a ()>>) {}
|
||||
| +++++++
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | fn f<'a>(x: Box<dyn X<Y<'a> = &'a ()>>) {}
|
||||
| ++++
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/issue-67510.rs:7:26
|
||||
--> $DIR/issue-67510.rs:7:28
|
||||
|
|
||||
LL | fn f(x: Box<dyn X<Y<'a>=&'a ()>>) {}
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `<'a>`
|
||||
LL | fn f(x: Box<dyn X<Y<'a> = &'a ()>>) {}
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
help: consider making the bound lifetime-generic with a new `'a` lifetime
|
||||
|
|
||||
LL | fn f(x: Box<dyn for<'a> X<Y<'a> = &'a ()>>) {}
|
||||
| +++++++
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | fn f<'a>(x: Box<dyn X<Y<'a> = &'a ()>>) {}
|
||||
| ++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0038]: the trait `X` cannot be made into an object
|
||||
--> $DIR/issue-67510.rs:7:13
|
||||
|
|
||||
LL | fn f(x: Box<dyn X<Y<'a> = &'a ()>>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/issue-67510.rs:4:10
|
||||
|
|
||||
LL | trait X {
|
||||
| - this trait cannot be made into an object...
|
||||
LL | type Y<'a>;
|
||||
| ^ ...because it contains the generic associated type `Y`
|
||||
= help: consider moving `Y` to another trait
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0038, E0261.
|
||||
For more information about an error, try `rustc --explain E0038`.
|
||||
|
@ -12,13 +12,10 @@ impl Document for DocumentImpl {
|
||||
type Cursor<'a> = DocCursorImpl<'a>;
|
||||
|
||||
fn cursor(&self) -> Self::Cursor<'_> {
|
||||
DocCursorImpl {
|
||||
document: &self,
|
||||
}
|
||||
DocCursorImpl { document: &self }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
trait DocCursor<'a> {}
|
||||
|
||||
struct DocCursorImpl<'a> {
|
||||
@ -35,7 +32,6 @@ where
|
||||
_phantom: std::marker::PhantomData<&'d ()>,
|
||||
}
|
||||
|
||||
|
||||
impl<'d, Cursor> Lexer<'d, Cursor>
|
||||
where
|
||||
Cursor: DocCursor<'d>,
|
||||
@ -44,10 +40,7 @@ where
|
||||
where
|
||||
Doc: Document<Cursor<'d> = Cursor>,
|
||||
{
|
||||
Lexer {
|
||||
cursor: document.cursor(),
|
||||
_phantom: std::marker::PhantomData,
|
||||
}
|
||||
Lexer { cursor: document.cursor(), _phantom: std::marker::PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-70304.rs:54:41
|
||||
--> $DIR/issue-70304.rs:47:41
|
||||
|
|
||||
LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> {
|
||||
| ^^ expected named lifetime parameter
|
||||
|
@ -2,7 +2,9 @@ error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/generic-extern-lifetime.rs:6:26
|
||||
|
|
||||
LL | pub fn life2<'b>(x: &'a i32, y: &'b i32);
|
||||
| ^^ undeclared lifetime
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `'a,`
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/generic-extern-lifetime.rs:8:37
|
||||
@ -13,8 +15,12 @@ LL | pub fn life4<'b>(x: for<'c> fn(&'a i32));
|
||||
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||
help: consider making the type lifetime-generic with a new `'a` lifetime
|
||||
|
|
||||
LL | pub fn life4<'b>(x: for<'c, 'a> fn(&'a i32));
|
||||
| ++++
|
||||
LL | pub fn life4<'b>(x: for<'a, 'c> fn(&'a i32));
|
||||
| +++
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | pub fn life4<'a, 'b>(x: for<'c> fn(&'a i32));
|
||||
| +++
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/generic-extern-lifetime.rs:11:39
|
||||
@ -22,11 +28,14 @@ error[E0261]: use of undeclared lifetime name `'a`
|
||||
LL | pub fn life7<'b>() -> for<'c> fn(&'a i32);
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||
help: consider making the type lifetime-generic with a new `'a` lifetime
|
||||
|
|
||||
LL | pub fn life7<'b>() -> for<'c, 'a> fn(&'a i32);
|
||||
| ++++
|
||||
LL | pub fn life7<'b>() -> for<'a, 'c> fn(&'a i32);
|
||||
| +++
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | pub fn life7<'a, 'b>() -> for<'c> fn(&'a i32);
|
||||
| +++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -2,9 +2,13 @@ error[E0726]: implicit elided lifetime not allowed here
|
||||
--> $DIR/path-elided.rs:7:18
|
||||
|
|
||||
LL | impl MyTrait for Foo {
|
||||
| ^^^- help: indicate the anonymous lifetime: `<'_>`
|
||||
| ^^^ expected lifetime parameter
|
||||
|
|
||||
= note: assuming a `'static` lifetime...
|
||||
help: indicate the anonymous lifetime
|
||||
|
|
||||
LL | impl MyTrait for Foo<'_> {
|
||||
| ++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
#![allow(warnings)]
|
||||
|
||||
trait MyTrait<'a> { }
|
||||
trait MyTrait<'a> {}
|
||||
|
||||
impl MyTrait for u32 {
|
||||
//~^ ERROR implicit elided lifetime not allowed here
|
||||
}
|
||||
impl MyTrait for u32 {}
|
||||
//~^ ERROR implicit elided lifetime not allowed here
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,10 +1,14 @@
|
||||
error[E0726]: implicit elided lifetime not allowed here
|
||||
--> $DIR/trait-elided.rs:5:6
|
||||
|
|
||||
LL | impl MyTrait for u32 {
|
||||
| ^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
|
||||
LL | impl MyTrait for u32 {}
|
||||
| ^^^^^^^ expected lifetime parameter
|
||||
|
|
||||
= note: assuming a `'static` lifetime...
|
||||
help: indicate the anonymous lifetime
|
||||
|
|
||||
LL | impl MyTrait<'_> for u32 {}
|
||||
| ++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,16 +1,20 @@
|
||||
trait Serializable<'self, T> { //~ ERROR lifetimes cannot use keyword names
|
||||
fn serialize(val : &'self T) -> Vec<u8>; //~ ERROR lifetimes cannot use keyword names
|
||||
fn deserialize(repr : &[u8]) -> &'self T; //~ ERROR lifetimes cannot use keyword names
|
||||
trait Serializable<'self, T> {
|
||||
//~^ ERROR lifetimes cannot use keyword names
|
||||
fn serialize(val: &'self T) -> Vec<u8>; //~ ERROR lifetimes cannot use keyword names
|
||||
fn deserialize(repr: &[u8]) -> &'self T; //~ ERROR lifetimes cannot use keyword names
|
||||
}
|
||||
|
||||
impl<'self> Serializable<str> for &'self str { //~ ERROR lifetimes cannot use keyword names
|
||||
impl<'self> Serializable<str> for &'self str {
|
||||
//~^ ERROR lifetimes cannot use keyword names
|
||||
//~| ERROR lifetimes cannot use keyword names
|
||||
//~| ERROR implicit elided lifetime not allowed here
|
||||
//~| ERROR the size for values of type `str` cannot be known at compilation time
|
||||
fn serialize(val : &'self str) -> Vec<u8> { //~ ERROR lifetimes cannot use keyword names
|
||||
//~| ERROR the size for values of type `str` cannot be known at compilation time [E0277]
|
||||
fn serialize(val: &'self str) -> Vec<u8> {
|
||||
//~^ ERROR lifetimes cannot use keyword names
|
||||
vec![1]
|
||||
}
|
||||
fn deserialize(repr: &[u8]) -> &'self str { //~ ERROR lifetimes cannot use keyword names
|
||||
fn deserialize(repr: &[u8]) -> &'self str {
|
||||
//~^ ERROR lifetimes cannot use keyword names
|
||||
"hi"
|
||||
}
|
||||
}
|
||||
|
@ -5,51 +5,55 @@ LL | trait Serializable<'self, T> {
|
||||
| ^^^^^
|
||||
|
||||
error: lifetimes cannot use keyword names
|
||||
--> $DIR/issue-10412.rs:2:25
|
||||
--> $DIR/issue-10412.rs:3:24
|
||||
|
|
||||
LL | fn serialize(val : &'self T) -> Vec<u8>;
|
||||
LL | fn serialize(val: &'self T) -> Vec<u8>;
|
||||
| ^^^^^
|
||||
|
||||
error: lifetimes cannot use keyword names
|
||||
--> $DIR/issue-10412.rs:3:38
|
||||
--> $DIR/issue-10412.rs:4:37
|
||||
|
|
||||
LL | fn deserialize(repr : &[u8]) -> &'self T;
|
||||
LL | fn deserialize(repr: &[u8]) -> &'self T;
|
||||
| ^^^^^
|
||||
|
||||
error: lifetimes cannot use keyword names
|
||||
--> $DIR/issue-10412.rs:6:6
|
||||
--> $DIR/issue-10412.rs:7:6
|
||||
|
|
||||
LL | impl<'self> Serializable<str> for &'self str {
|
||||
| ^^^^^
|
||||
|
||||
error: lifetimes cannot use keyword names
|
||||
--> $DIR/issue-10412.rs:6:36
|
||||
--> $DIR/issue-10412.rs:7:36
|
||||
|
|
||||
LL | impl<'self> Serializable<str> for &'self str {
|
||||
| ^^^^^
|
||||
|
||||
error: lifetimes cannot use keyword names
|
||||
--> $DIR/issue-10412.rs:10:25
|
||||
--> $DIR/issue-10412.rs:12:24
|
||||
|
|
||||
LL | fn serialize(val : &'self str) -> Vec<u8> {
|
||||
LL | fn serialize(val: &'self str) -> Vec<u8> {
|
||||
| ^^^^^
|
||||
|
||||
error: lifetimes cannot use keyword names
|
||||
--> $DIR/issue-10412.rs:13:37
|
||||
--> $DIR/issue-10412.rs:16:37
|
||||
|
|
||||
LL | fn deserialize(repr: &[u8]) -> &'self str {
|
||||
| ^^^^^
|
||||
|
||||
error[E0726]: implicit elided lifetime not allowed here
|
||||
--> $DIR/issue-10412.rs:6:13
|
||||
--> $DIR/issue-10412.rs:7:13
|
||||
|
|
||||
LL | impl<'self> Serializable<str> for &'self str {
|
||||
| ^^^^^^^^^^^^^^^^^ help: indicate the anonymous lifetime: `Serializable<'_, str>`
|
||||
| ^^^^^^^^^^^^^^^^^ expected lifetime parameter
|
||||
|
|
||||
= note: assuming a `'static` lifetime...
|
||||
help: indicate the anonymous lifetime
|
||||
|
|
||||
LL | impl<'self> Serializable<'_, str> for &'self str {
|
||||
| +++
|
||||
|
||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
--> $DIR/issue-10412.rs:6:13
|
||||
--> $DIR/issue-10412.rs:7:13
|
||||
|
|
||||
LL | impl<'self> Serializable<str> for &'self str {
|
||||
| ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
@ -2,13 +2,17 @@ error: hidden lifetime parameters in types are deprecated
|
||||
--> $DIR/issue-91763.rs:8:20
|
||||
|
|
||||
LL | fn f() -> Ptr<Thing>;
|
||||
| ^ expected named lifetime parameter
|
||||
| ^ expected lifetime parameter
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-91763.rs:3:9
|
||||
|
|
||||
LL | #![deny(elided_lifetimes_in_paths)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: indicate the anonymous lifetime
|
||||
|
|
||||
LL | fn f() -> Ptr<Thing><'_>;
|
||||
| ++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -9,6 +9,8 @@ LL | a: &'b str,
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/undeclared-lifetime-used-in-debug-macro-issue-70152.rs:3:9
|
||||
|
|
||||
LL | #[derive(Eq, PartialEq)]
|
||||
| -- lifetime `'b` is missing in item created through this procedural macro
|
||||
LL | struct Test {
|
||||
| - help: consider introducing lifetime `'b` here: `<'b>`
|
||||
LL | a: &'b str,
|
||||
@ -22,11 +24,11 @@ LL | fn foo(&'b self) {}
|
||||
|
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | impl<'b> T for Test {
|
||||
LL | fn foo<'b>(&'b self) {}
|
||||
| ++++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn foo<'b>(&'b self) {}
|
||||
LL | impl<'b> T for Test {
|
||||
| ++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
@ -2,13 +2,13 @@ warning: hidden lifetime parameters in types are deprecated
|
||||
--> $DIR/allowed-by-default-lint.rs:9:12
|
||||
|
|
||||
LL | fn foo(x: &Foo) {}
|
||||
| ^^^ expected named lifetime parameter
|
||||
| ^^^ expected lifetime parameter
|
||||
|
|
||||
= note: requested on the command line with `--force-warn elided-lifetimes-in-paths`
|
||||
help: consider using the `'_` lifetime
|
||||
help: indicate the anonymous lifetime
|
||||
|
|
||||
LL | fn foo(x: &Foo<'_>) {}
|
||||
| ~~~~~~~
|
||||
| ++++
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
|
@ -19,9 +19,9 @@ pub struct CheaterDetectionMechanism {}
|
||||
impl fmt::Debug for CheaterDetectionMechanism {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
//~^ WARN hidden lifetime parameters in types are deprecated
|
||||
//~| NOTE expected named lifetime parameter
|
||||
//~| NOTE expected lifetime parameter
|
||||
//~| NOTE explicit anonymous lifetimes aid
|
||||
//~| HELP consider using the `'_` lifetime
|
||||
//~| HELP indicate the anonymous lifetime
|
||||
fmt.debug_struct("CheaterDetectionMechanism").finish()
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,9 @@ warning: hidden lifetime parameters in types are deprecated
|
||||
--> $DIR/reasons.rs:20:34
|
||||
|
|
||||
LL | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
| ^^^^^^^^^ expected named lifetime parameter
|
||||
| -----^^^^^^^^^
|
||||
| |
|
||||
| expected lifetime parameter
|
||||
|
|
||||
= note: explicit anonymous lifetimes aid reasoning about ownership
|
||||
note: the lint level is defined here
|
||||
@ -10,10 +12,10 @@ note: the lint level is defined here
|
||||
|
|
||||
LL | #![warn(elided_lifetimes_in_paths,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: consider using the `'_` lifetime
|
||||
help: indicate the anonymous lifetime
|
||||
|
|
||||
LL | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
| ~~~~~~~~~~~~~
|
||||
| ++++
|
||||
|
||||
warning: variable `Social_exchange_psychology` should have a snake case name
|
||||
--> $DIR/reasons.rs:30:9
|
||||
|
@ -1,3 +1,6 @@
|
||||
fn main() {
|
||||
0.clone::<'a>(); //~ ERROR use of undeclared lifetime name `'a`
|
||||
0.clone::<'a>();
|
||||
//~^ ERROR use of undeclared lifetime name `'a`
|
||||
//~| WARN cannot specify lifetime arguments explicitly if late bound
|
||||
//~| WARN this was previously accepted by the compiler
|
||||
}
|
||||
|
@ -6,6 +6,21 @@ LL | fn main() {
|
||||
LL | 0.clone::<'a>();
|
||||
| ^^ undeclared lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/method-call-lifetime-args-unresolved.rs:2:15
|
||||
|
|
||||
LL | 0.clone::<'a>();
|
||||
| ^^
|
||||
|
|
||||
::: $SRC_DIR/core/src/clone.rs:LL:COL
|
||||
|
|
||||
LL | fn clone(&self) -> Self;
|
||||
| - the late bound lifetime parameter is introduced here
|
||||
|
|
||||
= note: `#[warn(late_bound_lifetime_arguments)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
|
@ -1,5 +1,6 @@
|
||||
struct Foo<'static> { //~ ERROR invalid lifetime parameter name: `'static`
|
||||
x: &'static isize
|
||||
struct Foo<'static> {
|
||||
//~^ ERROR invalid lifetime parameter name: `'static`
|
||||
x: &'static isize,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -23,14 +23,14 @@ fn bar<'a>(x: &'a isize) {
|
||||
let y: &'a isize = x;
|
||||
|
||||
// &'a is not visible to *items*:
|
||||
type X = Option<&'a isize>; //~ ERROR undeclared lifetime
|
||||
type X = Option<&'a isize>; //~ ERROR can't use generic parameters from outer item
|
||||
enum E {
|
||||
E1(&'a isize) //~ ERROR undeclared lifetime
|
||||
E1(&'a isize) //~ ERROR can't use generic parameters from outer item
|
||||
}
|
||||
struct S {
|
||||
f: &'a isize //~ ERROR undeclared lifetime
|
||||
f: &'a isize //~ ERROR can't use generic parameters from outer item
|
||||
}
|
||||
fn f(a: &'a isize) { } //~ ERROR undeclared lifetime
|
||||
fn f(a: &'a isize) { } //~ ERROR can't use generic parameters from outer item
|
||||
|
||||
// &'a CAN be declared on functions and used then:
|
||||
fn g<'a>(a: &'a isize) { } // OK
|
||||
|
@ -1,19 +1,3 @@
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/regions-name-undeclared.rs:28:13
|
||||
|
|
||||
LL | enum E {
|
||||
| - help: consider introducing lifetime `'a` here: `<'a>`
|
||||
LL | E1(&'a isize)
|
||||
| ^^ undeclared lifetime
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/regions-name-undeclared.rs:31:13
|
||||
|
|
||||
LL | struct S {
|
||||
| - help: consider introducing lifetime `'a` here: `<'a>`
|
||||
LL | f: &'a isize
|
||||
| ^^ undeclared lifetime
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/regions-name-undeclared.rs:16:24
|
||||
|
|
||||
@ -22,12 +6,12 @@ LL | fn m4(&self, arg: &'b isize) { }
|
||||
|
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | impl<'b, 'a> Foo<'a> {
|
||||
| +++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn m4<'b>(&self, arg: &'b isize) { }
|
||||
| ++++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | impl<'b, 'a> Foo<'a> {
|
||||
| +++
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/regions-name-undeclared.rs:17:12
|
||||
@ -37,12 +21,12 @@ LL | fn m5(&'b self) { }
|
||||
|
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | impl<'b, 'a> Foo<'a> {
|
||||
| +++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn m5<'b>(&'b self) { }
|
||||
| ++++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | impl<'b, 'a> Foo<'a> {
|
||||
| +++
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/regions-name-undeclared.rs:18:27
|
||||
@ -52,26 +36,54 @@ LL | fn m6(&self, arg: Foo<'b>) { }
|
||||
|
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | impl<'b, 'a> Foo<'a> {
|
||||
| +++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn m6<'b>(&self, arg: Foo<'b>) { }
|
||||
| ++++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | impl<'b, 'a> Foo<'a> {
|
||||
| +++
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
error[E0401]: can't use generic parameters from outer item
|
||||
--> $DIR/regions-name-undeclared.rs:26:22
|
||||
|
|
||||
LL | fn bar<'a>(x: &'a isize) {
|
||||
| -- lifetime parameter from outer item
|
||||
...
|
||||
LL | type X = Option<&'a isize>;
|
||||
| - ^^ undeclared lifetime
|
||||
| - ^^ use of generic parameter from outer item
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `<'a>`
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
error[E0401]: can't use generic parameters from outer item
|
||||
--> $DIR/regions-name-undeclared.rs:28:13
|
||||
|
|
||||
LL | fn bar<'a>(x: &'a isize) {
|
||||
| -- lifetime parameter from outer item
|
||||
...
|
||||
LL | enum E {
|
||||
| - help: consider introducing lifetime `'a` here: `<'a>`
|
||||
LL | E1(&'a isize)
|
||||
| ^^ use of generic parameter from outer item
|
||||
|
||||
error[E0401]: can't use generic parameters from outer item
|
||||
--> $DIR/regions-name-undeclared.rs:31:13
|
||||
|
|
||||
LL | fn bar<'a>(x: &'a isize) {
|
||||
| -- lifetime parameter from outer item
|
||||
...
|
||||
LL | struct S {
|
||||
| - help: consider introducing lifetime `'a` here: `<'a>`
|
||||
LL | f: &'a isize
|
||||
| ^^ use of generic parameter from outer item
|
||||
|
||||
error[E0401]: can't use generic parameters from outer item
|
||||
--> $DIR/regions-name-undeclared.rs:33:14
|
||||
|
|
||||
LL | fn bar<'a>(x: &'a isize) {
|
||||
| -- lifetime parameter from outer item
|
||||
...
|
||||
LL | fn f(a: &'a isize) { }
|
||||
| - ^^ undeclared lifetime
|
||||
| - ^^ use of generic parameter from outer item
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `<'a>`
|
||||
|
||||
@ -90,14 +102,14 @@ LL | ... &'b isize,
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||
help: consider making the bound lifetime-generic with a new `'b` lifetime
|
||||
|
|
||||
LL | b: Box<dyn for<'b, 'a> FnOnce(&'a isize,
|
||||
| +++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn fn_types<'b>(a: &'a isize,
|
||||
| ++++
|
||||
help: consider making the bound lifetime-generic with a new `'b` lifetime
|
||||
|
|
||||
LL | b: Box<dyn for<'a, 'b> FnOnce(&'a isize,
|
||||
| ++++
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/regions-name-undeclared.rs:46:36
|
||||
@ -105,15 +117,14 @@ error[E0261]: use of undeclared lifetime name `'b`
|
||||
LL | ... &'b isize)>,
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||
help: consider making the bound lifetime-generic with a new `'b` lifetime
|
||||
|
|
||||
LL | b: Box<dyn for<'b, 'a> FnOnce(&'a isize,
|
||||
| +++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn fn_types<'b>(a: &'a isize,
|
||||
| ++++
|
||||
help: consider making the bound lifetime-generic with a new `'b` lifetime
|
||||
|
|
||||
LL | b: Box<dyn for<'a, 'b> FnOnce(&'a isize,
|
||||
| ++++
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/regions-name-undeclared.rs:47:17
|
||||
@ -132,13 +143,14 @@ LL | async fn buggy(&self) -> &'a str {
|
||||
|
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | impl<'a> Bug {
|
||||
LL | async fn buggy<'a>(&self) -> &'a str {
|
||||
| ++++
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | async fn buggy<'a>(&self) -> &'a str {
|
||||
LL | impl<'a> Bug {
|
||||
| ++++
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
Some errors have detailed explanations: E0261, E0401.
|
||||
For more information about an error, try `rustc --explain E0261`.
|
||||
|
@ -5,14 +5,14 @@ LL | struct S1<F: Fn(&i32, &i32) -> &'a i32>(F);
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | struct S1<'a, F: Fn(&i32, &i32) -> &'a i32>(F);
|
||||
| +++
|
||||
help: consider making the bound lifetime-generic with a new `'a` lifetime
|
||||
|
|
||||
LL | struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
|
||||
| +++++++
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | struct S1<'a, F: Fn(&i32, &i32) -> &'a i32>(F);
|
||||
| +++
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/fn-missing-lifetime-in-item.rs:2:32
|
||||
|
@ -0,0 +1,106 @@
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:38:11
|
||||
|
|
||||
LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `'a,`
|
||||
|
||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:19:5
|
||||
|
|
||||
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
|
||||
| ------ hidden type `[closure@$DIR/missing-lifetimes-in-signature.rs:19:5: 22:6]` captures the anonymous lifetime defined here
|
||||
...
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'_` lifetime bound
|
||||
|
|
||||
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ++++
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:32:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:26:26
|
||||
|
|
||||
LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:55:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:49:34
|
||||
|
|
||||
LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:65:9
|
||||
|
|
||||
LL | / move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
| |_________^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:62:47
|
||||
|
|
||||
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
| ^^^^^^
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:77:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:72:34
|
||||
|
|
||||
LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
|
||||
| ^^^^^^
|
||||
|
||||
error[E0621]: explicit lifetime required in the type of `dest`
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:77:5
|
||||
|
|
||||
LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
|
||||
| ------ help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T`
|
||||
...
|
||||
LL | / move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
| |_____^ lifetime `'a` required
|
||||
|
||||
error[E0309]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:89:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
= help: consider adding an explicit lifetime bound `G: 'a`...
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0261, E0309, E0621, E0700.
|
||||
For more information about an error, try `rustc --explain E0261`.
|
@ -14,28 +14,31 @@ impl Get<usize> for Foo {
|
||||
|
||||
fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
|
||||
where
|
||||
G: Get<T>
|
||||
G: Get<T>,
|
||||
{
|
||||
move || {
|
||||
//~^ ERROR hidden type for `impl Trait` captures lifetime
|
||||
*dest = g.get();
|
||||
}
|
||||
}
|
||||
|
||||
// After applying suggestion for `foo`:
|
||||
fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
//~^ ERROR the parameter type `G` may not live long enough
|
||||
where
|
||||
G: Get<T>
|
||||
G: Get<T>,
|
||||
{
|
||||
//~^ ERROR the parameter type `G` may not live long enough
|
||||
move || {
|
||||
*dest = g.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// After applying suggestion for `bar`:
|
||||
fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ //~ ERROR undeclared lifetime
|
||||
fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
//~^ ERROR undeclared lifetime name `'a`
|
||||
where
|
||||
G: Get<T>
|
||||
G: Get<T>,
|
||||
{
|
||||
move || {
|
||||
*dest = g.get();
|
||||
@ -44,9 +47,11 @@ where
|
||||
|
||||
// After applying suggestion for `baz`:
|
||||
fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
//~^ ERROR the parameter type `G` may not live long enough
|
||||
where
|
||||
G: Get<T>
|
||||
G: Get<T>,
|
||||
{
|
||||
//~^ ERROR the parameter type `G` may not live long enough
|
||||
move || {
|
||||
*dest = g.get();
|
||||
}
|
||||
@ -55,6 +60,8 @@ where
|
||||
// Same as above, but show that we pay attention to lifetime names from parent item
|
||||
impl<'a> Foo {
|
||||
fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
//~^ ERROR the parameter type `G` may not live long enough
|
||||
//~| ERROR the parameter type `G` may not live long enough
|
||||
move || {
|
||||
*dest = g.get();
|
||||
}
|
||||
@ -63,8 +70,9 @@ impl<'a> Foo {
|
||||
|
||||
// After applying suggestion for `qux`:
|
||||
fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
|
||||
//~^ ERROR explicit lifetime required in the type of `dest`
|
||||
where
|
||||
G: Get<T>
|
||||
G: Get<T>,
|
||||
{
|
||||
move || {
|
||||
*dest = g.get();
|
||||
@ -73,19 +81,20 @@ where
|
||||
|
||||
// Potential incorrect attempt:
|
||||
fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
|
||||
//~^ ERROR the parameter type `G` may not live long enough
|
||||
where
|
||||
G: Get<T>
|
||||
G: Get<T>,
|
||||
{
|
||||
//~^ ERROR the parameter type `G` may not live long enough
|
||||
move || {
|
||||
*dest = g.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// We need to tie the lifetime of `G` with the lifetime of `&mut T` and the returned closure:
|
||||
fn ok<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
|
||||
where
|
||||
G: Get<T>
|
||||
G: Get<T>,
|
||||
{
|
||||
move || {
|
||||
*dest = g.get();
|
||||
@ -95,7 +104,7 @@ where
|
||||
// This also works. The `'_` isn't necessary but it's where we arrive to following the suggestions:
|
||||
fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a
|
||||
where
|
||||
G: Get<T>
|
||||
G: Get<T>,
|
||||
{
|
||||
move || {
|
||||
*dest = g.get();
|
||||
|
@ -1,11 +1,234 @@
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:36:11
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:38:11
|
||||
|
|
||||
LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `'a,`
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:19:5
|
||||
|
|
||||
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
|
||||
| ------ hidden type `[closure@$DIR/missing-lifetimes-in-signature.rs:19:5: 22:6]` captures the anonymous lifetime defined here
|
||||
...
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'_` lifetime bound
|
||||
|
|
||||
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ++++
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:26:37
|
||||
|
|
||||
LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:26:26
|
||||
|
|
||||
LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^
|
||||
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:32:5: 34:6]` will meet its required lifetime bounds
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:26:37
|
||||
|
|
||||
LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: consider introducing an explicit lifetime bound
|
||||
|
|
||||
LL | fn bar<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
|
||||
| ~~~~~ ++++
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:30:1
|
||||
|
|
||||
LL | / {
|
||||
LL | |
|
||||
LL | | move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:26:26
|
||||
|
|
||||
LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^
|
||||
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:32:5: 34:6]` will meet its required lifetime bounds
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:30:1
|
||||
|
|
||||
LL | / {
|
||||
LL | |
|
||||
LL | | move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
help: consider introducing an explicit lifetime bound
|
||||
|
|
||||
LL ~ fn bar<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
LL |
|
||||
LL | where
|
||||
LL | G: Get<T>,
|
||||
LL | {
|
||||
LL |
|
||||
...
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:49:45
|
||||
|
|
||||
LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:49:34
|
||||
|
|
||||
LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^
|
||||
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:55:5: 57:6]` will meet its required lifetime bounds
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:49:45
|
||||
|
|
||||
LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: consider introducing an explicit lifetime bound
|
||||
|
|
||||
LL | fn qux<'b, 'a, G: 'b + 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'b
|
||||
| +++ ~~~~~~~ ++++
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:53:1
|
||||
|
|
||||
LL | / {
|
||||
LL | |
|
||||
LL | | move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:49:34
|
||||
|
|
||||
LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^
|
||||
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:55:5: 57:6]` will meet its required lifetime bounds
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:53:1
|
||||
|
|
||||
LL | / {
|
||||
LL | |
|
||||
LL | | move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
help: consider introducing an explicit lifetime bound
|
||||
|
|
||||
LL ~ fn qux<'b, 'a, G: 'b + 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
LL |
|
||||
LL | where
|
||||
LL | G: Get<T>,
|
||||
LL | {
|
||||
LL |
|
||||
...
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:62:58
|
||||
|
|
||||
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:62:47
|
||||
|
|
||||
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
| ^^^^^^
|
||||
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:65:9: 67:10]` will meet its required lifetime bounds
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:62:58
|
||||
|
|
||||
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: consider introducing an explicit lifetime bound
|
||||
|
|
||||
LL | fn qux<'c, 'b, G: 'c + Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'c {
|
||||
| +++ ~~~~~~~ ++++
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:62:77
|
||||
|
|
||||
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
| _____________________________________________________________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined here...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:62:47
|
||||
|
|
||||
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
| ^^^^^^
|
||||
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:65:9: 67:10]` will meet its required lifetime bounds
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:62:77
|
||||
|
|
||||
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
| _____________________________________________________________________________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
help: consider introducing an explicit lifetime bound
|
||||
|
|
||||
LL ~ fn qux<'c, 'b, G: 'c + Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
LL |
|
||||
LL |
|
||||
LL | move || {
|
||||
LL | *dest = g.get();
|
||||
LL | }
|
||||
...
|
||||
|
||||
error[E0621]: explicit lifetime required in the type of `dest`
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:72:45
|
||||
|
|
||||
LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
|
||||
| ------ ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
|
||||
| |
|
||||
| help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T`
|
||||
|
||||
error[E0309]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:83:44
|
||||
|
|
||||
LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
|
||||
| - ^^^^^^^^^^^^^^^^^^ ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:89:5: 91:6]` will meet its required lifetime bounds
|
||||
| |
|
||||
| help: consider adding an explicit lifetime bound...: `G: 'a`
|
||||
|
||||
error[E0309]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:87:1
|
||||
|
|
||||
LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
|
||||
| - help: consider adding an explicit lifetime bound...: `G: 'a`
|
||||
...
|
||||
LL | / {
|
||||
LL | |
|
||||
LL | | move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^ ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:89:5: 91:6]` will meet its required lifetime bounds
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0261, E0309, E0621, E0700.
|
||||
For more information about an error, try `rustc --explain E0261`.
|
||||
|
@ -18,5 +18,7 @@ type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>;
|
||||
//~^ ERROR use of undeclared lifetime name `'a`
|
||||
|
||||
fn my_fun() -> Return<()> {}
|
||||
//~^ ERROR non-defining opaque type use in defining scope
|
||||
//~| ERROR non-defining opaque type use in defining scope
|
||||
|
||||
fn main() {}
|
||||
|
@ -2,10 +2,42 @@ error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/issue-69136-inner-lifetime-resolve-error.rs:17:65
|
||||
|
|
||||
LL | type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>;
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `'a,`
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||
help: consider making the bound lifetime-generic with a new `'a` lifetime
|
||||
|
|
||||
LL | type Return<A> = impl for<'a> WithAssoc<A, AssocType = impl SomeTrait + 'a>;
|
||||
| +++++++
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | type Return<'a, A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>;
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/issue-69136-inner-lifetime-resolve-error.rs:20:27
|
||||
|
|
||||
LL | fn my_fun() -> Return<()> {}
|
||||
| ^^
|
||||
|
|
||||
note: used non-generic type `()` for generic parameter
|
||||
--> $DIR/issue-69136-inner-lifetime-resolve-error.rs:17:13
|
||||
|
|
||||
LL | type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>;
|
||||
| ^
|
||||
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/issue-69136-inner-lifetime-resolve-error.rs:20:27
|
||||
|
|
||||
LL | fn my_fun() -> Return<()> {}
|
||||
| ^^
|
||||
|
|
||||
note: used non-generic type `()` for generic parameter
|
||||
--> $DIR/issue-69136-inner-lifetime-resolve-error.rs:17:13
|
||||
|
|
||||
LL | type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>;
|
||||
| ^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
|
@ -10,22 +10,22 @@ impl<'_> IceCube<'_> {}
|
||||
//~^ ERROR `'_` cannot be used here
|
||||
|
||||
struct Struct<'_> {
|
||||
//~^ ERROR `'_` cannot be used here
|
||||
//~^ ERROR `'_` cannot be used here
|
||||
v: Vec<&'static char>
|
||||
}
|
||||
|
||||
enum Enum<'_> {
|
||||
//~^ ERROR `'_` cannot be used here
|
||||
//~^ ERROR `'_` cannot be used here
|
||||
Variant
|
||||
}
|
||||
|
||||
union Union<'_> {
|
||||
//~^ ERROR `'_` cannot be used here
|
||||
//~^ ERROR `'_` cannot be used here
|
||||
a: u32
|
||||
}
|
||||
|
||||
trait Trait<'_> {
|
||||
//~^ ERROR `'_` cannot be used here
|
||||
//~^ ERROR `'_` cannot be used here
|
||||
}
|
||||
|
||||
fn foo<'_>() {
|
||||
|
@ -2,9 +2,13 @@ error[E0726]: implicit elided lifetime not allowed here
|
||||
--> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:13:16
|
||||
|
|
||||
LL | impl Trait for Ref {}
|
||||
| ^^^- help: indicate the anonymous lifetime: `<'_>`
|
||||
| ^^^ expected lifetime parameter
|
||||
|
|
||||
= note: assuming a `'static` lifetime...
|
||||
help: indicate the anonymous lifetime
|
||||
|
|
||||
LL | impl Trait for Ref<'_> {}
|
||||
| ++++
|
||||
|
||||
error: incompatible lifetime on type
|
||||
--> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:21
|
||||
|
@ -1,20 +1,41 @@
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/where-lifetime-resolution.rs:6:38
|
||||
|
|
||||
LL | fn f() where
|
||||
| - help: consider introducing lifetime `'a` here: `<'a>`
|
||||
LL | for<'a> dyn Trait1<'a>: Trait1<'a>, // OK
|
||||
LL | (dyn for<'a> Trait1<'a>): Trait1<'a>,
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||
help: consider making the bound lifetime-generic with a new `'a` lifetime
|
||||
|
|
||||
LL | (dyn for<'a> Trait1<'a>): for<'a> Trait1<'a>,
|
||||
| +++++++
|
||||
help: consider making the bound lifetime-generic with a new `'a` lifetime
|
||||
|
|
||||
LL | for<'a> (dyn for<'a> Trait1<'a>): Trait1<'a>,
|
||||
| +++++++
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | fn f<'a>() where
|
||||
| ++++
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/where-lifetime-resolution.rs:8:52
|
||||
|
|
||||
LL | fn f() where
|
||||
| - help: consider introducing lifetime `'b` here: `<'b>`
|
||||
...
|
||||
LL | for<'a> dyn for<'b> Trait2<'a, 'b>: Trait2<'a, 'b>,
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
help: consider making the bound lifetime-generic with a new `'b` lifetime
|
||||
|
|
||||
LL | for<'a> dyn for<'b> Trait2<'a, 'b>: for<'b> Trait2<'a, 'b>,
|
||||
| +++++++
|
||||
help: consider making the bound lifetime-generic with a new `'b` lifetime
|
||||
|
|
||||
LL | for<'b, 'a> dyn for<'b> Trait2<'a, 'b>: Trait2<'a, 'b>,
|
||||
| +++
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn f<'b>() where
|
||||
| ++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: unneeded unit return type
|
||||
--> $DIR/unused_unit.rs:19:28
|
||||
--> $DIR/unused_unit.rs:19:58
|
||||
|
|
||||
LL | pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()
|
||||
| ^^^^^^ help: remove the `-> ()`
|
||||
@ -11,15 +11,15 @@ LL | #![deny(clippy::unused_unit)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unneeded unit return type
|
||||
--> $DIR/unused_unit.rs:20:18
|
||||
--> $DIR/unused_unit.rs:19:28
|
||||
|
|
||||
LL | where G: Fn() -> () {
|
||||
LL | pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()
|
||||
| ^^^^^^ help: remove the `-> ()`
|
||||
|
||||
error: unneeded unit return type
|
||||
--> $DIR/unused_unit.rs:19:58
|
||||
--> $DIR/unused_unit.rs:20:18
|
||||
|
|
||||
LL | pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()
|
||||
LL | where G: Fn() -> () {
|
||||
| ^^^^^^ help: remove the `-> ()`
|
||||
|
||||
error: unneeded unit return type
|
||||
|
@ -204,12 +204,11 @@ impl<'a> FnSig<'a> {
|
||||
|
||||
pub(crate) fn from_fn_kind(
|
||||
fn_kind: &'a visit::FnKind<'_>,
|
||||
generics: &'a ast::Generics,
|
||||
decl: &'a ast::FnDecl,
|
||||
defaultness: ast::Defaultness,
|
||||
) -> FnSig<'a> {
|
||||
match *fn_kind {
|
||||
visit::FnKind::Fn(fn_ctxt, _, fn_sig, vis, _) => match fn_ctxt {
|
||||
visit::FnKind::Fn(fn_ctxt, _, fn_sig, vis, generics, _) => match fn_ctxt {
|
||||
visit::FnCtxt::Assoc(..) => {
|
||||
let mut fn_sig = FnSig::from_method_sig(fn_sig, generics, vis);
|
||||
fn_sig.defaultness = defaultness;
|
||||
@ -3180,8 +3179,14 @@ impl Rewrite for ast::ForeignItem {
|
||||
let inner_attrs = inner_attributes(&self.attrs);
|
||||
let fn_ctxt = visit::FnCtxt::Foreign;
|
||||
visitor.visit_fn(
|
||||
visit::FnKind::Fn(fn_ctxt, self.ident, sig, &self.vis, Some(body)),
|
||||
visit::FnKind::Fn(
|
||||
fn_ctxt,
|
||||
self.ident,
|
||||
sig,
|
||||
&self.vis,
|
||||
generics,
|
||||
Some(body),
|
||||
),
|
||||
&sig.decl,
|
||||
self.span,
|
||||
defaultness,
|
||||
|
@ -382,7 +382,6 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
|
||||
pub(crate) fn visit_fn(
|
||||
&mut self,
|
||||
fk: visit::FnKind<'_>,
|
||||
generics: &ast::Generics,
|
||||
fd: &ast::FnDecl,
|
||||
s: Span,
|
||||
defaultness: ast::Defaultness,
|
||||
@ -391,12 +390,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
|
||||
let indent = self.block_indent;
|
||||
let block;
|
||||
let rewrite = match fk {
|
||||
visit::FnKind::Fn(_, ident, _, _, Some(ref b)) => {
|
||||
visit::FnKind::Fn(_, ident, _, _, _, Some(ref b)) => {
|
||||
block = b;
|
||||
self.rewrite_fn_before_block(
|
||||
indent,
|
||||
ident,
|
||||
&FnSig::from_fn_kind(&fk, generics, fd, defaultness),
|
||||
&FnSig::from_fn_kind(&fk, fd, defaultness),
|
||||
mk_sp(s.lo(), b.span.lo()),
|
||||
)
|
||||
}
|
||||
@ -552,8 +551,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
|
||||
_ => visit::FnCtxt::Foreign,
|
||||
};
|
||||
self.visit_fn(
|
||||
visit::FnKind::Fn(fn_ctxt, item.ident, sig, &item.vis, Some(body)),
|
||||
visit::FnKind::Fn(
|
||||
fn_ctxt,
|
||||
item.ident,
|
||||
sig,
|
||||
&item.vis,
|
||||
generics,
|
||||
Some(body),
|
||||
),
|
||||
&sig.decl,
|
||||
item.span,
|
||||
defaultness,
|
||||
@ -642,8 +647,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
|
||||
let inner_attrs = inner_attributes(&ai.attrs);
|
||||
let fn_ctxt = visit::FnCtxt::Assoc(assoc_ctxt);
|
||||
self.visit_fn(
|
||||
visit::FnKind::Fn(fn_ctxt, ai.ident, sig, &ai.vis, Some(body)),
|
||||
generics,
|
||||
visit::FnKind::Fn(fn_ctxt, ai.ident, sig, &ai.vis, generics, Some(body)),
|
||||
&sig.decl,
|
||||
ai.span,
|
||||
defaultness,
|
||||
|
Loading…
Reference in New Issue
Block a user