未验证 提交 f50e285e 编写于 作者: P Pietro Albini 提交者: GitHub

Rollup merge of #55173 - estebank:suggest-static, r=oli-obk

Suggest appropriate syntax on missing lifetime specifier in return type

Suggest using `'static` when a lifetime is missing in the return type
with a structured suggestion instead of a note.

Fix #55170.
......@@ -1147,7 +1147,7 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::T
TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
TyKind::Rptr(ref region, ref mt) => {
let span = t.span.shrink_to_lo();
let span = self.sess.source_map().next_point(t.span.shrink_to_lo());
let lifetime = match *region {
Some(ref lt) => self.lower_lifetime(lt),
None => self.elided_ref_lifetime(span),
......
......@@ -2235,21 +2235,46 @@ fn resolve_elided_lifetimes(&mut self, lifetime_refs: Vec<&'tcx hir::Lifetime>)
};
let mut err = report_missing_lifetime_specifiers(self.tcx.sess, span, lifetime_refs.len());
let mut add_label = true;
if let Some(params) = error {
if lifetime_refs.len() == 1 {
self.report_elision_failure(&mut err, params);
add_label = add_label && self.report_elision_failure(&mut err, params, span);
}
}
if add_label {
add_missing_lifetime_specifiers_label(&mut err, span, lifetime_refs.len());
}
err.emit();
}
fn suggest_lifetime(&self, db: &mut DiagnosticBuilder<'_>, span: Span, msg: &str) -> bool {
match self.tcx.sess.source_map().span_to_snippet(span) {
Ok(ref snippet) => {
let (sugg, applicability) = if snippet == "&" {
("&'static ".to_owned(), Applicability::MachineApplicable)
} else if snippet == "'_" {
("'static".to_owned(), Applicability::MachineApplicable)
} else {
(format!("{} + 'static", snippet), Applicability::MaybeIncorrect)
};
db.span_suggestion_with_applicability(span, msg, sugg, applicability);
false
}
Err(_) => {
db.help(msg);
true
}
}
}
fn report_elision_failure(
&mut self,
db: &mut DiagnosticBuilder<'_>,
params: &[ElisionFailureInfo],
) {
span: Span,
) -> bool {
let mut m = String::new();
let len = params.len();
......@@ -2304,7 +2329,7 @@ fn report_elision_failure(
"this function's return type contains a borrowed value, but \
there is no value for it to be borrowed from"
);
help!(db, "consider giving it a 'static lifetime");
self.suggest_lifetime(db, span, "consider giving it a 'static lifetime")
} else if elided_len == 0 {
help!(
db,
......@@ -2312,11 +2337,8 @@ fn report_elision_failure(
an elided lifetime, but the lifetime cannot be derived from \
the arguments"
);
help!(
db,
"consider giving it an explicit bounded or 'static \
lifetime"
);
let msg = "consider giving it an explicit bounded or 'static lifetime";
self.suggest_lifetime(db, span, msg)
} else if elided_len == 1 {
help!(
db,
......@@ -2324,6 +2346,7 @@ fn report_elision_failure(
the signature does not say which {} it is borrowed from",
m
);
true
} else {
help!(
db,
......@@ -2331,6 +2354,7 @@ fn report_elision_failure(
the signature does not say whether it is borrowed from {}",
m
);
true
}
}
......@@ -2744,26 +2768,28 @@ fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
}
}
pub fn report_missing_lifetime_specifiers(
fn report_missing_lifetime_specifiers(
sess: &Session,
span: Span,
count: usize,
) -> DiagnosticBuilder<'_> {
let mut err = struct_span_err!(
struct_span_err!(
sess,
span,
E0106,
"missing lifetime specifier{}",
if count > 1 { "s" } else { "" }
);
)
}
let msg: Cow<'static, str> = if count > 1 {
format!("expected {} lifetime parameters", count).into()
fn add_missing_lifetime_specifiers_label(
err: &mut DiagnosticBuilder<'_>,
span: Span,
count: usize,
) {
if count > 1 {
err.span_label(span, format!("expected {} lifetime parameters", count));
} else {
"expected lifetime parameter".into()
err.span_label(span, "expected lifetime parameter");
};
err.span_label(span, msg);
err
}
......@@ -2,10 +2,9 @@ error[E0106]: missing lifetime specifier
--> $DIR/bound-lifetime-in-binding-only.rs:62:23
|
LL | fn elision<T: Fn() -> &i32>() {
| ^ expected lifetime parameter
| ^ help: consider giving it a 'static lifetime: `&'static`
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
= help: consider giving it a 'static lifetime
error: aborting due to previous error
......
......@@ -2,10 +2,9 @@ error[E0106]: missing lifetime specifier
--> $DIR/bound-lifetime-in-return-only.rs:44:23
|
LL | fn elision(_: fn() -> &i32) {
| ^ expected lifetime parameter
| ^ help: consider giving it a 'static lifetime: `&'static`
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
= help: consider giving it a 'static lifetime
error: aborting due to previous error
......
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// run-rustfix
extern "C" {
pub fn g(_: &u8) -> &u8; // OK
pub fn f() -> &'static u8; //~ ERROR missing lifetime specifier
}
fn main() {}
......@@ -8,9 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// run-rustfix
extern "C" {
fn g(_: &u8) -> &u8; // OK
fn f() -> &u8; //~ ERROR missing lifetime specifier
pub fn g(_: &u8) -> &u8; // OK
pub fn f() -> &u8; //~ ERROR missing lifetime specifier
}
fn main() {}
error[E0106]: missing lifetime specifier
--> $DIR/foreign-fn-return-lifetime.rs:13:15
--> $DIR/foreign-fn-return-lifetime.rs:15:19
|
LL | fn f() -> &u8; //~ ERROR missing lifetime specifier
| ^ expected lifetime parameter
LL | pub fn f() -> &u8; //~ ERROR missing lifetime specifier
| ^ help: consider giving it a 'static lifetime: `&'static`
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
= help: consider giving it a 'static lifetime
error: aborting due to previous error
......
......@@ -2,10 +2,9 @@ error[E0106]: missing lifetime specifier
--> $DIR/issue-13497.rs:12:5
|
LL | &str //~ ERROR missing lifetime specifier
| ^ expected lifetime parameter
| ^ help: consider giving it a 'static lifetime: `&'static`
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
= help: consider giving it a 'static lifetime
error: aborting due to previous error
......
......@@ -10,19 +10,17 @@ error[E0106]: missing lifetime specifier
--> $DIR/issue-26638.rs:14:40
|
LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
| ^ expected lifetime parameter
| ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
= help: consider giving it an explicit bounded or 'static lifetime
error[E0106]: missing lifetime specifier
--> $DIR/issue-26638.rs:17:22
|
LL | fn parse_type_3() -> &str { unimplemented!() }
| ^ expected lifetime parameter
| ^ help: consider giving it a 'static lifetime: `&'static`
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
= help: consider giving it a 'static lifetime
error: aborting due to 3 previous errors
......
......@@ -2,10 +2,9 @@ error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:12:11
|
LL | fn f() -> &isize { //~ ERROR missing lifetime specifier
| ^ expected lifetime parameter
| ^ help: consider giving it a 'static lifetime: `&'static`
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
= help: consider giving it a 'static lifetime
error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:33
......@@ -27,28 +26,25 @@ error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:31:20
|
LL | fn i(_x: isize) -> &isize { //~ ERROR missing lifetime specifier
| ^ expected lifetime parameter
| ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
= help: consider giving it an explicit bounded or 'static lifetime
error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:44:24
|
LL | fn j(_x: StaticStr) -> &isize { //~ ERROR missing lifetime specifier
| ^ expected lifetime parameter
| ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
= help: consider giving it an explicit bounded or 'static lifetime
error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:50:49
|
LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize {
| ^ expected lifetime parameter
| ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
= help: consider giving it an explicit bounded or 'static lifetime
error: aborting due to 6 previous errors
......
trait Future {
type Item;
type Error;
}
use std::error::Error;
fn foo() -> impl Future<Item=(), Error=Box<Error>> {
Ok(())
}
fn main() {}
error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-trait.rs:8:44
|
LL | fn foo() -> impl Future<Item=(), Error=Box<Error>> {
| ^^^^^ help: consider giving it a 'static lifetime: `Error + 'static`
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
error: aborting due to previous error
For more information about this error, try `rustc --explain E0106`.
......@@ -20,10 +20,9 @@ error[E0106]: missing lifetime specifier
--> $DIR/underscore-lifetime-binders.rs:20:29
|
LL | fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR cannot be used here
| ^^ expected lifetime parameter
| ^^ help: consider giving it a 'static lifetime: `'static`
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
= help: consider giving it a 'static lifetime
error[E0106]: missing lifetime specifier
--> $DIR/underscore-lifetime-binders.rs:26:35
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册