From d4fe9553f65df51a18999e956fd507e26271e74e Mon Sep 17 00:00:00 2001
From: mibac138 <5672750+mibac138@users.noreply.github.com>
Date: Thu, 7 May 2020 03:57:31 +0200
Subject: [PATCH 01/40] Implement partial error recovery for `let` with
`BinOpEq`
When parsing `let x: i8 += 1` the compiler interprets `i8` as a trait
which makes it more complicated to do error recovery. More advanced
error recovery is not implemented in this commit.
---
src/librustc_parse/parser/stmt.rs | 29 ++++++++++++++++++++++--
src/test/ui/parser/let-binop-plus.rs | 7 ++++++
src/test/ui/parser/let-binop-plus.stderr | 9 ++++++++
src/test/ui/parser/let-binop.rs | 8 +++++++
src/test/ui/parser/let-binop.stderr | 21 +++++++++++++++++
5 files changed, 72 insertions(+), 2 deletions(-)
create mode 100644 src/test/ui/parser/let-binop-plus.rs
create mode 100644 src/test/ui/parser/let-binop-plus.stderr
create mode 100644 src/test/ui/parser/let-binop.rs
create mode 100644 src/test/ui/parser/let-binop.stderr
diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs
index 849193151c33..049aa7447f4d 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -12,7 +12,7 @@ use rustc_ast::ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKin
use rustc_ast::ptr::P;
use rustc_ast::token::{self, TokenKind};
use rustc_ast::util::classify;
-use rustc_errors::{Applicability, PResult};
+use rustc_errors::{struct_span_err, Applicability, PResult};
use rustc_span::source_map::{BytePos, Span};
use rustc_span::symbol::{kw, sym};
@@ -217,7 +217,32 @@ impl<'a> Parser<'a> {
/// Parses the RHS of a local variable declaration (e.g., '= 14;').
fn parse_initializer(&mut self, skip_eq: bool) -> PResult<'a, Option
>> {
- if self.eat(&token::Eq) || skip_eq { Ok(Some(self.parse_expr()?)) } else { Ok(None) }
+ let parse = if !self.eat(&token::Eq) && !skip_eq {
+ // Error recovery for `let x += 1`
+ if matches!(self.token.kind, TokenKind::BinOpEq(_)) {
+ struct_span_err!(
+ self.sess.span_diagnostic,
+ self.token.span,
+ E0067,
+ "can't reassign to a uninitialized variable"
+ )
+ .span_suggestion_short(
+ self.token.span,
+ "replace with `=` to initialize the variable",
+ "=".to_string(),
+ Applicability::MaybeIncorrect,
+ )
+ .emit();
+ self.bump();
+ true
+ } else {
+ false
+ }
+ } else {
+ true
+ };
+
+ if parse { Ok(Some(self.parse_expr()?)) } else { Ok(None) }
}
/// Parses a block. No inner attributes are allowed.
diff --git a/src/test/ui/parser/let-binop-plus.rs b/src/test/ui/parser/let-binop-plus.rs
new file mode 100644
index 000000000000..8d883d6e2489
--- /dev/null
+++ b/src/test/ui/parser/let-binop-plus.rs
@@ -0,0 +1,7 @@
+#![allow(bare_trait_objects)]
+
+fn main() {
+ let a: i8 += 1;
+ //~^ ERROR expected trait, found builtin type `i8`
+ let _ = a;
+}
diff --git a/src/test/ui/parser/let-binop-plus.stderr b/src/test/ui/parser/let-binop-plus.stderr
new file mode 100644
index 000000000000..baa935aff713
--- /dev/null
+++ b/src/test/ui/parser/let-binop-plus.stderr
@@ -0,0 +1,9 @@
+error[E0404]: expected trait, found builtin type `i8`
+ --> $DIR/let-binop-plus.rs:4:12
+ |
+LL | let a: i8 += 1;
+ | ^^ not a trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0404`.
diff --git a/src/test/ui/parser/let-binop.rs b/src/test/ui/parser/let-binop.rs
new file mode 100644
index 000000000000..d445ab6bb8a1
--- /dev/null
+++ b/src/test/ui/parser/let-binop.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let a: i8 *= 1; //~ ERROR can't reassign to a uninitialized variable
+ let _ = a;
+ let b += 1; //~ ERROR can't reassign to a uninitialized variable
+ let _ = b;
+ let c *= 1; //~ ERROR can't reassign to a uninitialized variable
+ let _ = c;
+}
diff --git a/src/test/ui/parser/let-binop.stderr b/src/test/ui/parser/let-binop.stderr
new file mode 100644
index 000000000000..3e9d4a80a70e
--- /dev/null
+++ b/src/test/ui/parser/let-binop.stderr
@@ -0,0 +1,21 @@
+error[E0067]: can't reassign to a uninitialized variable
+ --> $DIR/let-binop.rs:2:15
+ |
+LL | let a: i8 *= 1;
+ | ^^ help: replace with `=` to initialize the variable
+
+error[E0067]: can't reassign to a uninitialized variable
+ --> $DIR/let-binop.rs:4:11
+ |
+LL | let b += 1;
+ | ^^ help: replace with `=` to initialize the variable
+
+error[E0067]: can't reassign to a uninitialized variable
+ --> $DIR/let-binop.rs:6:11
+ |
+LL | let c *= 1;
+ | ^^ help: replace with `=` to initialize the variable
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0067`.
From 48ff12acb184672393692e087927a66ff7907d71 Mon Sep 17 00:00:00 2001
From: mibac138 <5672750+mibac138@users.noreply.github.com>
Date: Thu, 7 May 2020 04:09:57 +0200
Subject: [PATCH 02/40] Expand partial error recovery for `let` with `BinOpEq`
---
src/librustc_parse/parser/stmt.rs | 40 +++++++++++++++++++++--------
src/test/ui/parser/let-binop.stderr | 22 ++++++++++++++--
2 files changed, 50 insertions(+), 12 deletions(-)
diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs
index 049aa7447f4d..aceee8143289 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -145,12 +145,12 @@ impl<'a> Parser<'a> {
}
fn parse_local_mk(&mut self, lo: Span, attrs: AttrVec) -> PResult<'a, Stmt> {
- let local = self.parse_local(attrs)?;
+ let local = self.parse_local(lo, attrs)?;
Ok(self.mk_stmt(lo.to(self.prev_token.span), StmtKind::Local(local)))
}
/// Parses a local variable declaration.
- fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P> {
+ fn parse_local(&mut self, let_span: Span, attrs: AttrVec) -> PResult<'a, P> {
let lo = self.prev_token.span;
let pat = self.parse_top_pat(GateOr::Yes)?;
@@ -174,7 +174,7 @@ impl<'a> Parser<'a> {
} else {
(None, None)
};
- let init = match (self.parse_initializer(err.is_some()), err) {
+ let init = match (self.parse_initializer(let_span, ty.is_some(), err.is_some()), err) {
(Ok(init), None) => {
// init parsed, ty parsed
init
@@ -216,23 +216,43 @@ impl<'a> Parser<'a> {
}
/// Parses the RHS of a local variable declaration (e.g., '= 14;').
- fn parse_initializer(&mut self, skip_eq: bool) -> PResult<'a, Option>> {
+ fn parse_initializer(
+ &mut self,
+ let_span: Span,
+ has_ty: bool,
+ skip_eq: bool,
+ ) -> PResult<'a, Option
>> {
let parse = if !self.eat(&token::Eq) && !skip_eq {
// Error recovery for `let x += 1`
if matches!(self.token.kind, TokenKind::BinOpEq(_)) {
- struct_span_err!(
+ let mut err = struct_span_err!(
self.sess.span_diagnostic,
self.token.span,
E0067,
"can't reassign to a uninitialized variable"
- )
- .span_suggestion_short(
+ );
+ err.span_suggestion_short(
self.token.span,
"replace with `=` to initialize the variable",
"=".to_string(),
- Applicability::MaybeIncorrect,
- )
- .emit();
+ if has_ty {
+ // for `let x: i8 += 1` it's highly likely that the `+` is a typo
+ Applicability::MachineApplicable
+ } else {
+ // for `let x += 1` it's a bit less likely that the `+` is a typo
+ Applicability::MaybeIncorrect
+ },
+ );
+ // In case of code like `let x += 1` it's possible the user may have meant to write `x += 1`
+ if !has_ty {
+ err.span_suggestion_short(
+ let_span,
+ "remove to reassign to a previously initialized variable",
+ "".to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ err.emit();
self.bump();
true
} else {
diff --git a/src/test/ui/parser/let-binop.stderr b/src/test/ui/parser/let-binop.stderr
index 3e9d4a80a70e..c37612430cef 100644
--- a/src/test/ui/parser/let-binop.stderr
+++ b/src/test/ui/parser/let-binop.stderr
@@ -8,13 +8,31 @@ error[E0067]: can't reassign to a uninitialized variable
--> $DIR/let-binop.rs:4:11
|
LL | let b += 1;
- | ^^ help: replace with `=` to initialize the variable
+ | ^^
+ |
+help: replace with `=` to initialize the variable
+ |
+LL | let b = 1;
+ | ^
+help: remove to reassign to a previously initialized variable
+ |
+LL | b += 1;
+ | --
error[E0067]: can't reassign to a uninitialized variable
--> $DIR/let-binop.rs:6:11
|
LL | let c *= 1;
- | ^^ help: replace with `=` to initialize the variable
+ | ^^
+ |
+help: replace with `=` to initialize the variable
+ |
+LL | let c = 1;
+ | ^
+help: remove to reassign to a previously initialized variable
+ |
+LL | c *= 1;
+ | --
error: aborting due to 3 previous errors
From 05d653199871955eba90abdd3b176603f030ab60 Mon Sep 17 00:00:00 2001
From: mibac138 <5672750+mibac138@users.noreply.github.com>
Date: Thu, 7 May 2020 05:00:59 +0200
Subject: [PATCH 03/40] Error recovery for `let` with `+=`
---
src/librustc_parse/parser/stmt.rs | 65 ++++++++++++------------
src/test/ui/parser/let-binop-plus.rs | 1 +
src/test/ui/parser/let-binop-plus.stderr | 11 +++-
3 files changed, 42 insertions(+), 35 deletions(-)
diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs
index aceee8143289..224f4ebf5382 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -222,44 +222,43 @@ impl<'a> Parser<'a> {
has_ty: bool,
skip_eq: bool,
) -> PResult<'a, Option
>> {
- let parse = if !self.eat(&token::Eq) && !skip_eq {
+ // In case of code like `let x: i8 += 1`, `i8` is interpreted as a trait consuming the `+`
+ // from `+=`.
+ let ate_plus = self.prev_token.is_like_plus() && has_ty;
+ let parse = if !skip_eq && (ate_plus || matches!(self.token.kind, TokenKind::BinOpEq(_))) {
// Error recovery for `let x += 1`
- if matches!(self.token.kind, TokenKind::BinOpEq(_)) {
- let mut err = struct_span_err!(
- self.sess.span_diagnostic,
- self.token.span,
- E0067,
- "can't reassign to a uninitialized variable"
- );
+ let mut err = struct_span_err!(
+ self.sess.span_diagnostic,
+ self.token.span,
+ E0067,
+ "can't reassign to a uninitialized variable"
+ );
+ err.span_suggestion_short(
+ self.token.span,
+ "replace with `=` to initialize the variable",
+ "=".to_string(),
+ if has_ty {
+ // for `let x: i8 += 1` it's highly likely that the `+` is a typo
+ Applicability::MachineApplicable
+ } else {
+ // for `let x += 1` it's a bit less likely that the `+` is a typo
+ Applicability::MaybeIncorrect
+ },
+ );
+ // In case of code like `let x += 1` it's possible the user may have meant to write `x += 1`
+ if !has_ty {
err.span_suggestion_short(
- self.token.span,
- "replace with `=` to initialize the variable",
- "=".to_string(),
- if has_ty {
- // for `let x: i8 += 1` it's highly likely that the `+` is a typo
- Applicability::MachineApplicable
- } else {
- // for `let x += 1` it's a bit less likely that the `+` is a typo
- Applicability::MaybeIncorrect
- },
+ let_span,
+ "remove to reassign to a previously initialized variable",
+ "".to_string(),
+ Applicability::MaybeIncorrect,
);
- // In case of code like `let x += 1` it's possible the user may have meant to write `x += 1`
- if !has_ty {
- err.span_suggestion_short(
- let_span,
- "remove to reassign to a previously initialized variable",
- "".to_string(),
- Applicability::MaybeIncorrect,
- );
- }
- err.emit();
- self.bump();
- true
- } else {
- false
}
- } else {
+ err.emit();
+ self.bump();
true
+ } else {
+ self.eat(&token::Eq) || skip_eq
};
if parse { Ok(Some(self.parse_expr()?)) } else { Ok(None) }
diff --git a/src/test/ui/parser/let-binop-plus.rs b/src/test/ui/parser/let-binop-plus.rs
index 8d883d6e2489..98473e9f096d 100644
--- a/src/test/ui/parser/let-binop-plus.rs
+++ b/src/test/ui/parser/let-binop-plus.rs
@@ -3,5 +3,6 @@
fn main() {
let a: i8 += 1;
//~^ ERROR expected trait, found builtin type `i8`
+ //~| ERROR can't reassign to a uninitialized variable
let _ = a;
}
diff --git a/src/test/ui/parser/let-binop-plus.stderr b/src/test/ui/parser/let-binop-plus.stderr
index baa935aff713..d7d84ff16a0a 100644
--- a/src/test/ui/parser/let-binop-plus.stderr
+++ b/src/test/ui/parser/let-binop-plus.stderr
@@ -1,9 +1,16 @@
+error[E0067]: can't reassign to a uninitialized variable
+ --> $DIR/let-binop-plus.rs:4:16
+ |
+LL | let a: i8 += 1;
+ | ^ help: replace with `=` to initialize the variable
+
error[E0404]: expected trait, found builtin type `i8`
--> $DIR/let-binop-plus.rs:4:12
|
LL | let a: i8 += 1;
| ^^ not a trait
-error: aborting due to previous error
+error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0404`.
+Some errors have detailed explanations: E0067, E0404.
+For more information about an error, try `rustc --explain E0067`.
From 6ad24baf06c687517f188e8c6e6ce848924d001c Mon Sep 17 00:00:00 2001
From: mibac138 <5672750+mibac138@users.noreply.github.com>
Date: Thu, 7 May 2020 23:45:51 +0200
Subject: [PATCH 04/40] Adjust according to estebank's review comments
---
src/librustc_parse/parser/stmt.rs | 19 ++++++++-----------
src/test/ui/parser/let-binop-plus.rs | 2 +-
src/test/ui/parser/let-binop-plus.stderr | 4 ++--
src/test/ui/parser/let-binop.rs | 6 +++---
src/test/ui/parser/let-binop.stderr | 20 ++++++++++----------
5 files changed, 24 insertions(+), 27 deletions(-)
diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs
index 224f4ebf5382..bec810fde081 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -174,7 +174,10 @@ impl<'a> Parser<'a> {
} else {
(None, None)
};
- let init = match (self.parse_initializer(let_span, ty.is_some(), err.is_some()), err) {
+ let init = match (
+ self.parse_initializer(let_span.until(pat.span), ty.is_some(), err.is_some()),
+ err,
+ ) {
(Ok(init), None) => {
// init parsed, ty parsed
init
@@ -231,25 +234,19 @@ impl<'a> Parser<'a> {
self.sess.span_diagnostic,
self.token.span,
E0067,
- "can't reassign to a uninitialized variable"
+ "can't reassign to an uninitialized variable"
);
err.span_suggestion_short(
self.token.span,
- "replace with `=` to initialize the variable",
+ "initialize the variable",
"=".to_string(),
- if has_ty {
- // for `let x: i8 += 1` it's highly likely that the `+` is a typo
- Applicability::MachineApplicable
- } else {
- // for `let x += 1` it's a bit less likely that the `+` is a typo
- Applicability::MaybeIncorrect
- },
+ Applicability::MaybeIncorrect,
);
// In case of code like `let x += 1` it's possible the user may have meant to write `x += 1`
if !has_ty {
err.span_suggestion_short(
let_span,
- "remove to reassign to a previously initialized variable",
+ "otherwise, reassign to a previously initialized variable",
"".to_string(),
Applicability::MaybeIncorrect,
);
diff --git a/src/test/ui/parser/let-binop-plus.rs b/src/test/ui/parser/let-binop-plus.rs
index 98473e9f096d..4d6d9b5c8d37 100644
--- a/src/test/ui/parser/let-binop-plus.rs
+++ b/src/test/ui/parser/let-binop-plus.rs
@@ -3,6 +3,6 @@
fn main() {
let a: i8 += 1;
//~^ ERROR expected trait, found builtin type `i8`
- //~| ERROR can't reassign to a uninitialized variable
+ //~| ERROR can't reassign to an uninitialized variable
let _ = a;
}
diff --git a/src/test/ui/parser/let-binop-plus.stderr b/src/test/ui/parser/let-binop-plus.stderr
index d7d84ff16a0a..91a59fe24fed 100644
--- a/src/test/ui/parser/let-binop-plus.stderr
+++ b/src/test/ui/parser/let-binop-plus.stderr
@@ -1,8 +1,8 @@
-error[E0067]: can't reassign to a uninitialized variable
+error[E0067]: can't reassign to an uninitialized variable
--> $DIR/let-binop-plus.rs:4:16
|
LL | let a: i8 += 1;
- | ^ help: replace with `=` to initialize the variable
+ | ^ help: initialize the variable
error[E0404]: expected trait, found builtin type `i8`
--> $DIR/let-binop-plus.rs:4:12
diff --git a/src/test/ui/parser/let-binop.rs b/src/test/ui/parser/let-binop.rs
index d445ab6bb8a1..7f58f5df2d41 100644
--- a/src/test/ui/parser/let-binop.rs
+++ b/src/test/ui/parser/let-binop.rs
@@ -1,8 +1,8 @@
fn main() {
- let a: i8 *= 1; //~ ERROR can't reassign to a uninitialized variable
+ let a: i8 *= 1; //~ ERROR can't reassign to an uninitialized variable
let _ = a;
- let b += 1; //~ ERROR can't reassign to a uninitialized variable
+ let b += 1; //~ ERROR can't reassign to an uninitialized variable
let _ = b;
- let c *= 1; //~ ERROR can't reassign to a uninitialized variable
+ let c *= 1; //~ ERROR can't reassign to an uninitialized variable
let _ = c;
}
diff --git a/src/test/ui/parser/let-binop.stderr b/src/test/ui/parser/let-binop.stderr
index c37612430cef..8a90b7cf74a4 100644
--- a/src/test/ui/parser/let-binop.stderr
+++ b/src/test/ui/parser/let-binop.stderr
@@ -1,37 +1,37 @@
-error[E0067]: can't reassign to a uninitialized variable
+error[E0067]: can't reassign to an uninitialized variable
--> $DIR/let-binop.rs:2:15
|
LL | let a: i8 *= 1;
- | ^^ help: replace with `=` to initialize the variable
+ | ^^ help: initialize the variable
-error[E0067]: can't reassign to a uninitialized variable
+error[E0067]: can't reassign to an uninitialized variable
--> $DIR/let-binop.rs:4:11
|
LL | let b += 1;
| ^^
|
-help: replace with `=` to initialize the variable
+help: initialize the variable
|
LL | let b = 1;
| ^
-help: remove to reassign to a previously initialized variable
+help: otherwise, reassign to a previously initialized variable
|
-LL | b += 1;
+LL | b += 1;
| --
-error[E0067]: can't reassign to a uninitialized variable
+error[E0067]: can't reassign to an uninitialized variable
--> $DIR/let-binop.rs:6:11
|
LL | let c *= 1;
| ^^
|
-help: replace with `=` to initialize the variable
+help: initialize the variable
|
LL | let c = 1;
| ^
-help: remove to reassign to a previously initialized variable
+help: otherwise, reassign to a previously initialized variable
|
-LL | c *= 1;
+LL | c *= 1;
| --
error: aborting due to 3 previous errors
From 98532a30901d7544c49fe82f499db53699645de0 Mon Sep 17 00:00:00 2001
From: mibac138 <5672750+mibac138@users.noreply.github.com>
Date: Wed, 20 May 2020 22:09:03 +0200
Subject: [PATCH 05/40] Adjust according to petrochenkov's review comments
---
src/librustc_parse/parser/stmt.rs | 65 ++++++++----------------
src/test/ui/parser/let-binop-plus.rs | 8 ---
src/test/ui/parser/let-binop-plus.stderr | 16 ------
src/test/ui/parser/let-binop.stderr | 29 ++---------
4 files changed, 27 insertions(+), 91 deletions(-)
delete mode 100644 src/test/ui/parser/let-binop-plus.rs
delete mode 100644 src/test/ui/parser/let-binop-plus.stderr
diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs
index bec810fde081..53f32b7c800b 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -12,7 +12,7 @@ use rustc_ast::ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKin
use rustc_ast::ptr::P;
use rustc_ast::token::{self, TokenKind};
use rustc_ast::util::classify;
-use rustc_errors::{struct_span_err, Applicability, PResult};
+use rustc_errors::{Applicability, PResult};
use rustc_span::source_map::{BytePos, Span};
use rustc_span::symbol::{kw, sym};
@@ -145,12 +145,12 @@ impl<'a> Parser<'a> {
}
fn parse_local_mk(&mut self, lo: Span, attrs: AttrVec) -> PResult<'a, Stmt> {
- let local = self.parse_local(lo, attrs)?;
+ let local = self.parse_local(attrs)?;
Ok(self.mk_stmt(lo.to(self.prev_token.span), StmtKind::Local(local)))
}
/// Parses a local variable declaration.
- fn parse_local(&mut self, let_span: Span, attrs: AttrVec) -> PResult<'a, P> {
+ fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P> {
let lo = self.prev_token.span;
let pat = self.parse_top_pat(GateOr::Yes)?;
@@ -174,10 +174,7 @@ impl<'a> Parser<'a> {
} else {
(None, None)
};
- let init = match (
- self.parse_initializer(let_span.until(pat.span), ty.is_some(), err.is_some()),
- err,
- ) {
+ let init = match (self.parse_initializer(err.is_some()), err) {
(Ok(init), None) => {
// init parsed, ty parsed
init
@@ -219,46 +216,28 @@ impl<'a> Parser<'a> {
}
/// Parses the RHS of a local variable declaration (e.g., '= 14;').
- fn parse_initializer(
- &mut self,
- let_span: Span,
- has_ty: bool,
- skip_eq: bool,
- ) -> PResult<'a, Option>> {
- // In case of code like `let x: i8 += 1`, `i8` is interpreted as a trait consuming the `+`
- // from `+=`.
- let ate_plus = self.prev_token.is_like_plus() && has_ty;
- let parse = if !skip_eq && (ate_plus || matches!(self.token.kind, TokenKind::BinOpEq(_))) {
- // Error recovery for `let x += 1`
- let mut err = struct_span_err!(
- self.sess.span_diagnostic,
- self.token.span,
- E0067,
- "can't reassign to an uninitialized variable"
- );
- err.span_suggestion_short(
- self.token.span,
- "initialize the variable",
- "=".to_string(),
- Applicability::MaybeIncorrect,
- );
- // In case of code like `let x += 1` it's possible the user may have meant to write `x += 1`
- if !has_ty {
- err.span_suggestion_short(
- let_span,
- "otherwise, reassign to a previously initialized variable",
- "".to_string(),
+ fn parse_initializer(&mut self, eq_optional: bool) -> PResult<'a, Option
>> {
+ let eq_consumed = match self.token.kind {
+ token::BinOpEq(..) => {
+ // Recover `let x = 1` as `let x = 1`
+ self.struct_span_err(
+ self.token.span,
+ "can't reassign to an uninitialized variable",
+ )
+ .span_suggestion_short(
+ self.token.span,
+ "initialize the variable",
+ "=".to_string(),
Applicability::MaybeIncorrect,
- );
+ )
+ .emit();
+ self.bump();
+ true
}
- err.emit();
- self.bump();
- true
- } else {
- self.eat(&token::Eq) || skip_eq
+ _ => self.eat(&token::Eq),
};
- if parse { Ok(Some(self.parse_expr()?)) } else { Ok(None) }
+ Ok(if eq_consumed || eq_optional { Some(self.parse_expr()?) } else { None })
}
/// Parses a block. No inner attributes are allowed.
diff --git a/src/test/ui/parser/let-binop-plus.rs b/src/test/ui/parser/let-binop-plus.rs
deleted file mode 100644
index 4d6d9b5c8d37..000000000000
--- a/src/test/ui/parser/let-binop-plus.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-#![allow(bare_trait_objects)]
-
-fn main() {
- let a: i8 += 1;
- //~^ ERROR expected trait, found builtin type `i8`
- //~| ERROR can't reassign to an uninitialized variable
- let _ = a;
-}
diff --git a/src/test/ui/parser/let-binop-plus.stderr b/src/test/ui/parser/let-binop-plus.stderr
deleted file mode 100644
index 91a59fe24fed..000000000000
--- a/src/test/ui/parser/let-binop-plus.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0067]: can't reassign to an uninitialized variable
- --> $DIR/let-binop-plus.rs:4:16
- |
-LL | let a: i8 += 1;
- | ^ help: initialize the variable
-
-error[E0404]: expected trait, found builtin type `i8`
- --> $DIR/let-binop-plus.rs:4:12
- |
-LL | let a: i8 += 1;
- | ^^ not a trait
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0067, E0404.
-For more information about an error, try `rustc --explain E0067`.
diff --git a/src/test/ui/parser/let-binop.stderr b/src/test/ui/parser/let-binop.stderr
index 8a90b7cf74a4..71431499ac70 100644
--- a/src/test/ui/parser/let-binop.stderr
+++ b/src/test/ui/parser/let-binop.stderr
@@ -1,39 +1,20 @@
-error[E0067]: can't reassign to an uninitialized variable
+error: can't reassign to an uninitialized variable
--> $DIR/let-binop.rs:2:15
|
LL | let a: i8 *= 1;
| ^^ help: initialize the variable
-error[E0067]: can't reassign to an uninitialized variable
+error: can't reassign to an uninitialized variable
--> $DIR/let-binop.rs:4:11
|
LL | let b += 1;
- | ^^
- |
-help: initialize the variable
- |
-LL | let b = 1;
- | ^
-help: otherwise, reassign to a previously initialized variable
- |
-LL | b += 1;
- | --
+ | ^^ help: initialize the variable
-error[E0067]: can't reassign to an uninitialized variable
+error: can't reassign to an uninitialized variable
--> $DIR/let-binop.rs:6:11
|
LL | let c *= 1;
- | ^^
- |
-help: initialize the variable
- |
-LL | let c = 1;
- | ^
-help: otherwise, reassign to a previously initialized variable
- |
-LL | c *= 1;
- | --
+ | ^^ help: initialize the variable
error: aborting due to 3 previous errors
-For more information about this error, try `rustc --explain E0067`.
From 1bc4e45b3fe3a0817908bd7cc21ec23798d38d63 Mon Sep 17 00:00:00 2001
From: "Carol (Nichols || Goulding)"
Date: Mon, 1 Jun 2020 22:18:38 -0400
Subject: [PATCH 06/40] Only highlight results via mouseover if mouse has moved
---
src/librustdoc/html/static/main.js | 37 +++++++++++++++++++-----------
1 file changed, 24 insertions(+), 13 deletions(-)
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index ac5a2f96b26c..fc31f6c76067 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -100,6 +100,8 @@ function defocusSearchBar() {
// 2 for "In Return Types"
var currentTab = 0;
+ var mouseMovedAfterSearch = true;
+
var titleBeforeSearch = document.title;
function clearInputTimeout() {
@@ -162,6 +164,7 @@ function defocusSearchBar() {
}
addClass(main, "hidden");
removeClass(search, "hidden");
+ mouseMovedAfterSearch = false;
}
function hideSearchResults(search) {
@@ -424,6 +427,12 @@ function defocusSearchBar() {
document.addEventListener("keypress", handleShortcut);
document.addEventListener("keydown", handleShortcut);
+ function resetMouseMoved(ev) {
+ mouseMovedAfterSearch = true;
+ }
+
+ document.addEventListener("mousemove", resetMouseMoved);
+
var handleSourceHighlight = (function() {
var prev_line_id = 0;
@@ -1353,20 +1362,22 @@ function defocusSearchBar() {
}
};
var mouseover_func = function(e) {
- var el = e.target;
- // to retrieve the real "owner" of the event.
- while (el.tagName !== "TR") {
- el = el.parentNode;
- }
- clearTimeout(hoverTimeout);
- hoverTimeout = setTimeout(function() {
- onEachLazy(document.getElementsByClassName("search-results"), function(e) {
- onEachLazy(e.getElementsByClassName("result"), function(i_e) {
- removeClass(i_e, "highlighted");
+ if (mouseMovedAfterSearch) {
+ var el = e.target;
+ // to retrieve the real "owner" of the event.
+ while (el.tagName !== "TR") {
+ el = el.parentNode;
+ }
+ clearTimeout(hoverTimeout);
+ hoverTimeout = setTimeout(function() {
+ onEachLazy(document.getElementsByClassName("search-results"), function(e) {
+ onEachLazy(e.getElementsByClassName("result"), function(i_e) {
+ removeClass(i_e, "highlighted");
+ });
});
- });
- addClass(el, "highlighted");
- }, 20);
+ addClass(el, "highlighted");
+ }, 20);
+ }
};
onEachLazy(document.getElementsByClassName("search-results"), function(e) {
onEachLazy(e.getElementsByClassName("result"), function(i_e) {
From bbb3321a655da8cd8eaf3ee92927f4ad23b1036b Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Mon, 8 Jun 2020 09:09:21 -0700
Subject: [PATCH 07/40] Ensure std benchmarks get tested.
---
src/liballoc/Cargo.toml | 1 +
src/libcore/Cargo.toml | 1 +
src/libstd/Cargo.toml | 5 +++++
3 files changed, 7 insertions(+)
diff --git a/src/liballoc/Cargo.toml b/src/liballoc/Cargo.toml
index d1119f7b7c0a..914195f015b5 100644
--- a/src/liballoc/Cargo.toml
+++ b/src/liballoc/Cargo.toml
@@ -25,6 +25,7 @@ path = "../liballoc/tests/lib.rs"
[[bench]]
name = "collectionsbenches"
path = "../liballoc/benches/lib.rs"
+test = true
[[bench]]
name = "vec_deque_append_bench"
diff --git a/src/libcore/Cargo.toml b/src/libcore/Cargo.toml
index ac07ffb14feb..42c555cafac8 100644
--- a/src/libcore/Cargo.toml
+++ b/src/libcore/Cargo.toml
@@ -19,6 +19,7 @@ path = "../libcore/tests/lib.rs"
[[bench]]
name = "corebenches"
path = "../libcore/benches/lib.rs"
+test = true
[dev-dependencies]
rand = "0.7"
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 39d786e59976..098b9f880cd1 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -74,3 +74,8 @@ std_detect_dlsym_getauxval = []
threads = 125
# Maximum heap size
heap_size = 0x8000000
+
+[[bench]]
+name = "stdbenches"
+path = "benches/lib.rs"
+test = true
From f0d2e78d39d0efdb431af0b59c498d532d8146e2 Mon Sep 17 00:00:00 2001
From: Ralf Jung
Date: Fri, 12 Jun 2020 18:17:30 +0200
Subject: [PATCH 08/40] add raw_ref macros
---
src/libcore/ptr/mod.rs | 67 ++++++++++++++++++++++++++++++++++++++++++
src/libstd/lib.rs | 1 +
2 files changed, 68 insertions(+)
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index 777284ca5c09..199f08c3d505 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -1399,3 +1399,70 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I }
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J }
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K }
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L }
+
+/// Create a `const` raw pointer to a place, without creating an intermediate reference.
+///
+/// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
+/// and points to initialized data. For cases where those requirements do not hold,
+/// raw pointers should be used instead. However, `&expr as *const _` creates a reference
+/// before casting it to a raw pointer, and that reference is subject to the same rules
+/// as all other references. This macro can create a raw pointer *without* creating
+/// a reference first.
+///
+/// # Example
+///
+/// ```
+/// #![feature(raw_ref_macros)]
+/// use std::ptr;
+///
+/// #[repr(packed)]
+/// struct Packed {
+/// f1: u8,
+/// f2: u16,
+/// }
+///
+/// let packed = Packed { f1: 1, f2: 2 };
+/// // `&packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
+/// let raw_f2 = ptr::raw_const!(packed.f2);
+/// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
+/// ```
+#[unstable(feature = "raw_ref_macros", issue = "none")]
+#[rustc_macro_transparency = "semitransparent"]
+#[allow_internal_unstable(raw_ref_op)]
+pub macro raw_const($e:expr) {
+ &raw const $e
+}
+
+/// Create a `mut` raw pointer to a place, without creating an intermediate reference.
+///
+/// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
+/// and points to initialized data. For cases where those requirements do not hold,
+/// raw pointers should be used instead. However, `&mut expr as *mut _` creates a reference
+/// before casting it to a raw pointer, and that reference is subject to the same rules
+/// as all other references. This macro can create a raw pointer *without* creating
+/// a reference first.
+///
+/// # Example
+///
+/// ```
+/// #![feature(raw_ref_macros)]
+/// use std::ptr;
+///
+/// #[repr(packed)]
+/// struct Packed {
+/// f1: u8,
+/// f2: u16,
+/// }
+///
+/// let mut packed = Packed { f1: 1, f2: 2 };
+/// // `&mut packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
+/// let raw_f2 = ptr::raw_mut!(packed.f2);
+/// unsafe { raw_f2.write_unaligned(42); }
+/// assert_eq!({packed.f2}, 42); // `{...}` forces copying the field instead of creating a reference.
+/// ```
+#[unstable(feature = "raw_ref_macros", issue = "none")]
+#[rustc_macro_transparency = "semitransparent"]
+#[allow_internal_unstable(raw_ref_op)]
+pub macro raw_mut($e:expr) {
+ &raw mut $e
+}
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index d6493454db59..ef699ede2a14 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -298,6 +298,7 @@
#![feature(prelude_import)]
#![feature(ptr_internals)]
#![feature(raw)]
+#![feature(raw_ref_macros)]
#![feature(renamed_spin_loop)]
#![feature(rustc_attrs)]
#![feature(rustc_private)]
From 724dfba460e2c98311cacb5d4f6bb6da36ceec67 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez
Date: Sat, 13 Jun 2020 15:05:37 +0200
Subject: [PATCH 09/40] Clean up some weird command strings
---
src/librustdoc/lib.rs | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 82d6cda986a9..95d113166e00 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -165,9 +165,8 @@ fn opts() -> Vec {
o.optmulti(
"",
"passes",
- "list of passes to also run, you might want \
- to pass it multiple times; a value of `list` \
- will print available passes",
+ "list of passes to also run, you might want to pass it multiple times; a value of \
+ `list` will print available passes",
"PASSES",
)
}),
@@ -248,8 +247,8 @@ fn opts() -> Vec {
"e",
"extend-css",
"To add some CSS rules with a given file to generate doc with your \
- own theme. However, your theme might break if the rustdoc's generated HTML \
- changes, so be careful!",
+ own theme. However, your theme might break if the rustdoc's generated HTML \
+ changes, so be careful!",
"PATH",
)
}),
@@ -262,7 +261,7 @@ fn opts() -> Vec {
"",
"playground-url",
"URL to send code snippets to, may be reset by --markdown-playground-url \
- or `#![doc(html_playground_url=...)]`",
+ or `#![doc(html_playground_url=...)]`",
"URL",
)
}),
@@ -276,8 +275,7 @@ fn opts() -> Vec {
o.optflag(
"",
"sort-modules-by-appearance",
- "sort modules by where they appear in the \
- program, rather than alphabetically",
+ "sort modules by where they appear in the program, rather than alphabetically",
)
}),
stable("theme", |o| {
@@ -358,7 +356,7 @@ fn opts() -> Vec {
"",
"static-root-path",
"Path string to force loading static files from in output pages. \
- If not set, uses combinations of '../' to reach the documentation root.",
+ If not set, uses combinations of '../' to reach the documentation root.",
"PATH",
)
}),
From d5ea0e9f8def9a3ec0eb2dd88f0465d4d1a81c21 Mon Sep 17 00:00:00 2001
From: oddg
Date: Thu, 14 May 2020 19:58:43 -0700
Subject: [PATCH 10/40] Report error when casting an C-like enum implementing
Drop
---
src/librustc_session/lint/builtin.rs | 11 ++++++++++
src/librustc_typeck/check/cast.rs | 30 +++++++++++++++++++++++++---
2 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs
index 58388bafbedd..5a8f5c1b9fbc 100644
--- a/src/librustc_session/lint/builtin.rs
+++ b/src/librustc_session/lint/builtin.rs
@@ -534,6 +534,16 @@ declare_lint! {
@feature_gate = sym::unsafe_block_in_unsafe_fn;
}
+declare_lint! {
+ pub CENUM_IMPL_DROP_CAST,
+ Warn,
+ "a C-like enum implementing Drop is cast",
+ @future_incompatible = FutureIncompatibleInfo {
+ reference: "issue #73333 ",
+ edition: None,
+ };
+}
+
declare_lint_pass! {
/// Does nothing as a lint pass, but registers some `Lint`s
/// that are used by other parts of the compiler.
@@ -607,6 +617,7 @@ declare_lint_pass! {
ASM_SUB_REGISTER,
UNSAFE_OP_IN_UNSAFE_FN,
INCOMPLETE_INCLUDE,
+ CENUM_IMPL_DROP_CAST,
]
}
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 46d6706cbf42..bea5e0e99665 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -609,7 +609,10 @@ impl<'a, 'tcx> CastCheck<'tcx> {
(FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
// prim -> prim
- (Int(CEnum), Int(_)) => Ok(CastKind::EnumCast),
+ (Int(CEnum), Int(_)) => {
+ self.cenum_impl_drop_lint(fcx);
+ Ok(CastKind::EnumCast)
+ }
(Int(Char) | Int(Bool), Int(_)) => Ok(CastKind::PrimIntCast),
(Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast),
@@ -706,11 +709,13 @@ impl<'a, 'tcx> CastCheck<'tcx> {
// Coerce to a raw pointer so that we generate AddressOf in MIR.
let array_ptr_type = fcx.tcx.mk_ptr(m_expr);
fcx.try_coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No)
- .unwrap_or_else(|_| bug!(
+ .unwrap_or_else(|_| {
+ bug!(
"could not cast from reference to array to pointer to array ({:?} to {:?})",
self.expr_ty,
array_ptr_type,
- ));
+ )
+ });
// this will report a type mismatch if needed
fcx.demand_eqtype(self.span, ety, m_cast.ty);
@@ -740,6 +745,25 @@ impl<'a, 'tcx> CastCheck<'tcx> {
Err(err) => Err(err),
}
}
+
+ fn cenum_impl_drop_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
+ if let ty::Adt(d, _) = self.expr_ty.kind {
+ if d.has_dtor(fcx.tcx) {
+ fcx.tcx.struct_span_lint_hir(
+ lint::builtin::CENUM_IMPL_DROP_CAST,
+ self.expr.hir_id,
+ self.span,
+ |err| {
+ err.build(&format!(
+ "Cast `enum` implementing `Drop` `{}` to integer `{}`",
+ self.expr_ty, self.cast_ty
+ ))
+ .emit();
+ },
+ );
+ }
+ }
+ }
}
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
From a40156e5b7053dcc36ba1ad65fb567b183c4e1fb Mon Sep 17 00:00:00 2001
From: oddg
Date: Sun, 14 Jun 2020 15:49:20 -0700
Subject: [PATCH 11/40] UI test for deprecation warning of casting enum
implementing Drop
---
src/test/ui/cenum_impl_drop_cast.rs | 18 ++++++++++++++++++
src/test/ui/cenum_impl_drop_cast.stderr | 16 ++++++++++++++++
2 files changed, 34 insertions(+)
create mode 100644 src/test/ui/cenum_impl_drop_cast.rs
create mode 100644 src/test/ui/cenum_impl_drop_cast.stderr
diff --git a/src/test/ui/cenum_impl_drop_cast.rs b/src/test/ui/cenum_impl_drop_cast.rs
new file mode 100644
index 000000000000..623460673bfa
--- /dev/null
+++ b/src/test/ui/cenum_impl_drop_cast.rs
@@ -0,0 +1,18 @@
+#![deny(cenum_impl_drop_cast)]
+
+enum E {
+ A = 0,
+}
+
+impl Drop for E {
+ fn drop(&mut self) {
+ println!("Drop");
+ }
+}
+
+fn main() {
+ let e = E::A;
+ let i = e as u32;
+ //~^ ERROR Cast `enum` implementing `Drop` `E` to integer `u32`
+ //~| WARN this was previously accepted
+}
diff --git a/src/test/ui/cenum_impl_drop_cast.stderr b/src/test/ui/cenum_impl_drop_cast.stderr
new file mode 100644
index 000000000000..5c8f86ffd72a
--- /dev/null
+++ b/src/test/ui/cenum_impl_drop_cast.stderr
@@ -0,0 +1,16 @@
+error: Cast `enum` implementing `Drop` `E` to integer `u32`
+ --> $DIR/cenum_impl_drop_cast.rs:15:13
+ |
+LL | let i = e as u32;
+ | ^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/cenum_impl_drop_cast.rs:1:9
+ |
+LL | #![deny(cenum_impl_drop_cast)]
+ | ^^^^^^^^^^^^^^^^^^^^
+ = 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 #73333
+
+error: aborting due to previous error
+
From 9e510085ecaedaee86b44410a4b3e4c85d97d6e0 Mon Sep 17 00:00:00 2001
From: Alexis Bourget
Date: Mon, 15 Jun 2020 15:19:02 +0200
Subject: [PATCH 12/40] Complete the std::time documentation to warn about the
inconsistencies between OS
---
src/libstd/time.rs | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index c36e78b1d004..c58168bd446d 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -60,6 +60,21 @@ pub use core::time::Duration;
/// }
/// ```
///
+/// # OS-specific behaviors
+///
+/// An `Instant` is a wrapper around system-specific types and it may behave
+/// differently depending on the underlying operating system. For example,
+/// the following snippet is fine on Linux but panics on macOS:
+///
+/// ```no_run
+/// use std::time::{Instant, Duration};
+///
+/// let now = Instant::now();
+/// let max_nanoseconds = u64::MAX / 1_000_000_000;
+/// let duration = Duration::new(max_nanoseconds, 0);
+/// println!("{:?}", now + duration);
+/// ```
+///
/// # Underlying System calls
/// Currently, the following system calls are being used to get the current time using `now()`:
///
From 81c909488eebcba16610402349563380772e0d1d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?=
Date: Fri, 29 May 2020 15:09:43 -0700
Subject: [PATCH 13/40] Suggest substituting `'static` lifetime in impl/dyn
`Trait + 'static` return types
---
.../nice_region_error/static_impl_trait.rs | 64 ++++++++--
src/librustc_middle/ty/context.rs | 13 +-
src/librustc_middle/ty/diagnostics.rs | 8 +-
...t_outlive_least_region_or_bound.nll.stderr | 38 +++++-
.../must_outlive_least_region_or_bound.rs | 21 ++++
.../must_outlive_least_region_or_bound.stderr | 117 ++++++++++++++++--
6 files changed, 232 insertions(+), 29 deletions(-)
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
index f4c86ddae604..88d6c23d5144 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -4,6 +4,7 @@ use crate::infer::error_reporting::msg_span_from_free_region;
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use rustc_errors::{Applicability, ErrorReported};
+use rustc_hir::{GenericBound, ItemKind, Lifetime, LifetimeName, TyKind};
use rustc_middle::ty::RegionKind;
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
@@ -20,8 +21,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
) = error.clone()
{
let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?;
- let (fn_return_span, is_dyn) =
- self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?;
+ let fn_return = self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?;
+ let is_dyn = matches!(fn_return.kind, TyKind::TraitObject(..));
+ let fn_return_span = fn_return.span;
if sub_r == &RegionKind::ReStatic {
let sp = var_origin.span();
let return_sp = sub_origin.span();
@@ -67,12 +69,58 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
lifetime,
);
// FIXME: account for the need of parens in `&(dyn Trait + '_)`
- err.span_suggestion_verbose(
- fn_return_span.shrink_to_hi(),
- &msg,
- format!(" + {}", lifetime_name),
- Applicability::MaybeIncorrect,
- );
+ match fn_return.kind {
+ TyKind::Def(item_id, _) => {
+ let item = self.tcx().hir().item(item_id.id);
+ let opaque = if let ItemKind::OpaqueTy(opaque) = &item.kind {
+ opaque
+ } else {
+ err.emit();
+ return Some(ErrorReported);
+ };
+ let (span, sugg) = opaque
+ .bounds
+ .iter()
+ .filter_map(|arg| match arg {
+ GenericBound::Outlives(Lifetime {
+ name: LifetimeName::Static,
+ span,
+ ..
+ }) => Some((*span, lifetime_name.clone())),
+ _ => None,
+ })
+ .next()
+ .unwrap_or_else(|| {
+ (
+ fn_return_span.shrink_to_hi(),
+ format!(" + {}", lifetime_name),
+ )
+ });
+
+ err.span_suggestion_verbose(
+ span,
+ &msg,
+ sugg,
+ Applicability::MaybeIncorrect,
+ );
+ }
+ TyKind::TraitObject(_, lt) => {
+ let (span, sugg) = match lt.name {
+ LifetimeName::ImplicitObjectLifetimeDefault => (
+ fn_return_span.shrink_to_hi(),
+ format!(" + {}", lifetime_name),
+ ),
+ _ => (lt.span, lifetime_name),
+ };
+ err.span_suggestion_verbose(
+ span,
+ &msg,
+ sugg,
+ Applicability::MaybeIncorrect,
+ );
+ }
+ _ => {}
+ }
}
err.emit();
return Some(ErrorReported);
diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs
index d5be3508d2d8..4770993d9cb0 100644
--- a/src/librustc_middle/ty/context.rs
+++ b/src/librustc_middle/ty/context.rs
@@ -1383,7 +1383,10 @@ impl<'tcx> TyCtxt<'tcx> {
})
}
- pub fn return_type_impl_or_dyn_trait(&self, scope_def_id: DefId) -> Option<(Span, bool)> {
+ pub fn return_type_impl_or_dyn_trait(
+ &self,
+ scope_def_id: DefId,
+ ) -> Option<&'tcx hir::Ty<'tcx>> {
let hir_id = self.hir().as_local_hir_id(scope_def_id.expect_local());
let hir_output = match self.hir().get(hir_id) {
Node::Item(hir::Item {
@@ -1429,15 +1432,17 @@ impl<'tcx> TyCtxt<'tcx> {
let output = self.erase_late_bound_regions(&sig.output());
if output.is_impl_trait() {
let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
- Some((fn_decl.output.span(), false))
+ if let hir::FnRetTy::Return(ty) = fn_decl.output {
+ return Some(ty);
+ }
} else {
let mut v = TraitObjectVisitor(vec![]);
rustc_hir::intravisit::walk_ty(&mut v, hir_output);
if v.0.len() == 1 {
- return Some((v.0[0], true));
+ return Some(v.0[0]);
}
- None
}
+ None
}
_ => None,
}
diff --git a/src/librustc_middle/ty/diagnostics.rs b/src/librustc_middle/ty/diagnostics.rs
index 2e9aa724ac5a..3ca506fe0d59 100644
--- a/src/librustc_middle/ty/diagnostics.rs
+++ b/src/librustc_middle/ty/diagnostics.rs
@@ -236,21 +236,21 @@ pub fn suggest_constraining_type_param(
}
}
-pub struct TraitObjectVisitor(pub Vec);
-impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor {
+pub struct TraitObjectVisitor<'tcx>(pub Vec<&'tcx hir::Ty<'tcx>>);
+impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
type Map = rustc_hir::intravisit::ErasedMap<'v>;
fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap {
hir::intravisit::NestedVisitorMap::None
}
- fn visit_ty(&mut self, ty: &hir::Ty<'_>) {
+ fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
if let hir::TyKind::TraitObject(
_,
hir::Lifetime { name: hir::LifetimeName::ImplicitObjectLifetimeDefault, .. },
) = ty.kind
{
- self.0.push(ty.span);
+ self.0.push(ty);
}
}
}
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
index 1806d2607a3a..ca9ca8a9debe 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
@@ -26,7 +26,34 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
| ^^^^^^^^^^^^^^
error: lifetime may not live long enough
- --> $DIR/must_outlive_least_region_or_bound.rs:12:69
+ --> $DIR/must_outlive_least_region_or_bound.rs:9:46
+ |
+LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
+ | - ^ returning this value requires that `'1` must outlive `'static`
+ | |
+ | let's call the lifetime of this reference `'1`
+ |
+ = help: consider replacing `'1` with `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/must_outlive_least_region_or_bound.rs:12:55
+ |
+LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
+ | -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static`
+ |
+ = help: consider replacing `'a` with `'static`
+ = help: consider replacing `'a` with `'static`
+
+error[E0621]: explicit lifetime required in the type of `x`
+ --> $DIR/must_outlive_least_region_or_bound.rs:15:41
+ |
+LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
+ | ---- ^ lifetime `'a` required
+ | |
+ | help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
+
+error: lifetime may not live long enough
+ --> $DIR/must_outlive_least_region_or_bound.rs:33:69
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static`
@@ -35,7 +62,7 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
= help: consider replacing `'a` with `'static`
error: lifetime may not live long enough
- --> $DIR/must_outlive_least_region_or_bound.rs:17:61
+ --> $DIR/must_outlive_least_region_or_bound.rs:38:61
|
LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
| -- -- lifetime `'b` defined here ^^^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a`
@@ -45,13 +72,14 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32
= help: consider adding the following bound: `'b: 'a`
error[E0310]: the parameter type `T` may not live long enough
- --> $DIR/must_outlive_least_region_or_bound.rs:22:51
+ --> $DIR/must_outlive_least_region_or_bound.rs:43:51
|
LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static {
| ^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'static`...
-error: aborting due to 5 previous errors
+error: aborting due to 8 previous errors
-For more information about this error, try `rustc --explain E0310`.
+Some errors have detailed explanations: E0310, E0621.
+For more information about an error, try `rustc --explain E0310`.
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
index 00f3490991b5..beafe9258209 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
@@ -6,6 +6,27 @@ fn elided(x: &i32) -> impl Copy { x }
fn explicit<'a>(x: &'a i32) -> impl Copy { x }
//~^ ERROR cannot infer an appropriate lifetime
+fn elided2(x: &i32) -> impl Copy + 'static { x }
+//~^ ERROR cannot infer an appropriate lifetime
+
+fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
+//~^ ERROR cannot infer an appropriate lifetime
+
+fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
+//~^ ERROR explicit lifetime required in the type of `x`
+
+fn elided3(x: &i32) -> Box { Box::new(x) }
+//~^ ERROR cannot infer an appropriate lifetime
+
+fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
+//~^ ERROR cannot infer an appropriate lifetime
+
+fn elided4(x: &i32) -> Box { Box::new(x) }
+//~^ ERROR explicit lifetime required in the type of `x`
+
+fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
+//~^ ERROR cannot infer an appropriate lifetime
+
trait LifetimeTrait<'a> {}
impl<'a> LifetimeTrait<'a> for &'a i32 {}
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
index d7dae6a08a7b..525e271bea9c 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
@@ -27,7 +27,43 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
| ^^^^
error: cannot infer an appropriate lifetime
- --> $DIR/must_outlive_least_region_or_bound.rs:12:69
+ --> $DIR/must_outlive_least_region_or_bound.rs:9:46
+ |
+LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
+ | ---- ------------------- ^ ...and is captured here
+ | | |
+ | | ...is required to be `'static` by this...
+ | data with this lifetime...
+ |
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 9:1
+ |
+LL | fn elided2(x: &i32) -> impl Copy + '_ { x }
+ | ^^
+
+error: cannot infer an appropriate lifetime
+ --> $DIR/must_outlive_least_region_or_bound.rs:12:55
+ |
+LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
+ | ------- ------------------- ^ ...and is captured here
+ | | |
+ | | ...is required to be `'static` by this...
+ | data with this lifetime...
+ |
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 12:14
+ |
+LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x }
+ | ^^
+
+error[E0621]: explicit lifetime required in the type of `x`
+ --> $DIR/must_outlive_least_region_or_bound.rs:15:24
+ |
+LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
+ | ---- ^^^^^^^^^^^^^^ lifetime `'a` required
+ | |
+ | help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
+
+error: cannot infer an appropriate lifetime
+ --> $DIR/must_outlive_least_region_or_bound.rs:33:69
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| ------- -------------------------------- ^ ...and is captured here
@@ -35,13 +71,13 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| | ...is required to be `'static` by this...
| data with this lifetime...
|
-help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 12:15
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 33:15
|
-LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static + 'a { x }
- | ^^^^
+LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x }
+ | ^^
error[E0623]: lifetime mismatch
- --> $DIR/must_outlive_least_region_or_bound.rs:17:61
+ --> $DIR/must_outlive_least_region_or_bound.rs:38:61
|
LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
| ------- ^^^^^^^^^^^^^^^^
@@ -50,14 +86,79 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32
| this parameter and the return type are declared with different lifetimes...
error[E0310]: the parameter type `T` may not live long enough
- --> $DIR/must_outlive_least_region_or_bound.rs:22:51
+ --> $DIR/must_outlive_least_region_or_bound.rs:43:51
|
LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static {
| -- ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
| |
| help: consider adding an explicit lifetime bound...: `T: 'static +`
-error: aborting due to 5 previous errors
+error: cannot infer an appropriate lifetime
+ --> $DIR/must_outlive_least_region_or_bound.rs:18:50
+ |
+LL | fn elided3(x: &i32) -> Box { Box::new(x) }
+ | ---- ---------^-
+ | | | |
+ | | | ...and is captured here
+ | | ...is required to be `'static` by this...
+ | data with this lifetime...
+ |
+help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1
+ |
+LL | fn elided3(x: &i32) -> Box { Box::new(x) }
+ | ^^^^
+
+error: cannot infer an appropriate lifetime
+ --> $DIR/must_outlive_least_region_or_bound.rs:21:59
+ |
+LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
+ | ------- ---------^-
+ | | | |
+ | | | ...and is captured here
+ | | ...is required to be `'static` by this...
+ | data with this lifetime...
+ |
+help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14
+ |
+LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
+ | ^^^^
+
+error[E0621]: explicit lifetime required in the type of `x`
+ --> $DIR/must_outlive_least_region_or_bound.rs:24:51
+ |
+LL | fn elided4(x: &i32) -> Box { Box::new(x) }
+ | ---- ^^^^^^^^^^^ lifetime `'static` required
+ | |
+ | help: add explicit lifetime `'static` to the type of `x`: `&'static i32`
+
+error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+ --> $DIR/must_outlive_least_region_or_bound.rs:27:69
+ |
+LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
+ | ^
+ |
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 27:14...
+ --> $DIR/must_outlive_least_region_or_bound.rs:27:14
+ |
+LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
+ | ^^
+note: ...so that the expression is assignable
+ --> $DIR/must_outlive_least_region_or_bound.rs:27:69
+ |
+LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
+ | ^
+ = note: expected `&i32`
+ found `&'a i32`
+ = note: but, the lifetime must be valid for the static lifetime...
+note: ...so that the expression is assignable
+ --> $DIR/must_outlive_least_region_or_bound.rs:27:60
+ |
+LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
+ | ^^^^^^^^^^^
+ = note: expected `std::boxed::Box<(dyn std::fmt::Debug + 'static)>`
+ found `std::boxed::Box`
+
+error: aborting due to 12 previous errors
-Some errors have detailed explanations: E0310, E0623.
+Some errors have detailed explanations: E0310, E0495, E0621, E0623.
For more information about an error, try `rustc --explain E0310`.
From 4e90f177cc530371a314f51f522a4c2e70885e03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?=
Date: Fri, 29 May 2020 18:05:20 -0700
Subject: [PATCH 14/40] When `'static` is explicit, suggest constraining
argument with it
---
.../infer/error_reporting/mod.rs | 3 +-
.../nice_region_error/static_impl_trait.rs | 115 +++++++++++-------
src/librustc_middle/ty/diagnostics.rs | 5 +-
.../must_outlive_least_region_or_bound.rs | 2 +-
.../must_outlive_least_region_or_bound.stderr | 75 +++++++-----
src/test/ui/issues/issue-16922.stderr | 2 +-
...ect-lifetime-default-from-box-error.stderr | 2 +-
...ion-object-lifetime-in-coercion.nll.stderr | 19 ++-
.../region-object-lifetime-in-coercion.rs | 5 +-
.../region-object-lifetime-in-coercion.stderr | 61 +++++++---
.../regions-close-object-into-object-2.stderr | 32 ++---
.../regions-close-object-into-object-4.stderr | 32 ++---
.../regions-proc-bound-capture.nll.stderr | 11 ++
.../ui/regions/regions-proc-bound-capture.rs | 4 +-
.../regions/regions-proc-bound-capture.stderr | 25 ++--
.../dyn-trait-underscore.stderr | 2 +-
16 files changed, 237 insertions(+), 158 deletions(-)
create mode 100644 src/test/ui/regions/regions-proc-bound-capture.nll.stderr
diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs
index 12f7a9c0ca50..9cfa11dd7c81 100644
--- a/src/librustc_infer/infer/error_reporting/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/mod.rs
@@ -2035,8 +2035,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.tcx.sess,
var_origin.span(),
E0495,
- "cannot infer an appropriate lifetime{} \
- due to conflicting requirements",
+ "cannot infer an appropriate lifetime{} due to conflicting requirements",
var_description
)
}
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 88d6c23d5144..e24535bba5fd 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -10,6 +10,7 @@ use rustc_middle::ty::RegionKind;
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
/// Print the error message for lifetime errors when the return type is a static impl Trait.
pub(super) fn try_report_static_impl_trait(&self) -> Option {
+ debug!("try_report_static_impl_trait(error={:?})", self.error);
if let Some(ref error) = self.error {
if let RegionResolutionError::SubSupConflict(
_,
@@ -18,19 +19,24 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
sub_r,
sup_origin,
sup_r,
- ) = error.clone()
+ ) = error
{
+ debug!(
+ "try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})",
+ var_origin, sub_origin, sub_r, sup_origin, sup_r
+ );
let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?;
+ debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup);
let fn_return = self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?;
- let is_dyn = matches!(fn_return.kind, TyKind::TraitObject(..));
- let fn_return_span = fn_return.span;
- if sub_r == &RegionKind::ReStatic {
+ debug!("try_report_static_impl_trait: fn_return={:?}", fn_return);
+ if **sub_r == RegionKind::ReStatic {
let sp = var_origin.span();
let return_sp = sub_origin.span();
+ let param_info = self.find_param_with_region(sup_r, sub_r)?;
let mut err =
self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime");
- let param_info = self.find_param_with_region(sup_r, sub_r)?;
err.span_label(param_info.param_ty_span, "data with this lifetime...");
+ debug!("try_report_static_impl_trait: param_info={:?}", param_info);
// We try to make the output have fewer overlapping spans if possible.
if (sp == sup_origin.span() || !return_sp.overlaps(sup_origin.span()))
@@ -60,14 +66,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
if sup_r.has_name() { sup_r.to_string() } else { "'_".to_owned() };
// only apply this suggestion onto functions with
// explicit non-desugar'able return.
- if fn_return_span.desugaring_kind().is_none() {
- let msg = format!(
- "to permit non-static references in {} `{} Trait` value, you can add \
- an explicit bound for {}",
- if is_dyn { "a" } else { "an" },
- if is_dyn { "dyn" } else { "impl" },
- lifetime,
- );
+ if fn_return.span.desugaring_kind().is_none() {
// FIXME: account for the need of parens in `&(dyn Trait + '_)`
match fn_return.kind {
TyKind::Def(item_id, _) => {
@@ -78,7 +77,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
err.emit();
return Some(ErrorReported);
};
- let (span, sugg) = opaque
+
+ if let Some(span) = opaque
.bounds
.iter()
.filter_map(|arg| match arg {
@@ -86,38 +86,71 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
name: LifetimeName::Static,
span,
..
- }) => Some((*span, lifetime_name.clone())),
+ }) => Some(*span),
_ => None,
})
.next()
- .unwrap_or_else(|| {
- (
- fn_return_span.shrink_to_hi(),
- format!(" + {}", lifetime_name),
- )
- });
-
- err.span_suggestion_verbose(
- span,
- &msg,
- sugg,
- Applicability::MaybeIncorrect,
- );
- }
- TyKind::TraitObject(_, lt) => {
- let (span, sugg) = match lt.name {
- LifetimeName::ImplicitObjectLifetimeDefault => (
- fn_return_span.shrink_to_hi(),
+ {
+ err.span_suggestion_verbose(
+ span,
+ "consider changing the `impl Trait`'s explicit \
+ `'static` bound",
+ lifetime_name,
+ Applicability::MaybeIncorrect,
+ );
+ err.span_suggestion_verbose(
+ param_info.param_ty_span,
+ "alternatively, set an explicit `'static` lifetime to \
+ this parameter",
+ param_info.param_ty.to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ } else {
+ err.span_suggestion_verbose(
+ fn_return.span.shrink_to_hi(),
+ &format!(
+ "to permit non-static references in an `impl Trait` \
+ value, you can add an explicit bound for {}",
+ lifetime,
+ ),
format!(" + {}", lifetime_name),
- ),
- _ => (lt.span, lifetime_name),
+ Applicability::MaybeIncorrect,
+ );
};
- err.span_suggestion_verbose(
- span,
- &msg,
- sugg,
- Applicability::MaybeIncorrect,
- );
+ }
+ TyKind::TraitObject(_, lt) => {
+ match lt.name {
+ LifetimeName::ImplicitObjectLifetimeDefault => {
+ err.span_suggestion_verbose(
+ fn_return.span.shrink_to_hi(),
+ &format!(
+ "to permit non-static references in a trait object \
+ value, you can add an explicit bound for {}",
+ lifetime,
+ ),
+ format!(" + {}", lifetime_name),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ _ => {
+ err.span_suggestion_verbose(
+ lt.span,
+ "consider changing the trait object's explicit \
+ `'static` bound",
+ lifetime_name,
+ Applicability::MaybeIncorrect,
+ );
+ err.span_suggestion_verbose(
+ param_info.param_ty_span,
+ &format!(
+ "alternatively, set an explicit `'static` lifetime \
+ in this parameter",
+ ),
+ param_info.param_ty.to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ }
}
_ => {}
}
diff --git a/src/librustc_middle/ty/diagnostics.rs b/src/librustc_middle/ty/diagnostics.rs
index 3ca506fe0d59..a2812e117ed3 100644
--- a/src/librustc_middle/ty/diagnostics.rs
+++ b/src/librustc_middle/ty/diagnostics.rs
@@ -247,7 +247,10 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
if let hir::TyKind::TraitObject(
_,
- hir::Lifetime { name: hir::LifetimeName::ImplicitObjectLifetimeDefault, .. },
+ hir::Lifetime {
+ name: hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static,
+ ..
+ },
) = ty.kind
{
self.0.push(ty);
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
index beafe9258209..837244b02272 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
@@ -22,7 +22,7 @@ fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
//~^ ERROR cannot infer an appropriate lifetime
fn elided4(x: &i32) -> Box { Box::new(x) }
-//~^ ERROR explicit lifetime required in the type of `x`
+//~^ ERROR cannot infer an appropriate lifetime
fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
//~^ ERROR cannot infer an appropriate lifetime
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
index 525e271bea9c..96d4a121c16a 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
@@ -35,10 +35,14 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
| | ...is required to be `'static` by this...
| data with this lifetime...
|
-help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 9:1
+help: consider changing the `impl Trait`'s explicit `'static` bound
|
LL | fn elided2(x: &i32) -> impl Copy + '_ { x }
| ^^
+help: alternatively, set an explicit `'static` lifetime to this parameter
+ |
+LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x }
+ | ^^^^^^^^^^^^
error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:12:55
@@ -49,10 +53,14 @@ LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
| | ...is required to be `'static` by this...
| data with this lifetime...
|
-help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 12:14
+help: consider changing the `impl Trait`'s explicit `'static` bound
|
LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x }
| ^^
+help: alternatively, set an explicit `'static` lifetime to this parameter
+ |
+LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x }
+ | ^^^^^^^^^^^^
error[E0621]: explicit lifetime required in the type of `x`
--> $DIR/must_outlive_least_region_or_bound.rs:15:24
@@ -71,10 +79,14 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| | ...is required to be `'static` by this...
| data with this lifetime...
|
-help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 33:15
+help: consider changing the `impl Trait`'s explicit `'static` bound
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x }
| ^^
+help: alternatively, set an explicit `'static` lifetime to this parameter
+ |
+LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x }
+ | ^^^^^^^^^^^^
error[E0623]: lifetime mismatch
--> $DIR/must_outlive_least_region_or_bound.rs:38:61
@@ -103,7 +115,7 @@ LL | fn elided3(x: &i32) -> Box { Box::new(x) }
| | ...is required to be `'static` by this...
| data with this lifetime...
|
-help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1
|
LL | fn elided3(x: &i32) -> Box { Box::new(x) }
| ^^^^
@@ -118,47 +130,48 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
| | ...is required to be `'static` by this...
| data with this lifetime...
|
-help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14
+help: to permit non-static references in a trait object value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14
|
LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
| ^^^^
-error[E0621]: explicit lifetime required in the type of `x`
- --> $DIR/must_outlive_least_region_or_bound.rs:24:51
+error: cannot infer an appropriate lifetime
+ --> $DIR/must_outlive_least_region_or_bound.rs:24:60
|
LL | fn elided4(x: &i32) -> Box { Box::new(x) }
- | ---- ^^^^^^^^^^^ lifetime `'static` required
- | |
- | help: add explicit lifetime `'static` to the type of `x`: `&'static i32`
-
-error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
- --> $DIR/must_outlive_least_region_or_bound.rs:27:69
+ | ---- ---------^-
+ | | | |
+ | | | ...and is captured here
+ | data with this lifetime... ...is required to be `'static` by this...
|
-LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
- | ^
+help: consider changing the trait object's explicit `'static` bound
|
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 27:14...
- --> $DIR/must_outlive_least_region_or_bound.rs:27:14
+LL | fn elided4(x: &i32) -> Box { Box::new(x) }
+ | ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
|
-LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
- | ^^
-note: ...so that the expression is assignable
+LL | fn elided4(x: &'static i32) -> Box { Box::new(x) }
+ | ^^^^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:27:69
|
LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
- | ^
- = note: expected `&i32`
- found `&'a i32`
- = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that the expression is assignable
- --> $DIR/must_outlive_least_region_or_bound.rs:27:60
+ | ------- ---------^-
+ | | | |
+ | | | ...and is captured here
+ | data with this lifetime... ...is required to be `'static` by this...
|
-LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
- | ^^^^^^^^^^^
- = note: expected `std::boxed::Box<(dyn std::fmt::Debug + 'static)>`
- found `std::boxed::Box`
+help: consider changing the trait object's explicit `'static` bound
+ |
+LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
+ | ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
+ |
+LL | fn explicit4<'a>(x: &'static i32) -> Box { Box::new(x) }
+ | ^^^^^^^^^^^^
error: aborting due to 12 previous errors
-Some errors have detailed explanations: E0310, E0495, E0621, E0623.
+Some errors have detailed explanations: E0310, E0621, E0623.
For more information about an error, try `rustc --explain E0310`.
diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr
index 02d33aae023f..038df47e1bd9 100644
--- a/src/test/ui/issues/issue-16922.stderr
+++ b/src/test/ui/issues/issue-16922.stderr
@@ -9,7 +9,7 @@ LL | Box::new(value) as Box
| | ...and is captured here
| ...is required to be `'static` by this...
|
-help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1
|
LL | fn foo(value: &T) -> Box {
| ^^^^
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
index 70a9bf22b8db..555622c9d13c 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
@@ -7,7 +7,7 @@ LL | fn load(ss: &mut SomeStruct) -> Box {
LL | ss.r
| ^^^^ ...is captured and required to be `'static` here
|
-help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1
|
LL | fn load(ss: &mut SomeStruct) -> Box {
| ^^^^
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
index bf02ba8eb919..7e8f78067e08 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
@@ -1,21 +1,21 @@
-error[E0621]: explicit lifetime required in the type of `v`
+error: lifetime may not live long enough
--> $DIR/region-object-lifetime-in-coercion.rs:8:12
|
LL | fn a(v: &[u8]) -> Box {
- | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
+ | - let's call the lifetime of this reference `'1`
LL | let x: Box = Box::new(v);
- | ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
+ | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
-error[E0621]: explicit lifetime required in the type of `v`
- --> $DIR/region-object-lifetime-in-coercion.rs:14:5
+error: lifetime may not live long enough
+ --> $DIR/region-object-lifetime-in-coercion.rs:13:5
|
LL | fn b(v: &[u8]) -> Box {
- | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
+ | - let's call the lifetime of this reference `'1`
LL | Box::new(v)
- | ^^^^^^^^^^^ lifetime `'static` required
+ | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
error: lifetime may not live long enough
- --> $DIR/region-object-lifetime-in-coercion.rs:20:5
+ --> $DIR/region-object-lifetime-in-coercion.rs:19:5
|
LL | fn c(v: &[u8]) -> Box {
| - let's call the lifetime of this reference `'1`
@@ -24,7 +24,7 @@ LL | Box::new(v)
| ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
error: lifetime may not live long enough
- --> $DIR/region-object-lifetime-in-coercion.rs:24:5
+ --> $DIR/region-object-lifetime-in-coercion.rs:23:5
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box {
| -- -- lifetime `'b` defined here
@@ -37,4 +37,3 @@ LL | Box::new(v)
error: aborting due to 4 previous errors
-For more information about this error, try `rustc --explain E0621`.
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.rs b/src/test/ui/regions/region-object-lifetime-in-coercion.rs
index d56eaf77b664..5d199149c39b 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.rs
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.rs
@@ -5,13 +5,12 @@ trait Foo {}
impl<'a> Foo for &'a [u8] {}
fn a(v: &[u8]) -> Box {
- let x: Box = Box::new(v);
- //~^ ERROR explicit lifetime required in the type of `v` [E0621]
+ let x: Box = Box::new(v); //~ ERROR cannot infer an appropriate lifetime
x
}
fn b(v: &[u8]) -> Box {
- Box::new(v) //~ ERROR explicit lifetime required in the type of `v` [E0621]
+ Box::new(v) //~ ERROR cannot infer an appropriate lifetime
}
fn c(v: &[u8]) -> Box {
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
index 1462af44cb15..673300cebc26 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
@@ -1,21 +1,45 @@
-error[E0621]: explicit lifetime required in the type of `v`
- --> $DIR/region-object-lifetime-in-coercion.rs:8:37
+error: cannot infer an appropriate lifetime
+ --> $DIR/region-object-lifetime-in-coercion.rs:8:46
|
LL | fn a(v: &[u8]) -> Box {
- | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
+ | ----- data with this lifetime...
LL | let x: Box = Box::new(v);
- | ^^^^^^^^^^^ lifetime `'static` required
+ | ---------^-
+ | | |
+ | | ...and is captured here
+ | ...is required to be `'static` by this...
+ |
+help: consider changing the trait object's explicit `'static` bound
+ |
+LL | fn a(v: &[u8]) -> Box {
+ | ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
+ |
+LL | fn a(v: &'static [u8]) -> Box {
+ | ^^^^^^^^^^^^^
-error[E0621]: explicit lifetime required in the type of `v`
- --> $DIR/region-object-lifetime-in-coercion.rs:14:5
+error: cannot infer an appropriate lifetime
+ --> $DIR/region-object-lifetime-in-coercion.rs:13:14
|
LL | fn b(v: &[u8]) -> Box {
- | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
+ | ----- data with this lifetime...
LL | Box::new(v)
- | ^^^^^^^^^^^ lifetime `'static` required
+ | ---------^-
+ | | |
+ | | ...and is captured here
+ | ...is required to be `'static` by this...
+ |
+help: consider changing the trait object's explicit `'static` bound
+ |
+LL | fn b(v: &[u8]) -> Box {
+ | ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
+ |
+LL | fn b(v: &'static [u8]) -> Box {
+ | ^^^^^^^^^^^^^
error: cannot infer an appropriate lifetime
- --> $DIR/region-object-lifetime-in-coercion.rs:20:14
+ --> $DIR/region-object-lifetime-in-coercion.rs:19:14
|
LL | fn c(v: &[u8]) -> Box {
| ----- data with this lifetime...
@@ -26,36 +50,36 @@ LL | Box::new(v)
| | ...and is captured here
| ...is required to be `'static` by this...
|
-help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 17:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 16:1
|
LL | fn c(v: &[u8]) -> Box {
| ^^^^
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
- --> $DIR/region-object-lifetime-in-coercion.rs:24:14
+ --> $DIR/region-object-lifetime-in-coercion.rs:23:14
|
LL | Box::new(v)
| ^
|
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 23:6...
- --> $DIR/region-object-lifetime-in-coercion.rs:23:6
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 22:6...
+ --> $DIR/region-object-lifetime-in-coercion.rs:22:6
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box {
| ^^
note: ...so that the expression is assignable
- --> $DIR/region-object-lifetime-in-coercion.rs:24:14
+ --> $DIR/region-object-lifetime-in-coercion.rs:23:14
|
LL | Box::new(v)
| ^
= note: expected `&[u8]`
found `&'a [u8]`
-note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 23:9...
- --> $DIR/region-object-lifetime-in-coercion.rs:23:9
+note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 22:9...
+ --> $DIR/region-object-lifetime-in-coercion.rs:22:9
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box {
| ^^
note: ...so that the expression is assignable
- --> $DIR/region-object-lifetime-in-coercion.rs:24:5
+ --> $DIR/region-object-lifetime-in-coercion.rs:23:5
|
LL | Box::new(v)
| ^^^^^^^^^^^
@@ -64,5 +88,4 @@ LL | Box::new(v)
error: aborting due to 4 previous errors
-Some errors have detailed explanations: E0495, E0621.
-For more information about an error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr
index 147f7f354181..982ed07232a8 100644
--- a/src/test/ui/regions/regions-close-object-into-object-2.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr
@@ -1,28 +1,22 @@
-error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
+error: cannot infer an appropriate lifetime
--> $DIR/regions-close-object-into-object-2.rs:10:11
|
+LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box {
+ | ------------------ data with this lifetime...
LL | box B(&*v) as Box
- | ^^^
- |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6...
- --> $DIR/regions-close-object-into-object-2.rs:9:6
+ | ------^^^---------------
+ | | |
+ | | ...and is captured here
+ | ...is required to be `'static` by this...
|
-LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box {
- | ^^
-note: ...so that the type `(dyn A + 'a)` is not borrowed for too long
- --> $DIR/regions-close-object-into-object-2.rs:10:11
+help: consider changing the trait object's explicit `'static` bound
|
-LL | box B(&*v) as Box
- | ^^^
- = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that the expression is assignable
- --> $DIR/regions-close-object-into-object-2.rs:10:5
+LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box {
+ | ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
|
-LL | box B(&*v) as Box
- | ^^^^^^^^^^^^^^^^^^^^^^^^
- = note: expected `std::boxed::Box<(dyn X + 'static)>`
- found `std::boxed::Box`
+LL | fn g<'a, T: 'static>(v: std::boxed::Box<(dyn A + 'static)>) -> Box {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr
index 6e7d6152cd09..1b82098ee13c 100644
--- a/src/test/ui/regions/regions-close-object-into-object-4.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr
@@ -1,28 +1,22 @@
-error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
+error: cannot infer an appropriate lifetime
--> $DIR/regions-close-object-into-object-4.rs:10:11
|
+LL | fn i<'a, T, U>(v: Box+'a>) -> Box {
+ | ---------------- data with this lifetime...
LL | box B(&*v) as Box
- | ^^^
- |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6...
- --> $DIR/regions-close-object-into-object-4.rs:9:6
+ | ------^^^---------------
+ | | |
+ | | ...and is captured here
+ | ...is required to be `'static` by this...
|
-LL | fn i<'a, T, U>(v: Box+'a>) -> Box {
- | ^^
-note: ...so that the type `(dyn A + 'a)` is not borrowed for too long
- --> $DIR/regions-close-object-into-object-4.rs:10:11
+help: consider changing the trait object's explicit `'static` bound
|
-LL | box B(&*v) as Box
- | ^^^
- = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that the expression is assignable
- --> $DIR/regions-close-object-into-object-4.rs:10:5
+LL | fn i<'a, T, U>(v: Box+'a>) -> Box {
+ | ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
|
-LL | box B(&*v) as Box
- | ^^^^^^^^^^^^^^^^^^^^^^^^
- = note: expected `std::boxed::Box<(dyn X + 'static)>`
- found `std::boxed::Box`
+LL | fn i<'a, T, U>(v: std::boxed::Box<(dyn A + 'static)>) -> Box {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-proc-bound-capture.nll.stderr b/src/test/ui/regions/regions-proc-bound-capture.nll.stderr
new file mode 100644
index 000000000000..75890b858153
--- /dev/null
+++ b/src/test/ui/regions/regions-proc-bound-capture.nll.stderr
@@ -0,0 +1,11 @@
+error: lifetime may not live long enough
+ --> $DIR/regions-proc-bound-capture.rs:9:5
+ |
+LL | fn static_proc(x: &isize) -> Box (isize) + 'static> {
+ | - let's call the lifetime of this reference `'1`
+LL | // This is illegal, because the region bound on `proc` is 'static.
+LL | Box::new(move || { *x })
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/regions/regions-proc-bound-capture.rs b/src/test/ui/regions/regions-proc-bound-capture.rs
index 0c903b738499..8617c0e9da8f 100644
--- a/src/test/ui/regions/regions-proc-bound-capture.rs
+++ b/src/test/ui/regions/regions-proc-bound-capture.rs
@@ -4,9 +4,9 @@ fn borrowed_proc<'a>(x: &'a isize) -> Box(isize) + 'a> {
Box::new(move|| { *x })
}
-fn static_proc(x: &isize) -> Box(isize) + 'static> {
+fn static_proc(x: &isize) -> Box (isize) + 'static> {
// This is illegal, because the region bound on `proc` is 'static.
- Box::new(move|| { *x }) //~ ERROR explicit lifetime required in the type of `x` [E0621]
+ Box::new(move || { *x }) //~ ERROR cannot infer an appropriate lifetime
}
fn main() { }
diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr
index c53af34456ef..e7bbfaababe8 100644
--- a/src/test/ui/regions/regions-proc-bound-capture.stderr
+++ b/src/test/ui/regions/regions-proc-bound-capture.stderr
@@ -1,12 +1,23 @@
-error[E0621]: explicit lifetime required in the type of `x`
- --> $DIR/regions-proc-bound-capture.rs:9:5
+error: cannot infer an appropriate lifetime
+ --> $DIR/regions-proc-bound-capture.rs:9:14
|
-LL | fn static_proc(x: &isize) -> Box(isize) + 'static> {
- | ------ help: add explicit lifetime `'static` to the type of `x`: `&'static isize`
+LL | fn static_proc(x: &isize) -> Box (isize) + 'static> {
+ | ------ data with this lifetime...
LL | // This is illegal, because the region bound on `proc` is 'static.
-LL | Box::new(move|| { *x })
- | ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
+LL | Box::new(move || { *x })
+ | ---------^^^^^^^^^^^^^^-
+ | | |
+ | | ...and is captured here
+ | ...is required to be `'static` by this...
+ |
+help: consider changing the trait object's explicit `'static` bound
+ |
+LL | fn static_proc(x: &isize) -> Box (isize) + '_> {
+ | ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
+ |
+LL | fn static_proc(x: &'static isize) -> Box (isize) + 'static> {
+ | ^^^^^^^^^^^^^^
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0621`.
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
index 3577dd59289e..4dc4aac6ceac 100644
--- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
@@ -7,7 +7,7 @@ LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to
LL | Box::new(items.iter())
| ---------------^^^^--- ...is captured and required to be `'static` here
|
-help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1
|
LL | fn a(items: &[T]) -> Box + '_> {
| ^^^^
From 921f35fe73e8749dee8531f7fbaf2cb4958fa799 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?=
Date: Fri, 29 May 2020 18:59:42 -0700
Subject: [PATCH 15/40] Reduce verbosity of suggestion message and mention
lifetime in label
---
.../nice_region_error/static_impl_trait.rs | 87 ++++++++++---------
.../ui/async-await/issues/issue-62097.stderr | 2 +-
.../must_outlive_least_region_or_bound.stderr | 38 ++++----
.../static-return-lifetime-infered.stderr | 8 +-
src/test/ui/issues/issue-16922.stderr | 4 +-
...ect-lifetime-default-from-box-error.stderr | 4 +-
.../region-object-lifetime-in-coercion.stderr | 12 +--
.../regions-close-object-into-object-2.stderr | 4 +-
.../regions-close-object-into-object-4.stderr | 4 +-
.../regions/regions-proc-bound-capture.stderr | 4 +-
...types_pin_lifetime_impl_trait-async.stderr | 2 +-
..._self_types_pin_lifetime_impl_trait.stderr | 4 +-
.../missing-lifetimes-in-signature.stderr | 4 +-
.../dyn-trait-underscore.stderr | 4 +-
14 files changed, 95 insertions(+), 86 deletions(-)
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
index e24535bba5fd..e9f165d309f8 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -1,6 +1,5 @@
//! Error Reporting for static impl Traits.
-use crate::infer::error_reporting::msg_span_from_free_region;
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use rustc_errors::{Applicability, ErrorReported};
@@ -33,9 +32,17 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let sp = var_origin.span();
let return_sp = sub_origin.span();
let param_info = self.find_param_with_region(sup_r, sub_r)?;
+ let (lifetime_name, lifetime) = if sup_r.has_name() {
+ (sup_r.to_string(), format!("lifetime `{}`", sup_r))
+ } else {
+ ("'_".to_owned(), "the anonymous lifetime `'_`".to_string())
+ };
let mut err =
self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime");
- err.span_label(param_info.param_ty_span, "data with this lifetime...");
+ err.span_label(
+ param_info.param_ty_span,
+ &format!("this data with {}...", lifetime),
+ );
debug!("try_report_static_impl_trait: param_info={:?}", param_info);
// We try to make the output have fewer overlapping spans if possible.
@@ -60,10 +67,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
);
}
- let (lifetime, _) = msg_span_from_free_region(self.tcx(), sup_r);
-
- let lifetime_name =
- if sup_r.has_name() { sup_r.to_string() } else { "'_".to_owned() };
// only apply this suggestion onto functions with
// explicit non-desugar'able return.
if fn_return.span.desugaring_kind().is_none() {
@@ -93,8 +96,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
{
err.span_suggestion_verbose(
span,
- "consider changing the `impl Trait`'s explicit \
- `'static` bound",
+ &format!(
+ "consider changing the `impl Trait`'s explicit \
+ `'static` bound to {}",
+ lifetime,
+ ),
lifetime_name,
Applicability::MaybeIncorrect,
);
@@ -118,40 +124,41 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
);
};
}
- TyKind::TraitObject(_, lt) => {
- match lt.name {
- LifetimeName::ImplicitObjectLifetimeDefault => {
- err.span_suggestion_verbose(
- fn_return.span.shrink_to_hi(),
- &format!(
- "to permit non-static references in a trait object \
- value, you can add an explicit bound for {}",
- lifetime,
- ),
- format!(" + {}", lifetime_name),
- Applicability::MaybeIncorrect,
- );
- }
- _ => {
- err.span_suggestion_verbose(
- lt.span,
+ TyKind::TraitObject(_, lt) => match lt.name {
+ LifetimeName::ImplicitObjectLifetimeDefault => {
+ err.span_suggestion_verbose(
+ fn_return.span.shrink_to_hi(),
+ &format!(
+ "to permit non-static references in a trait object \
+ value, you can add an explicit bound for {}",
+ lifetime,
+ ),
+ format!(" + {}", lifetime_name),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ _ => {
+ err.span_suggestion_verbose(
+ lt.span,
+ &format!(
"consider changing the trait object's explicit \
- `'static` bound",
- lifetime_name,
- Applicability::MaybeIncorrect,
- );
- err.span_suggestion_verbose(
- param_info.param_ty_span,
- &format!(
- "alternatively, set an explicit `'static` lifetime \
- in this parameter",
- ),
- param_info.param_ty.to_string(),
- Applicability::MaybeIncorrect,
- );
- }
+ `'static` bound to {}",
+ lifetime,
+ ),
+ lifetime_name,
+ Applicability::MaybeIncorrect,
+ );
+ err.span_suggestion_verbose(
+ param_info.param_ty_span,
+ &format!(
+ "alternatively, set an explicit `'static` lifetime \
+ in this parameter",
+ ),
+ param_info.param_ty.to_string(),
+ Applicability::MaybeIncorrect,
+ );
}
- }
+ },
_ => {}
}
}
diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr
index af8fc2cd2ab4..fff43ae9f47b 100644
--- a/src/test/ui/async-await/issues/issue-62097.stderr
+++ b/src/test/ui/async-await/issues/issue-62097.stderr
@@ -4,7 +4,7 @@ error: cannot infer an appropriate lifetime
LL | pub async fn run_dummy_fn(&self) {
| ^^^^^
| |
- | data with this lifetime...
+ | this data with the anonymous lifetime `'_`...
| ...is captured here...
LL | foo(|| self.bar()).await;
| --- ...and required to be `'static` by this
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
index 96d4a121c16a..00b6ec38323c 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
@@ -5,9 +5,9 @@ LL | fn elided(x: &i32) -> impl Copy { x }
| ---- --------- ^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
- | data with this lifetime...
+ | this data with the anonymous lifetime `'_`...
|
-help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn elided(x: &i32) -> impl Copy + '_ { x }
| ^^^^
@@ -19,9 +19,9 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
| ------- --------- ^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
- | data with this lifetime...
+ | this data with lifetime `'a`...
|
-help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 6:13
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for lifetime `'a`
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
| ^^^^
@@ -33,9 +33,9 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
| ---- ------------------- ^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
- | data with this lifetime...
+ | this data with the anonymous lifetime `'_`...
|
-help: consider changing the `impl Trait`'s explicit `'static` bound
+help: consider changing the `impl Trait`'s explicit `'static` bound to the anonymous lifetime `'_`
|
LL | fn elided2(x: &i32) -> impl Copy + '_ { x }
| ^^
@@ -51,9 +51,9 @@ LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
| ------- ------------------- ^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
- | data with this lifetime...
+ | this data with lifetime `'a`...
|
-help: consider changing the `impl Trait`'s explicit `'static` bound
+help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a`
|
LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x }
| ^^
@@ -77,9 +77,9 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| ------- -------------------------------- ^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
- | data with this lifetime...
+ | this data with lifetime `'a`...
|
-help: consider changing the `impl Trait`'s explicit `'static` bound
+help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a`
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x }
| ^^
@@ -113,9 +113,9 @@ LL | fn elided3(x: &i32) -> Box { Box::new(x) }
| | | |
| | | ...and is captured here
| | ...is required to be `'static` by this...
- | data with this lifetime...
+ | this data with the anonymous lifetime `'_`...
|
-help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn elided3(x: &i32) -> Box { Box::new(x) }
| ^^^^
@@ -128,9 +128,9 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
| | | |
| | | ...and is captured here
| | ...is required to be `'static` by this...
- | data with this lifetime...
+ | this data with lifetime `'a`...
|
-help: to permit non-static references in a trait object value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14
+help: to permit non-static references in a trait object value, you can add an explicit bound for lifetime `'a`
|
LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
| ^^^^
@@ -142,9 +142,10 @@ LL | fn elided4(x: &i32) -> Box { Box::new(x) }
| ---- ---------^-
| | | |
| | | ...and is captured here
- | data with this lifetime... ...is required to be `'static` by this...
+ | | ...is required to be `'static` by this...
+ | this data with the anonymous lifetime `'_`...
|
-help: consider changing the trait object's explicit `'static` bound
+help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_`
|
LL | fn elided4(x: &i32) -> Box { Box::new(x) }
| ^^
@@ -160,9 +161,10 @@ LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
| ------- ---------^-
| | | |
| | | ...and is captured here
- | data with this lifetime... ...is required to be `'static` by this...
+ | | ...is required to be `'static` by this...
+ | this data with lifetime `'a`...
|
-help: consider changing the trait object's explicit `'static` bound
+help: consider changing the trait object's explicit `'static` bound to lifetime `'a`
|
LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
| ^^
diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr
index 1c3a5979ee55..67d4f60dff6f 100644
--- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr
+++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr
@@ -4,13 +4,13 @@ error: cannot infer an appropriate lifetime
LL | fn iter_values_anon(&self) -> impl Iterator- {
| ----- ----------------------- ...is required to be `'static` by this...
| |
- | data with this lifetime...
+ | this data with the anonymous lifetime `'_`...
LL | self.x.iter().map(|a| a.0)
| ------ ^^^^
| |
| ...and is captured here
|
-help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the method body at 6:5
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn iter_values_anon(&self) -> impl Iterator
- + '_ {
| ^^^^
@@ -21,13 +21,13 @@ error: cannot infer an appropriate lifetime
LL | fn iter_values<'a>(&'a self) -> impl Iterator
- {
| -------- ----------------------- ...is required to be `'static` by this...
| |
- | data with this lifetime...
+ | this data with lifetime `'a`...
LL | self.x.iter().map(|a| a.0)
| ------ ^^^^
| |
| ...and is captured here
|
-help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the method body at 10:20
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for lifetime `'a`
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator
- + 'a {
| ^^^^
diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr
index 038df47e1bd9..c533a72dfc01 100644
--- a/src/test/ui/issues/issue-16922.stderr
+++ b/src/test/ui/issues/issue-16922.stderr
@@ -2,14 +2,14 @@ error: cannot infer an appropriate lifetime
--> $DIR/issue-16922.rs:4:14
|
LL | fn foo(value: &T) -> Box {
- | -- data with this lifetime...
+ | -- this data with the anonymous lifetime `'_`...
LL | Box::new(value) as Box
| ---------^^^^^-
| | |
| | ...and is captured here
| ...is required to be `'static` by this...
|
-help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn foo(value: &T) -> Box {
| ^^^^
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
index 555622c9d13c..6edef8086b93 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
@@ -2,12 +2,12 @@ error: cannot infer an appropriate lifetime
--> $DIR/object-lifetime-default-from-box-error.rs:18:5
|
LL | fn load(ss: &mut SomeStruct) -> Box {
- | --------------- data with this lifetime...
+ | --------------- this data with the anonymous lifetime `'_`...
...
LL | ss.r
| ^^^^ ...is captured and required to be `'static` here
|
-help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn load(ss: &mut SomeStruct) -> Box {
| ^^^^
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
index 673300cebc26..4b08c4bff2eb 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
@@ -2,14 +2,14 @@ error: cannot infer an appropriate lifetime
--> $DIR/region-object-lifetime-in-coercion.rs:8:46
|
LL | fn a(v: &[u8]) -> Box {
- | ----- data with this lifetime...
+ | ----- this data with the anonymous lifetime `'_`...
LL | let x: Box = Box::new(v);
| ---------^-
| | |
| | ...and is captured here
| ...is required to be `'static` by this...
|
-help: consider changing the trait object's explicit `'static` bound
+help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_`
|
LL | fn a(v: &[u8]) -> Box {
| ^^
@@ -22,14 +22,14 @@ error: cannot infer an appropriate lifetime
--> $DIR/region-object-lifetime-in-coercion.rs:13:14
|
LL | fn b(v: &[u8]) -> Box {
- | ----- data with this lifetime...
+ | ----- this data with the anonymous lifetime `'_`...
LL | Box::new(v)
| ---------^-
| | |
| | ...and is captured here
| ...is required to be `'static` by this...
|
-help: consider changing the trait object's explicit `'static` bound
+help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_`
|
LL | fn b(v: &[u8]) -> Box {
| ^^
@@ -42,7 +42,7 @@ error: cannot infer an appropriate lifetime
--> $DIR/region-object-lifetime-in-coercion.rs:19:14
|
LL | fn c(v: &[u8]) -> Box {
- | ----- data with this lifetime...
+ | ----- this data with the anonymous lifetime `'_`...
...
LL | Box::new(v)
| ---------^-
@@ -50,7 +50,7 @@ LL | Box::new(v)
| | ...and is captured here
| ...is required to be `'static` by this...
|
-help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 16:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn c(v: &[u8]) -> Box {
| ^^^^
diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr
index 982ed07232a8..894be310fd14 100644
--- a/src/test/ui/regions/regions-close-object-into-object-2.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr
@@ -2,14 +2,14 @@ error: cannot infer an appropriate lifetime
--> $DIR/regions-close-object-into-object-2.rs:10:11
|
LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box {
- | ------------------ data with this lifetime...
+ | ------------------ this data with lifetime `'a`...
LL | box B(&*v) as Box
| ------^^^---------------
| | |
| | ...and is captured here
| ...is required to be `'static` by this...
|
-help: consider changing the trait object's explicit `'static` bound
+help: consider changing the trait object's explicit `'static` bound to lifetime `'a`
|
LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box {
| ^^
diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr
index 1b82098ee13c..ce261d78c290 100644
--- a/src/test/ui/regions/regions-close-object-into-object-4.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr
@@ -2,14 +2,14 @@ error: cannot infer an appropriate lifetime
--> $DIR/regions-close-object-into-object-4.rs:10:11
|
LL | fn i<'a, T, U>(v: Box+'a>) -> Box {
- | ---------------- data with this lifetime...
+ | ---------------- this data with lifetime `'a`...
LL | box B(&*v) as Box
| ------^^^---------------
| | |
| | ...and is captured here
| ...is required to be `'static` by this...
|
-help: consider changing the trait object's explicit `'static` bound
+help: consider changing the trait object's explicit `'static` bound to lifetime `'a`
|
LL | fn i<'a, T, U>(v: Box+'a>) -> Box {
| ^^
diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr
index e7bbfaababe8..a0df1815247c 100644
--- a/src/test/ui/regions/regions-proc-bound-capture.stderr
+++ b/src/test/ui/regions/regions-proc-bound-capture.stderr
@@ -2,7 +2,7 @@ error: cannot infer an appropriate lifetime
--> $DIR/regions-proc-bound-capture.rs:9:14
|
LL | fn static_proc(x: &isize) -> Box (isize) + 'static> {
- | ------ data with this lifetime...
+ | ------ this data with the anonymous lifetime `'_`...
LL | // This is illegal, because the region bound on `proc` is 'static.
LL | Box::new(move || { *x })
| ---------^^^^^^^^^^^^^^-
@@ -10,7 +10,7 @@ LL | Box::new(move || { *x })
| | ...and is captured here
| ...is required to be `'static` by this...
|
-help: consider changing the trait object's explicit `'static` bound
+help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_`
|
LL | fn static_proc(x: &isize) -> Box (isize) + '_> {
| ^^
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
index 1aeabce5e8aa..5520341b5b1c 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
@@ -4,7 +4,7 @@ error: cannot infer an appropriate lifetime
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
| ^^^^ ---------- ---------- ...and required to be `'static` by this
| | |
- | | data with this lifetime...
+ | | this data with the anonymous lifetime `'_`...
| ...is captured here...
error: aborting due to previous error
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr
index 04c475be787b..5374929f3a45 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr
@@ -5,9 +5,9 @@ LL | fn f(self: Pin<&Self>) -> impl Clone { self }
| ---------- ---------- ^^^^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
- | data with this lifetime...
+ | this data with the anonymous lifetime `'_`...
|
-help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the method body at 6:5
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
| ^^^^
diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
index 5cf170d566ca..471f3cd14aa3 100644
--- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
+++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
@@ -12,14 +12,14 @@ error: cannot infer an appropriate lifetime
LL | fn foo(g: G, dest: &mut T) -> impl FnOnce()
| ------ ------------- ...is required to be `'static` by this...
| |
- | data with this lifetime...
+ | this data with the anonymous lifetime `'_`...
...
LL | / move || {
LL | | *dest = g.get();
LL | | }
| |_____^ ...and is captured here
|
-help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 15:1
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() + '_
| ^^^^
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
index 4dc4aac6ceac..5fd03f9770e5 100644
--- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
@@ -2,12 +2,12 @@ error: cannot infer an appropriate lifetime
--> $DIR/dyn-trait-underscore.rs:8:20
|
LL | fn a(items: &[T]) -> Box> {
- | ---- data with this lifetime...
+ | ---- this data with the anonymous lifetime `'_`...
LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
LL | Box::new(items.iter())
| ---------------^^^^--- ...is captured and required to be `'static` here
|
-help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn a(items: &[T]) -> Box + '_> {
| ^^^^
From e75588934c01d6bc9abb02979eb61168a7b5c598 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?=
Date: Fri, 29 May 2020 19:46:22 -0700
Subject: [PATCH 16/40] Move overlapping span to a note
---
.../nice_region_error/static_impl_trait.rs | 31 ++++++++++++-
.../must_outlive_least_region_or_bound.stderr | 44 ++++++++++++-------
src/test/ui/issues/issue-16922.stderr | 10 +++--
.../region-object-lifetime-in-coercion.stderr | 30 ++++++++-----
.../regions-close-object-into-object-2.stderr | 10 +++--
.../regions-close-object-into-object-4.stderr | 10 +++--
.../regions/regions-proc-bound-capture.stderr | 10 +++--
7 files changed, 99 insertions(+), 46 deletions(-)
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
index e9f165d309f8..cc95441b68a0 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -53,7 +53,36 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
// Customize the spans and labels depending on their relative order so
// that split sentences flow correctly.
- if sup_origin.span().shrink_to_hi() <= return_sp.shrink_to_lo() {
+ if sup_origin.span().overlaps(return_sp) && sp == sup_origin.span() {
+ // Avoid the following:
+ //
+ // error: cannot infer an appropriate lifetime
+ // --> $DIR/must_outlive_least_region_or_bound.rs:18:50
+ // |
+ // LL | fn foo(x: &i32) -> Box { Box::new(x) }
+ // | ---- ---------^-
+ // | | | |
+ // | | | ...and is captured here
+ // | | ...is required to be `'static` by this...
+ // | this data with the anonymous lifetime `'_`...
+ //
+ // and instead show:
+ //
+ // error: cannot infer an appropriate lifetime
+ // --> $DIR/must_outlive_least_region_or_bound.rs:18:50
+ // |
+ // LL | fn foo(x: &i32) -> Box { Box::new(x) }
+ // | ---- ^ ...is captured here with a `'static` requirement
+ // | |
+ // | this data with the anonymous lifetime `'_`...
+ // |
+ // note: ...is required to be `'static` by this
+ // |
+ // LL | fn elided3(x: &i32) -> Box { Box::new(x) }
+ // | ^^^^^^^^^^^
+ err.span_label(sup_origin.span(), "...is captured here...");
+ err.span_note(return_sp, "...and required to be `'static` by this");
+ } else if sup_origin.span() <= return_sp {
err.span_label(sup_origin.span(), "...is captured here...");
err.span_label(return_sp, "...and required to be `'static` by this");
} else {
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
index 00b6ec38323c..2da49379ea8c 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
@@ -109,12 +109,15 @@ error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:18:50
|
LL | fn elided3(x: &i32) -> Box { Box::new(x) }
- | ---- ---------^-
- | | | |
- | | | ...and is captured here
- | | ...is required to be `'static` by this...
+ | ---- ^ ...is captured here...
+ | |
| this data with the anonymous lifetime `'_`...
|
+note: ...and required to be `'static` by this
+ --> $DIR/must_outlive_least_region_or_bound.rs:18:41
+ |
+LL | fn elided3(x: &i32) -> Box { Box::new(x) }
+ | ^^^^^^^^^^^
help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn elided3(x: &i32) -> Box { Box::new(x) }
@@ -124,12 +127,15 @@ error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:21:59
|
LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
- | ------- ---------^-
- | | | |
- | | | ...and is captured here
- | | ...is required to be `'static` by this...
+ | ------- ^ ...is captured here...
+ | |
| this data with lifetime `'a`...
|
+note: ...and required to be `'static` by this
+ --> $DIR/must_outlive_least_region_or_bound.rs:21:50
+ |
+LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
+ | ^^^^^^^^^^^
help: to permit non-static references in a trait object value, you can add an explicit bound for lifetime `'a`
|
LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
@@ -139,12 +145,15 @@ error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:24:60
|
LL | fn elided4(x: &i32) -> Box { Box::new(x) }
- | ---- ---------^-
- | | | |
- | | | ...and is captured here
- | | ...is required to be `'static` by this...
+ | ---- ^ ...is captured here...
+ | |
| this data with the anonymous lifetime `'_`...
|
+note: ...and required to be `'static` by this
+ --> $DIR/must_outlive_least_region_or_bound.rs:24:51
+ |
+LL | fn elided4(x: &i32) -> Box { Box::new(x) }
+ | ^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_`
|
LL | fn elided4(x: &i32) -> Box { Box::new(x) }
@@ -158,12 +167,13 @@ error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:27:69
|
LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
- | ------- ---------^-
- | | | |
- | | | ...and is captured here
- | | ...is required to be `'static` by this...
- | this data with lifetime `'a`...
+ | ------- this data with lifetime `'a`... ^ ...is captured here...
|
+note: ...and required to be `'static` by this
+ --> $DIR/must_outlive_least_region_or_bound.rs:27:60
+ |
+LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
+ | ^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to lifetime `'a`
|
LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr
index c533a72dfc01..6c0b26a86b65 100644
--- a/src/test/ui/issues/issue-16922.stderr
+++ b/src/test/ui/issues/issue-16922.stderr
@@ -4,11 +4,13 @@ error: cannot infer an appropriate lifetime
LL | fn foo(value: &T) -> Box {
| -- this data with the anonymous lifetime `'_`...
LL | Box::new(value) as Box
- | ---------^^^^^-
- | | |
- | | ...and is captured here
- | ...is required to be `'static` by this...
+ | ^^^^^ ...is captured here...
|
+note: ...and required to be `'static` by this
+ --> $DIR/issue-16922.rs:4:5
+ |
+LL | Box::new(value) as Box
+ | ^^^^^^^^^^^^^^^
help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn foo(value: &T) -> Box {
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
index 4b08c4bff2eb..b333c314c57c 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
@@ -4,11 +4,13 @@ error: cannot infer an appropriate lifetime
LL | fn a(v: &[u8]) -> Box {
| ----- this data with the anonymous lifetime `'_`...
LL | let x: Box = Box::new(v);
- | ---------^-
- | | |
- | | ...and is captured here
- | ...is required to be `'static` by this...
+ | ^ ...is captured here...
|
+note: ...and required to be `'static` by this
+ --> $DIR/region-object-lifetime-in-coercion.rs:8:37
+ |
+LL | let x: Box = Box::new(v);
+ | ^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_`
|
LL | fn a(v: &[u8]) -> Box {
@@ -24,11 +26,13 @@ error: cannot infer an appropriate lifetime
LL | fn b(v: &[u8]) -> Box {
| ----- this data with the anonymous lifetime `'_`...
LL | Box::new(v)
- | ---------^-
- | | |
- | | ...and is captured here
- | ...is required to be `'static` by this...
+ | ^ ...is captured here...
|
+note: ...and required to be `'static` by this
+ --> $DIR/region-object-lifetime-in-coercion.rs:13:5
+ |
+LL | Box::new(v)
+ | ^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_`
|
LL | fn b(v: &[u8]) -> Box {
@@ -45,11 +49,13 @@ LL | fn c(v: &[u8]) -> Box {
| ----- this data with the anonymous lifetime `'_`...
...
LL | Box::new(v)
- | ---------^-
- | | |
- | | ...and is captured here
- | ...is required to be `'static` by this...
+ | ^ ...is captured here...
+ |
+note: ...and required to be `'static` by this
+ --> $DIR/region-object-lifetime-in-coercion.rs:19:5
|
+LL | Box::new(v)
+ | ^^^^^^^^^^^
help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn c(v: &[u8]) -> Box {
diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr
index 894be310fd14..3127ae65ace7 100644
--- a/src/test/ui/regions/regions-close-object-into-object-2.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr
@@ -4,11 +4,13 @@ error: cannot infer an appropriate lifetime
LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box {
| ------------------ this data with lifetime `'a`...
LL | box B(&*v) as Box
- | ------^^^---------------
- | | |
- | | ...and is captured here
- | ...is required to be `'static` by this...
+ | ^^^ ...is captured here...
|
+note: ...and required to be `'static` by this
+ --> $DIR/regions-close-object-into-object-2.rs:10:5
+ |
+LL | box B(&*v) as Box
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to lifetime `'a`
|
LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box {
diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr
index ce261d78c290..b18c61f13769 100644
--- a/src/test/ui/regions/regions-close-object-into-object-4.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr
@@ -4,11 +4,13 @@ error: cannot infer an appropriate lifetime
LL | fn i<'a, T, U>(v: Box+'a>) -> Box {
| ---------------- this data with lifetime `'a`...
LL | box B(&*v) as Box
- | ------^^^---------------
- | | |
- | | ...and is captured here
- | ...is required to be `'static` by this...
+ | ^^^ ...is captured here...
|
+note: ...and required to be `'static` by this
+ --> $DIR/regions-close-object-into-object-4.rs:10:5
+ |
+LL | box B(&*v) as Box
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to lifetime `'a`
|
LL | fn i<'a, T, U>(v: Box+'a>) -> Box {
diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr
index a0df1815247c..5cb9506afd35 100644
--- a/src/test/ui/regions/regions-proc-bound-capture.stderr
+++ b/src/test/ui/regions/regions-proc-bound-capture.stderr
@@ -5,11 +5,13 @@ LL | fn static_proc(x: &isize) -> Box (isize) + 'static> {
| ------ this data with the anonymous lifetime `'_`...
LL | // This is illegal, because the region bound on `proc` is 'static.
LL | Box::new(move || { *x })
- | ---------^^^^^^^^^^^^^^-
- | | |
- | | ...and is captured here
- | ...is required to be `'static` by this...
+ | ^^^^^^^^^^^^^^ ...is captured here...
|
+note: ...and required to be `'static` by this
+ --> $DIR/regions-proc-bound-capture.rs:9:5
+ |
+LL | Box::new(move || { *x })
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_`
|
LL | fn static_proc(x: &isize) -> Box (isize) + '_> {
From bc1579060981b5e95a18409e876c92bf0c9307e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?=
Date: Sat, 30 May 2020 09:54:05 -0700
Subject: [PATCH 17/40] Tweak output for overlapping required/captured spans
---
.../nice_region_error/static_impl_trait.rs | 10 +++----
.../must_outlive_least_region_or_bound.stderr | 28 +++----------------
src/test/ui/issues/issue-16922.stderr | 7 +----
.../region-object-lifetime-in-coercion.stderr | 21 ++------------
.../regions-close-object-into-object-2.stderr | 7 +----
.../regions-close-object-into-object-4.stderr | 7 +----
.../regions/regions-proc-bound-capture.stderr | 7 +----
7 files changed, 15 insertions(+), 72 deletions(-)
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
index cc95441b68a0..253057536f13 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -76,12 +76,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
// | |
// | this data with the anonymous lifetime `'_`...
// |
- // note: ...is required to be `'static` by this
- // |
- // LL | fn elided3(x: &i32) -> Box { Box::new(x) }
- // | ^^^^^^^^^^^
- err.span_label(sup_origin.span(), "...is captured here...");
- err.span_note(return_sp, "...and required to be `'static` by this");
+ err.span_label(
+ sup_origin.span(),
+ "...is captured here with a `'static` requirement",
+ );
} else if sup_origin.span() <= return_sp {
err.span_label(sup_origin.span(), "...is captured here...");
err.span_label(return_sp, "...and required to be `'static` by this");
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
index 2da49379ea8c..82e44cff9cc4 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
@@ -109,15 +109,10 @@ error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:18:50
|
LL | fn elided3(x: &i32) -> Box { Box::new(x) }
- | ---- ^ ...is captured here...
+ | ---- ^ ...is captured here with a `'static` requirement
| |
| this data with the anonymous lifetime `'_`...
|
-note: ...and required to be `'static` by this
- --> $DIR/must_outlive_least_region_or_bound.rs:18:41
- |
-LL | fn elided3(x: &i32) -> Box { Box::new(x) }
- | ^^^^^^^^^^^
help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn elided3(x: &i32) -> Box { Box::new(x) }
@@ -127,15 +122,10 @@ error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:21:59
|
LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
- | ------- ^ ...is captured here...
+ | ------- ^ ...is captured here with a `'static` requirement
| |
| this data with lifetime `'a`...
|
-note: ...and required to be `'static` by this
- --> $DIR/must_outlive_least_region_or_bound.rs:21:50
- |
-LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
- | ^^^^^^^^^^^
help: to permit non-static references in a trait object value, you can add an explicit bound for lifetime `'a`
|
LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) }
@@ -145,15 +135,10 @@ error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:24:60
|
LL | fn elided4(x: &i32) -> Box { Box::new(x) }
- | ---- ^ ...is captured here...
+ | ---- ^ ...is captured here with a `'static` requirement
| |
| this data with the anonymous lifetime `'_`...
|
-note: ...and required to be `'static` by this
- --> $DIR/must_outlive_least_region_or_bound.rs:24:51
- |
-LL | fn elided4(x: &i32) -> Box { Box::new(x) }
- | ^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_`
|
LL | fn elided4(x: &i32) -> Box { Box::new(x) }
@@ -167,13 +152,8 @@ error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:27:69
|
LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
- | ------- this data with lifetime `'a`... ^ ...is captured here...
+ | ------- this data with lifetime `'a`... ^ ...is captured here with a `'static` requirement
|
-note: ...and required to be `'static` by this
- --> $DIR/must_outlive_least_region_or_bound.rs:27:60
- |
-LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
- | ^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to lifetime `'a`
|
LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) }
diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr
index 6c0b26a86b65..a254343cd1bb 100644
--- a/src/test/ui/issues/issue-16922.stderr
+++ b/src/test/ui/issues/issue-16922.stderr
@@ -4,13 +4,8 @@ error: cannot infer an appropriate lifetime
LL | fn foo(value: &T) -> Box {
| -- this data with the anonymous lifetime `'_`...
LL | Box::new(value) as Box
- | ^^^^^ ...is captured here...
+ | ^^^^^ ...is captured here with a `'static` requirement
|
-note: ...and required to be `'static` by this
- --> $DIR/issue-16922.rs:4:5
- |
-LL | Box::new(value) as Box
- | ^^^^^^^^^^^^^^^
help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn foo(value: &T) -> Box {
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
index b333c314c57c..97d1f3579fcd 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
@@ -4,13 +4,8 @@ error: cannot infer an appropriate lifetime
LL | fn a(v: &[u8]) -> Box {
| ----- this data with the anonymous lifetime `'_`...
LL | let x: Box = Box::new(v);
- | ^ ...is captured here...
+ | ^ ...is captured here with a `'static` requirement
|
-note: ...and required to be `'static` by this
- --> $DIR/region-object-lifetime-in-coercion.rs:8:37
- |
-LL | let x: Box = Box::new(v);
- | ^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_`
|
LL | fn a(v: &[u8]) -> Box {
@@ -26,13 +21,8 @@ error: cannot infer an appropriate lifetime
LL | fn b(v: &[u8]) -> Box {
| ----- this data with the anonymous lifetime `'_`...
LL | Box::new(v)
- | ^ ...is captured here...
+ | ^ ...is captured here with a `'static` requirement
|
-note: ...and required to be `'static` by this
- --> $DIR/region-object-lifetime-in-coercion.rs:13:5
- |
-LL | Box::new(v)
- | ^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_`
|
LL | fn b(v: &[u8]) -> Box {
@@ -49,13 +39,8 @@ LL | fn c(v: &[u8]) -> Box {
| ----- this data with the anonymous lifetime `'_`...
...
LL | Box::new(v)
- | ^ ...is captured here...
- |
-note: ...and required to be `'static` by this
- --> $DIR/region-object-lifetime-in-coercion.rs:19:5
+ | ^ ...is captured here with a `'static` requirement
|
-LL | Box::new(v)
- | ^^^^^^^^^^^
help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_`
|
LL | fn c(v: &[u8]) -> Box {
diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr
index 3127ae65ace7..3d707f2d9994 100644
--- a/src/test/ui/regions/regions-close-object-into-object-2.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr
@@ -4,13 +4,8 @@ error: cannot infer an appropriate lifetime
LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box {
| ------------------ this data with lifetime `'a`...
LL | box B(&*v) as Box
- | ^^^ ...is captured here...
+ | ^^^ ...is captured here with a `'static` requirement
|
-note: ...and required to be `'static` by this
- --> $DIR/regions-close-object-into-object-2.rs:10:5
- |
-LL | box B(&*v) as Box
- | ^^^^^^^^^^^^^^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to lifetime `'a`
|
LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box {
diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr
index b18c61f13769..70282c8cbdb3 100644
--- a/src/test/ui/regions/regions-close-object-into-object-4.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr
@@ -4,13 +4,8 @@ error: cannot infer an appropriate lifetime
LL | fn i<'a, T, U>(v: Box+'a>) -> Box {
| ---------------- this data with lifetime `'a`...
LL | box B(&*v) as Box
- | ^^^ ...is captured here...
+ | ^^^ ...is captured here with a `'static` requirement
|
-note: ...and required to be `'static` by this
- --> $DIR/regions-close-object-into-object-4.rs:10:5
- |
-LL | box B(&*v) as Box
- | ^^^^^^^^^^^^^^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to lifetime `'a`
|
LL | fn i<'a, T, U>(v: Box+'a>) -> Box {
diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr
index 5cb9506afd35..8f93fad7fe9d 100644
--- a/src/test/ui/regions/regions-proc-bound-capture.stderr
+++ b/src/test/ui/regions/regions-proc-bound-capture.stderr
@@ -5,13 +5,8 @@ LL | fn static_proc(x: &isize) -> Box (isize) + 'static> {
| ------ this data with the anonymous lifetime `'_`...
LL | // This is illegal, because the region bound on `proc` is 'static.
LL | Box::new(move || { *x })
- | ^^^^^^^^^^^^^^ ...is captured here...
+ | ^^^^^^^^^^^^^^ ...is captured here with a `'static` requirement
|
-note: ...and required to be `'static` by this
- --> $DIR/regions-proc-bound-capture.rs:9:5
- |
-LL | Box::new(move || { *x })
- | ^^^^^^^^^^^^^^^^^^^^^^^^
help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_`
|
LL | fn static_proc(x: &isize) -> Box (isize) + '_> {
From 539e9783dfb713b3af0a9967af8fd0639d700555 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?=