mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-09 13:33:43 +00:00
Suggest using 'static
in assoc consts and suggest when multiple lts are needed
This commit is contained in:
parent
becd479482
commit
6a3deb0ae0
@ -33,6 +33,7 @@ enum AssocSuggestion {
|
||||
crate enum MissingLifetimeSpot<'tcx> {
|
||||
Generics(&'tcx hir::Generics<'tcx>),
|
||||
HigherRanked { span: Span, span_type: ForLifetimeSpanType },
|
||||
Static,
|
||||
}
|
||||
|
||||
crate enum ForLifetimeSpanType {
|
||||
@ -1186,6 +1187,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
|
||||
https://doc.rust-lang.org/nomicon/hrtb.html",
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if nightly_options::is_nightly_build()
|
||||
@ -1358,6 +1360,42 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
|
||||
);
|
||||
(*span, span_type.suggestion("'a"))
|
||||
}
|
||||
MissingLifetimeSpot::Static => {
|
||||
let (span, sugg) = match snippet.as_deref() {
|
||||
Some("&") => (span.shrink_to_hi(), "'static ".to_owned()),
|
||||
Some("'_") => (span, "'static".to_owned()),
|
||||
Some(snippet) if !snippet.ends_with('>') => {
|
||||
if snippet == "" {
|
||||
(
|
||||
span,
|
||||
std::iter::repeat("'static")
|
||||
.take(count)
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
span.shrink_to_hi(),
|
||||
format!(
|
||||
"<{}>",
|
||||
std::iter::repeat("'static")
|
||||
.take(count)
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
"consider using the `'static` lifetime",
|
||||
sugg.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
});
|
||||
for param in params {
|
||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(param.span) {
|
||||
@ -1408,13 +1446,23 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
|
||||
([], Some("'_")) if count == 1 => {
|
||||
suggest_new(err, "'a");
|
||||
}
|
||||
([], Some(snippet)) if !snippet.ends_with('>') && count == 1 => {
|
||||
([], Some(snippet)) if !snippet.ends_with('>') => {
|
||||
if snippet == "" {
|
||||
// This happens when we have `type Bar<'a> = Foo<T>` where we point at the space
|
||||
// before `T`. We will suggest `type Bar<'a> = Foo<'a, T>`.
|
||||
suggest_new(err, "'a, ");
|
||||
suggest_new(
|
||||
err,
|
||||
&std::iter::repeat("'a, ").take(count).collect::<Vec<_>>().join(""),
|
||||
);
|
||||
} else {
|
||||
suggest_new(err, &format!("{}<'a>", snippet));
|
||||
suggest_new(
|
||||
err,
|
||||
&format!(
|
||||
"{}<{}>",
|
||||
snippet,
|
||||
std::iter::repeat("'a").take(count).collect::<Vec<_>>().join(", ")
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
(lts, ..) if lts.len() > 1 => {
|
||||
|
@ -764,26 +764,30 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
Const(_, _) => {
|
||||
// Only methods and types support generics.
|
||||
assert!(trait_item.generics.params.is_empty());
|
||||
self.missing_named_lifetime_spots.push(MissingLifetimeSpot::Static);
|
||||
intravisit::walk_trait_item(self, trait_item);
|
||||
self.missing_named_lifetime_spots.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
|
||||
use self::hir::ImplItemKind::*;
|
||||
self.missing_named_lifetime_spots.push((&impl_item.generics).into());
|
||||
match impl_item.kind {
|
||||
Fn(ref sig, _) => {
|
||||
self.missing_named_lifetime_spots.push((&impl_item.generics).into());
|
||||
let tcx = self.tcx;
|
||||
self.visit_early_late(
|
||||
Some(tcx.hir().get_parent_item(impl_item.hir_id)),
|
||||
&sig.decl,
|
||||
&impl_item.generics,
|
||||
|this| intravisit::walk_impl_item(this, impl_item),
|
||||
)
|
||||
);
|
||||
self.missing_named_lifetime_spots.pop();
|
||||
}
|
||||
TyAlias(ref ty) => {
|
||||
let generics = &impl_item.generics;
|
||||
self.missing_named_lifetime_spots.push(generics.into());
|
||||
let mut index = self.next_early_index();
|
||||
let mut non_lifetime_count = 0;
|
||||
debug!("visit_ty: index = {}", index);
|
||||
@ -812,14 +816,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
this.visit_generics(generics);
|
||||
this.visit_ty(ty);
|
||||
});
|
||||
self.missing_named_lifetime_spots.pop();
|
||||
}
|
||||
Const(_, _) => {
|
||||
// Only methods and types support generics.
|
||||
assert!(impl_item.generics.params.is_empty());
|
||||
self.missing_named_lifetime_spots.push(MissingLifetimeSpot::Static);
|
||||
intravisit::walk_impl_item(self, impl_item);
|
||||
self.missing_named_lifetime_spots.pop();
|
||||
}
|
||||
}
|
||||
self.missing_named_lifetime_spots.pop();
|
||||
}
|
||||
|
||||
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
|
||||
|
@ -51,6 +51,15 @@ error[E0106]: missing lifetime specifiers
|
||||
|
|
||||
LL | buzz: Buzz,
|
||||
| ^^^^ expected 2 lifetime parameters
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | struct Quux<'a> {
|
||||
LL | baz: Baz,
|
||||
LL |
|
||||
LL |
|
||||
LL | buzz: Buzz<'a, 'a>,
|
||||
|
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
@ -1,5 +1,16 @@
|
||||
trait ZstAssert: Sized {
|
||||
const TYPE_NAME: &str = ""; //~ ERROR missing lifetime specifier
|
||||
const A: &str = ""; //~ ERROR missing lifetime specifier
|
||||
const B: S = S { s: &() }; //~ ERROR missing lifetime specifier
|
||||
const C: &'_ str = ""; //~ ERROR missing lifetime specifier
|
||||
const D: T = T { a: &(), b: &() }; //~ ERROR missing lifetime specifier
|
||||
}
|
||||
|
||||
struct S<'a> {
|
||||
s: &'a (),
|
||||
}
|
||||
struct T<'a, 'b> {
|
||||
a: &'a (),
|
||||
b: &'b (),
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,15 +1,73 @@
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/missing-lifetime-in-assoc-const-type.rs:2:22
|
||||
--> $DIR/missing-lifetime-in-assoc-const-type.rs:2:14
|
||||
|
|
||||
LL | const TYPE_NAME: &str = "";
|
||||
| ^ expected named lifetime parameter
|
||||
LL | const A: &str = "";
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | const A: &'static str = "";
|
||||
| ^^^^^^^
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | trait ZstAssert<'a>: Sized {
|
||||
LL | const TYPE_NAME: &'a str = "";
|
||||
LL | const A: &'a str = "";
|
||||
|
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/missing-lifetime-in-assoc-const-type.rs:3:14
|
||||
|
|
||||
LL | const B: S = S { s: &() };
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | const B: S<'static> = S { s: &() };
|
||||
| ^^^^^^^^^
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | trait ZstAssert<'a>: Sized {
|
||||
LL | const A: &str = "";
|
||||
LL | const B: S<'a> = S { s: &() };
|
||||
|
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/missing-lifetime-in-assoc-const-type.rs:4:15
|
||||
|
|
||||
LL | const C: &'_ str = "";
|
||||
| ^^ expected named lifetime parameter
|
||||
|
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | const C: &'static str = "";
|
||||
| ^^^^^^^
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | trait ZstAssert<'a>: Sized {
|
||||
LL | const A: &str = "";
|
||||
LL | const B: S = S { s: &() };
|
||||
LL | const C: &'a str = "";
|
||||
|
|
||||
|
||||
error[E0106]: missing lifetime specifiers
|
||||
--> $DIR/missing-lifetime-in-assoc-const-type.rs:5:14
|
||||
|
|
||||
LL | const D: T = T { a: &(), b: &() };
|
||||
| ^ expected 2 lifetime parameters
|
||||
|
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | const D: T<'static, 'static> = T { a: &(), b: &() };
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | trait ZstAssert<'a>: Sized {
|
||||
LL | const A: &str = "";
|
||||
LL | const B: S = S { s: &() };
|
||||
LL | const C: &'_ str = "";
|
||||
LL | const D: T<'a, 'a> = T { a: &(), b: &() };
|
||||
|
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0106`.
|
||||
|
Loading…
Reference in New Issue
Block a user