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/28] 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 849193151c335..049aa7447f4db 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 0000000000000..8d883d6e24894
--- /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 0000000000000..baa935aff713c
--- /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 0000000000000..d445ab6bb8a1f
--- /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 0000000000000..3e9d4a80a70ef
--- /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/28] 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 049aa7447f4db..aceee81432896 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 3e9d4a80a70ef..c37612430cef1 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/28] 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 aceee81432896..224f4ebf53828 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 8d883d6e24894..98473e9f096d8 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 baa935aff713c..d7d84ff16a0a1 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/28] 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 224f4ebf53828..bec810fde081d 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 98473e9f096d8..4d6d9b5c8d37f 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 d7d84ff16a0a1..91a59fe24fedc 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 d445ab6bb8a1f..7f58f5df2d412 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 c37612430cef1..8a90b7cf74a4a 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/28] 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 bec810fde081d..53f32b7c800bd 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 4d6d9b5c8d37f..0000000000000
--- 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 91a59fe24fedc..0000000000000
--- 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 8a90b7cf74a4a..71431499ac70b 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 591584e71f7d8a613d586066c8b01c1eecf08f35 Mon Sep 17 00:00:00 2001
From: Mikail Bagishov
Date: Tue, 26 May 2020 23:48:36 +0300
Subject: [PATCH 06/28] Add tests for 'impl Default for [T; N]'
---
src/libcore/tests/array.rs | 41 ++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/src/libcore/tests/array.rs b/src/libcore/tests/array.rs
index c2a816f0a7d90..41855a9a8cbab 100644
--- a/src/libcore/tests/array.rs
+++ b/src/libcore/tests/array.rs
@@ -241,3 +241,44 @@ fn iterator_drops() {
}
assert_eq!(i.get(), 5);
}
+
+#[test]
+fn array_default_impl_avoids_leaks_on_panic() {
+ use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
+ static COUNTER: AtomicUsize = AtomicUsize::new(0);
+ #[derive(Debug)]
+ struct Bomb(usize);
+
+ impl Default for Bomb {
+ fn default() -> Bomb {
+ if COUNTER.load(Relaxed) == 3 {
+ panic!("bomb limit exceeded");
+ }
+
+ COUNTER.fetch_add(1, Relaxed);
+ Bomb(COUNTER.load(Relaxed))
+ }
+ }
+
+ impl Drop for Bomb {
+ fn drop(&mut self) {
+ COUNTER.fetch_sub(1, Relaxed);
+ }
+ }
+
+ let res = std::panic::catch_unwind(|| <[Bomb; 5]>::default());
+ let panic_msg = match res {
+ Ok(_) => unreachable!(),
+ Err(p) => p.downcast::<&'static str>().unwrap(),
+ };
+ assert_eq!(*panic_msg, "bomb limit exceeded");
+ // check that all bombs are successfully dropped
+ assert_eq!(COUNTER.load(Relaxed), 0);
+}
+
+#[test]
+fn empty_array_is_always_default() {
+ struct DoesNotImplDefault;
+
+ let _arr = <[DoesNotImplDefault; 0]>::default();
+}
From 3313bf62ac45fab2c39e49c788423153754087a9 Mon Sep 17 00:00:00 2001
From: Mikail Bagishov
Date: Thu, 28 May 2020 20:45:21 +0300
Subject: [PATCH 07/28] Skip leak test on targets without panic=unwind
---
src/libcore/tests/array.rs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/libcore/tests/array.rs b/src/libcore/tests/array.rs
index 41855a9a8cbab..4bc44e98fc802 100644
--- a/src/libcore/tests/array.rs
+++ b/src/libcore/tests/array.rs
@@ -242,7 +242,14 @@ fn iterator_drops() {
assert_eq!(i.get(), 5);
}
+// This test does not work on targets without panic=unwind support.
+// To work around this problem, test is marked is should_panic, so it will
+// be automagically skipped on unsuitable targets, such as
+// wasm32-unknown-unkown.
+//
+// It means that we use panic for indicating success.
#[test]
+#[should_panic(expected = "test succeeded")]
fn array_default_impl_avoids_leaks_on_panic() {
use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
static COUNTER: AtomicUsize = AtomicUsize::new(0);
@@ -274,6 +281,7 @@ fn array_default_impl_avoids_leaks_on_panic() {
assert_eq!(*panic_msg, "bomb limit exceeded");
// check that all bombs are successfully dropped
assert_eq!(COUNTER.load(Relaxed), 0);
+ panic!("test succeeded")
}
#[test]
From e9b67d281a3a1e740217ded7df9fc292f5ba6559 Mon Sep 17 00:00:00 2001
From: Amanieu d'Antras
Date: Sat, 6 Jun 2020 18:26:15 +0100
Subject: [PATCH 08/28] Fix link error with #[thread_local] introduced by
#71192
---
src/librustc_mir/monomorphize/collector.rs | 8 ++++++++
src/test/ui/tls.rs | 12 ++++++++++++
2 files changed, 20 insertions(+)
create mode 100644 src/test/ui/tls.rs
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 297b899ef0bd6..e0e9bea5eb225 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -586,6 +586,14 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
self.output.push(create_fn_mono_item(instance));
}
}
+ mir::Rvalue::ThreadLocalRef(def_id) => {
+ assert!(self.tcx.is_thread_local_static(def_id));
+ let instance = Instance::mono(self.tcx, def_id);
+ if should_monomorphize_locally(self.tcx, &instance) {
+ trace!("collecting thread-local static {:?}", def_id);
+ self.output.push(MonoItem::Static(def_id));
+ }
+ }
_ => { /* not interesting */ }
}
diff --git a/src/test/ui/tls.rs b/src/test/ui/tls.rs
new file mode 100644
index 0000000000000..cfc94c10c9e9b
--- /dev/null
+++ b/src/test/ui/tls.rs
@@ -0,0 +1,12 @@
+// run-pass
+
+#![feature(thread_local)]
+
+#[thread_local]
+static S: u32 = 222;
+
+fn main() {
+ let local = &S as *const u32 as usize;
+ let foreign = std::thread::spawn(|| &S as *const u32 as usize).join().unwrap();
+ assert_ne!(local, foreign);
+}
From 2af53e9a15aed1e9798867c9233a722530d03177 Mon Sep 17 00:00:00 2001
From: Amanieu d'Antras
Date: Wed, 10 Jun 2020 22:11:17 +0100
Subject: [PATCH 09/28] Add -O compile flag to test
---
src/test/ui/tls.rs | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/test/ui/tls.rs b/src/test/ui/tls.rs
index cfc94c10c9e9b..c696318e70f5f 100644
--- a/src/test/ui/tls.rs
+++ b/src/test/ui/tls.rs
@@ -1,4 +1,5 @@
// run-pass
+// compile-flags: -O
#![feature(thread_local)]
From f0d2e78d39d0efdb431af0b59c498d532d8146e2 Mon Sep 17 00:00:00 2001
From: Ralf Jung
Date: Fri, 12 Jun 2020 18:17:30 +0200
Subject: [PATCH 10/28] 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 777284ca5c096..199f08c3d5058 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 d6493454db591..ef699ede2a140 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 01e29c778c3749bca42e38adaad5a5ff58449031 Mon Sep 17 00:00:00 2001
From: Amanieu d'Antras
Date: Sat, 13 Jun 2020 13:24:19 +0100
Subject: [PATCH 11/28] Don't run test on emscripten which doesn't have threads
---
src/test/ui/tls.rs | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/test/ui/tls.rs b/src/test/ui/tls.rs
index c696318e70f5f..fbd3413885f8f 100644
--- a/src/test/ui/tls.rs
+++ b/src/test/ui/tls.rs
@@ -1,4 +1,5 @@
// run-pass
+// ignore-emscripten no threads support
// compile-flags: -O
#![feature(thread_local)]
From 724dfba460e2c98311cacb5d4f6bb6da36ceec67 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez
Date: Sat, 13 Jun 2020 15:05:37 +0200
Subject: [PATCH 12/28] 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 82d6cda986a9a..95d113166e001 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 0687b78d56b93d28ceeaa05e794849757d7341a4 Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Sat, 13 Jun 2020 10:29:56 -0700
Subject: [PATCH 13/28] Speed up bootstrap a little.
---
src/bootstrap/flags.rs | 7 ++---
src/bootstrap/lib.rs | 2 +-
src/bootstrap/metadata.rs | 65 +++++++++++++++++----------------------
src/bootstrap/test.rs | 4 +--
4 files changed, 33 insertions(+), 45 deletions(-)
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index cfaa43f397095..03b7028b2fa55 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -10,12 +10,10 @@ use std::process;
use getopts::Options;
use crate::builder::Builder;
+use crate::cache::{Interned, INTERNER};
use crate::config::Config;
-use crate::metadata;
use crate::{Build, DocTests};
-use crate::cache::{Interned, INTERNER};
-
/// Deserialized version of all flags for this compile.
pub struct Flags {
pub verbose: usize, // number of -v args; each extra -v after the first is passed to Cargo
@@ -444,8 +442,7 @@ Arguments:
// All subcommands except `clean` can have an optional "Available paths" section
if matches.opt_present("verbose") {
let config = Config::parse(&["build".to_string()]);
- let mut build = Build::new(config);
- metadata::build(&mut build);
+ let build = Build::new(config);
let maybe_rules_help = Builder::get_help(&build, subcommand.as_str());
extra_help.push_str(maybe_rules_help.unwrap_or_default().as_str());
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 8d8a036caef88..a125b49fc01e6 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -271,7 +271,7 @@ struct Crate {
impl Crate {
fn is_local(&self, build: &Build) -> bool {
- self.path.starts_with(&build.config.src) && !self.path.to_string_lossy().ends_with("_shim")
+ self.path.starts_with(&build.config.src)
}
fn local_path(&self, build: &Build) -> PathBuf {
diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs
index 292aa3b1e24a7..185f0ddb831e7 100644
--- a/src/bootstrap/metadata.rs
+++ b/src/bootstrap/metadata.rs
@@ -35,49 +35,24 @@ struct ResolveNode {
}
pub fn build(build: &mut Build) {
- let mut resolves = Vec::new();
- build_krate(&build.std_features(), build, &mut resolves, "src/libstd");
- build_krate("", build, &mut resolves, "src/libtest");
- build_krate(&build.rustc_features(), build, &mut resolves, "src/rustc");
-
- let mut id2name = HashMap::with_capacity(build.crates.len());
- for (name, krate) in build.crates.iter() {
- id2name.insert(krate.id.clone(), name.clone());
- }
-
- for node in resolves {
- let name = match id2name.get(&node.id) {
- Some(name) => name,
- None => continue,
- };
-
- let krate = build.crates.get_mut(name).unwrap();
- for dep in node.dependencies.iter() {
- let dep = match id2name.get(dep) {
- Some(dep) => dep,
- None => continue,
- };
- krate.deps.insert(*dep);
- }
- }
-}
-
-fn build_krate(features: &str, build: &mut Build, resolves: &mut Vec, krate: &str) {
// Run `cargo metadata` to figure out what crates we're testing.
- //
- // Down below we're going to call `cargo test`, but to test the right set
- // of packages we're going to have to know what `-p` arguments to pass it
- // to know what crates to test. Here we run `cargo metadata` to learn about
- // the dependency graph and what `-p` arguments there are.
+ let features: Vec<_> = build
+ .std_features()
+ .split_whitespace()
+ .map(|f| format!("test/{}", f))
+ .chain(build.rustc_features().split_whitespace().map(|f| format!("rustc-main/{}", f)))
+ .collect();
let mut cargo = Command::new(&build.initial_cargo);
cargo
.arg("metadata")
.arg("--format-version")
.arg("1")
.arg("--features")
- .arg(features)
+ .arg(features.join(","))
+ .arg("-Zpackage-features")
.arg("--manifest-path")
- .arg(build.src.join(krate).join("Cargo.toml"));
+ .arg(build.src.join("Cargo.toml"))
+ .env("RUSTC_BOOTSTRAP", "1");
let output = output(&mut cargo);
let output: Output = serde_json::from_str(&output).unwrap();
for package in output.packages {
@@ -88,5 +63,23 @@ fn build_krate(features: &str, build: &mut Build, resolves: &mut Vec =
+ build.crates.iter().map(|(name, krate)| (krate.id.clone(), name.clone())).collect();
+
+ for node in output.resolve.nodes {
+ let name = match id2name.get(&node.id) {
+ Some(name) => name,
+ None => continue,
+ };
+
+ let krate = build.crates.get_mut(name).unwrap();
+ for dep in node.dependencies.iter() {
+ let dep = match id2name.get(dep) {
+ Some(dep) => dep,
+ None => continue,
+ };
+ krate.deps.insert(*dep);
+ }
+ }
}
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 163132f563425..8659acf1cc5a5 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1654,9 +1654,7 @@ impl Step for Crate {
fn should_run(mut run: ShouldRun<'_>) -> ShouldRun<'_> {
let builder = run.builder;
for krate in run.builder.in_tree_crates("test") {
- if !(krate.name.starts_with("rustc_") && krate.name.ends_with("san")) {
- run = run.path(krate.local_path(&builder).to_str().unwrap());
- }
+ run = run.path(krate.local_path(&builder).to_str().unwrap());
}
run
}
From 607e85110ef9c79ce5a52286bb69d385471bc675 Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Sun, 14 Jun 2020 15:57:21 -0700
Subject: [PATCH 14/28] Switch bootstrap metadata to --no-deps.
This should run much faster.
There are also some drive-by cleanups here to try to simplify things.
Also, the paths for in-tree crates are now displayed as relative
in `x.py test -h -v`.
---
src/bootstrap/builder.rs | 6 +++--
src/bootstrap/doc.rs | 20 ++------------
src/bootstrap/lib.rs | 25 +++++++++++-------
src/bootstrap/metadata.rs | 55 +++++++++------------------------------
src/bootstrap/test.rs | 8 ++----
5 files changed, 37 insertions(+), 77 deletions(-)
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index ffdd8485181f4..345af600c2adb 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -255,7 +255,8 @@ impl<'a> ShouldRun<'a> {
pub fn all_krates(mut self, name: &str) -> Self {
let mut set = BTreeSet::new();
for krate in self.builder.in_tree_crates(name) {
- set.insert(PathBuf::from(&krate.path));
+ let path = krate.local_path(self.builder);
+ set.insert(path);
}
self.paths.insert(PathSet::Set(set));
self
@@ -263,7 +264,8 @@ impl<'a> ShouldRun<'a> {
pub fn krate(mut self, name: &str) -> Self {
for krate in self.builder.in_tree_crates(name) {
- self.paths.insert(PathSet::one(&krate.path));
+ let path = krate.local_path(self.builder);
+ self.paths.insert(PathSet::one(path));
}
self
}
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 5c01c5e852c48..6d7fb7acfcb04 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -548,8 +548,8 @@ impl Step for Rustc {
// Find dependencies for top level crates.
let mut compiler_crates = HashSet::new();
for root_crate in &["rustc_driver", "rustc_codegen_llvm", "rustc_codegen_ssa"] {
- let interned_root_crate = INTERNER.intern_str(root_crate);
- find_compiler_crates(builder, &interned_root_crate, &mut compiler_crates);
+ compiler_crates
+ .extend(builder.in_tree_crates(root_crate).into_iter().map(|krate| krate.name));
}
for krate in &compiler_crates {
@@ -564,22 +564,6 @@ impl Step for Rustc {
}
}
-fn find_compiler_crates(
- builder: &Builder<'_>,
- name: &Interned,
- crates: &mut HashSet>,
-) {
- // Add current crate.
- crates.insert(*name);
-
- // Look for dependencies.
- for dep in builder.crates.get(name).unwrap().deps.iter() {
- if builder.crates.get(dep).unwrap().is_local(builder) {
- find_compiler_crates(builder, dep, crates);
- }
- }
-}
-
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Rustdoc {
stage: u32,
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index a125b49fc01e6..9d3830da39066 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -270,12 +270,7 @@ struct Crate {
}
impl Crate {
- fn is_local(&self, build: &Build) -> bool {
- self.path.starts_with(&build.config.src)
- }
-
fn local_path(&self, build: &Build) -> PathBuf {
- assert!(self.is_local(build));
self.path.strip_prefix(&build.config.src).unwrap().into()
}
}
@@ -1079,17 +1074,29 @@ impl Build {
}
}
+ /// Returns a Vec of all the dependencies of the given root crate,
+ /// including transitive dependencies and the root itself. Only includes
+ /// "local" crates (those in the local source tree, not from a registry).
fn in_tree_crates(&self, root: &str) -> Vec<&Crate> {
let mut ret = Vec::new();
let mut list = vec![INTERNER.intern_str(root)];
let mut visited = HashSet::new();
while let Some(krate) = list.pop() {
let krate = &self.crates[&krate];
- if krate.is_local(self) {
- ret.push(krate);
- }
+ ret.push(krate);
for dep in &krate.deps {
- if visited.insert(dep) && dep != "build_helper" {
+ // Don't include optional deps if their features are not
+ // enabled. Ideally this would be computed from `cargo
+ // metadata --features …`, but that is somewhat slow. Just
+ // skip `build_helper` since there aren't any operations we
+ // want to perform on it. In the future, we may want to
+ // consider just filtering all build and dev dependencies in
+ // metadata::build.
+ if visited.insert(dep)
+ && dep != "build_helper"
+ && (dep != "profiler_builtins" || self.config.profiler)
+ && (dep != "rustc_codegen_llvm" || self.config.llvm_enabled())
+ {
list.push(*dep);
}
}
diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs
index 185f0ddb831e7..a38391c7b88f2 100644
--- a/src/bootstrap/metadata.rs
+++ b/src/bootstrap/metadata.rs
@@ -1,5 +1,3 @@
-use std::collections::HashMap;
-use std::collections::HashSet;
use std::path::PathBuf;
use std::process::Command;
@@ -12,7 +10,6 @@ use crate::{Build, Crate};
#[derive(Deserialize)]
struct Output {
packages: Vec,
- resolve: Resolve,
}
#[derive(Deserialize)]
@@ -21,38 +18,25 @@ struct Package {
name: String,
source: Option,
manifest_path: String,
+ dependencies: Vec,
}
#[derive(Deserialize)]
-struct Resolve {
- nodes: Vec,
-}
-
-#[derive(Deserialize)]
-struct ResolveNode {
- id: String,
- dependencies: Vec,
+struct Dependency {
+ name: String,
+ source: Option,
}
pub fn build(build: &mut Build) {
// Run `cargo metadata` to figure out what crates we're testing.
- let features: Vec<_> = build
- .std_features()
- .split_whitespace()
- .map(|f| format!("test/{}", f))
- .chain(build.rustc_features().split_whitespace().map(|f| format!("rustc-main/{}", f)))
- .collect();
let mut cargo = Command::new(&build.initial_cargo);
cargo
.arg("metadata")
.arg("--format-version")
.arg("1")
- .arg("--features")
- .arg(features.join(","))
- .arg("-Zpackage-features")
+ .arg("--no-deps")
.arg("--manifest-path")
- .arg(build.src.join("Cargo.toml"))
- .env("RUSTC_BOOTSTRAP", "1");
+ .arg(build.src.join("Cargo.toml"));
let output = output(&mut cargo);
let output: Output = serde_json::from_str(&output).unwrap();
for package in output.packages {
@@ -60,26 +44,13 @@ pub fn build(build: &mut Build) {
let name = INTERNER.intern_string(package.name);
let mut path = PathBuf::from(package.manifest_path);
path.pop();
- build.crates.insert(name, Crate { name, id: package.id, deps: HashSet::new(), path });
- }
- }
-
- let id2name: HashMap<_, _> =
- build.crates.iter().map(|(name, krate)| (krate.id.clone(), name.clone())).collect();
-
- for node in output.resolve.nodes {
- let name = match id2name.get(&node.id) {
- Some(name) => name,
- None => continue,
- };
-
- let krate = build.crates.get_mut(name).unwrap();
- for dep in node.dependencies.iter() {
- let dep = match id2name.get(dep) {
- Some(dep) => dep,
- None => continue,
- };
- krate.deps.insert(*dep);
+ let deps = package
+ .dependencies
+ .into_iter()
+ .filter(|dep| dep.source.is_none())
+ .map(|dep| INTERNER.intern_string(dep.name))
+ .collect();
+ build.crates.insert(name, Crate { name, id: package.id, deps, path });
}
}
}
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 8659acf1cc5a5..c1d0316920be7 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1651,12 +1651,8 @@ impl Step for Crate {
type Output = ();
const DEFAULT: bool = true;
- fn should_run(mut run: ShouldRun<'_>) -> ShouldRun<'_> {
- let builder = run.builder;
- for krate in run.builder.in_tree_crates("test") {
- run = run.path(krate.local_path(&builder).to_str().unwrap());
- }
- run
+ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+ run.krate("test")
}
fn make_run(run: RunConfig<'_>) {
From c2b920fab328201a2b5507b9a484c8c09752af93 Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Sun, 14 Jun 2020 16:58:45 -0700
Subject: [PATCH 15/28] Show suite paths (`src/test/ui/...`) in help output.
---
src/bootstrap/builder.rs | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 345af600c2adb..545ad64ba2cf6 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -489,13 +489,19 @@ impl<'a> Builder<'a> {
should_run = (desc.should_run)(should_run);
}
let mut help = String::from("Available paths:\n");
+ let mut add_path = |path: &Path| {
+ help.push_str(&format!(" ./x.py {} {}\n", subcommand, path.display()));
+ };
for pathset in should_run.paths {
- if let PathSet::Set(set) = pathset {
- set.iter().for_each(|path| {
- help.push_str(
- format!(" ./x.py {} {}\n", subcommand, path.display()).as_str(),
- )
- })
+ match pathset {
+ PathSet::Set(set) => {
+ for path in set {
+ add_path(&path);
+ }
+ }
+ PathSet::Suite(path) => {
+ add_path(&path.join("..."));
+ }
}
}
Some(help)
From f17fd7b0e692c59075db58ac2e7ca3ac2d5e19bd Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Sun, 14 Jun 2020 17:00:34 -0700
Subject: [PATCH 16/28] Add some doc comments regarding PathSet.
---
src/bootstrap/builder.rs | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 545ad64ba2cf6..c2f748f161f18 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -97,9 +97,21 @@ struct StepDescription {
name: &'static str,
}
+/// Collection of paths used to match a task rule.
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub enum PathSet {
+ /// A collection of individual paths.
+ ///
+ /// These are generally matched as a path suffix. For example, a
+ /// command-line value of `libstd` will match if `src/libstd` is in the
+ /// set.
Set(BTreeSet),
+ /// A "suite" of paths.
+ ///
+ /// These can match as a path suffix (like `Set`), or as a prefix. For
+ /// example, a command-line value of `src/test/ui/abi/variadic-ffi.rs`
+ /// will match `src/test/ui`. A command-line value of `ui` would also
+ /// match `src/test/ui`.
Suite(PathBuf),
}
@@ -249,9 +261,15 @@ impl<'a> ShouldRun<'a> {
self
}
- // Unlike `krate` this will create just one pathset. As such, it probably shouldn't actually
- // ever be used, but as we transition to having all rules properly handle passing krate(...) by
- // actually doing something different for every crate passed.
+ /// Indicates it should run if the command-line selects the given crate or
+ /// any of its (local) dependencies.
+ ///
+ /// Compared to `krate`, this treats the dependencies as aliases for the
+ /// same job. Generally it is preferred to use `krate`, and treat each
+ /// individual path separately. For example `./x.py test src/liballoc`
+ /// (which uses `krate`) will test just `liballoc`. However, `./x.py check
+ /// src/liballoc` (which uses `all_krates`) will check all of `libtest`.
+ /// `all_krates` should probably be removed at some point.
pub fn all_krates(mut self, name: &str) -> Self {
let mut set = BTreeSet::new();
for krate in self.builder.in_tree_crates(name) {
@@ -262,6 +280,10 @@ impl<'a> ShouldRun<'a> {
self
}
+ /// Indicates it should run if the command-line selects the given crate or
+ /// any of its (local) dependencies.
+ ///
+ /// `make_run` will be called separately for each matching command-line path.
pub fn krate(mut self, name: &str) -> Self {
for krate in self.builder.in_tree_crates(name) {
let path = krate.local_path(self.builder);
From 9e510085ecaedaee86b44410a4b3e4c85d97d6e0 Mon Sep 17 00:00:00 2001
From: Alexis Bourget
Date: Mon, 15 Jun 2020 15:19:02 +0200
Subject: [PATCH 17/28] 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 c36e78b1d004e..c58168bd446d7 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 d6156e8fe5619143c687983d3ffa5b7ccc37c77e Mon Sep 17 00:00:00 2001
From: Alex Crichton
Date: Mon, 8 Jun 2020 09:02:57 -0700
Subject: [PATCH 18/28] Change how compiler-builtins gets many CGUs
This commit intends to fix an accidental regression from #70846. The
goal of #70846 was to build compiler-builtins with a maximal number of
CGUs to ensure that each module in the source corresponds to an object
file. This high degree of control for compiler-builtins is desirable to
ensure that there's at most one exported symbol per CGU, ideally
enabling compiler-builtins to not conflict with the system libgcc as
often.
In #70846, however, only part of the compiler understands that
compiler-builtins is built with many CGUs. The rest of the compiler
thinks it's building with `sess.codegen_units()`. Notably the
calculation of `sess.lto()` consults `sess.codegen_units()`, which when
there's only one CGU it disables ThinLTO. This means that
compiler-builtins is built without ThinLTO, which is quite harmful to
performance! This is the root of the cause from #73135 where intrinsics
were found to not be inlining trivial functions.
The fix applied in this commit is to remove the special-casing of
compiler-builtins in the compiler. Instead the build system is now
responsible for special-casing compiler-builtins. It doesn't know
exactly how many CGUs will be needed but it passes a large number that
is assumed to be much greater than the number of source-level modules
needed. After reading the various locations in the compiler source, this
seemed like the best solution rather than adding more and more special
casing in the compiler for compiler-builtins.
Closes #73135
---
Cargo.toml | 13 ++++++
src/librustc_mir/monomorphize/partitioning.rs | 9 +----
.../partitioning/compiler-builtins.rs | 40 -------------------
3 files changed, 14 insertions(+), 48 deletions(-)
delete mode 100644 src/test/codegen-units/partitioning/compiler-builtins.rs
diff --git a/Cargo.toml b/Cargo.toml
index f2177a99a9b88..f10d539d8296b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -42,6 +42,19 @@ debug-assertions = false
debug = false
debug-assertions = false
+[profile.release.package.compiler_builtins]
+# For compiler-builtins we always use a high number of codegen units.
+# The goal here is to place every single intrinsic into its own object
+# file to avoid symbol clashes with the system libgcc if possible. Note
+# that this number doesn't actually produce this many object files, we
+# just don't create more than this number of object files.
+#
+# It's a bit of a bummer that we have to pass this here, unfortunately.
+# Ideally this would be specified through an env var to Cargo so Cargo
+# knows how many CGUs are for this specific crate, but for now
+# per-crate configuration isn't specifiable in the environment.
+codegen-units = 10000
+
# We want the RLS to use the version of Cargo that we've got vendored in this
# repository to ensure that the same exact version of Cargo is used by both the
# RLS and the Cargo binary itself. The RLS depends on Cargo as a git repository
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index db1ea72c0a531..a945c1d626a9a 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -454,18 +454,11 @@ fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibilit
fn merge_codegen_units<'tcx>(
tcx: TyCtxt<'tcx>,
initial_partitioning: &mut PreInliningPartitioning<'tcx>,
- mut target_cgu_count: usize,
+ target_cgu_count: usize,
) {
assert!(target_cgu_count >= 1);
let codegen_units = &mut initial_partitioning.codegen_units;
- if tcx.is_compiler_builtins(LOCAL_CRATE) {
- // Compiler builtins require some degree of control over how mono items
- // are partitioned into compilation units. Provide it by keeping the
- // original partitioning when compiling the compiler builtins crate.
- target_cgu_count = codegen_units.len();
- }
-
// Note that at this point in time the `codegen_units` here may not be in a
// deterministic order (but we know they're deterministically the same set).
// We want this merging to produce a deterministic ordering of codegen units
diff --git a/src/test/codegen-units/partitioning/compiler-builtins.rs b/src/test/codegen-units/partitioning/compiler-builtins.rs
deleted file mode 100644
index 25195743b0400..0000000000000
--- a/src/test/codegen-units/partitioning/compiler-builtins.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Verifies that during compiler_builtins compilation the codegen units are kept
-// unmerged. Even when only a single codegen unit is requested with -Ccodegen-units=1.
-//
-// compile-flags: -Zprint-mono-items=eager -Ccodegen-units=1
-
-#![compiler_builtins]
-#![crate_type="lib"]
-#![feature(compiler_builtins)]
-
-mod atomics {
- //~ MONO_ITEM fn compiler_builtins::atomics[0]::sync_1[0] @@ compiler_builtins-cgu.0[External]
- #[no_mangle]
- pub extern "C" fn sync_1() {}
-
- //~ MONO_ITEM fn compiler_builtins::atomics[0]::sync_2[0] @@ compiler_builtins-cgu.0[External]
- #[no_mangle]
- pub extern "C" fn sync_2() {}
-
- //~ MONO_ITEM fn compiler_builtins::atomics[0]::sync_3[0] @@ compiler_builtins-cgu.0[External]
- #[no_mangle]
- pub extern "C" fn sync_3() {}
-}
-
-mod x {
- //~ MONO_ITEM fn compiler_builtins::x[0]::x[0] @@ compiler_builtins-cgu.1[External]
- #[no_mangle]
- pub extern "C" fn x() {}
-}
-
-mod y {
- //~ MONO_ITEM fn compiler_builtins::y[0]::y[0] @@ compiler_builtins-cgu.2[External]
- #[no_mangle]
- pub extern "C" fn y() {}
-}
-
-mod z {
- //~ MONO_ITEM fn compiler_builtins::z[0]::z[0] @@ compiler_builtins-cgu.3[External]
- #[no_mangle]
- pub extern "C" fn z() {}
-}
From 96f5584b808cd08c3c8208db4fee04d2c2b71d79 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?=
Date: Sun, 19 Apr 2020 16:52:15 -0700
Subject: [PATCH 19/28] Expand "recursive opaque type" diagnostic
Fix #70968, partially address #66523.
---
src/librustc_hir/hir.rs | 12 ++
.../traits/error_reporting/suggestions.rs | 4 +-
src/librustc_typeck/check/mod.rs | 195 ++++++++++++++++--
.../ui/impl-trait/binding-without-value.rs | 9 +
.../impl-trait/binding-without-value.stderr | 16 ++
.../issues/infinite-impl-trait-issue-38064.rs | 4 +-
.../infinite-impl-trait-issue-38064.stderr | 24 ++-
.../recursive-impl-trait-type-direct.stderr | 9 +-
.../recursive-impl-trait-type-indirect.stderr | 153 ++++++++------
...e-impl-trait-type-through-non-recursive.rs | 8 +-
...pl-trait-type-through-non-recursive.stderr | 44 ++--
src/test/ui/impl-trait/where-allowed-2.rs | 3 +-
src/test/ui/impl-trait/where-allowed-2.stderr | 8 +-
13 files changed, 374 insertions(+), 115 deletions(-)
create mode 100644 src/test/ui/impl-trait/binding-without-value.rs
create mode 100644 src/test/ui/impl-trait/binding-without-value.stderr
diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs
index 634ab32a28542..bed2044c70855 100644
--- a/src/librustc_hir/hir.rs
+++ b/src/librustc_hir/hir.rs
@@ -2726,6 +2726,18 @@ impl Node<'_> {
}
}
+ pub fn body_id(&self) -> Option {
+ match self {
+ Node::TraitItem(TraitItem {
+ kind: TraitItemKind::Fn(_, TraitFn::Provided(body_id)),
+ ..
+ })
+ | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. })
+ | Node::Item(Item { kind: ItemKind::Fn(.., body_id), .. }) => Some(*body_id),
+ _ => None,
+ }
+ }
+
pub fn generics(&self) -> Option<&Generics<'_>> {
match self {
Node::TraitItem(TraitItem { generics, .. })
diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
index 8796cfb52165d..edff67929f6d0 100644
--- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
@@ -1992,8 +1992,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
/// Collect all the returned expressions within the input expression.
/// Used to point at the return spans when we want to suggest some change to them.
#[derive(Default)]
-struct ReturnsVisitor<'v> {
- returns: Vec<&'v hir::Expr<'v>>,
+pub struct ReturnsVisitor<'v> {
+ pub returns: Vec<&'v hir::Expr<'v>>,
in_block_tail: bool,
}
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a409e20953da1..d4db32abe2a16 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -138,6 +138,7 @@ use rustc_target::spec::abi::Abi;
use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::opaque_types::{InferCtxtExt as _, OpaqueTypeDecl};
use rustc_trait_selection::traits::error_reporting::recursive_type_with_infinite_size_error;
+use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_trait_selection::traits::{
@@ -1711,6 +1712,181 @@ fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId,
}
}
+/// Given a `DefId` for an opaque type in return position, find its parent item's return
+/// expressions.
+fn get_owner_return_paths(
+ tcx: TyCtxt<'tcx>,
+ def_id: LocalDefId,
+) -> Option<(hir::HirId, ReturnsVisitor<'tcx>)> {
+ let hir_id = tcx.hir().as_local_hir_id(def_id);
+ let id = tcx.hir().get_parent_item(hir_id);
+ tcx.hir()
+ .find(id)
+ .map(|n| (id, n))
+ .and_then(|(hir_id, node)| node.body_id().map(|b| (hir_id, b)))
+ .map(|(hir_id, body_id)| {
+ let body = tcx.hir().body(body_id);
+ let mut visitor = ReturnsVisitor::default();
+ visitor.visit_body(body);
+ (hir_id, visitor)
+ })
+}
+
+/// Emit an error for recursive opaque types.
+///
+/// If this is a return `impl Trait`, find the item's return expressions and point at them. For
+/// direct recursion this is enough, but for indirect recursion also point at the last intermediary
+/// `impl Trait`.
+///
+/// If all the return expressions evaluate to `!`, then we explain that the error will go away
+/// after changing it. This can happen when a user uses `panic!()` or similar as a placeholder.
+fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
+ let mut err =
+ struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type to a concrete type");
+
+ let mut label = false;
+ if let Some((hir_id, visitor)) = get_owner_return_paths(tcx, def_id) {
+ let tables = tcx.typeck_tables_of(tcx.hir().local_def_id(hir_id));
+ if visitor
+ .returns
+ .iter()
+ .filter_map(|expr| tables.node_type_opt(expr.hir_id))
+ .map(|ty| tcx.infer_ctxt().enter(|infcx| infcx.resolve_vars_if_possible(&ty)))
+ .all(|ty| matches!(ty.kind, ty::Never))
+ {
+ let spans = visitor
+ .returns
+ .iter()
+ .filter(|expr| tables.node_type_opt(expr.hir_id).is_some())
+ .map(|expr| expr.span)
+ .collect::>();
+ let span_len = spans.len();
+ if span_len == 1 {
+ err.span_label(spans[0], "this returned value is of `!` type");
+ } else {
+ let mut multispan: MultiSpan = spans.clone().into();
+ for span in spans {
+ multispan
+ .push_span_label(span, "this returned value is of `!` type".to_string());
+ }
+ err.span_note(multispan, "these returned values have a concrete \"never\" type");
+ }
+ err.help("this error will resolve once the item's body returns a concrete type");
+ } else {
+ let mut seen = FxHashSet::default();
+ seen.insert(span);
+ err.span_label(span, "recursive opaque type");
+ label = true;
+ for (sp, ty) in visitor
+ .returns
+ .iter()
+ .filter_map(|e| tables.node_type_opt(e.hir_id).map(|t| (e.span, t)))
+ .filter(|(_, ty)| !matches!(ty.kind, ty::Never))
+ .map(|(sp, ty)| {
+ (sp, tcx.infer_ctxt().enter(|infcx| infcx.resolve_vars_if_possible(&ty)))
+ })
+ {
+ struct VisitTypes(Vec);
+ impl<'tcx> ty::fold::TypeVisitor<'tcx> for VisitTypes {
+ fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
+ match t.kind {
+ ty::Opaque(def, _) => {
+ self.0.push(def);
+ false
+ }
+ _ => t.super_visit_with(self),
+ }
+ }
+ }
+ let mut visitor = VisitTypes(vec![]);
+ ty.visit_with(&mut visitor);
+ for def_id in visitor.0 {
+ let ty_span = tcx.def_span(def_id);
+ if !seen.contains(&ty_span) {
+ err.span_label(ty_span, &format!("returning this opaque type `{}`", ty));
+ seen.insert(ty_span);
+ }
+ err.span_label(sp, &format!("returning here with type `{}`", ty));
+ }
+ }
+ }
+ }
+ if !label {
+ err.span_label(span, "cannot resolve to a concrete type");
+ }
+ err.emit();
+}
+
+/// Emit an error for recursive opaque types in a `let` binding.
+fn binding_opaque_type_cycle_error(
+ tcx: TyCtxt<'tcx>,
+ def_id: LocalDefId,
+ span: Span,
+ partially_expanded_type: Ty<'tcx>,
+) {
+ let mut err =
+ struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type to a concrete type");
+ err.span_label(span, "cannot resolve to a concrete type");
+ let hir_id = tcx.hir().as_local_hir_id(def_id);
+ let mut prev_hir_id = hir_id;
+ let mut hir_id = tcx.hir().get_parent_node(hir_id);
+ while let Some(node) = tcx.hir().find(hir_id) {
+ match node {
+ hir::Node::Local(hir::Local {
+ pat,
+ init: None,
+ ty: Some(ty),
+ source: hir::LocalSource::Normal,
+ ..
+ }) => {
+ err.span_label(pat.span, "this binding might not have a concrete type");
+ err.span_suggestion_verbose(
+ ty.span.shrink_to_hi(),
+ "set the binding to a value for a concrete type to be resolved",
+ " = /* value */".to_string(),
+ Applicability::HasPlaceholders,
+ );
+ }
+ hir::Node::Local(hir::Local {
+ init: Some(expr),
+ source: hir::LocalSource::Normal,
+ ..
+ }) => {
+ let hir_id = tcx.hir().as_local_hir_id(def_id);
+ let tables =
+ tcx.typeck_tables_of(tcx.hir().local_def_id(tcx.hir().get_parent_item(hir_id)));
+ let ty = tables.node_type_opt(expr.hir_id);
+ if let Some(ty) =
+ tcx.infer_ctxt().enter(|infcx| infcx.resolve_vars_if_possible(&ty))
+ {
+ err.span_label(
+ expr.span,
+ &format!(
+ "this is of type `{}`, which doesn't constrain \
+ `{}` enough to arrive to a concrete type",
+ ty, partially_expanded_type
+ ),
+ );
+ }
+ }
+ _ => {}
+ }
+ if prev_hir_id == hir_id {
+ break;
+ }
+ prev_hir_id = hir_id;
+ hir_id = tcx.hir().get_parent_node(hir_id);
+ }
+ err.emit();
+}
+
+fn async_opaque_type_cycle_error(tcx: TyCtxt<'tcx>, span: Span) {
+ struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing")
+ .span_label(span, "recursive `async fn`")
+ .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
+ .emit();
+}
+
/// Checks that an opaque type does not contain cycles.
fn check_opaque_for_cycles<'tcx>(
tcx: TyCtxt<'tcx>,
@@ -1721,21 +1897,12 @@ fn check_opaque_for_cycles<'tcx>(
) {
if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs)
{
- if let hir::OpaqueTyOrigin::AsyncFn = origin {
- struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing",)
- .span_label(span, "recursive `async fn`")
- .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
- .emit();
- } else {
- let mut err =
- struct_span_err!(tcx.sess, span, E0720, "opaque type expands to a recursive type",);
- err.span_label(span, "expands to a recursive type");
- if let ty::Opaque(..) = partially_expanded_type.kind {
- err.note("type resolves to itself");
- } else {
- err.note(&format!("expanded type is `{}`", partially_expanded_type));
+ match origin {
+ hir::OpaqueTyOrigin::AsyncFn => async_opaque_type_cycle_error(tcx, span),
+ hir::OpaqueTyOrigin::Binding => {
+ binding_opaque_type_cycle_error(tcx, def_id, span, partially_expanded_type)
}
- err.emit();
+ _ => opaque_type_cycle_error(tcx, def_id, span),
}
}
}
diff --git a/src/test/ui/impl-trait/binding-without-value.rs b/src/test/ui/impl-trait/binding-without-value.rs
new file mode 100644
index 0000000000000..6a97f28ff552b
--- /dev/null
+++ b/src/test/ui/impl-trait/binding-without-value.rs
@@ -0,0 +1,9 @@
+#![allow(incomplete_features)]
+#![feature(impl_trait_in_bindings)]
+
+fn foo() {
+ let _ : impl Copy;
+ //~^ ERROR cannot resolve opaque type
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/binding-without-value.stderr b/src/test/ui/impl-trait/binding-without-value.stderr
new file mode 100644
index 0000000000000..1898af5b63eeb
--- /dev/null
+++ b/src/test/ui/impl-trait/binding-without-value.stderr
@@ -0,0 +1,16 @@
+error[E0720]: cannot resolve opaque type to a concrete type
+ --> $DIR/binding-without-value.rs:5:13
+ |
+LL | let _ : impl Copy;
+ | - ^^^^^^^^^ cannot resolve to a concrete type
+ | |
+ | this binding might not have a concrete type
+ |
+help: set the binding to a value for a concrete type to be resolved
+ |
+LL | let _ : impl Copy = /* value */;
+ | ^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0720`.
diff --git a/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs b/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs
index 150a8015cbc75..451ddb3cce0e0 100644
--- a/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs
+++ b/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs
@@ -5,13 +5,13 @@
trait Quux {}
-fn foo() -> impl Quux { //~ opaque type expands to a recursive type
+fn foo() -> impl Quux { //~ ERROR cannot resolve opaque type
struct Foo(T);
impl Quux for Foo {}
Foo(bar())
}
-fn bar() -> impl Quux { //~ opaque type expands to a recursive type
+fn bar() -> impl Quux { //~ ERROR cannot resolve opaque type
struct Bar(T);
impl Quux for Bar {}
Bar(foo())
diff --git a/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr b/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr
index d10001e8a8e53..a38fb7cb56e9d 100644
--- a/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr
+++ b/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr
@@ -1,18 +1,26 @@
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/infinite-impl-trait-issue-38064.rs:8:13
|
LL | fn foo() -> impl Quux {
- | ^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `foo::Foo>`
+ | ^^^^^^^^^ recursive opaque type
+...
+LL | Foo(bar())
+ | ---------- returning here with type `foo::Foo`
+...
+LL | fn bar() -> impl Quux {
+ | --------- returning this opaque type `foo::Foo`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/infinite-impl-trait-issue-38064.rs:14:13
|
+LL | fn foo() -> impl Quux {
+ | --------- returning this opaque type `bar::Bar`
+...
LL | fn bar() -> impl Quux {
- | ^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `bar::Bar>`
+ | ^^^^^^^^^ recursive opaque type
+...
+LL | Bar(foo())
+ | ---------- returning here with type `bar::Bar`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr
index 5a95e2969d1b0..5149d42370c75 100644
--- a/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr
+++ b/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr
@@ -1,10 +1,11 @@
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-direct.rs:5:14
|
LL | fn test() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: type resolves to itself
+ | ^^^^^^^^^^ recursive opaque type
+LL |
+LL | test()
+ | ------ returning here with type `impl Sized`
error: aborting due to previous error
diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
index 6573b00870c5b..0bf362e9a6d4a 100644
--- a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
+++ b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
@@ -1,114 +1,147 @@
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:7:22
|
LL | fn option(i: i32) -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `std::option::Option<(impl Sized, i32)>`
+ | ^^^^^^^^^^ recursive opaque type
+LL |
+LL | if i < 0 { None } else { Some((option(i - 1), i)) }
+ | ---- ------------------------ returning here with type `std::option::Option<(impl Sized, i32)>`
+ | |
+ | returning here with type `std::option::Option<(impl Sized, i32)>`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:12:15
|
LL | fn tuple() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `(impl Sized,)`
+ | ^^^^^^^^^^ recursive opaque type
+LL |
+LL | (tuple(),)
+ | ---------- returning here with type `(impl Sized,)`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:17:15
|
LL | fn array() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `[impl Sized; 1]`
+ | ^^^^^^^^^^ recursive opaque type
+LL |
+LL | [array()]
+ | --------- returning here with type `[impl Sized; 1]`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:22:13
|
LL | fn ptr() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `*const impl Sized`
+ | ^^^^^^^^^^ recursive opaque type
+LL |
+LL | &ptr() as *const _
+ | ------------------ returning here with type `*const impl Sized`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:27:16
|
LL | fn fn_ptr() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `fn() -> impl Sized`
+ | ^^^^^^^^^^ recursive opaque type
+LL |
+LL | fn_ptr as fn() -> _
+ | ------------------- returning here with type `fn() -> impl Sized`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:32:25
|
-LL | fn closure_capture() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `[closure@$DIR/recursive-impl-trait-type-indirect.rs:35:5: 37:6 x:impl Sized]`
+LL | fn closure_capture() -> impl Sized {
+ | ^^^^^^^^^^ recursive opaque type
+...
+LL | / move || {
+LL | | x;
+LL | | }
+ | |_____- returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:35:5: 37:6 x:impl Sized]`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:40:29
|
-LL | fn closure_ref_capture() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `[closure@$DIR/recursive-impl-trait-type-indirect.rs:43:5: 45:6 x:impl Sized]`
+LL | fn closure_ref_capture() -> impl Sized {
+ | ^^^^^^^^^^ recursive opaque type
+...
+LL | / move || {
+LL | | &x;
+LL | | }
+ | |_____- returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:43:5: 45:6 x:impl Sized]`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:48:21
|
LL | fn closure_sig() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `[closure@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:21]`
+ | ^^^^^^^^^^ recursive opaque type
+LL |
+LL | || closure_sig()
+ | ---------------- returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:21]`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:53:23
|
LL | fn generator_sig() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `[closure@$DIR/recursive-impl-trait-type-indirect.rs:55:5: 55:23]`
+ | ^^^^^^^^^^ recursive opaque type
+LL |
+LL | || generator_sig()
+ | ------------------ returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:55:5: 55:23]`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:58:27
|
-LL | fn generator_capture() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:61:5: 64:6 x:impl Sized {()}]`
+LL | fn generator_capture() -> impl Sized {
+ | ^^^^^^^^^^ recursive opaque type
+...
+LL | / move || {
+LL | | yield;
+LL | | x;
+LL | | }
+ | |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:61:5: 64:6 x:impl Sized {()}]`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:67:35
|
LL | fn substs_change() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `(impl Sized,)`
+ | ^^^^^^^^^^ recursive opaque type
+LL |
+LL | (substs_change::<&T>(),)
+ | ------------------------ returning here with type `(impl Sized,)`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:72:24
|
-LL | fn generator_hold() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:74:5: 78:6 {impl Sized, ()}]`
+LL | fn generator_hold() -> impl Sized {
+ | ^^^^^^^^^^ recursive opaque type
+LL |
+LL | / move || {
+LL | | let x = generator_hold();
+LL | | yield;
+LL | | x;
+LL | | }
+ | |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:74:5: 78:6 {impl Sized, ()}]`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:86:26
|
LL | fn mutual_recursion() -> impl Sync {
- | ^^^^^^^^^ expands to a recursive type
- |
- = note: type resolves to itself
+ | ^^^^^^^^^ recursive opaque type
+LL |
+LL | mutual_recursion_b()
+ | -------------------- returning here with type `impl Sized`
+...
+LL | fn mutual_recursion_b() -> impl Sized {
+ | ---------- returning this opaque type `impl Sized`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-indirect.rs:91:28
|
+LL | fn mutual_recursion() -> impl Sync {
+ | --------- returning this opaque type `impl std::marker::Sync`
+...
LL | fn mutual_recursion_b() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: type resolves to itself
+ | ^^^^^^^^^^ recursive opaque type
+LL |
+LL | mutual_recursion()
+ | ------------------ returning here with type `impl std::marker::Sync`
error: aborting due to 14 previous errors
diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.rs b/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.rs
index cfd9c0ec5b45b..818e40365394d 100644
--- a/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.rs
+++ b/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.rs
@@ -4,21 +4,21 @@
fn id(t: T) -> impl Sized { t }
-fn recursive_id() -> impl Sized { //~ ERROR opaque type expands to a recursive type
+fn recursive_id() -> impl Sized { //~ ERROR cannot resolve opaque type
id(recursive_id2())
}
-fn recursive_id2() -> impl Sized { //~ ERROR opaque type expands to a recursive type
+fn recursive_id2() -> impl Sized { //~ ERROR cannot resolve opaque type
id(recursive_id())
}
fn wrap(t: T) -> impl Sized { (t,) }
-fn recursive_wrap() -> impl Sized { //~ ERROR opaque type expands to a recursive type
+fn recursive_wrap() -> impl Sized { //~ ERROR cannot resolve opaque type
wrap(recursive_wrap2())
}
-fn recursive_wrap2() -> impl Sized { //~ ERROR opaque type expands to a recursive type
+fn recursive_wrap2() -> impl Sized { //~ ERROR cannot resolve opaque type
wrap(recursive_wrap())
}
diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.stderr
index 73c12f6137d24..65e0b8882c425 100644
--- a/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.stderr
+++ b/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.stderr
@@ -1,34 +1,46 @@
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-through-non-recursive.rs:7:22
|
+LL | fn id(t: T) -> impl Sized { t }
+ | ---------- returning this opaque type `impl Sized`
+LL |
LL | fn recursive_id() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: type resolves to itself
+ | ^^^^^^^^^^ recursive opaque type
+LL | id(recursive_id2())
+ | ------------------- returning here with type `impl Sized`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-through-non-recursive.rs:11:23
|
+LL | fn id(t: T) -> impl Sized { t }
+ | ---------- returning this opaque type `impl Sized`
+...
LL | fn recursive_id2() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: type resolves to itself
+ | ^^^^^^^^^^ recursive opaque type
+LL | id(recursive_id())
+ | ------------------ returning here with type `impl Sized`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-through-non-recursive.rs:17:24
|
+LL | fn wrap(t: T) -> impl Sized { (t,) }
+ | ---------- returning this opaque type `impl Sized`
+LL |
LL | fn recursive_wrap() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `((impl Sized,),)`
+ | ^^^^^^^^^^ recursive opaque type
+LL | wrap(recursive_wrap2())
+ | ----------------------- returning here with type `impl Sized`
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/recursive-impl-trait-type-through-non-recursive.rs:21:25
|
+LL | fn wrap(t: T) -> impl Sized { (t,) }
+ | ---------- returning this opaque type `impl Sized`
+...
LL | fn recursive_wrap2() -> impl Sized {
- | ^^^^^^^^^^ expands to a recursive type
- |
- = note: expanded type is `((impl Sized,),)`
+ | ^^^^^^^^^^ recursive opaque type
+LL | wrap(recursive_wrap())
+ | ---------------------- returning here with type `impl Sized`
error: aborting due to 4 previous errors
diff --git a/src/test/ui/impl-trait/where-allowed-2.rs b/src/test/ui/impl-trait/where-allowed-2.rs
index f7744ef1b3eae..462508f306ef3 100644
--- a/src/test/ui/impl-trait/where-allowed-2.rs
+++ b/src/test/ui/impl-trait/where-allowed-2.rs
@@ -3,7 +3,6 @@
use std::fmt::Debug;
// Disallowed
-fn in_adt_in_return() -> Vec { panic!() }
-//~^ ERROR opaque type expands to a recursive type
+fn in_adt_in_return() -> Vec { panic!() } //~ ERROR cannot resolve opaque type
fn main() {}
diff --git a/src/test/ui/impl-trait/where-allowed-2.stderr b/src/test/ui/impl-trait/where-allowed-2.stderr
index 1de15014c1f8d..6c0e0a4c9a38b 100644
--- a/src/test/ui/impl-trait/where-allowed-2.stderr
+++ b/src/test/ui/impl-trait/where-allowed-2.stderr
@@ -1,10 +1,12 @@
-error[E0720]: opaque type expands to a recursive type
+error[E0720]: cannot resolve opaque type to a concrete type
--> $DIR/where-allowed-2.rs:6:30
|
LL | fn in_adt_in_return() -> Vec { panic!() }
- | ^^^^^^^^^^ expands to a recursive type
+ | ^^^^^^^^^^ -------- this returned value is of `!` type
+ | |
+ | cannot resolve to a concrete type
|
- = note: type resolves to itself
+ = help: this error will resolve once the item's body returns a concrete type
error: aborting due to previous error
From 8f12485335f506f4c9633305f323e55cdc3c8c2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?=
Date: Mon, 15 Jun 2020 12:11:28 -0700
Subject: [PATCH 20/28] review comments
---
src/librustc_typeck/check/mod.rs | 22 +++++----------
.../impl-trait/binding-without-value.stderr | 4 +--
.../infinite-impl-trait-issue-38064.stderr | 4 +--
.../recursive-impl-trait-type-direct.stderr | 2 +-
.../recursive-impl-trait-type-indirect.stderr | 28 +++++++++----------
...pl-trait-type-through-non-recursive.stderr | 8 +++---
src/test/ui/impl-trait/where-allowed-2.stderr | 4 +--
7 files changed, 32 insertions(+), 40 deletions(-)
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index d4db32abe2a16..1fff8fff9c03a 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1741,8 +1741,7 @@ fn get_owner_return_paths(
/// If all the return expressions evaluate to `!`, then we explain that the error will go away
/// after changing it. This can happen when a user uses `panic!()` or similar as a placeholder.
fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
- let mut err =
- struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type to a concrete type");
+ let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
let mut label = false;
if let Some((hir_id, visitor)) = get_owner_return_paths(tcx, def_id) {
@@ -1751,7 +1750,6 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
.returns
.iter()
.filter_map(|expr| tables.node_type_opt(expr.hir_id))
- .map(|ty| tcx.infer_ctxt().enter(|infcx| infcx.resolve_vars_if_possible(&ty)))
.all(|ty| matches!(ty.kind, ty::Never))
{
let spans = visitor
@@ -1782,9 +1780,6 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
.iter()
.filter_map(|e| tables.node_type_opt(e.hir_id).map(|t| (e.span, t)))
.filter(|(_, ty)| !matches!(ty.kind, ty::Never))
- .map(|(sp, ty)| {
- (sp, tcx.infer_ctxt().enter(|infcx| infcx.resolve_vars_if_possible(&ty)))
- })
{
struct VisitTypes(Vec);
impl<'tcx> ty::fold::TypeVisitor<'tcx> for VisitTypes {
@@ -1812,7 +1807,7 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
}
}
if !label {
- err.span_label(span, "cannot resolve to a concrete type");
+ err.span_label(span, "cannot resolve opaque type");
}
err.emit();
}
@@ -1824,9 +1819,9 @@ fn binding_opaque_type_cycle_error(
span: Span,
partially_expanded_type: Ty<'tcx>,
) {
- let mut err =
- struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type to a concrete type");
- err.span_label(span, "cannot resolve to a concrete type");
+ let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
+ err.span_label(span, "cannot resolve opaque type");
+ // Find the the owner that declared this `impl Trait` type.
let hir_id = tcx.hir().as_local_hir_id(def_id);
let mut prev_hir_id = hir_id;
let mut hir_id = tcx.hir().get_parent_node(hir_id);
@@ -1855,15 +1850,12 @@ fn binding_opaque_type_cycle_error(
let hir_id = tcx.hir().as_local_hir_id(def_id);
let tables =
tcx.typeck_tables_of(tcx.hir().local_def_id(tcx.hir().get_parent_item(hir_id)));
- let ty = tables.node_type_opt(expr.hir_id);
- if let Some(ty) =
- tcx.infer_ctxt().enter(|infcx| infcx.resolve_vars_if_possible(&ty))
- {
+ if let Some(ty) = tables.node_type_opt(expr.hir_id) {
err.span_label(
expr.span,
&format!(
"this is of type `{}`, which doesn't constrain \
- `{}` enough to arrive to a concrete type",
+ `{}` enough to arrive to a concrete type",
ty, partially_expanded_type
),
);
diff --git a/src/test/ui/impl-trait/binding-without-value.stderr b/src/test/ui/impl-trait/binding-without-value.stderr
index 1898af5b63eeb..0d2faeaf85d10 100644
--- a/src/test/ui/impl-trait/binding-without-value.stderr
+++ b/src/test/ui/impl-trait/binding-without-value.stderr
@@ -1,8 +1,8 @@
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/binding-without-value.rs:5:13
|
LL | let _ : impl Copy;
- | - ^^^^^^^^^ cannot resolve to a concrete type
+ | - ^^^^^^^^^ cannot resolve opaque type
| |
| this binding might not have a concrete type
|
diff --git a/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr b/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr
index a38fb7cb56e9d..c538b77098a2d 100644
--- a/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr
+++ b/src/test/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr
@@ -1,4 +1,4 @@
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/infinite-impl-trait-issue-38064.rs:8:13
|
LL | fn foo() -> impl Quux {
@@ -10,7 +10,7 @@ LL | Foo(bar())
LL | fn bar() -> impl Quux {
| --------- returning this opaque type `foo::Foo`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/infinite-impl-trait-issue-38064.rs:14:13
|
LL | fn foo() -> impl Quux {
diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr
index 5149d42370c75..5a3027ec751a9 100644
--- a/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr
+++ b/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr
@@ -1,4 +1,4 @@
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-direct.rs:5:14
|
LL | fn test() -> impl Sized {
diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
index 0bf362e9a6d4a..75ff9e078cc2c 100644
--- a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
+++ b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
@@ -1,4 +1,4 @@
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:7:22
|
LL | fn option(i: i32) -> impl Sized {
@@ -9,7 +9,7 @@ LL | if i < 0 { None } else { Some((option(i - 1), i)) }
| |
| returning here with type `std::option::Option<(impl Sized, i32)>`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:12:15
|
LL | fn tuple() -> impl Sized {
@@ -18,7 +18,7 @@ LL |
LL | (tuple(),)
| ---------- returning here with type `(impl Sized,)`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:17:15
|
LL | fn array() -> impl Sized {
@@ -27,7 +27,7 @@ LL |
LL | [array()]
| --------- returning here with type `[impl Sized; 1]`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:22:13
|
LL | fn ptr() -> impl Sized {
@@ -36,7 +36,7 @@ LL |
LL | &ptr() as *const _
| ------------------ returning here with type `*const impl Sized`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:27:16
|
LL | fn fn_ptr() -> impl Sized {
@@ -45,7 +45,7 @@ LL |
LL | fn_ptr as fn() -> _
| ------------------- returning here with type `fn() -> impl Sized`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:32:25
|
LL | fn closure_capture() -> impl Sized {
@@ -56,7 +56,7 @@ LL | | x;
LL | | }
| |_____- returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:35:5: 37:6 x:impl Sized]`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:40:29
|
LL | fn closure_ref_capture() -> impl Sized {
@@ -67,7 +67,7 @@ LL | | &x;
LL | | }
| |_____- returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:43:5: 45:6 x:impl Sized]`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:48:21
|
LL | fn closure_sig() -> impl Sized {
@@ -76,7 +76,7 @@ LL |
LL | || closure_sig()
| ---------------- returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:21]`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:53:23
|
LL | fn generator_sig() -> impl Sized {
@@ -85,7 +85,7 @@ LL |
LL | || generator_sig()
| ------------------ returning here with type `[closure@$DIR/recursive-impl-trait-type-indirect.rs:55:5: 55:23]`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:58:27
|
LL | fn generator_capture() -> impl Sized {
@@ -97,7 +97,7 @@ LL | | x;
LL | | }
| |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:61:5: 64:6 x:impl Sized {()}]`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:67:35
|
LL | fn substs_change() -> impl Sized {
@@ -106,7 +106,7 @@ LL |
LL | (substs_change::<&T>(),)
| ------------------------ returning here with type `(impl Sized,)`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:72:24
|
LL | fn generator_hold() -> impl Sized {
@@ -119,7 +119,7 @@ LL | | x;
LL | | }
| |_____- returning here with type `[generator@$DIR/recursive-impl-trait-type-indirect.rs:74:5: 78:6 {impl Sized, ()}]`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:86:26
|
LL | fn mutual_recursion() -> impl Sync {
@@ -131,7 +131,7 @@ LL | mutual_recursion_b()
LL | fn mutual_recursion_b() -> impl Sized {
| ---------- returning this opaque type `impl Sized`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-indirect.rs:91:28
|
LL | fn mutual_recursion() -> impl Sync {
diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.stderr
index 65e0b8882c425..fbc58837a8e94 100644
--- a/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.stderr
+++ b/src/test/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.stderr
@@ -1,4 +1,4 @@
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-through-non-recursive.rs:7:22
|
LL | fn id(t: T) -> impl Sized { t }
@@ -9,7 +9,7 @@ LL | fn recursive_id() -> impl Sized {
LL | id(recursive_id2())
| ------------------- returning here with type `impl Sized`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-through-non-recursive.rs:11:23
|
LL | fn id(t: T) -> impl Sized { t }
@@ -20,7 +20,7 @@ LL | fn recursive_id2() -> impl Sized {
LL | id(recursive_id())
| ------------------ returning here with type `impl Sized`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-through-non-recursive.rs:17:24
|
LL | fn wrap(t: T) -> impl Sized { (t,) }
@@ -31,7 +31,7 @@ LL | fn recursive_wrap() -> impl Sized {
LL | wrap(recursive_wrap2())
| ----------------------- returning here with type `impl Sized`
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/recursive-impl-trait-type-through-non-recursive.rs:21:25
|
LL | fn wrap(t: T) -> impl Sized { (t,) }
diff --git a/src/test/ui/impl-trait/where-allowed-2.stderr b/src/test/ui/impl-trait/where-allowed-2.stderr
index 6c0e0a4c9a38b..b8e06725cbcdd 100644
--- a/src/test/ui/impl-trait/where-allowed-2.stderr
+++ b/src/test/ui/impl-trait/where-allowed-2.stderr
@@ -1,10 +1,10 @@
-error[E0720]: cannot resolve opaque type to a concrete type
+error[E0720]: cannot resolve opaque type
--> $DIR/where-allowed-2.rs:6:30
|
LL | fn in_adt_in_return() -> Vec { panic!() }
| ^^^^^^^^^^ -------- this returned value is of `!` type
| |
- | cannot resolve to a concrete type
+ | cannot resolve opaque type
|
= help: this error will resolve once the item's body returns a concrete type
From c06876c90437c7eecd1dc246d3515d6211397f16 Mon Sep 17 00:00:00 2001
From: Wesley Wiser
Date: Wed, 22 Apr 2020 21:31:51 -0400
Subject: [PATCH 21/28] [const-prop] Remove `ConstPropMode::NoPropagation`
This mode is unnecessary because it's always ok to evaluate the
right-hand side of assignments even if the left-hand side should not
have reads propagated.
---
src/librustc_mir/transform/const_prop.rs | 47 +++++++++----------
.../rustc.main.ConstProp.diff | 6 ++-
.../32bit/rustc.main.SimplifyArmIdentity.diff | 9 ++--
.../64bit/rustc.main.SimplifyArmIdentity.diff | 9 ++--
.../rustc.main.SimplifyArmIdentity.diff | 11 ++---
.../rustc.map.SimplifyLocals.diff | 8 +++-
6 files changed, 45 insertions(+), 45 deletions(-)
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 83ed2fc2d439b..4dbe6642a3043 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -721,8 +721,6 @@ enum ConstPropMode {
OnlyInsideOwnBlock,
/// The `Local` can be propagated into but reads cannot be propagated.
OnlyPropagateInto,
- /// No propagation is allowed at all.
- NoPropagation,
}
struct CanConstProp {
@@ -793,7 +791,7 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
"local {:?} can't be propagated because of multiple assignments",
local,
);
- *other = ConstPropMode::NoPropagation;
+ *other = ConstPropMode::OnlyPropagateInto;
}
}
}
@@ -820,7 +818,7 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
| MutatingUse(MutatingUseContext::Borrow)
| MutatingUse(MutatingUseContext::AddressOf) => {
trace!("local {:?} can't be propagaged because it's used: {:?}", local, context);
- self.can_const_prop[local] = ConstPropMode::NoPropagation;
+ self.can_const_prop[local] = ConstPropMode::OnlyPropagateInto;
}
}
}
@@ -852,31 +850,28 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) {
let can_const_prop = self.can_const_prop[place.local];
if let Some(()) = self.const_prop(rval, place_layout, source_info, place) {
- if can_const_prop != ConstPropMode::NoPropagation {
- // This will return None for variables that are from other blocks,
- // so it should be okay to propagate from here on down.
- if let Some(value) = self.get_const(place) {
- if self.should_const_prop(value) {
- trace!("replacing {:?} with {:?}", rval, value);
- self.replace_with_const(rval, value, source_info);
- if can_const_prop == ConstPropMode::FullConstProp
- || can_const_prop == ConstPropMode::OnlyInsideOwnBlock
- {
- trace!("propagated into {:?}", place);
- }
- }
- if can_const_prop == ConstPropMode::OnlyInsideOwnBlock {
- trace!(
- "found local restricted to its block. Will remove it from const-prop after block is finished. Local: {:?}",
- place.local
- );
- self.locals_of_current_block.insert(place.local);
+ // This will return None for variables that are from other blocks,
+ // so it should be okay to propagate from here on down.
+ if let Some(value) = self.get_const(place) {
+ if self.should_const_prop(value) {
+ trace!("replacing {:?} with {:?}", rval, value);
+ self.replace_with_const(rval, value, source_info);
+ if can_const_prop == ConstPropMode::FullConstProp
+ || can_const_prop == ConstPropMode::OnlyInsideOwnBlock
+ {
+ trace!("propagated into {:?}", place);
}
}
}
- if can_const_prop == ConstPropMode::OnlyPropagateInto
- || can_const_prop == ConstPropMode::NoPropagation
- {
+ if can_const_prop == ConstPropMode::OnlyInsideOwnBlock {
+ trace!(
+ "found local restricted to its block. Will remove it from const-prop after block is finished. Local: {:?}",
+ place.local
+ );
+ self.locals_of_current_block.insert(place.local);
+ }
+
+ if can_const_prop == ConstPropMode::OnlyPropagateInto {
trace!("can't propagate into {:?}", place);
if place.local != RETURN_PLACE {
Self::remove_const(&mut self.ecx, place.local);
diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref/rustc.main.ConstProp.diff
index 44203ac327ab1..0d703068d41f4 100644
--- a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref/rustc.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref/rustc.main.ConstProp.diff
@@ -23,13 +23,15 @@
// + ty: i32
// + val: Value(Scalar(0x0000002a))
// mir::Constant
- // + span: $DIR/mutable_variable_aggregate_mut_ref.rs:5:18: 5:20
+- // + span: $DIR/mutable_variable_aggregate_mut_ref.rs:5:18: 5:20
++ // + span: $DIR/mutable_variable_aggregate_mut_ref.rs:5:17: 5:25
// + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x0000002b))
// mir::Constant
- // + span: $DIR/mutable_variable_aggregate_mut_ref.rs:5:22: 5:24
+- // + span: $DIR/mutable_variable_aggregate_mut_ref.rs:5:22: 5:24
++ // + span: $DIR/mutable_variable_aggregate_mut_ref.rs:5:17: 5:25
// + literal: Const { ty: i32, val: Value(Scalar(0x0000002b)) }
StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:6:9: 6:10
_2 = &mut _1; // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:6:13: 6:19
diff --git a/src/test/mir-opt/simplify-arm-identity/32bit/rustc.main.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify-arm-identity/32bit/rustc.main.SimplifyArmIdentity.diff
index dfd6d6f0f2ecd..94759dca038b1 100644
--- a/src/test/mir-opt/simplify-arm-identity/32bit/rustc.main.SimplifyArmIdentity.diff
+++ b/src/test/mir-opt/simplify-arm-identity/32bit/rustc.main.SimplifyArmIdentity.diff
@@ -39,14 +39,13 @@
}
bb1: {
- ((_2 as Foo).0: u8) = const 0u8; // scope 1 at $DIR/simplify-arm-identity.rs:21:21: 21:32
+ _2 = const Dst::Foo(0u8); // scope 1 at $DIR/simplify-arm-identity.rs:21:21: 21:32
// ty::Const
- // + ty: u8
+ // + ty: Dst
// + val: Value(Scalar(0x00))
// mir::Constant
- // + span: $DIR/simplify-arm-identity.rs:21:30: 21:31
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
- discriminant(_2) = 0; // scope 1 at $DIR/simplify-arm-identity.rs:21:21: 21:32
+ // + span: $DIR/simplify-arm-identity.rs:21:21: 21:32
+ // + literal: Const { ty: Dst, val: Value(Scalar(0x00)) }
goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:19:18: 22:6
}
diff --git a/src/test/mir-opt/simplify-arm-identity/64bit/rustc.main.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify-arm-identity/64bit/rustc.main.SimplifyArmIdentity.diff
index f2bbd19586993..ba21f16b685d4 100644
--- a/src/test/mir-opt/simplify-arm-identity/64bit/rustc.main.SimplifyArmIdentity.diff
+++ b/src/test/mir-opt/simplify-arm-identity/64bit/rustc.main.SimplifyArmIdentity.diff
@@ -39,14 +39,13 @@
}
bb1: {
- ((_2 as Foo).0: u8) = const 0u8; // scope 1 at $DIR/simplify-arm-identity.rs:21:21: 21:32
+ _2 = const Dst::Foo(0u8); // scope 1 at $DIR/simplify-arm-identity.rs:21:21: 21:32
// ty::Const
- // + ty: u8
+ // + ty: Dst
// + val: Value(Scalar(0x00))
// mir::Constant
- // + span: $DIR/simplify-arm-identity.rs:21:30: 21:31
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
- discriminant(_2) = 0; // scope 1 at $DIR/simplify-arm-identity.rs:21:21: 21:32
+ // + span: $DIR/simplify-arm-identity.rs:21:21: 21:32
+ // + literal: Const { ty: Dst, val: Value(Scalar(0x00)) }
goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:19:18: 22:6
}
diff --git a/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff
index b2517cb7012b4..e7373391b79c7 100644
--- a/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff
+++ b/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff
@@ -33,15 +33,14 @@
}
bb1: {
- ((_2 as Foo).0: u8) = const 0u8; // scope 1 at $DIR/simplify-arm-identity.rs:20:21: 20:32
+ _2 = const Dst::Foo(0u8); // bb1[0]: scope 1 at $DIR/simplify-arm-identity.rs:20:21: 20:32
// ty::Const
- // + ty: u8
+ // + ty: Dst
// + val: Value(Scalar(0x00))
// mir::Constant
- // + span: $DIR/simplify-arm-identity.rs:20:30: 20:31
- // + literal: Const { ty: u8, val: Value(Scalar(0x00)) }
- discriminant(_2) = 0; // scope 1 at $DIR/simplify-arm-identity.rs:20:21: 20:32
- goto -> bb4; // scope 1 at $DIR/simplify-arm-identity.rs:18:18: 21:6
+ // + span: $DIR/simplify-arm-identity.rs:20:21: 20:32
+ // + literal: Const { ty: Dst, val: Value(Scalar(0x00)) }
+ goto -> bb4; // bb1[1]: scope 1 at $DIR/simplify-arm-identity.rs:18:18: 21:6
}
bb2: {
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff
index 0ca54af85e3b6..a97fa98a7b09e 100644
--- a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff
+++ b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff
@@ -24,7 +24,13 @@
}
bb2: {
- discriminant(_0) = 0; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:17: 3:21
+ _0 = const std::option::Option::>::None; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:17: 3:21
+ // ty::Const
+ // + ty: std::option::Option>
+ // + val: Value(Scalar(0x0000000000000000))
+ // mir::Constant
+ // + span: $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:17: 3:21
+ // + literal: Const { ty: std::option::Option>, val: Value(Scalar(0x0000000000000000)) }
goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6
}
From 2f49d554ff1afd1633a01d6b84192ad0147d9097 Mon Sep 17 00:00:00 2001
From: Wesley Wiser
Date: Tue, 5 May 2020 09:44:08 -0400
Subject: [PATCH 22/28] Add EMIR_MIR_FOR_EACH_BIT_WIDTH to failing test
---
...ocals-removes-unused-discriminant-reads.rs | 1 +
.../32bit/rustc.map.SimplifyLocals.diff | 42 +++++++++++++++++++
.../{ => 64bit}/rustc.map.SimplifyLocals.diff | 0
3 files changed, 43 insertions(+)
create mode 100644 src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/32bit/rustc.map.SimplifyLocals.diff
rename src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/{ => 64bit}/rustc.map.SimplifyLocals.diff (100%)
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs
index 067fa879b4038..7047b542aa607 100644
--- a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs
+++ b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs
@@ -9,4 +9,5 @@ fn main() {
map(None);
}
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
// EMIT_MIR rustc.map.SimplifyLocals.diff
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/32bit/rustc.map.SimplifyLocals.diff b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/32bit/rustc.map.SimplifyLocals.diff
new file mode 100644
index 0000000000000..2f78671763d51
--- /dev/null
+++ b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/32bit/rustc.map.SimplifyLocals.diff
@@ -0,0 +1,42 @@
+- // MIR for `map` before SimplifyLocals
++ // MIR for `map` after SimplifyLocals
+
+ fn map(_1: std::option::Option>) -> std::option::Option> {
+ debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:8: 1:9
+ let mut _0: std::option::Option>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:31: 1:46
+ let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
+ let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
+- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:25: 4:26
+- let mut _5: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
+- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
+ scope 1 {
+ debug x => _3; // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15
+ }
+
+ bb0: {
+ _2 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
+ switchInt(move _2) -> [0isize: bb2, otherwise: bb1]; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13
+ }
+
+ bb1: {
+ _0 = move _1; // scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27
+ goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6
+ }
+
+ bb2: {
+ _0 = const std::option::Option::>::None; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:17: 3:21
+ // ty::Const
+ // + ty: std::option::Option>
+ // + val: Value(Scalar(0x00000000))
+ // mir::Constant
+ // + span: $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:17: 3:21
+ // + literal: Const { ty: std::option::Option>, val: Value(Scalar(0x00000000)) }
+ goto -> bb3; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6
+ }
+
+ bb3: {
+- _5 = discriminant(_1); // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2
+ return; // scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:2: 6:2
+ }
+ }
+
diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/64bit/rustc.map.SimplifyLocals.diff
similarity index 100%
rename from src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff
rename to src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/64bit/rustc.map.SimplifyLocals.diff
From 0265e4e61bcd51b11f0b13b712245feb9c59ab50 Mon Sep 17 00:00:00 2001
From: Ralf Jung
Date: Tue, 16 Jun 2020 09:25:29 +0200
Subject: [PATCH 23/28] add tracking issue
---
src/libcore/ptr/mod.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index 199f08c3d5058..30c0f9a375714 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -1426,7 +1426,7 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L }
/// let raw_f2 = ptr::raw_const!(packed.f2);
/// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
/// ```
-#[unstable(feature = "raw_ref_macros", issue = "none")]
+#[unstable(feature = "raw_ref_macros", issue = "73394")]
#[rustc_macro_transparency = "semitransparent"]
#[allow_internal_unstable(raw_ref_op)]
pub macro raw_const($e:expr) {
@@ -1460,7 +1460,7 @@ pub macro raw_const($e:expr) {
/// 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")]
+#[unstable(feature = "raw_ref_macros", issue = "73394")]
#[rustc_macro_transparency = "semitransparent"]
#[allow_internal_unstable(raw_ref_op)]
pub macro raw_mut($e:expr) {
From 0bcefd9b5e68eb3a026843ed7b624761bea2de1e Mon Sep 17 00:00:00 2001
From: Ralf Jung
Date: Sun, 31 May 2020 12:13:29 +0200
Subject: [PATCH 24/28] remove visit_terminator_kind from MIR visitor
---
src/librustc_codegen_ssa/mir/analyze.rs | 6 +++---
src/librustc_middle/mir/visit.rs | 14 +-------------
src/librustc_mir/borrow_check/invalidation.rs | 8 ++++----
src/librustc_mir/borrow_check/used_muts.rs | 16 ++++++++++++----
src/librustc_mir/monomorphize/collector.rs | 8 ++++----
.../transform/check_consts/resolver.rs | 7 ++++---
src/librustc_mir/transform/generator.rs | 6 +++---
src/librustc_mir/transform/inline.rs | 12 ++++++------
src/librustc_mir/transform/no_landing_pads.rs | 6 +++---
src/librustc_mir/transform/promote_consts.rs | 6 +++---
10 files changed, 43 insertions(+), 46 deletions(-)
diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs
index 61692280d2a77..db935c2b3e265 100644
--- a/src/librustc_codegen_ssa/mir/analyze.rs
+++ b/src/librustc_codegen_ssa/mir/analyze.rs
@@ -234,8 +234,8 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
self.visit_rvalue(rvalue, location);
}
- fn visit_terminator_kind(&mut self, kind: &mir::TerminatorKind<'tcx>, location: Location) {
- let check = match *kind {
+ fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) {
+ let check = match terminator.kind {
mir::TerminatorKind::Call { func: mir::Operand::Constant(ref c), ref args, .. } => {
match c.literal.ty.kind {
ty::FnDef(did, _) => Some((did, args)),
@@ -259,7 +259,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
}
}
- self.super_terminator_kind(kind, location);
+ self.super_terminator(terminator, location);
}
fn visit_place(&mut self, place: &mir::Place<'tcx>, context: PlaceContext, location: Location) {
diff --git a/src/librustc_middle/mir/visit.rs b/src/librustc_middle/mir/visit.rs
index 5f9fcdca516b1..1c5ed837b5131 100644
--- a/src/librustc_middle/mir/visit.rs
+++ b/src/librustc_middle/mir/visit.rs
@@ -108,12 +108,6 @@ macro_rules! make_mir_visitor {
self.super_terminator(terminator, location);
}
- fn visit_terminator_kind(&mut self,
- kind: & $($mutability)? TerminatorKind<'tcx>,
- location: Location) {
- self.super_terminator_kind(kind, location);
- }
-
fn visit_assert_message(&mut self,
msg: & $($mutability)? AssertMessage<'tcx>,
location: Location) {
@@ -413,16 +407,10 @@ macro_rules! make_mir_visitor {
fn super_terminator(&mut self,
terminator: &$($mutability)? Terminator<'tcx>,
- location: Location) {
+ source_location: Location) {
let Terminator { source_info, kind } = terminator;
self.visit_source_info(source_info);
- self.visit_terminator_kind(kind, location);
- }
-
- fn super_terminator_kind(&mut self,
- kind: & $($mutability)? TerminatorKind<'tcx>,
- source_location: Location) {
match kind {
TerminatorKind::Goto { .. } |
TerminatorKind::Resume |
diff --git a/src/librustc_mir/borrow_check/invalidation.rs b/src/librustc_mir/borrow_check/invalidation.rs
index 17fa641ae6c17..e9475937de228 100644
--- a/src/librustc_mir/borrow_check/invalidation.rs
+++ b/src/librustc_mir/borrow_check/invalidation.rs
@@ -2,7 +2,7 @@ use rustc_data_structures::graph::dominators::Dominators;
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{BasicBlock, Body, Location, Place, Rvalue};
use rustc_middle::mir::{BorrowKind, Mutability, Operand};
-use rustc_middle::mir::{InlineAsmOperand, TerminatorKind};
+use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind};
use rustc_middle::mir::{Statement, StatementKind};
use rustc_middle::ty::TyCtxt;
@@ -112,10 +112,10 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
self.super_statement(statement, location);
}
- fn visit_terminator_kind(&mut self, kind: &TerminatorKind<'tcx>, location: Location) {
+ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
self.check_activations(location);
- match kind {
+ match &terminator.kind {
TerminatorKind::SwitchInt { ref discr, switch_ty: _, values: _, targets: _ } => {
self.consume_operand(location, discr);
}
@@ -222,7 +222,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
}
}
- self.super_terminator_kind(kind, location);
+ self.super_terminator(terminator, location);
}
}
diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs
index 2da72f3bcc517..0216298463470 100644
--- a/src/librustc_mir/borrow_check/used_muts.rs
+++ b/src/librustc_mir/borrow_check/used_muts.rs
@@ -1,5 +1,7 @@
use rustc_middle::mir::visit::{PlaceContext, Visitor};
-use rustc_middle::mir::{Local, Location, Place, Statement, StatementKind, TerminatorKind};
+use rustc_middle::mir::{
+ Local, Location, Place, Statement, StatementKind, Terminator, TerminatorKind,
+};
use rustc_data_structures::fx::FxHashSet;
@@ -62,9 +64,9 @@ impl GatherUsedMutsVisitor<'_, '_, '_> {
}
impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tcx> {
- fn visit_terminator_kind(&mut self, kind: &TerminatorKind<'tcx>, _location: Location) {
- debug!("visit_terminator_kind: kind={:?}", kind);
- match &kind {
+ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, _location: Location) {
+ debug!("visit_terminator: terminator={:?}", terminator);
+ match &terminator.kind {
TerminatorKind::Call { destination: Some((into, _)), .. } => {
self.remove_never_initialized_mut_locals(*into);
}
@@ -73,6 +75,8 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
}
_ => {}
}
+
+ // FIXME: no super_terminator?
}
fn visit_statement(&mut self, statement: &Statement<'tcx>, _location: Location) {
@@ -84,6 +88,8 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
);
self.remove_never_initialized_mut_locals(*into);
}
+
+ // FIXME: no super_statement?
}
fn visit_local(&mut self, local: &Local, place_context: PlaceContext, location: Location) {
@@ -101,5 +107,7 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
}
}
}
+
+ // FIXME: no super_local?
}
}
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 994d1e69f2e3e..ac19d59f04fb8 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -616,11 +616,11 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
self.super_const(constant);
}
- fn visit_terminator_kind(&mut self, kind: &mir::TerminatorKind<'tcx>, location: Location) {
- debug!("visiting terminator {:?} @ {:?}", kind, location);
+ fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) {
+ debug!("visiting terminator {:?} @ {:?}", terminator, location);
let tcx = self.tcx;
- match *kind {
+ match terminator.kind {
mir::TerminatorKind::Call { ref func, .. } => {
let callee_ty = func.ty(self.body, tcx);
let callee_ty = self.monomorphize(callee_ty);
@@ -663,7 +663,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
| mir::TerminatorKind::FalseUnwind { .. } => bug!(),
}
- self.super_terminator_kind(kind, location);
+ self.super_terminator(terminator, location);
}
fn visit_local(
diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/src/librustc_mir/transform/check_consts/resolver.rs
index a81d7a23be2fb..c67545d5b39e4 100644
--- a/src/librustc_mir/transform/check_consts/resolver.rs
+++ b/src/librustc_mir/transform/check_consts/resolver.rs
@@ -121,11 +121,12 @@ where
self.super_assign(place, rvalue, location);
}
- fn visit_terminator_kind(&mut self, kind: &mir::TerminatorKind<'tcx>, location: Location) {
+ fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) {
// The effect of assignment to the return place in `TerminatorKind::Call` is not applied
// here; that occurs in `apply_call_return_effect`.
- if let mir::TerminatorKind::DropAndReplace { value, location: dest, .. } = kind {
+ if let mir::TerminatorKind::DropAndReplace { value, location: dest, .. } = &terminator.kind
+ {
let qualif = qualifs::in_operand::(
self.ccx,
&mut |l| self.qualifs_per_local.contains(l),
@@ -139,7 +140,7 @@ where
// We need to assign qualifs to the dropped location before visiting the operand that
// replaces it since qualifs can be cleared on move.
- self.super_terminator_kind(kind, location);
+ self.super_terminator(terminator, location);
}
}
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 25b6a51d91b97..7215f390d40d2 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -93,13 +93,13 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor<'tcx> {
}
}
- fn visit_terminator_kind(&mut self, kind: &mut TerminatorKind<'tcx>, location: Location) {
- match kind {
+ fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) {
+ match terminator.kind {
TerminatorKind::Return => {
// Do not replace the implicit `_0` access here, as that's not possible. The
// transform already handles `return` correctly.
}
- _ => self.super_terminator_kind(kind, location),
+ _ => self.super_terminator(terminator, location),
}
}
}
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 47aa4fbf60c03..65400b58eebcb 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -731,14 +731,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
}
}
- fn visit_terminator_kind(&mut self, kind: &mut TerminatorKind<'tcx>, loc: Location) {
+ fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, loc: Location) {
// Don't try to modify the implicit `_0` access on return (`return` terminators are
// replaced down below anyways).
- if !matches!(kind, TerminatorKind::Return) {
- self.super_terminator_kind(kind, loc);
+ if !matches!(terminator.kind, TerminatorKind::Return) {
+ self.super_terminator(terminator, loc);
}
- match *kind {
+ match terminator.kind {
TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => bug!(),
TerminatorKind::Goto { ref mut target } => {
*target = self.update_target(*target);
@@ -782,11 +782,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
}
}
TerminatorKind::Return => {
- *kind = TerminatorKind::Goto { target: self.return_block };
+ terminator.kind = TerminatorKind::Goto { target: self.return_block };
}
TerminatorKind::Resume => {
if let Some(tgt) = self.cleanup_block {
- *kind = TerminatorKind::Goto { target: tgt }
+ terminator.kind = TerminatorKind::Goto { target: tgt }
}
}
TerminatorKind::Abort => {}
diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs
index 3bffafa1b2f9c..1d83733e4cd30 100644
--- a/src/librustc_mir/transform/no_landing_pads.rs
+++ b/src/librustc_mir/transform/no_landing_pads.rs
@@ -34,10 +34,10 @@ impl<'tcx> MutVisitor<'tcx> for NoLandingPads<'tcx> {
self.tcx
}
- fn visit_terminator_kind(&mut self, kind: &mut TerminatorKind<'tcx>, location: Location) {
- if let Some(unwind) = kind.unwind_mut() {
+ fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) {
+ if let Some(unwind) = terminator.kind.unwind_mut() {
unwind.take();
}
- self.super_terminator_kind(kind, location);
+ self.super_terminator(terminator, location);
}
}
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index e1311ccd3746f..f2179a21a3f43 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -216,10 +216,10 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
}
}
- fn visit_terminator_kind(&mut self, kind: &TerminatorKind<'tcx>, location: Location) {
- self.super_terminator_kind(kind, location);
+ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
+ self.super_terminator(terminator, location);
- match *kind {
+ match terminator.kind {
TerminatorKind::Call { ref func, .. } => {
if let ty::FnDef(def_id, _) = func.ty(self.ccx.body, self.ccx.tcx).kind {
let fn_sig = self.ccx.tcx.fn_sig(def_id);
From 302fb5039b6434ac1be617d3f4ac2863cf9ecfb1 Mon Sep 17 00:00:00 2001
From: Ralf Jung
Date: Sun, 31 May 2020 14:47:54 +0200
Subject: [PATCH 25/28] get rid of an unused 'span' field
---
src/librustc_mir/transform/promote_consts.rs | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index f2179a21a3f43..6624310326360 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -147,7 +147,6 @@ struct Collector<'a, 'tcx> {
ccx: &'a ConstCx<'a, 'tcx>,
temps: IndexVec,
candidates: Vec,
- span: Span,
}
impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
@@ -254,10 +253,6 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
_ => {}
}
}
-
- fn visit_source_info(&mut self, source_info: &SourceInfo) {
- self.span = source_info.span;
- }
}
pub fn collect_temps_and_candidates(
@@ -267,7 +262,6 @@ pub fn collect_temps_and_candidates(
let mut collector = Collector {
temps: IndexVec::from_elem(TempState::Undefined, &ccx.body.local_decls),
candidates: vec![],
- span: ccx.body.span,
ccx,
};
for (bb, data) in rpo {
From 046165a80729a22b9692614a658f105d833bfc8d Mon Sep 17 00:00:00 2001
From: Ralf Jung
Date: Wed, 10 Jun 2020 09:56:54 +0200
Subject: [PATCH 26/28] rename location field of Drop terminators to place
---
src/librustc_codegen_ssa/mir/block.rs | 4 +-
src/librustc_middle/mir/mod.rs | 10 ++---
src/librustc_middle/mir/type_foldable.rs | 14 +++---
src/librustc_middle/mir/visit.rs | 8 ++--
src/librustc_mir/borrow_check/invalidation.rs | 4 +-
src/librustc_mir/borrow_check/mod.rs | 4 +-
.../borrow_check/type_check/mod.rs | 4 +-
src/librustc_mir/borrow_check/used_muts.rs | 4 +-
.../dataflow/framework/direction.rs | 4 +-
.../dataflow/impls/borrowed_locals.rs | 4 +-
.../dataflow/move_paths/builder.rs | 10 ++---
src/librustc_mir/interpret/terminator.rs | 6 +--
src/librustc_mir/monomorphize/collector.rs | 6 +--
src/librustc_mir/shim.rs | 16 ++-----
.../transform/add_moves_for_packed_drops.rs | 14 +++---
.../check_consts/post_drop_elaboration.rs | 2 +-
.../transform/check_consts/resolver.rs | 7 ++-
.../transform/check_consts/validation.rs | 4 +-
src/librustc_mir/transform/elaborate_drops.rs | 44 +++++++++----------
src/librustc_mir/transform/generator.rs | 11 ++---
src/librustc_mir/transform/inline.rs | 8 ++--
src/librustc_mir/transform/promote_consts.rs | 2 +-
.../transform/qualify_min_const_fn.rs | 6 +--
src/librustc_mir/util/elaborate_drops.rs | 6 +--
src/librustc_mir_build/build/scope.rs | 8 ++--
25 files changed, 99 insertions(+), 111 deletions(-)
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index ef59ad486eefe..c486d5c64baa2 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -998,8 +998,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx.unreachable();
}
- mir::TerminatorKind::Drop { location, target, unwind } => {
- self.codegen_drop_terminator(helper, bx, location, target, unwind);
+ mir::TerminatorKind::Drop { place, target, unwind } => {
+ self.codegen_drop_terminator(helper, bx, place, target, unwind);
}
mir::TerminatorKind::Assert { ref cond, expected, ref msg, target, cleanup } => {
diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs
index 27848684706d6..f281c13517663 100644
--- a/src/librustc_middle/mir/mod.rs
+++ b/src/librustc_middle/mir/mod.rs
@@ -1112,7 +1112,7 @@ pub enum TerminatorKind<'tcx> {
Unreachable,
/// Drop the `Place`.
- Drop { location: Place<'tcx>, target: BasicBlock, unwind: Option },
+ Drop { place: Place<'tcx>, target: BasicBlock, unwind: Option },
/// Drop the `Place` and assign the new value over it. This ensures
/// that the assignment to `P` occurs *even if* the destructor for
@@ -1141,7 +1141,7 @@ pub enum TerminatorKind<'tcx> {
/// }
/// ```
DropAndReplace {
- location: Place<'tcx>,
+ place: Place<'tcx>,
value: Operand<'tcx>,
target: BasicBlock,
unwind: Option,
@@ -1607,9 +1607,9 @@ impl<'tcx> TerminatorKind<'tcx> {
Abort => write!(fmt, "abort"),
Yield { value, resume_arg, .. } => write!(fmt, "{:?} = yield({:?})", resume_arg, value),
Unreachable => write!(fmt, "unreachable"),
- Drop { location, .. } => write!(fmt, "drop({:?})", location),
- DropAndReplace { location, value, .. } => {
- write!(fmt, "replace({:?} <- {:?})", location, value)
+ Drop { place, .. } => write!(fmt, "drop({:?})", place),
+ DropAndReplace { place, value, .. } => {
+ write!(fmt, "replace({:?} <- {:?})", place, value)
}
Call { func, args, destination, .. } => {
if let Some((destination, _)) = destination {
diff --git a/src/librustc_middle/mir/type_foldable.rs b/src/librustc_middle/mir/type_foldable.rs
index 3f5d528d9e7c4..89f8f10449e2d 100644
--- a/src/librustc_middle/mir/type_foldable.rs
+++ b/src/librustc_middle/mir/type_foldable.rs
@@ -27,11 +27,11 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
values: values.clone(),
targets: targets.clone(),
},
- Drop { ref location, target, unwind } => {
- Drop { location: location.fold_with(folder), target, unwind }
+ Drop { ref place, target, unwind } => {
+ Drop { place: place.fold_with(folder), target, unwind }
}
- DropAndReplace { ref location, ref value, target, unwind } => DropAndReplace {
- location: location.fold_with(folder),
+ DropAndReplace { ref place, ref value, target, unwind } => DropAndReplace {
+ place: place.fold_with(folder),
value: value.fold_with(folder),
target,
unwind,
@@ -97,9 +97,9 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
SwitchInt { ref discr, switch_ty, .. } => {
discr.visit_with(visitor) || switch_ty.visit_with(visitor)
}
- Drop { ref location, .. } => location.visit_with(visitor),
- DropAndReplace { ref location, ref value, .. } => {
- location.visit_with(visitor) || value.visit_with(visitor)
+ Drop { ref place, .. } => place.visit_with(visitor),
+ DropAndReplace { ref place, ref value, .. } => {
+ place.visit_with(visitor) || value.visit_with(visitor)
}
Yield { ref value, .. } => value.visit_with(visitor),
Call { ref func, ref args, ref destination, .. } => {
diff --git a/src/librustc_middle/mir/visit.rs b/src/librustc_middle/mir/visit.rs
index 1c5ed837b5131..f2eda96f34ad1 100644
--- a/src/librustc_middle/mir/visit.rs
+++ b/src/librustc_middle/mir/visit.rs
@@ -449,25 +449,25 @@ macro_rules! make_mir_visitor {
}
TerminatorKind::Drop {
- location,
+ place,
target: _,
unwind: _,
} => {
self.visit_place(
- location,
+ place,
PlaceContext::MutatingUse(MutatingUseContext::Drop),
source_location
);
}
TerminatorKind::DropAndReplace {
- location,
+ place,
value,
target: _,
unwind: _,
} => {
self.visit_place(
- location,
+ place,
PlaceContext::MutatingUse(MutatingUseContext::Drop),
source_location
);
diff --git a/src/librustc_mir/borrow_check/invalidation.rs b/src/librustc_mir/borrow_check/invalidation.rs
index e9475937de228..fd8f17718e795 100644
--- a/src/librustc_mir/borrow_check/invalidation.rs
+++ b/src/librustc_mir/borrow_check/invalidation.rs
@@ -119,7 +119,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
TerminatorKind::SwitchInt { ref discr, switch_ty: _, values: _, targets: _ } => {
self.consume_operand(location, discr);
}
- TerminatorKind::Drop { location: drop_place, target: _, unwind: _ } => {
+ TerminatorKind::Drop { place: drop_place, target: _, unwind: _ } => {
self.access_place(
location,
*drop_place,
@@ -128,7 +128,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
);
}
TerminatorKind::DropAndReplace {
- location: drop_place,
+ place: drop_place,
value: ref new_value,
target: _,
unwind: _,
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index d099f48adc5c6..83691d439eb81 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -663,7 +663,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
TerminatorKind::SwitchInt { ref discr, switch_ty: _, values: _, targets: _ } => {
self.consume_operand(loc, (discr, span), flow_state);
}
- TerminatorKind::Drop { location: ref drop_place, target: _, unwind: _ } => {
+ TerminatorKind::Drop { place: ref drop_place, target: _, unwind: _ } => {
let tcx = self.infcx.tcx;
// Compute the type with accurate region information.
@@ -692,7 +692,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
);
}
TerminatorKind::DropAndReplace {
- location: drop_place,
+ place: drop_place,
value: ref new_value,
target: _,
unwind: _,
diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs
index 168612f9beec0..0eb0651d5fdc0 100644
--- a/src/librustc_mir/borrow_check/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/type_check/mod.rs
@@ -1558,8 +1558,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// no checks needed for these
}
- TerminatorKind::DropAndReplace { ref location, ref value, target: _, unwind: _ } => {
- let place_ty = location.ty(body, tcx).ty;
+ TerminatorKind::DropAndReplace { ref place, ref value, target: _, unwind: _ } => {
+ let place_ty = place.ty(body, tcx).ty;
let rv_ty = value.ty(body, tcx);
let locations = term_location.to_locations();
diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs
index 0216298463470..56764a4be5d91 100644
--- a/src/librustc_mir/borrow_check/used_muts.rs
+++ b/src/librustc_mir/borrow_check/used_muts.rs
@@ -70,8 +70,8 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
TerminatorKind::Call { destination: Some((into, _)), .. } => {
self.remove_never_initialized_mut_locals(*into);
}
- TerminatorKind::DropAndReplace { location, .. } => {
- self.remove_never_initialized_mut_locals(*location);
+ TerminatorKind::DropAndReplace { place, .. } => {
+ self.remove_never_initialized_mut_locals(*place);
}
_ => {}
}
diff --git a/src/librustc_mir/dataflow/framework/direction.rs b/src/librustc_mir/dataflow/framework/direction.rs
index 6c9cb529dc2f3..4512ae96c0833 100644
--- a/src/librustc_mir/dataflow/framework/direction.rs
+++ b/src/librustc_mir/dataflow/framework/direction.rs
@@ -441,8 +441,8 @@ impl Direction for Forward {
Goto { target } => propagate(target, exit_state),
Assert { target, cleanup: unwind, expected: _, msg: _, cond: _ }
- | Drop { target, unwind, location: _ }
- | DropAndReplace { target, unwind, value: _, location: _ }
+ | Drop { target, unwind, place: _ }
+ | DropAndReplace { target, unwind, value: _, place: _ }
| FalseUnwind { real_target: target, unwind } => {
if let Some(unwind) = unwind {
if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) {
diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
index 1d49a32e19645..70c916a089270 100644
--- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs
+++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
@@ -189,8 +189,8 @@ where
self.super_terminator(terminator, location);
match terminator.kind {
- mir::TerminatorKind::Drop { location: dropped_place, .. }
- | mir::TerminatorKind::DropAndReplace { location: dropped_place, .. } => {
+ mir::TerminatorKind::Drop { place: dropped_place, .. }
+ | mir::TerminatorKind::DropAndReplace { place: dropped_place, .. } => {
// See documentation for `unsound_ignore_borrow_on_drop` for an explanation.
if !self.ignore_borrow_on_drop {
self.trans.gen(dropped_place.local);
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 41c7bd95a96cc..7c8aa1db71ff8 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -387,13 +387,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
self.gather_init(place.as_ref(), InitKind::Deep);
}
- TerminatorKind::Drop { location, target: _, unwind: _ } => {
- self.gather_move(location);
+ TerminatorKind::Drop { place, target: _, unwind: _ } => {
+ self.gather_move(place);
}
- TerminatorKind::DropAndReplace { location, ref value, .. } => {
- self.create_move_path(location);
+ TerminatorKind::DropAndReplace { place, ref value, .. } => {
+ self.create_move_path(place);
self.gather_operand(value);
- self.gather_init(location.as_ref(), InitKind::Deep);
+ self.gather_init(place.as_ref(), InitKind::Deep);
}
TerminatorKind::Call {
ref func,
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index cd7621ea9752b..1d57fce39734e 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -91,10 +91,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}
- Drop { location, target, unwind } => {
- let place = self.eval_place(location)?;
+ Drop { place, target, unwind } => {
+ let place = self.eval_place(place)?;
let ty = place.layout.ty;
- trace!("TerminatorKind::drop: {:?}, type {}", location, ty);
+ trace!("TerminatorKind::drop: {:?}, type {}", place, ty);
let instance = Instance::resolve_drop_in_place(*self.tcx, ty);
self.drop_in_place(place, instance, target, unwind)?;
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index ac19d59f04fb8..5869445424102 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -626,9 +626,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
let callee_ty = self.monomorphize(callee_ty);
visit_fn_use(self.tcx, callee_ty, true, &mut self.output);
}
- mir::TerminatorKind::Drop { ref location, .. }
- | mir::TerminatorKind::DropAndReplace { ref location, .. } => {
- let ty = location.ty(self.body, self.tcx).ty;
+ mir::TerminatorKind::Drop { ref place, .. }
+ | mir::TerminatorKind::DropAndReplace { ref place, .. } => {
+ let ty = place.ty(self.body, self.tcx).ty;
let ty = self.monomorphize(ty);
visit_drop_use(self.tcx, ty, true, self.output);
}
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index f95fd9b9e90c5..71fff85153141 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -582,7 +582,7 @@ impl CloneShimBuilder<'tcx> {
self.block(
vec![],
TerminatorKind::Drop {
- location: self.tcx.mk_place_index(dest, beg),
+ place: self.tcx.mk_place_index(dest, beg),
target: BasicBlock::new(8),
unwind: None,
},
@@ -634,7 +634,7 @@ impl CloneShimBuilder<'tcx> {
self.block(
vec![],
TerminatorKind::Drop {
- location: previous_field,
+ place: previous_field,
target: previous_cleanup,
unwind: None,
},
@@ -799,11 +799,7 @@ fn build_call_shim<'tcx>(
block(
&mut blocks,
vec![],
- TerminatorKind::Drop {
- location: rcvr_place(),
- target: BasicBlock::new(2),
- unwind: None,
- },
+ TerminatorKind::Drop { place: rcvr_place(), target: BasicBlock::new(2), unwind: None },
false,
);
}
@@ -814,11 +810,7 @@ fn build_call_shim<'tcx>(
block(
&mut blocks,
vec![],
- TerminatorKind::Drop {
- location: rcvr_place(),
- target: BasicBlock::new(4),
- unwind: None,
- },
+ TerminatorKind::Drop { place: rcvr_place(), target: BasicBlock::new(4), unwind: None },
true,
);
diff --git a/src/librustc_mir/transform/add_moves_for_packed_drops.rs b/src/librustc_mir/transform/add_moves_for_packed_drops.rs
index 39ce2340aed21..a02d0f655600d 100644
--- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs
+++ b/src/librustc_mir/transform/add_moves_for_packed_drops.rs
@@ -64,8 +64,8 @@ fn add_moves_for_packed_drops_patch<'tcx>(
let terminator = data.terminator();
match terminator.kind {
- TerminatorKind::Drop { location, .. }
- if util::is_disaligned(tcx, body, param_env, location) =>
+ TerminatorKind::Drop { place, .. }
+ if util::is_disaligned(tcx, body, param_env, place) =>
{
add_move_for_packed_drop(tcx, body, &mut patch, terminator, loc, data.is_cleanup);
}
@@ -88,13 +88,13 @@ fn add_move_for_packed_drop<'tcx>(
is_cleanup: bool,
) {
debug!("add_move_for_packed_drop({:?} @ {:?})", terminator, loc);
- let (location, target, unwind) = match terminator.kind {
- TerminatorKind::Drop { ref location, target, unwind } => (location, target, unwind),
+ let (place, target, unwind) = match terminator.kind {
+ TerminatorKind::Drop { ref place, target, unwind } => (place, target, unwind),
_ => unreachable!(),
};
let source_info = terminator.source_info;
- let ty = location.ty(body, tcx).ty;
+ let ty = place.ty(body, tcx).ty;
let temp = patch.new_temp(ty, terminator.source_info.span);
let storage_dead_block = patch.new_block(BasicBlockData {
@@ -104,9 +104,9 @@ fn add_move_for_packed_drop<'tcx>(
});
patch.add_statement(loc, StatementKind::StorageLive(temp));
- patch.add_assign(loc, Place::from(temp), Rvalue::Use(Operand::Move(*location)));
+ patch.add_assign(loc, Place::from(temp), Rvalue::Use(Operand::Move(*place)));
patch.patch_terminator(
loc.block,
- TerminatorKind::Drop { location: Place::from(temp), target: storage_dead_block, unwind },
+ TerminatorKind::Drop { place: Place::from(temp), target: storage_dead_block, unwind },
);
}
diff --git a/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs b/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs
index 226e0e2049ebd..124606fb423e6 100644
--- a/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs
+++ b/src/librustc_mir/transform/check_consts/post_drop_elaboration.rs
@@ -78,7 +78,7 @@ impl Visitor<'tcx> for CheckLiveDrops<'mir, 'tcx> {
trace!("visit_terminator: terminator={:?} location={:?}", terminator, location);
match &terminator.kind {
- mir::TerminatorKind::Drop { location: dropped_place, .. } => {
+ mir::TerminatorKind::Drop { place: dropped_place, .. } => {
let dropped_ty = dropped_place.ty(self.body, self.tcx).ty;
if !NeedsDrop::in_any_value_of_ty(self.ccx, dropped_ty) {
return;
diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/src/librustc_mir/transform/check_consts/resolver.rs
index c67545d5b39e4..b8104292aab23 100644
--- a/src/librustc_mir/transform/check_consts/resolver.rs
+++ b/src/librustc_mir/transform/check_consts/resolver.rs
@@ -125,16 +125,15 @@ where
// The effect of assignment to the return place in `TerminatorKind::Call` is not applied
// here; that occurs in `apply_call_return_effect`.
- if let mir::TerminatorKind::DropAndReplace { value, location: dest, .. } = &terminator.kind
- {
+ if let mir::TerminatorKind::DropAndReplace { value, place, .. } = &terminator.kind {
let qualif = qualifs::in_operand::(
self.ccx,
&mut |l| self.qualifs_per_local.contains(l),
value,
);
- if !dest.is_indirect() {
- self.assign_qualif_direct(dest, qualif);
+ if !place.is_indirect() {
+ self.assign_qualif_direct(place, qualif);
}
}
diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs
index 428a74bcdcbfb..35a8df62cb83a 100644
--- a/src/librustc_mir/transform/check_consts/validation.rs
+++ b/src/librustc_mir/transform/check_consts/validation.rs
@@ -560,8 +560,8 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
// Forbid all `Drop` terminators unless the place being dropped is a local with no
// projections that cannot be `NeedsDrop`.
- TerminatorKind::Drop { location: dropped_place, .. }
- | TerminatorKind::DropAndReplace { location: dropped_place, .. } => {
+ TerminatorKind::Drop { place: dropped_place, .. }
+ | TerminatorKind::DropAndReplace { place: dropped_place, .. } => {
// If we are checking live drops after drop-elaboration, don't emit duplicate
// errors here.
if super::post_drop_elaboration::checking_enabled(self.tcx) {
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index e4129f447d532..1704d8baabdc8 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -85,15 +85,15 @@ fn find_dead_unwinds<'tcx>(
.iterate_to_fixpoint()
.into_results_cursor(body);
for (bb, bb_data) in body.basic_blocks().iter_enumerated() {
- let location = match bb_data.terminator().kind {
- TerminatorKind::Drop { ref location, unwind: Some(_), .. }
- | TerminatorKind::DropAndReplace { ref location, unwind: Some(_), .. } => location,
+ let place = match bb_data.terminator().kind {
+ TerminatorKind::Drop { ref place, unwind: Some(_), .. }
+ | TerminatorKind::DropAndReplace { ref place, unwind: Some(_), .. } => place,
_ => continue,
};
debug!("find_dead_unwinds @ {:?}: {:?}", bb, bb_data);
- let path = match env.move_data.rev_lookup.find(location.as_ref()) {
+ let path = match env.move_data.rev_lookup.find(place.as_ref()) {
LookupResult::Exact(e) => e,
LookupResult::Parent(..) => {
debug!("find_dead_unwinds: has parent; skipping");
@@ -105,7 +105,7 @@ fn find_dead_unwinds<'tcx>(
debug!(
"find_dead_unwinds @ {:?}: path({:?})={:?}; init_data={:?}",
bb,
- location,
+ place,
path,
flow_inits.get()
);
@@ -294,16 +294,16 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
fn collect_drop_flags(&mut self) {
for (bb, data) in self.body.basic_blocks().iter_enumerated() {
let terminator = data.terminator();
- let location = match terminator.kind {
- TerminatorKind::Drop { ref location, .. }
- | TerminatorKind::DropAndReplace { ref location, .. } => location,
+ let place = match terminator.kind {
+ TerminatorKind::Drop { ref place, .. }
+ | TerminatorKind::DropAndReplace { ref place, .. } => place,
_ => continue,
};
self.init_data.seek_before(self.body.terminator_loc(bb));
- let path = self.move_data().rev_lookup.find(location.as_ref());
- debug!("collect_drop_flags: {:?}, place {:?} ({:?})", bb, location, path);
+ let path = self.move_data().rev_lookup.find(place.as_ref());
+ debug!("collect_drop_flags: {:?}, place {:?} ({:?})", bb, place, path);
let path = match path {
LookupResult::Exact(e) => e,
@@ -315,7 +315,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
terminator.source_info.span,
"drop of untracked, uninitialized value {:?}, place {:?} ({:?})",
bb,
- location,
+ place,
path
);
}
@@ -328,7 +328,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
debug!(
"collect_drop_flags: collecting {:?} from {:?}@{:?} - {:?}",
child,
- location,
+ place,
path,
(maybe_live, maybe_dead)
);
@@ -346,13 +346,13 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
let resume_block = self.patch.resume_block();
match terminator.kind {
- TerminatorKind::Drop { location, target, unwind } => {
+ TerminatorKind::Drop { place, target, unwind } => {
self.init_data.seek_before(loc);
- match self.move_data().rev_lookup.find(location.as_ref()) {
+ match self.move_data().rev_lookup.find(place.as_ref()) {
LookupResult::Exact(path) => elaborate_drop(
&mut Elaborator { ctxt: self },
terminator.source_info,
- location,
+ place,
path,
target,
if data.is_cleanup {
@@ -371,10 +371,10 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
}
}
}
- TerminatorKind::DropAndReplace { location, ref value, target, unwind } => {
+ TerminatorKind::DropAndReplace { place, ref value, target, unwind } => {
assert!(!data.is_cleanup);
- self.elaborate_replace(loc, location, value, target, unwind);
+ self.elaborate_replace(loc, place, value, target, unwind);
}
_ => continue,
}
@@ -396,7 +396,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
fn elaborate_replace(
&mut self,
loc: Location,
- location: Place<'tcx>,
+ place: Place<'tcx>,
value: &Operand<'tcx>,
target: BasicBlock,
unwind: Option,
@@ -407,7 +407,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
assert!(!data.is_cleanup, "DropAndReplace in unwind path not supported");
let assign = Statement {
- kind: StatementKind::Assign(box (location, Rvalue::Use(value.clone()))),
+ kind: StatementKind::Assign(box (place, Rvalue::Use(value.clone()))),
source_info: terminator.source_info,
};
@@ -427,14 +427,14 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
is_cleanup: false,
});
- match self.move_data().rev_lookup.find(location.as_ref()) {
+ match self.move_data().rev_lookup.find(place.as_ref()) {
LookupResult::Exact(path) => {
debug!("elaborate_drop_and_replace({:?}) - tracked {:?}", terminator, path);
self.init_data.seek_before(loc);
elaborate_drop(
&mut Elaborator { ctxt: self },
terminator.source_info,
- location,
+ place,
path,
target,
Unwind::To(unwind),
@@ -459,7 +459,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
debug!("elaborate_drop_and_replace({:?}) - untracked {:?}", terminator, parent);
self.patch.patch_terminator(
bb,
- TerminatorKind::Drop { location, target, unwind: Some(unwind) },
+ TerminatorKind::Drop { place, target, unwind: Some(unwind) },
);
}
}
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 7215f390d40d2..b2431e98e2d01 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -835,8 +835,8 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, body: &mut
for (block, block_data) in body.basic_blocks().iter_enumerated() {
let (target, unwind, source_info) = match block_data.terminator() {
- Terminator { source_info, kind: TerminatorKind::Drop { location, target, unwind } } => {
- if let Some(local) = location.as_local() {
+ Terminator { source_info, kind: TerminatorKind::Drop { place, target, unwind } } => {
+ if let Some(local) = place.as_local() {
if local == SELF_ARG {
(target, unwind, source_info)
} else {
@@ -1102,11 +1102,8 @@ fn create_generator_resume_function<'tcx>(
fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock {
let return_block = insert_term_block(body, TerminatorKind::Return);
- let term = TerminatorKind::Drop {
- location: Place::from(SELF_ARG),
- target: return_block,
- unwind: None,
- };
+ let term =
+ TerminatorKind::Drop { place: Place::from(SELF_ARG), target: return_block, unwind: None };
let source_info = SourceInfo::outermost(body.span);
// Create a block to destroy an unresumed generators. This can only destroy upvars.
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 65400b58eebcb..db909494aed6b 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -319,13 +319,13 @@ impl Inliner<'tcx> {
let term = blk.terminator();
let mut is_drop = false;
match term.kind {
- TerminatorKind::Drop { ref location, target, unwind }
- | TerminatorKind::DropAndReplace { ref location, target, unwind, .. } => {
+ TerminatorKind::Drop { ref place, target, unwind }
+ | TerminatorKind::DropAndReplace { ref place, target, unwind, .. } => {
is_drop = true;
work_list.push(target);
- // If the location doesn't actually need dropping, treat it like
+ // If the place doesn't actually need dropping, treat it like
// a regular goto.
- let ty = location.ty(callee_body, tcx).subst(tcx, callsite.substs).ty;
+ let ty = place.ty(callee_body, tcx).subst(tcx, callsite.substs).ty;
if ty.needs_drop(tcx, param_env) {
cost += CALL_PENALTY;
if let Some(unwind) = unwind {
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 6624310326360..330f6c1640ff4 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -1186,7 +1186,7 @@ pub fn promote_candidates<'tcx>(
_ => true,
});
let terminator = block.terminator_mut();
- if let TerminatorKind::Drop { location: place, target, .. } = &terminator.kind {
+ if let TerminatorKind::Drop { place, target, .. } = &terminator.kind {
if let Some(index) = place.as_local() {
if promoted(index) {
terminator.kind = TerminatorKind::Goto { target: *target };
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index 4c8fc49099b2a..caf6c7715a9e1 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -349,9 +349,9 @@ fn check_terminator(
| TerminatorKind::Resume
| TerminatorKind::Unreachable => Ok(()),
- TerminatorKind::Drop { location, .. } => check_place(tcx, *location, span, def_id, body),
- TerminatorKind::DropAndReplace { location, value, .. } => {
- check_place(tcx, *location, span, def_id, body)?;
+ TerminatorKind::Drop { place, .. } => check_place(tcx, *place, span, def_id, body),
+ TerminatorKind::DropAndReplace { place, value, .. } => {
+ check_place(tcx, *place, span, def_id, body)?;
check_operand(tcx, value, span, def_id, body)
}
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index a1345452ca979..5f55a812a4e0d 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -238,7 +238,7 @@ where
self.elaborator.patch().patch_terminator(
bb,
TerminatorKind::Drop {
- location: self.place,
+ place: self.place,
target: self.succ,
unwind: self.unwind.into_option(),
},
@@ -723,7 +723,7 @@ where
self.elaborator.patch().patch_terminator(
drop_block,
TerminatorKind::Drop {
- location: tcx.mk_place_deref(ptr),
+ place: tcx.mk_place_deref(ptr),
target: loop_block,
unwind: unwind.into_option(),
},
@@ -1000,7 +1000,7 @@ where
fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock {
let block =
- TerminatorKind::Drop { location: self.place, target, unwind: unwind.into_option() };
+ TerminatorKind::Drop { place: self.place, target, unwind: unwind.into_option() };
self.new_block(unwind, block)
}
diff --git a/src/librustc_mir_build/build/scope.rs b/src/librustc_mir_build/build/scope.rs
index 4daf567d7d451..b8df27094471f 100644
--- a/src/librustc_mir_build/build/scope.rs
+++ b/src/librustc_mir_build/build/scope.rs
@@ -1037,7 +1037,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut self,
block: BasicBlock,
span: Span,
- location: Place<'tcx>,
+ place: Place<'tcx>,
value: Operand<'tcx>,
) -> BlockAnd<()> {
let source_info = self.source_info(span);
@@ -1047,7 +1047,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block,
source_info,
TerminatorKind::DropAndReplace {
- location,
+ place,
value,
target: next_target,
unwind: Some(diverge_target),
@@ -1158,7 +1158,7 @@ fn build_scope_drops<'tcx>(
block,
source_info,
TerminatorKind::Drop {
- location: local.into(),
+ place: local.into(),
target: next,
unwind: Some(unwind_to),
},
@@ -1272,7 +1272,7 @@ fn build_diverge_scope<'tcx>(
block,
source_info(drop_data.span),
TerminatorKind::Drop {
- location: drop_data.local.into(),
+ place: drop_data.local.into(),
target,
unwind: None,
},
From 6c5345f2defa99fd8fef8940f682fe2b6c6249f9 Mon Sep 17 00:00:00 2001
From: Ralf Jung
Date: Wed, 10 Jun 2020 10:03:26 +0200
Subject: [PATCH 27/28] fmt; make visit_terminator arg names consistent with
the rest
---
src/librustc_middle/mir/visit.rs | 38 ++++++++++++++++----------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/src/librustc_middle/mir/visit.rs b/src/librustc_middle/mir/visit.rs
index f2eda96f34ad1..2efc5f1dabedc 100644
--- a/src/librustc_middle/mir/visit.rs
+++ b/src/librustc_middle/mir/visit.rs
@@ -407,7 +407,7 @@ macro_rules! make_mir_visitor {
fn super_terminator(&mut self,
terminator: &$($mutability)? Terminator<'tcx>,
- source_location: Location) {
+ location: Location) {
let Terminator { source_info, kind } = terminator;
self.visit_source_info(source_info);
@@ -428,7 +428,7 @@ macro_rules! make_mir_visitor {
self.visit_local(
& $($mutability)? local,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move),
- source_location,
+ location,
);
assert_eq!(
@@ -444,8 +444,8 @@ macro_rules! make_mir_visitor {
values: _,
targets: _
} => {
- self.visit_operand(discr, source_location);
- self.visit_ty(switch_ty, TyContext::Location(source_location));
+ self.visit_operand(discr, location);
+ self.visit_ty(switch_ty, TyContext::Location(location));
}
TerminatorKind::Drop {
@@ -456,7 +456,7 @@ macro_rules! make_mir_visitor {
self.visit_place(
place,
PlaceContext::MutatingUse(MutatingUseContext::Drop),
- source_location
+ location
);
}
@@ -469,9 +469,9 @@ macro_rules! make_mir_visitor {
self.visit_place(
place,
PlaceContext::MutatingUse(MutatingUseContext::Drop),
- source_location
+ location
);
- self.visit_operand(value, source_location);
+ self.visit_operand(value, location);
}
TerminatorKind::Call {
@@ -482,15 +482,15 @@ macro_rules! make_mir_visitor {
from_hir_call: _,
fn_span: _
} => {
- self.visit_operand(func, source_location);
+ self.visit_operand(func, location);
for arg in args {
- self.visit_operand(arg, source_location);
+ self.visit_operand(arg, location);
}
if let Some((destination, _)) = destination {
self.visit_place(
destination,
PlaceContext::MutatingUse(MutatingUseContext::Call),
- source_location
+ location
);
}
}
@@ -502,8 +502,8 @@ macro_rules! make_mir_visitor {
target: _,
cleanup: _,
} => {
- self.visit_operand(cond, source_location);
- self.visit_assert_message(msg, source_location);
+ self.visit_operand(cond, location);
+ self.visit_assert_message(msg, location);
}
TerminatorKind::Yield {
@@ -512,11 +512,11 @@ macro_rules! make_mir_visitor {
resume_arg,
drop: _,
} => {
- self.visit_operand(value, source_location);
+ self.visit_operand(value, location);
self.visit_place(
resume_arg,
PlaceContext::MutatingUse(MutatingUseContext::Yield),
- source_location,
+ location,
);
}
@@ -531,29 +531,29 @@ macro_rules! make_mir_visitor {
match op {
InlineAsmOperand::In { value, .. }
| InlineAsmOperand::Const { value } => {
- self.visit_operand(value, source_location);
+ self.visit_operand(value, location);
}
InlineAsmOperand::Out { place, .. } => {
if let Some(place) = place {
self.visit_place(
place,
PlaceContext::MutatingUse(MutatingUseContext::Store),
- source_location,
+ location,
);
}
}
InlineAsmOperand::InOut { in_value, out_place, .. } => {
- self.visit_operand(in_value, source_location);
+ self.visit_operand(in_value, location);
if let Some(out_place) = out_place {
self.visit_place(
out_place,
PlaceContext::MutatingUse(MutatingUseContext::Store),
- source_location,
+ location,
);
}
}
InlineAsmOperand::SymFn { value } => {
- self.visit_constant(value, source_location);
+ self.visit_constant(value, location);
}
InlineAsmOperand::SymStatic { def_id: _ } => {}
}
From 827ccf77183c02dc7d362b64debe2bf1c6bfd5fa Mon Sep 17 00:00:00 2001
From: Ralf Jung
Date: Wed, 10 Jun 2020 10:10:09 +0200
Subject: [PATCH 28/28] add probably accidentally missing super_* calls
---
src/librustc_mir/borrow_check/used_muts.rs | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs
index 56764a4be5d91..e027056842db9 100644
--- a/src/librustc_mir/borrow_check/used_muts.rs
+++ b/src/librustc_mir/borrow_check/used_muts.rs
@@ -64,7 +64,7 @@ impl GatherUsedMutsVisitor<'_, '_, '_> {
}
impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tcx> {
- fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, _location: Location) {
+ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
debug!("visit_terminator: terminator={:?}", terminator);
match &terminator.kind {
TerminatorKind::Call { destination: Some((into, _)), .. } => {
@@ -76,10 +76,10 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
_ => {}
}
- // FIXME: no super_terminator?
+ self.super_terminator(terminator, location);
}
- fn visit_statement(&mut self, statement: &Statement<'tcx>, _location: Location) {
+ fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
if let StatementKind::Assign(box (into, _)) = &statement.kind {
debug!(
"visit_statement: statement={:?} local={:?} \
@@ -89,7 +89,7 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
self.remove_never_initialized_mut_locals(*into);
}
- // FIXME: no super_statement?
+ self.super_statement(statement, location);
}
fn visit_local(&mut self, local: &Local, place_context: PlaceContext, location: Location) {
@@ -107,7 +107,5 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
}
}
}
-
- // FIXME: no super_local?
}
}