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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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/60] 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 358dc1d8c2e10eceaf3c04d532bbde73b0dd4bb7 Mon Sep 17 00:00:00 2001 From: Nathan West Date: Thu, 28 May 2020 15:02:48 -0400 Subject: [PATCH 08/60] Added io forwarding methods to the stdio structs --- src/libstd/io/stdio.rs | 83 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index b65b150d2c3a1..cce9a0dc7a43b 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -96,7 +96,20 @@ impl Read for StdinRaw { unsafe fn initializer(&self) -> Initializer { Initializer::nop() } + + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + self.0.read_to_end(buf) + } + + fn read_to_string(&mut self, buf: &mut String) -> io::Result { + self.0.read_to_string(buf) + } + + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + self.0.read_exact(buf) + } } + impl Write for StdoutRaw { fn write(&mut self, buf: &[u8]) -> io::Result { self.0.write(buf) @@ -114,7 +127,20 @@ impl Write for StdoutRaw { fn flush(&mut self) -> io::Result<()> { self.0.flush() } + + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.0.write_all(buf) + } + + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + self.0.write_all_vectored(bufs) + } + + fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { + self.0.write_fmt(fmt) + } } + impl Write for StderrRaw { fn write(&mut self, buf: &[u8]) -> io::Result { self.0.write(buf) @@ -132,6 +158,18 @@ impl Write for StderrRaw { fn flush(&mut self) -> io::Result<()> { self.0.flush() } + + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.0.write_all(buf) + } + + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + self.0.write_all_vectored(bufs) + } + + fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { + self.0.write_fmt(fmt) + } } enum Maybe { @@ -420,6 +458,18 @@ impl Read for StdinLock<'_> { unsafe fn initializer(&self) -> Initializer { Initializer::nop() } + + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + self.inner.read_to_end(buf) + } + + fn read_to_string(&mut self, buf: &mut String) -> io::Result { + self.inner.read_to_string(buf) + } + + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + self.inner.read_exact(buf) + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -427,9 +477,18 @@ impl BufRead for StdinLock<'_> { fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() } + fn consume(&mut self, n: usize) { self.inner.consume(n) } + + fn read_until(&mut self, byte: u8, buf: &mut Vec) -> io::Result { + self.inner.read_until(byte, buf) + } + + fn read_line(&mut self, buf: &mut String) -> io::Result { + self.inner.read_line(buf) + } } #[stable(feature = "std_debug", since = "1.16.0")] @@ -596,6 +655,9 @@ impl Write for Stdout { fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> { self.lock().write_fmt(args) } + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + self.lock().write_all_vectored(bufs) + } } #[stable(feature = "rust1", since = "1.0.0")] impl Write for StdoutLock<'_> { @@ -612,6 +674,15 @@ impl Write for StdoutLock<'_> { fn flush(&mut self) -> io::Result<()> { self.inner.borrow_mut().flush() } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.inner.borrow_mut().write_all(buf) + } + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + self.inner.borrow_mut().write_all_vectored(bufs) + } + fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { + self.inner.borrow_mut().write_fmt(fmt) + } } #[stable(feature = "std_debug", since = "1.16.0")] @@ -770,6 +841,9 @@ impl Write for Stderr { fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> { self.lock().write_fmt(args) } + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + self.lock().write_all_vectored(bufs) + } } #[stable(feature = "rust1", since = "1.0.0")] impl Write for StderrLock<'_> { @@ -786,6 +860,15 @@ impl Write for StderrLock<'_> { fn flush(&mut self) -> io::Result<()> { self.inner.borrow_mut().flush() } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.inner.borrow_mut().write_all(buf) + } + fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + self.inner.borrow_mut().write_all_vectored(bufs) + } + fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { + self.inner.borrow_mut().write_fmt(fmt) + } } #[stable(feature = "std_debug", since = "1.16.0")] From f7d745f33d950c050e0a5a2ee2ee9f0e1269e956 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 23 May 2020 13:22:45 +0200 Subject: [PATCH 09/60] tag/niche terminology cleanup --- .../debuginfo/metadata.rs | 105 +++++++++--------- src/librustc_codegen_ssa/mir/place.rs | 44 ++++---- src/librustc_lint/types.rs | 14 +-- src/librustc_middle/ty/layout.rs | 58 +++++----- src/librustc_mir/interpret/operand.rs | 27 ++--- src/librustc_mir/interpret/place.rs | 41 +++---- src/librustc_mir/interpret/step.rs | 4 +- src/librustc_mir/interpret/validity.rs | 4 +- src/librustc_target/abi/mod.rs | 27 +++-- src/test/ui/layout/debug.stderr | 12 +- 10 files changed, 167 insertions(+), 169 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 0cce0b25e5893..01f630a31a18b 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1,4 +1,4 @@ -use self::EnumDiscriminantInfo::*; +use self::EnumTagInfo::*; use self::MemberDescriptionFactory::*; use self::RecursiveTypeDescription::*; @@ -40,7 +40,7 @@ use rustc_middle::{bug, span_bug}; use rustc_session::config::{self, DebugInfo}; use rustc_span::symbol::{Interner, Symbol}; use rustc_span::{self, SourceFile, SourceFileHash, Span}; -use rustc_target::abi::{Abi, Align, DiscriminantKind, HasDataLayout, Integer, LayoutOf}; +use rustc_target::abi::{Abi, Align, HasDataLayout, Integer, LayoutOf, TagEncoding}; use rustc_target::abi::{Int, Pointer, F32, F64}; use rustc_target::abi::{Primitive, Size, VariantIdx, Variants}; @@ -1335,7 +1335,7 @@ fn generator_layout_and_saved_local_names( struct EnumMemberDescriptionFactory<'ll, 'tcx> { enum_type: Ty<'tcx>, layout: TyAndLayout<'tcx>, - discriminant_type_metadata: Option<&'ll DIType>, + tag_type_metadata: Option<&'ll DIType>, containing_scope: &'ll DIScope, span: Span, } @@ -1385,7 +1385,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { cx, self.layout, variant_info, - NoDiscriminant, + NoTag, self_metadata, self.span, ); @@ -1409,19 +1409,19 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { }] } Variants::Multiple { - discr_kind: DiscriminantKind::Tag, - discr_index, + tag_encoding: TagEncoding::Direct, + tag_field, ref variants, .. } => { - let discriminant_info = if fallback { - RegularDiscriminant { - discr_field: Field::from(discr_index), - discr_type_metadata: self.discriminant_type_metadata.unwrap(), + let tag_info = if fallback { + RegularTag { + tag_field: Field::from(tag_field), + tag_type_metadata: self.tag_type_metadata.unwrap(), } } else { // This doesn't matter in this case. - NoDiscriminant + NoTag }; variants .iter_enumerated() @@ -1432,7 +1432,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { cx, variant, variant_info, - discriminant_info, + tag_info, self_metadata, self.span, ); @@ -1467,11 +1467,11 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { .collect() } Variants::Multiple { - discr_kind: - DiscriminantKind::Niche { ref niche_variants, niche_start, dataful_variant }, - ref discr, + tag_encoding: + TagEncoding::Niche { ref niche_variants, niche_start, dataful_variant }, + ref tag, ref variants, - discr_index, + tag_field, } => { if fallback { let variant = self.layout.for_variant(cx, dataful_variant); @@ -1480,7 +1480,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { cx, variant, variant_info_for(dataful_variant), - OptimizedDiscriminant, + OptimizedTag, self.containing_scope, self.span, ); @@ -1524,8 +1524,8 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { cx, &mut name, self.layout, - self.layout.fields.offset(discr_index), - self.layout.field(cx, discr_index).size, + self.layout.fields.offset(tag_field), + self.layout.field(cx, tag_field).size, ); variant_info_for(*niche_variants.start()).map_struct_name(|variant_name| { name.push_str(variant_name); @@ -1552,7 +1552,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { cx, variant, variant_info, - OptimizedDiscriminant, + OptimizedTag, self_metadata, self.span, ); @@ -1573,7 +1573,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { let value = (i.as_u32() as u128) .wrapping_sub(niche_variants.start().as_u32() as u128) .wrapping_add(niche_start); - let value = truncate(value, discr.value.size(cx)); + let value = truncate(value, tag.value.size(cx)); // NOTE(eddyb) do *NOT* remove this assert, until // we pass the full 128-bit value to LLVM, otherwise // truncation will be silent and remain undetected. @@ -1603,7 +1603,7 @@ struct VariantMemberDescriptionFactory<'ll, 'tcx> { /// Cloned from the `layout::Struct` describing the variant. offsets: Vec, args: Vec<(String, Ty<'tcx>)>, - discriminant_type_metadata: Option<&'ll DIType>, + tag_type_metadata: Option<&'ll DIType>, span: Span, } @@ -1617,7 +1617,7 @@ impl VariantMemberDescriptionFactory<'ll, 'tcx> { MemberDescription { name: name.to_string(), type_metadata: if use_enum_fallback(cx) { - match self.discriminant_type_metadata { + match self.tag_type_metadata { // Discriminant is always the first field of our variant // when using the enum fallback. Some(metadata) if i == 0 => metadata, @@ -1638,10 +1638,10 @@ impl VariantMemberDescriptionFactory<'ll, 'tcx> { } #[derive(Copy, Clone)] -enum EnumDiscriminantInfo<'ll> { - RegularDiscriminant { discr_field: Field, discr_type_metadata: &'ll DIType }, - OptimizedDiscriminant, - NoDiscriminant, +enum EnumTagInfo<'ll> { + RegularTag { tag_field: Field, tag_type_metadata: &'ll DIType }, + OptimizedTag, + NoTag, } #[derive(Copy, Clone)] @@ -1706,7 +1706,7 @@ fn describe_enum_variant( cx: &CodegenCx<'ll, 'tcx>, layout: layout::TyAndLayout<'tcx>, variant: VariantInfo<'_, 'tcx>, - discriminant_info: EnumDiscriminantInfo<'ll>, + discriminant_info: EnumTagInfo<'ll>, containing_scope: &'ll DIScope, span: Span, ) -> (&'ll DICompositeType, MemberDescriptionFactory<'ll, 'tcx>) { @@ -1722,12 +1722,12 @@ fn describe_enum_variant( let (offsets, args) = if use_enum_fallback(cx) { // If this is not a univariant enum, there is also the discriminant field. let (discr_offset, discr_arg) = match discriminant_info { - RegularDiscriminant { discr_field, .. } => { + RegularTag { tag_field, .. } => { // We have the layout of an enum variant, we need the layout of the outer enum let enum_layout = cx.layout_of(layout.ty); - let offset = enum_layout.fields.offset(discr_field.as_usize()); + let offset = enum_layout.fields.offset(tag_field.as_usize()); let args = - ("RUST$ENUM$DISR".to_owned(), enum_layout.field(cx, discr_field.as_usize()).ty); + ("RUST$ENUM$DISR".to_owned(), enum_layout.field(cx, tag_field.as_usize()).ty); (Some(offset), Some(args)) } _ => (None, None), @@ -1757,8 +1757,8 @@ fn describe_enum_variant( let member_description_factory = VariantMDF(VariantMemberDescriptionFactory { offsets, args, - discriminant_type_metadata: match discriminant_info { - RegularDiscriminant { discr_type_metadata, .. } => Some(discr_type_metadata), + tag_type_metadata: match discriminant_info { + RegularTag { tag_type_metadata, .. } => Some(tag_type_metadata), _ => None, }, span, @@ -1880,18 +1880,18 @@ fn prepare_enum_metadata( if let ( &Abi::Scalar(_), - &Variants::Multiple { discr_kind: DiscriminantKind::Tag, ref discr, .. }, + &Variants::Multiple { tag_encoding: TagEncoding::Direct, ref tag, .. }, ) = (&layout.abi, &layout.variants) { - return FinalMetadata(discriminant_type_metadata(discr.value)); + return FinalMetadata(discriminant_type_metadata(tag.value)); } if use_enum_fallback(cx) { let discriminant_type_metadata = match layout.variants { Variants::Single { .. } - | Variants::Multiple { discr_kind: DiscriminantKind::Niche { .. }, .. } => None, - Variants::Multiple { discr_kind: DiscriminantKind::Tag, ref discr, .. } => { - Some(discriminant_type_metadata(discr.value)) + | Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, .. } => None, + Variants::Multiple { tag_encoding: TagEncoding::Direct, ref tag, .. } => { + Some(discriminant_type_metadata(tag.value)) } }; @@ -1927,7 +1927,7 @@ fn prepare_enum_metadata( EnumMDF(EnumMemberDescriptionFactory { enum_type, layout, - discriminant_type_metadata, + tag_type_metadata: discriminant_type_metadata, containing_scope, span, }), @@ -1943,16 +1943,13 @@ fn prepare_enum_metadata( Variants::Single { .. } => None, Variants::Multiple { - discr_kind: DiscriminantKind::Niche { .. }, - ref discr, - discr_index, - .. + tag_encoding: TagEncoding::Niche { .. }, ref tag, tag_field, .. } => { // Find the integer type of the correct size. - let size = discr.value.size(cx); - let align = discr.value.align(cx); + let size = tag.value.size(cx); + let align = tag.value.align(cx); - let discr_type = match discr.value { + let tag_type = match tag.value { Int(t, _) => t, F32 => Integer::I32, F64 => Integer::I64, @@ -1960,7 +1957,7 @@ fn prepare_enum_metadata( } .to_ty(cx.tcx, false); - let discr_metadata = basic_type_metadata(cx, discr_type); + let tag_metadata = basic_type_metadata(cx, tag_type); unsafe { Some(llvm::LLVMRustDIBuilderCreateMemberType( DIB(cx), @@ -1971,17 +1968,15 @@ fn prepare_enum_metadata( UNKNOWN_LINE_NUMBER, size.bits(), align.abi.bits() as u32, - layout.fields.offset(discr_index).bits(), + layout.fields.offset(tag_field).bits(), DIFlags::FlagArtificial, - discr_metadata, + tag_metadata, )) } } - Variants::Multiple { - discr_kind: DiscriminantKind::Tag, ref discr, discr_index, .. - } => { - let discr_type = discr.value.to_ty(cx.tcx); + Variants::Multiple { tag_encoding: TagEncoding::Direct, ref tag, tag_field, .. } => { + let discr_type = tag.value.to_ty(cx.tcx); let (size, align) = cx.size_and_align_of(discr_type); let discr_metadata = basic_type_metadata(cx, discr_type); @@ -1995,7 +1990,7 @@ fn prepare_enum_metadata( UNKNOWN_LINE_NUMBER, size.bits(), align.bits() as u32, - layout.fields.offset(discr_index).bits(), + layout.fields.offset(tag_field).bits(), DIFlags::FlagArtificial, discr_metadata, )) @@ -2081,7 +2076,7 @@ fn prepare_enum_metadata( EnumMDF(EnumMemberDescriptionFactory { enum_type, layout, - discriminant_type_metadata: None, + tag_type_metadata: None, containing_scope, span, }), diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 2be0679382900..0c8638b673d4f 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -10,7 +10,7 @@ use rustc_middle::mir; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout}; use rustc_middle::ty::{self, Ty}; -use rustc_target::abi::{Abi, Align, DiscriminantKind, FieldsShape, Int}; +use rustc_target::abi::{Abi, Align, FieldsShape, Int, TagEncoding}; use rustc_target::abi::{LayoutOf, VariantIdx, Variants}; #[derive(Copy, Clone, Debug)] @@ -199,7 +199,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { if self.layout.abi.is_uninhabited() { return bx.cx().const_undef(cast_to); } - let (discr_scalar, discr_kind, discr_index) = match self.layout.variants { + let (tag_scalar, tag_encoding, tag_field) = match self.layout.variants { Variants::Single { index } => { let discr_val = self .layout @@ -208,33 +208,33 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { .map_or(index.as_u32() as u128, |discr| discr.val); return bx.cx().const_uint_big(cast_to, discr_val); } - Variants::Multiple { ref discr, ref discr_kind, discr_index, .. } => { - (discr, discr_kind, discr_index) + Variants::Multiple { ref tag, ref tag_encoding, tag_field, .. } => { + (tag, tag_encoding, tag_field) } }; // Read the tag/niche-encoded discriminant from memory. - let encoded_discr = self.project_field(bx, discr_index); - let encoded_discr = bx.load_operand(encoded_discr); + let tag = self.project_field(bx, tag_field); + let tag = bx.load_operand(tag); // Decode the discriminant (specifically if it's niche-encoded). - match *discr_kind { - DiscriminantKind::Tag => { - let signed = match discr_scalar.value { + match *tag_encoding { + TagEncoding::Direct => { + let signed = match tag_scalar.value { // We use `i1` for bytes that are always `0` or `1`, // e.g., `#[repr(i8)] enum E { A, B }`, but we can't // let LLVM interpret the `i1` as signed, because // then `i1 1` (i.e., `E::B`) is effectively `i8 -1`. - Int(_, signed) => !discr_scalar.is_bool() && signed, + Int(_, signed) => !tag_scalar.is_bool() && signed, _ => false, }; - bx.intcast(encoded_discr.immediate(), cast_to, signed) + bx.intcast(tag.immediate(), cast_to, signed) } - DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start } => { + TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => { // Rebase from niche values to discriminants, and check // whether the result is in range for the niche variants. - let niche_llty = bx.cx().immediate_backend_type(encoded_discr.layout); - let encoded_discr = encoded_discr.immediate(); + let niche_llty = bx.cx().immediate_backend_type(tag.layout); + let tag = tag.immediate(); // We first compute the "relative discriminant" (wrt `niche_variants`), // that is, if `n = niche_variants.end() - niche_variants.start()`, @@ -248,9 +248,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { let relative_discr = if niche_start == 0 { // Avoid subtracting `0`, which wouldn't work for pointers. // FIXME(eddyb) check the actual primitive type here. - encoded_discr + tag } else { - bx.sub(encoded_discr, bx.cx().const_uint_big(niche_llty, niche_start)) + bx.sub(tag, bx.cx().const_uint_big(niche_llty, niche_start)) }; let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32(); let is_niche = { @@ -312,8 +312,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { Variants::Single { index } => { assert_eq!(index, variant_index); } - Variants::Multiple { discr_kind: DiscriminantKind::Tag, discr_index, .. } => { - let ptr = self.project_field(bx, discr_index); + Variants::Multiple { tag_encoding: TagEncoding::Direct, tag_field, .. } => { + let ptr = self.project_field(bx, tag_field); let to = self.layout.ty.discriminant_for_variant(bx.tcx(), variant_index).unwrap().val; bx.store( @@ -323,9 +323,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { ); } Variants::Multiple { - discr_kind: - DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start }, - discr_index, + tag_encoding: + TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start }, + tag_field, .. } => { if variant_index != dataful_variant { @@ -339,7 +339,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { bx.memset(self.llval, fill_byte, size, self.align, MemFlags::empty()); } - let niche = self.project_field(bx, discr_index); + let niche = self.project_field(bx, tag_field); let niche_llty = bx.cx().immediate_backend_type(niche.layout); let niche_value = variant_index.as_u32() - niche_variants.start().as_u32(); let niche_value = (niche_value as u128).wrapping_add(niche_start); diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 703c2a7a443a9..6f4e2c69e339f 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -16,7 +16,7 @@ use rustc_middle::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; use rustc_span::source_map; use rustc_span::symbol::sym; use rustc_span::Span; -use rustc_target::abi::{DiscriminantKind, Integer, LayoutOf, VariantIdx, Variants}; +use rustc_target::abi::{Integer, LayoutOf, TagEncoding, VariantIdx, Variants}; use rustc_target::spec::abi::Abi; use log::debug; @@ -1036,15 +1036,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences { }; let (variants, tag) = match layout.variants { Variants::Multiple { - discr_kind: DiscriminantKind::Tag, - ref discr, + tag_encoding: TagEncoding::Direct, + ref tag, ref variants, .. - } => (variants, discr), + } => (variants, tag), _ => return, }; - let discr_size = tag.value.size(&cx.tcx).bytes(); + let tag_size = tag.value.size(&cx.tcx).bytes(); debug!( "enum `{}` is {} bytes large with layout:\n{:#?}", @@ -1058,8 +1058,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences { .iter() .zip(variants) .map(|(variant, variant_layout)| { - // Subtract the size of the enum discriminant. - let bytes = variant_layout.size.bytes().saturating_sub(discr_size); + // Subtract the size of the enum tag. + let bytes = variant_layout.size.bytes().saturating_sub(tag_size); debug!("- variant `{}` is {} bytes large", variant.ident, bytes); bytes diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs index 5566e187c0c5c..fde2627e29dcb 100644 --- a/src/librustc_middle/ty/layout.rs +++ b/src/librustc_middle/ty/layout.rs @@ -975,13 +975,13 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { return Ok(tcx.intern_layout(Layout { variants: Variants::Multiple { - discr: niche_scalar, - discr_kind: DiscriminantKind::Niche { + tag: niche_scalar, + tag_encoding: TagEncoding::Niche { dataful_variant: i, niche_variants, niche_start, }, - discr_index: 0, + tag_field: 0, variants: st, }, fields: FieldsShape::Arbitrary { @@ -1217,9 +1217,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { tcx.intern_layout(Layout { variants: Variants::Multiple { - discr: tag, - discr_kind: DiscriminantKind::Tag, - discr_index: 0, + tag, + tag_encoding: TagEncoding::Direct, + tag_field: 0, variants: layout_variants, }, fields: FieldsShape::Arbitrary { @@ -1400,15 +1400,15 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // Build a prefix layout, including "promoting" all ineligible // locals as part of the prefix. We compute the layout of all of // these fields at once to get optimal packing. - let discr_index = substs.as_generator().prefix_tys().count(); + let tag_index = substs.as_generator().prefix_tys().count(); // `info.variant_fields` already accounts for the reserved variants, so no need to add them. let max_discr = (info.variant_fields.len() - 1) as u128; let discr_int = Integer::fit_unsigned(max_discr); let discr_int_ty = discr_int.to_ty(tcx, false); - let discr = Scalar { value: Primitive::Int(discr_int, false), valid_range: 0..=max_discr }; - let discr_layout = self.tcx.intern_layout(Layout::scalar(self, discr.clone())); - let discr_layout = TyAndLayout { ty: discr_int_ty, layout: discr_layout }; + let tag = Scalar { value: Primitive::Int(discr_int, false), valid_range: 0..=max_discr }; + let tag_layout = self.tcx.intern_layout(Layout::scalar(self, tag.clone())); + let tag_layout = TyAndLayout { ty: discr_int_ty, layout: tag_layout }; let promoted_layouts = ineligible_locals .iter() @@ -1419,7 +1419,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { .as_generator() .prefix_tys() .map(|ty| self.layout_of(ty)) - .chain(iter::once(Ok(discr_layout))) + .chain(iter::once(Ok(tag_layout))) .chain(promoted_layouts) .collect::, _>>()?; let prefix = self.univariant_uninterned( @@ -1442,7 +1442,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // "a" (`0..b_start`) and "b" (`b_start..`) correspond to // "outer" and "promoted" fields respectively. - let b_start = (discr_index + 1) as u32; + let b_start = (tag_index + 1) as u32; let offsets_b = offsets.split_off(b_start as usize); let offsets_a = offsets; @@ -1559,9 +1559,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let layout = tcx.intern_layout(Layout { variants: Variants::Multiple { - discr, - discr_kind: DiscriminantKind::Tag, - discr_index, + tag: tag, + tag_encoding: TagEncoding::Direct, + tag_field: tag_index, variants, }, fields: outer_fields, @@ -1681,7 +1681,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } } - Variants::Multiple { ref discr, ref discr_kind, .. } => { + Variants::Multiple { ref tag, ref tag_encoding, .. } => { debug!( "print-type-size `{:#?}` adt general variants def {}", layout.ty, @@ -1703,8 +1703,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { record( adt_kind.into(), adt_packed, - match discr_kind { - DiscriminantKind::Tag => Some(discr.value.size(self)), + match tag_encoding { + TagEncoding::Direct => Some(tag.value.size(self)), _ => None, }, variant_infos, @@ -2029,11 +2029,11 @@ where fn field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> C::TyAndLayout { let tcx = cx.tcx(); - let discr_layout = |discr: &Scalar| -> C::TyAndLayout { - let layout = Layout::scalar(cx, discr.clone()); + let tag_layout = |tag: &Scalar| -> C::TyAndLayout { + let layout = Layout::scalar(cx, tag.clone()); MaybeResult::from(Ok(TyAndLayout { layout: tcx.intern_layout(layout), - ty: discr.value.to_ty(tcx), + ty: tag.value.to_ty(tcx), })) }; @@ -2110,9 +2110,9 @@ where .unwrap() .nth(i) .unwrap(), - Variants::Multiple { ref discr, discr_index, .. } => { - if i == discr_index { - return discr_layout(discr); + Variants::Multiple { ref tag, tag_field, .. } => { + if i == tag_field { + return tag_layout(tag); } substs.as_generator().prefix_tys().nth(i).unwrap() } @@ -2129,9 +2129,9 @@ where Variants::Single { index } => def.variants[index].fields[i].ty(tcx, substs), // Discriminant field for enums (where applicable). - Variants::Multiple { ref discr, .. } => { + Variants::Multiple { ref tag, .. } => { assert_eq!(i, 0); - return discr_layout(discr); + return tag_layout(tag); } } } @@ -2208,10 +2208,10 @@ where // using more niches than just null (e.g., the first page of // the address space, or unaligned pointers). Variants::Multiple { - discr_kind: DiscriminantKind::Niche { dataful_variant, .. }, - discr_index, + tag_encoding: TagEncoding::Niche { dataful_variant, .. }, + tag_field, .. - } if this.fields.offset(discr_index) == offset => { + } if this.fields.offset(tag_field) == offset => { Some(this.for_variant(cx, dataful_variant)) } _ => Some(this), diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index db4473154c471..7da50eaa3e392 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::layout::{PrimitiveExt, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer}; use rustc_middle::ty::Ty; use rustc_middle::{mir, ty}; -use rustc_target::abi::{Abi, DiscriminantKind, HasDataLayout, LayoutOf, Size}; +use rustc_target::abi::{Abi, TagEncoding, HasDataLayout, LayoutOf, Size}; use rustc_target::abi::{VariantIdx, Variants}; use super::{ @@ -587,7 +587,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { op: OpTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx, (Scalar, VariantIdx)> { trace!("read_discriminant_value {:#?}", op.layout); - // Get type and layout of the discriminant. let discr_layout = self.layout_of(op.layout.ty.discriminant_ty(*self.tcx))?; trace!("discriminant type: {:?}", discr_layout.ty); @@ -596,10 +595,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // This is not to be confused with its "variant index", which is just determining its position in the // declared list of variants -- they can differ with explicitly assigned discriminants. // We use "tag" to refer to how the discriminant is encoded in memory, which can be either - // straight-forward (`DiscriminantKind::Tag`) or with a niche (`DiscriminantKind::Niche`). - // Unfortunately, the rest of the compiler calls the latter "discriminant", too, which makes things - // rather confusing. - let (tag_scalar_layout, tag_kind, tag_index) = match op.layout.variants { + // straight-forward (`TagEncoding::Direct`) or with a niche (`TagEncoding::Niche`). + let (tag_scalar_layout, tag_encoding, tag_field) = match op.layout.variants { Variants::Single { index } => { let discr = match op.layout.ty.discriminant_for_variant(*self.tcx, index) { Some(discr) => { @@ -615,8 +612,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; return Ok((discr, index)); } - Variants::Multiple { ref discr, ref discr_kind, discr_index, .. } => { - (discr, discr_kind, discr_index) + Variants::Multiple { ref tag, ref tag_encoding, tag_field, .. } => { + (tag, tag_encoding, tag_field) } }; @@ -633,21 +630,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let tag_layout = self.layout_of(tag_scalar_layout.value.to_int_ty(*self.tcx))?; // Read tag and sanity-check `tag_layout`. - let tag_val = self.read_immediate(self.operand_field(op, tag_index)?)?; + let tag_val = self.read_immediate(self.operand_field(op, tag_field)?)?; assert_eq!(tag_layout.size, tag_val.layout.size); assert_eq!(tag_layout.abi.is_signed(), tag_val.layout.abi.is_signed()); let tag_val = tag_val.to_scalar()?; trace!("tag value: {:?}", tag_val); // Figure out which discriminant and variant this corresponds to. - Ok(match *tag_kind { - DiscriminantKind::Tag => { + Ok(match *tag_encoding { + TagEncoding::Direct => { let tag_bits = self .force_bits(tag_val, tag_layout.size) .map_err(|_| err_ub!(InvalidDiscriminant(tag_val.erase_tag())))?; // Cast bits from tag layout to discriminant layout. - let discr_val_cast = self.cast_from_scalar(tag_bits, tag_layout, discr_layout.ty); - let discr_bits = discr_val_cast.assert_bits(discr_layout.size); + let discr_val = self.cast_from_scalar(tag_bits, tag_layout, discr_layout.ty); + let discr_bits = discr_val.assert_bits(discr_layout.size); // Convert discriminant to variant index, and catch invalid discriminants. let index = match op.layout.ty.kind { ty::Adt(adt, _) => { @@ -663,9 +660,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } .ok_or_else(|| err_ub!(InvalidDiscriminant(tag_val.erase_tag())))?; // Return the cast value, and the index. - (discr_val_cast, index.0) + (discr_val, index.0) } - DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start } => { + TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => { // Compute the variant this niche value/"tag" corresponds to. With niche layout, // discriminant (encoded in niche/tag) and variant index are the same. let variants_start = niche_variants.start().as_u32(); diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 3f0800b12b549..1e6335c871e7c 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -9,7 +9,7 @@ use rustc_macros::HashStable; use rustc_middle::mir; use rustc_middle::ty::layout::{PrimitiveExt, TyAndLayout}; use rustc_middle::ty::{self, Ty}; -use rustc_target::abi::{Abi, Align, DiscriminantKind, FieldsShape}; +use rustc_target::abi::{Abi, Align, FieldsShape, TagEncoding}; use rustc_target::abi::{HasDataLayout, LayoutOf, Size, VariantIdx, Variants}; use super::{ @@ -1031,7 +1031,8 @@ where MPlaceTy { mplace, layout } } - pub fn write_discriminant_index( + /// Writes the discriminant of the given variant. + pub fn write_discriminant( &mut self, variant_index: VariantIdx, dest: PlaceTy<'tcx, M::PointerTag>, @@ -1047,9 +1048,9 @@ where assert_eq!(index, variant_index); } Variants::Multiple { - discr_kind: DiscriminantKind::Tag, - discr: ref discr_layout, - discr_index, + tag_encoding: TagEncoding::Direct, + tag: ref tag_layout, + tag_field, .. } => { // No need to validate that the discriminant here because the @@ -1061,17 +1062,17 @@ where // raw discriminants for enums are isize or bigger during // their computation, but the in-memory tag is the smallest possible // representation - let size = discr_layout.value.size(self); - let discr_val = truncate(discr_val, size); + let size = tag_layout.value.size(self); + let tag_val = truncate(discr_val, size); - let discr_dest = self.place_field(dest, discr_index)?; - self.write_scalar(Scalar::from_uint(discr_val, size), discr_dest)?; + let tag_dest = self.place_field(dest, tag_field)?; + self.write_scalar(Scalar::from_uint(tag_val, size), tag_dest)?; } Variants::Multiple { - discr_kind: - DiscriminantKind::Niche { dataful_variant, ref niche_variants, niche_start }, - discr: ref discr_layout, - discr_index, + tag_encoding: + TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start }, + tag: ref tag_layout, + tag_field, .. } => { // No need to validate that the discriminant here because the @@ -1084,19 +1085,19 @@ where .checked_sub(variants_start) .expect("overflow computing relative variant idx"); // We need to use machine arithmetic when taking into account `niche_start`: - // discr_val = variant_index_relative + niche_start_val - let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?; - let niche_start_val = ImmTy::from_uint(niche_start, discr_layout); + // tag_val = variant_index_relative + niche_start_val + let tag_layout = self.layout_of(tag_layout.value.to_int_ty(*self.tcx))?; + let niche_start_val = ImmTy::from_uint(niche_start, tag_layout); let variant_index_relative_val = - ImmTy::from_uint(variant_index_relative, discr_layout); - let discr_val = self.binary_op( + ImmTy::from_uint(variant_index_relative, tag_layout); + let tag_val = self.binary_op( mir::BinOp::Add, variant_index_relative_val, niche_start_val, )?; // Write result. - let niche_dest = self.place_field(dest, discr_index)?; - self.write_immediate(*discr_val, niche_dest)?; + let niche_dest = self.place_field(dest, tag_field)?; + self.write_immediate(*tag_val, niche_dest)?; } } } diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index bd4df788057e2..029b83492d593 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -89,7 +89,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { SetDiscriminant { place, variant_index } => { let dest = self.eval_place(**place)?; - self.write_discriminant_index(*variant_index, dest)?; + self.write_discriminant(*variant_index, dest)?; } // Mark locals as alive @@ -174,7 +174,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Aggregate(ref kind, ref operands) => { let (dest, active_field_index) = match **kind { mir::AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => { - self.write_discriminant_index(variant_index, dest)?; + self.write_discriminant(variant_index, dest)?; if adt_def.is_enum() { (self.place_downcast(dest, variant_index)?, active_field_index) } else { diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index e962dfb2b3e86..f21a96a979092 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -208,8 +208,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' fn aggregate_field_path_elem(&mut self, layout: TyAndLayout<'tcx>, field: usize) -> PathElem { // First, check if we are projecting to a variant. match layout.variants { - Variants::Multiple { discr_index, .. } => { - if discr_index == field { + Variants::Multiple { tag_field, .. } => { + if tag_field == field { return match layout.ty.kind { ty::Adt(def, ..) if def.is_enum() => PathElem::EnumTag, ty::Generator(..) => PathElem::GeneratorTag, diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index dcf181cb59f4a..c79e9bb289008 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -809,25 +809,30 @@ pub enum Variants { /// Single enum variants, structs/tuples, unions, and all non-ADTs. Single { index: VariantIdx }, - /// Enum-likes with more than one inhabited variant: for each case there is - /// a struct, and they all have space reserved for the discriminant. - /// For enums this is the sole field of the layout. + /// Enum-likes with more than one inhabited variant: each variant comes with + /// a *discriminant* (usually the same as the variant index but the user can + /// assign explicit discriminant values). That discriminant is encoded + /// as a *tag* on the machine. The layout of each variant is + /// a struct, and they all have space reserved for the tag. + /// For enums, the tag is the sole field of the layout. Multiple { - discr: Scalar, - discr_kind: DiscriminantKind, - discr_index: usize, + tag: Scalar, + tag_encoding: TagEncoding, + tag_field: usize, variants: IndexVec, }, } #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] -pub enum DiscriminantKind { - /// Integer tag holding the discriminant value itself. - Tag, +pub enum TagEncoding { + /// The tag directly stores the discriminant, but possibly with a smaller layout + /// (so converting the tag to the discriminant can require sign extension). + Direct, /// Niche (values invalid for a type) encoding the discriminant: - /// the variant `dataful_variant` contains a niche at an arbitrary - /// offset (field `discr_index` of the enum), which for a variant with + /// Discriminant and variant index coincide. + /// The variant `dataful_variant` contains a niche at an arbitrary + /// offset (field `tag_field` of the enum), which for a variant with /// discriminant `d` is set to /// `(d - niche_variants.start).wrapping_add(niche_start)`. /// diff --git a/src/test/ui/layout/debug.stderr b/src/test/ui/layout/debug.stderr index cd8ebdffb730b..1a371c6b17000 100644 --- a/src/test/ui/layout/debug.stderr +++ b/src/test/ui/layout/debug.stderr @@ -10,15 +10,15 @@ error: layout_of(E) = Layout { ], }, variants: Multiple { - discr: Scalar { + tag: Scalar { value: Int( I32, false, ), valid_range: 0..=0, }, - discr_kind: Tag, - discr_index: 0, + tag_encoding: Direct, + tag_field: 0, variants: [ Layout { fields: Arbitrary { @@ -202,15 +202,15 @@ error: layout_of(std::result::Result) = Layout { ], }, variants: Multiple { - discr: Scalar { + tag: Scalar { value: Int( I32, false, ), valid_range: 0..=1, }, - discr_kind: Tag, - discr_index: 0, + tag_encoding: Direct, + tag_field: 0, variants: [ Layout { fields: Arbitrary { From 7a6d03c2699787644b44f7bc3e8252d1508880b8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 30 May 2020 14:21:56 +0200 Subject: [PATCH 10/60] miri errors: rename InvalidDiscriminant -> InvalidTag --- src/librustc_middle/mir/interpret/error.rs | 6 +++--- src/librustc_mir/interpret/operand.rs | 8 ++++---- src/librustc_mir/interpret/validity.rs | 4 ++-- src/test/ui/consts/const-eval/double_check2.stderr | 2 +- src/test/ui/consts/const-eval/ub-enum.stderr | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs index fc588e049d7d8..6646aad6fc740 100644 --- a/src/librustc_middle/mir/interpret/error.rs +++ b/src/librustc_middle/mir/interpret/error.rs @@ -390,8 +390,8 @@ pub enum UndefinedBehaviorInfo<'tcx> { InvalidBool(u8), /// Using a non-character `u32` as character. InvalidChar(u32), - /// An enum discriminant was set to a value which was outside the range of valid values. - InvalidDiscriminant(Scalar), + /// The tag of an enum does not encode an actual discriminant. + InvalidTag(Scalar), /// Using a pointer-not-to-a-function as function pointer. InvalidFunctionPointer(Pointer), /// Using a string that is not valid UTF-8, @@ -463,7 +463,7 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> { InvalidChar(c) => { write!(f, "interpreting an invalid 32-bit value as a char: 0x{:08x}", c) } - InvalidDiscriminant(val) => write!(f, "enum value has invalid discriminant: {}", val), + InvalidTag(val) => write!(f, "enum value has invalid tag: {}", val), InvalidFunctionPointer(p) => { write!(f, "using {} as function pointer but it does not point to a function", p) } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 7da50eaa3e392..fb08e83b76942 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::layout::{PrimitiveExt, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer}; use rustc_middle::ty::Ty; use rustc_middle::{mir, ty}; -use rustc_target::abi::{Abi, TagEncoding, HasDataLayout, LayoutOf, Size}; +use rustc_target::abi::{Abi, HasDataLayout, LayoutOf, Size, TagEncoding}; use rustc_target::abi::{VariantIdx, Variants}; use super::{ @@ -641,7 +641,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { TagEncoding::Direct => { let tag_bits = self .force_bits(tag_val, tag_layout.size) - .map_err(|_| err_ub!(InvalidDiscriminant(tag_val.erase_tag())))?; + .map_err(|_| err_ub!(InvalidTag(tag_val.erase_tag())))?; // Cast bits from tag layout to discriminant layout. let discr_val = self.cast_from_scalar(tag_bits, tag_layout, discr_layout.ty); let discr_bits = discr_val.assert_bits(discr_layout.size); @@ -658,7 +658,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } _ => bug!("tagged layout for non-adt non-generator"), } - .ok_or_else(|| err_ub!(InvalidDiscriminant(tag_val.erase_tag())))?; + .ok_or_else(|| err_ub!(InvalidTag(tag_val.erase_tag())))?; // Return the cast value, and the index. (discr_val, index.0) } @@ -674,7 +674,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { && variants_start == variants_end && !self.memory.ptr_may_be_null(ptr); if !ptr_valid { - throw_ub!(InvalidDiscriminant(tag_val.erase_tag())) + throw_ub!(InvalidTag(tag_val.erase_tag())) } dataful_variant } diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index f21a96a979092..8dea811d8bcd4 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -696,8 +696,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> try_validation!( self.walk_value(op), self.path, - err_ub!(InvalidDiscriminant(val)) => - { "{}", val } expected { "a valid enum discriminant" }, + err_ub!(InvalidTag(val)) => + { "{}", val } expected { "a valid enum tag" }, err_unsup!(ReadPointerAsBytes) => { "a pointer" } expected { "plain (non-pointer) bytes" }, ); diff --git a/src/test/ui/consts/const-eval/double_check2.stderr b/src/test/ui/consts/const-eval/double_check2.stderr index 81fa5c0df13f6..93dd9a53ec99f 100644 --- a/src/test/ui/consts/const-eval/double_check2.stderr +++ b/src/test/ui/consts/const-eval/double_check2.stderr @@ -5,7 +5,7 @@ LL | / static FOO: (&Foo, &Bar) = unsafe {( LL | | Union { u8: &BAR }.foo, LL | | Union { u8: &BAR }.bar, LL | | )}; - | |___^ type validation failed: encountered 0x05 at .1., but expected a valid enum discriminant + | |___^ type validation failed: encountered 0x05 at .1., but expected a valid enum tag | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. diff --git a/src/test/ui/consts/const-eval/ub-enum.stderr b/src/test/ui/consts/const-eval/ub-enum.stderr index d8dafac3e70a1..d40073fb18fb0 100644 --- a/src/test/ui/consts/const-eval/ub-enum.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.stderr @@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:24:1 | LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000001, but expected a valid enum discriminant + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000001, but expected a valid enum tag | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. @@ -26,7 +26,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:42:1 | LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000000, but expected a valid enum discriminant + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000000, but expected a valid enum tag | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. From 1bc4e45b3fe3a0817908bd7cc21ec23798d38d63 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Mon, 1 Jun 2020 22:18:38 -0400 Subject: [PATCH 11/60] Only highlight results via mouseover if mouse has moved --- src/librustdoc/html/static/main.js | 37 +++++++++++++++++++----------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index ac5a2f96b26c6..fc31f6c760675 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -100,6 +100,8 @@ function defocusSearchBar() { // 2 for "In Return Types" var currentTab = 0; + var mouseMovedAfterSearch = true; + var titleBeforeSearch = document.title; function clearInputTimeout() { @@ -162,6 +164,7 @@ function defocusSearchBar() { } addClass(main, "hidden"); removeClass(search, "hidden"); + mouseMovedAfterSearch = false; } function hideSearchResults(search) { @@ -424,6 +427,12 @@ function defocusSearchBar() { document.addEventListener("keypress", handleShortcut); document.addEventListener("keydown", handleShortcut); + function resetMouseMoved(ev) { + mouseMovedAfterSearch = true; + } + + document.addEventListener("mousemove", resetMouseMoved); + var handleSourceHighlight = (function() { var prev_line_id = 0; @@ -1353,20 +1362,22 @@ function defocusSearchBar() { } }; var mouseover_func = function(e) { - var el = e.target; - // to retrieve the real "owner" of the event. - while (el.tagName !== "TR") { - el = el.parentNode; - } - clearTimeout(hoverTimeout); - hoverTimeout = setTimeout(function() { - onEachLazy(document.getElementsByClassName("search-results"), function(e) { - onEachLazy(e.getElementsByClassName("result"), function(i_e) { - removeClass(i_e, "highlighted"); + if (mouseMovedAfterSearch) { + var el = e.target; + // to retrieve the real "owner" of the event. + while (el.tagName !== "TR") { + el = el.parentNode; + } + clearTimeout(hoverTimeout); + hoverTimeout = setTimeout(function() { + onEachLazy(document.getElementsByClassName("search-results"), function(e) { + onEachLazy(e.getElementsByClassName("result"), function(i_e) { + removeClass(i_e, "highlighted"); + }); }); - }); - addClass(el, "highlighted"); - }, 20); + addClass(el, "highlighted"); + }, 20); + } }; onEachLazy(document.getElementsByClassName("search-results"), function(e) { onEachLazy(e.getElementsByClassName("result"), function(i_e) { From 724dfba460e2c98311cacb5d4f6bb6da36ceec67 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 13 Jun 2020 15:05:37 +0200 Subject: [PATCH 12/60] 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 4606168dd508007fb1014b6ab12b27e320e07038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 13 Jun 2020 11:12:29 -0700 Subject: [PATCH 13/60] Make new type param suggestion more targetted Do not suggest new type param when encountering a missing type in an ADT field with generic parameters. Fix #72640. --- src/librustc_resolve/build_reduced_graph.rs | 1 + src/librustc_resolve/late/diagnostics.rs | 2 +- src/librustc_resolve/lib.rs | 14 ++++++++------ .../ui/suggestions/type-not-found-in-adt-field.rs | 5 +++++ .../suggestions/type-not-found-in-adt-field.stderr | 9 +++++++++ 5 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/suggestions/type-not-found-in-adt-field.rs create mode 100644 src/test/ui/suggestions/type-not-found-in-adt-field.stderr diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 2ae063660e38d..8661af6d7a1de 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -485,6 +485,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { module_path.push(Segment { ident: Ident { name: kw::PathRoot, span: source.ident.span }, id: Some(self.r.next_node_id()), + has_args: false, }); source.ident.name = crate_name; } diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index b1a1f8725a180..28ff89f66925e 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -920,7 +920,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { path: &[Segment], ) -> Option<(Span, &'static str, String, Applicability)> { let ident = match path { - [segment] => segment.ident, + [segment] if !segment.has_args => segment.ident, _ => return None, }; match ( diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 6bd73877fab75..f7ec919fa04e3 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -225,13 +225,15 @@ enum VisResolutionError<'a> { ModuleOnly(Span), } -// A minimal representation of a path segment. We use this in resolve because -// we synthesize 'path segments' which don't have the rest of an AST or HIR -// `PathSegment`. +/// A minimal representation of a path segment. We use this in resolve because we synthesize 'path +/// segments' which don't have the rest of an AST or HIR `PathSegment`. #[derive(Clone, Copy, Debug)] pub struct Segment { ident: Ident, id: Option, + /// Signals whether this `PathSegment` has generic arguments. Used to avoid providing + /// nonsensical suggestions. + has_args: bool, } impl Segment { @@ -240,7 +242,7 @@ impl Segment { } fn from_ident(ident: Ident) -> Segment { - Segment { ident, id: None } + Segment { ident, id: None, has_args: false } } fn names_to_string(segments: &[Segment]) -> String { @@ -250,7 +252,7 @@ impl Segment { impl<'a> From<&'a ast::PathSegment> for Segment { fn from(seg: &'a ast::PathSegment) -> Segment { - Segment { ident: seg.ident, id: Some(seg.id) } + Segment { ident: seg.ident, id: Some(seg.id), has_args: seg.args.is_some() } } } @@ -2017,7 +2019,7 @@ impl<'a> Resolver<'a> { path, opt_ns, record_used, path_span, crate_lint, ); - for (i, &Segment { ident, id }) in path.iter().enumerate() { + for (i, &Segment { ident, id, has_args: _ }) in path.iter().enumerate() { debug!("resolve_path ident {} {:?} {:?}", i, ident, id); let record_segment_res = |this: &mut Self, res| { if record_used { diff --git a/src/test/ui/suggestions/type-not-found-in-adt-field.rs b/src/test/ui/suggestions/type-not-found-in-adt-field.rs new file mode 100644 index 0000000000000..6bd42472f5a55 --- /dev/null +++ b/src/test/ui/suggestions/type-not-found-in-adt-field.rs @@ -0,0 +1,5 @@ +struct S { + m: Vec>, //~ ERROR cannot find type `Hashmap` in this scope + //~^ NOTE not found in this scope +} +fn main() {} diff --git a/src/test/ui/suggestions/type-not-found-in-adt-field.stderr b/src/test/ui/suggestions/type-not-found-in-adt-field.stderr new file mode 100644 index 0000000000000..cfad8c689d038 --- /dev/null +++ b/src/test/ui/suggestions/type-not-found-in-adt-field.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Hashmap` in this scope + --> $DIR/type-not-found-in-adt-field.rs:2:12 + | +LL | m: Vec>, + | ^^^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. From afbbd383ccee8b91b1d1bbdcfb0f7a906bba71f7 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sat, 13 Jun 2020 16:22:24 -0700 Subject: [PATCH 14/60] Note numeric literals that can never fit in an expected type re https://github.com/rust-lang/rust/pull/72380#discussion_r438289385 Given the toy code ```rust fn is_positive(n: usize) { n > -1_isize; } ``` We currently get a type mismatch error like the following: ``` error[E0308]: mismatched types --> src/main.rs:2:9 | 2 | n > -1_isize; | ^^^^^^^^ expected `usize`, found `isize` | help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit | 2 | n > (-1_isize).try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``` But clearly, `-1` can never fit into a `usize`, so the suggestion will always panic. A more useful message would tell the user that the value can never fit in the expected type: ``` error[E0308]: mismatched types --> test.rs:2:9 | 2 | n > -1_isize; | ^^^^^^^^ expected `usize`, found `isize` | note: `-1_isize` can never fit into `usize` --> test.rs:2:9 | 2 | n > -1_isize; | ^^^^^^^^ ``` Which is what this commit implements. I only added this check for negative literals because - Currently we can only perform such a check for literals (constant value propagation is outside the scope of the typechecker at this point) - A lint error for out-of-range numeric literals is already emitted IMO it makes more sense to put this check in librustc_lint, but as far as I can tell the typecheck pass happens before the lint pass, so I've added it here. r? @estebank --- src/librustc_typeck/check/demand.rs | 14 +++- src/test/ui/numeric/numeric-cast-no-fix.rs | 22 ++++++ .../ui/numeric/numeric-cast-no-fix.stderr | 74 +++++++++++++++++++ src/test/ui/repeat_count.stderr | 12 +++ 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/numeric/numeric-cast-no-fix.rs create mode 100644 src/test/ui/numeric/numeric-cast-no-fix.stderr diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 019b4ca66060c..7fc880b6c7c6c 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -783,6 +783,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let literal_is_ty_suffixed = |expr: &hir::Expr<'_>| { if let hir::ExprKind::Lit(lit) = &expr.kind { lit.node.is_suffixed() } else { false } }; + let is_negative_int = + |expr: &hir::Expr<'_>| matches!(expr.kind, hir::ExprKind::Unary(hir::UnOp::UnNeg, ..)); + let is_uint = |ty: Ty<'_>| matches!(ty.kind, ty::Uint(..)); let in_const_context = self.tcx.hir().is_inside_const_context(expr.hir_id); @@ -807,7 +810,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "you can convert `{}` from `{}` to `{}`, matching the type of `{}`", lhs_src, expected_ty, checked_ty, src ); - let suggestion = format!("{}::from({})", checked_ty, lhs_src,); + let suggestion = format!("{}::from({})", checked_ty, lhs_src); (lhs_expr.span, msg, suggestion) } else { let msg = format!("{} and panic if the converted value wouldn't fit", msg); @@ -822,8 +825,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |err: &mut DiagnosticBuilder<'_>, found_to_exp_is_fallible: bool, exp_to_found_is_fallible: bool| { + let always_fallible = found_to_exp_is_fallible + && (exp_to_found_is_fallible || expected_ty_expr.is_none()); let msg = if literal_is_ty_suffixed(expr) { &lit_msg + } else if always_fallible && (is_negative_int(expr) && is_uint(expected_ty)) { + // We now know that converting either the lhs or rhs is fallible. Before we + // suggest a fallible conversion, check if the value can never fit in the + // expected type. + let msg = format!("`{}` can never fit into `{}`", src, expected_ty); + err.span_note(expr.span, &msg); + return; } else if in_const_context { // Do not recommend `into` or `try_into` in const contexts. return; diff --git a/src/test/ui/numeric/numeric-cast-no-fix.rs b/src/test/ui/numeric/numeric-cast-no-fix.rs new file mode 100644 index 0000000000000..8bfd833354164 --- /dev/null +++ b/src/test/ui/numeric/numeric-cast-no-fix.rs @@ -0,0 +1,22 @@ +#[allow(unused_must_use)] +fn main() { + let x_usize: usize = 1; + let x_u128: u128 = 2; + let x_u64: u64 = 3; + let x_u32: u32 = 4; + let x_u16: u16 = 5; + let x_u8: u8 = 6; + + x_usize > -1_isize; + //~^ ERROR mismatched types + x_u128 > -1_isize; + //~^ ERROR mismatched types + x_u64 > -1_isize; + //~^ ERROR mismatched types + x_u32 > -1_isize; + //~^ ERROR mismatched types + x_u16 > -1_isize; + //~^ ERROR mismatched types + x_u8 > -1_isize; + //~^ ERROR mismatched types +} diff --git a/src/test/ui/numeric/numeric-cast-no-fix.stderr b/src/test/ui/numeric/numeric-cast-no-fix.stderr new file mode 100644 index 0000000000000..51e263d636f98 --- /dev/null +++ b/src/test/ui/numeric/numeric-cast-no-fix.stderr @@ -0,0 +1,74 @@ +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:10:15 + | +LL | x_usize > -1_isize; + | ^^^^^^^^ expected `usize`, found `isize` + | +note: `-1_isize` can never fit into `usize` + --> $DIR/numeric-cast-no-fix.rs:10:15 + | +LL | x_usize > -1_isize; + | ^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:12:14 + | +LL | x_u128 > -1_isize; + | ^^^^^^^^ expected `u128`, found `isize` + | +note: `-1_isize` can never fit into `u128` + --> $DIR/numeric-cast-no-fix.rs:12:14 + | +LL | x_u128 > -1_isize; + | ^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:14:13 + | +LL | x_u64 > -1_isize; + | ^^^^^^^^ expected `u64`, found `isize` + | +note: `-1_isize` can never fit into `u64` + --> $DIR/numeric-cast-no-fix.rs:14:13 + | +LL | x_u64 > -1_isize; + | ^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:16:13 + | +LL | x_u32 > -1_isize; + | ^^^^^^^^ expected `u32`, found `isize` + | +note: `-1_isize` can never fit into `u32` + --> $DIR/numeric-cast-no-fix.rs:16:13 + | +LL | x_u32 > -1_isize; + | ^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:18:13 + | +LL | x_u16 > -1_isize; + | ^^^^^^^^ expected `u16`, found `isize` + | +note: `-1_isize` can never fit into `u16` + --> $DIR/numeric-cast-no-fix.rs:18:13 + | +LL | x_u16 > -1_isize; + | ^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:20:12 + | +LL | x_u8 > -1_isize; + | ^^^^^^^^ expected `u8`, found `isize` + | +help: you can convert `x_u8` from `u8` to `isize`, matching the type of `-1_isize` + | +LL | isize::from(x_u8) > -1_isize; + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr index 6a081e23d9d37..a1d5b36931dac 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat_count.stderr @@ -39,12 +39,24 @@ error[E0308]: mismatched types | LL | let f = [0; -4_isize]; | ^^^^^^^^ expected `usize`, found `isize` + | +note: `-4_isize` can never fit into `usize` + --> $DIR/repeat_count.rs:19:17 + | +LL | let f = [0; -4_isize]; + | ^^^^^^^^ error[E0308]: mismatched types --> $DIR/repeat_count.rs:22:23 | LL | let f = [0_usize; -1_isize]; | ^^^^^^^^ expected `usize`, found `isize` + | +note: `-1_isize` can never fit into `usize` + --> $DIR/repeat_count.rs:22:23 + | +LL | let f = [0_usize; -1_isize]; + | ^^^^^^^^ error[E0308]: mismatched types --> $DIR/repeat_count.rs:25:17 From 2b936bb5a26f1f10daa5a6c5ed546dd274995942 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sat, 13 Jun 2020 22:31:31 -0700 Subject: [PATCH 15/60] fixup! Note numeric literals that can never fit in an expected type --- src/librustc_typeck/check/demand.rs | 2 +- src/test/ui/numeric/numeric-cast-no-fix.stderr | 10 +++++----- src/test/ui/repeat_count.stderr | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 7fc880b6c7c6c..79fc9772423fd 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -833,7 +833,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We now know that converting either the lhs or rhs is fallible. Before we // suggest a fallible conversion, check if the value can never fit in the // expected type. - let msg = format!("`{}` can never fit into `{}`", src, expected_ty); + let msg = format!("`{}` cannot fit into type `{}`", src, expected_ty); err.span_note(expr.span, &msg); return; } else if in_const_context { diff --git a/src/test/ui/numeric/numeric-cast-no-fix.stderr b/src/test/ui/numeric/numeric-cast-no-fix.stderr index 51e263d636f98..63b563aafb6de 100644 --- a/src/test/ui/numeric/numeric-cast-no-fix.stderr +++ b/src/test/ui/numeric/numeric-cast-no-fix.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | x_usize > -1_isize; | ^^^^^^^^ expected `usize`, found `isize` | -note: `-1_isize` can never fit into `usize` +note: `-1_isize` cannot fit into type `usize` --> $DIR/numeric-cast-no-fix.rs:10:15 | LL | x_usize > -1_isize; @@ -16,7 +16,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_isize; | ^^^^^^^^ expected `u128`, found `isize` | -note: `-1_isize` can never fit into `u128` +note: `-1_isize` cannot fit into type `u128` --> $DIR/numeric-cast-no-fix.rs:12:14 | LL | x_u128 > -1_isize; @@ -28,7 +28,7 @@ error[E0308]: mismatched types LL | x_u64 > -1_isize; | ^^^^^^^^ expected `u64`, found `isize` | -note: `-1_isize` can never fit into `u64` +note: `-1_isize` cannot fit into type `u64` --> $DIR/numeric-cast-no-fix.rs:14:13 | LL | x_u64 > -1_isize; @@ -40,7 +40,7 @@ error[E0308]: mismatched types LL | x_u32 > -1_isize; | ^^^^^^^^ expected `u32`, found `isize` | -note: `-1_isize` can never fit into `u32` +note: `-1_isize` cannot fit into type `u32` --> $DIR/numeric-cast-no-fix.rs:16:13 | LL | x_u32 > -1_isize; @@ -52,7 +52,7 @@ error[E0308]: mismatched types LL | x_u16 > -1_isize; | ^^^^^^^^ expected `u16`, found `isize` | -note: `-1_isize` can never fit into `u16` +note: `-1_isize` cannot fit into type `u16` --> $DIR/numeric-cast-no-fix.rs:18:13 | LL | x_u16 > -1_isize; diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr index a1d5b36931dac..34641be22150f 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat_count.stderr @@ -40,7 +40,7 @@ error[E0308]: mismatched types LL | let f = [0; -4_isize]; | ^^^^^^^^ expected `usize`, found `isize` | -note: `-4_isize` can never fit into `usize` +note: `-4_isize` cannot fit into type `usize` --> $DIR/repeat_count.rs:19:17 | LL | let f = [0; -4_isize]; @@ -52,7 +52,7 @@ error[E0308]: mismatched types LL | let f = [0_usize; -1_isize]; | ^^^^^^^^ expected `usize`, found `isize` | -note: `-1_isize` can never fit into `usize` +note: `-1_isize` cannot fit into type `usize` --> $DIR/repeat_count.rs:22:23 | LL | let f = [0_usize; -1_isize]; From e32db8458457849f5d894ffa4a1672b9071708f0 Mon Sep 17 00:00:00 2001 From: asrar Date: Sun, 14 Jun 2020 21:44:11 +0530 Subject: [PATCH 16/60] Add rust features to print target features `crt-static` is a rust specific target feature that's absent from llvm feature table, adding it there. --- src/rustllvm/PassWrapper.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 3d252fe70afeb..7586dd91ab68b 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -425,6 +425,9 @@ extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) { for (auto &Feature : FeatTable) printf(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc); printf("\n"); + // Rust specific target features + printf(" %-*s - %s.\n", MaxFeatLen, "crt-static", "Enables libraries with C Run-time Libraries(CRT) to be statically linked"); + printf("\n"); printf("Use +feature to enable a feature, or -feature to disable it.\n" "For example, rustc -C -target-cpu=mycpu -C " From f62903b74a8630fa62e721f69e6621d1d441e7f1 Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Fri, 5 Jun 2020 16:47:37 +0100 Subject: [PATCH 17/60] Export `#[inline] #[no_mangle]` fns in cdylibs and staticlibs --- src/librustc_codegen_ssa/back/symbol_export.rs | 9 +++++---- src/librustc_middle/mir/mono.rs | 1 + src/librustc_middle/query/mod.rs | 4 ++++ src/librustc_typeck/collect.rs | 12 ++++++++++++ src/test/codegen/cdylib-external-no-mangle-fns.rs | 13 +++++++++++++ .../codegen/staticlib-external-no-mangle-fns.rs | 13 +++++++++++++ 6 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 src/test/codegen/cdylib-external-no-mangle-fns.rs create mode 100644 src/test/codegen/staticlib-external-no-mangle-fns.rs diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 970d13b30c04e..bf8693f3547a4 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -89,10 +89,11 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap< | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => { let def_id = tcx.hir().local_def_id(hir_id); let generics = tcx.generics_of(def_id); - if !generics.requires_monomorphization(tcx) && - // Functions marked with #[inline] are only ever codegened - // with "internal" linkage and are never exported. - !Instance::mono(tcx, def_id.to_def_id()).def.generates_cgu_internal_copy(tcx) + if !generics.requires_monomorphization(tcx) + && (!Instance::mono(tcx, def_id.to_def_id()) + .def + .generates_cgu_internal_copy(tcx) + || tcx.inline_exportable(def_id.to_def_id())) { Some(def_id) } else { diff --git a/src/librustc_middle/mir/mono.rs b/src/librustc_middle/mir/mono.rs index c889dbc0a4498..d8dcf0dea8a5f 100644 --- a/src/librustc_middle/mir/mono.rs +++ b/src/librustc_middle/mir/mono.rs @@ -95,6 +95,7 @@ impl<'tcx> MonoItem<'tcx> { // linkage, then we'll be creating a globally shared version. if self.explicit_linkage(tcx).is_some() || !instance.def.generates_cgu_internal_copy(tcx) + || tcx.inline_exportable(instance.def_id()) || Some(instance.def_id()) == entry_def_id.map(LocalDefId::to_def_id) { return InstantiationMode::GloballyShared { may_conflict: false }; diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index be15e6c576f69..20487fdb6696d 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -697,6 +697,10 @@ rustc_queries! { storage(ArenaCacheSelector<'tcx>) cache_on_disk_if { true } } + + query inline_exportable(def_id: DefId) -> bool { + desc { |tcx| "computing whether `{}` should be explicitly exported", tcx.def_path_str(def_id) } + } } Other { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1d59d749634ee..08a6330e718e6 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -40,6 +40,7 @@ use rustc_middle::ty::util::Discr; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, AdtKind, Const, ToPolyTraitRef, Ty, TyCtxt}; use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness}; +use rustc_session::config::CrateType; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -79,6 +80,7 @@ pub fn provide(providers: &mut Providers<'_>) { static_mutability, generator_kind, codegen_fn_attrs, + inline_exportable, collect_mod_item_types, ..*providers }; @@ -2599,6 +2601,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { codegen_fn_attrs } +fn inline_exportable(tcx: TyCtxt<'_>, def_id: DefId) -> bool { + // Functions marked with #[inline] are only ever codegened + // with "internal" linkage and are never exported unless we're + // building a `staticlib` or `cdylib` and they are marked + // `#[no_mangle]`. + tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NO_MANGLE) + && (tcx.sess.crate_types().contains(&CrateType::Cdylib) + || tcx.sess.crate_types().contains(&CrateType::Staticlib)) +} + /// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller /// applied to the method prototype. fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool { diff --git a/src/test/codegen/cdylib-external-no-mangle-fns.rs b/src/test/codegen/cdylib-external-no-mangle-fns.rs new file mode 100644 index 0000000000000..827de7e5c11d9 --- /dev/null +++ b/src/test/codegen/cdylib-external-no-mangle-fns.rs @@ -0,0 +1,13 @@ +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "cdylib"] + +// CHECK: define void @a() +#[no_mangle] +#[inline] +pub extern "C" fn a() { + // side effect to keep `a` around + unsafe { + core::ptr::read_volatile(&42); + } +} diff --git a/src/test/codegen/staticlib-external-no-mangle-fns.rs b/src/test/codegen/staticlib-external-no-mangle-fns.rs new file mode 100644 index 0000000000000..0b4a37febb209 --- /dev/null +++ b/src/test/codegen/staticlib-external-no-mangle-fns.rs @@ -0,0 +1,13 @@ +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "staticlib"] + +// CHECK: define void @a() +#[no_mangle] +#[inline] +pub extern "C" fn a() { + // side effect to keep `a` around + unsafe { + core::ptr::read_volatile(&42); + } +} From 6b7cacb2c99567a76cf0d5ce6833a129c8bb8814 Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Mon, 8 Jun 2020 09:37:11 +0100 Subject: [PATCH 18/60] Export all fns with extern indicator --- .../back/symbol_export.rs | 9 ++++---- src/librustc_middle/mir/mono.rs | 12 ++++++---- src/librustc_middle/query/mod.rs | 4 ---- src/librustc_typeck/collect.rs | 12 ---------- .../codegen/cdylib-external-inline-fns.rs | 23 +++++++++++++++++++ .../codegen/cdylib-external-no-mangle-fns.rs | 13 ----------- src/test/codegen/export-no-mangle.rs | 5 ++++ src/test/codegen/external-no-mangle-fns.rs | 10 ++++++++ .../codegen/staticlib-external-inline-fns.rs | 23 +++++++++++++++++++ .../staticlib-external-no-mangle-fns.rs | 13 ----------- 10 files changed, 74 insertions(+), 50 deletions(-) create mode 100644 src/test/codegen/cdylib-external-inline-fns.rs delete mode 100644 src/test/codegen/cdylib-external-no-mangle-fns.rs create mode 100644 src/test/codegen/staticlib-external-inline-fns.rs delete mode 100644 src/test/codegen/staticlib-external-no-mangle-fns.rs diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index bf8693f3547a4..98f7da8361cc4 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -90,10 +90,11 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap< let def_id = tcx.hir().local_def_id(hir_id); let generics = tcx.generics_of(def_id); if !generics.requires_monomorphization(tcx) - && (!Instance::mono(tcx, def_id.to_def_id()) - .def - .generates_cgu_internal_copy(tcx) - || tcx.inline_exportable(def_id.to_def_id())) + // Functions marked with #[inline] are codegened with "internal" + // linkage and are not exported unless marked with an extern + // inidicator + && (!Instance::mono(tcx, def_id.to_def_id()).def.generates_cgu_internal_copy(tcx) + || tcx.codegen_fn_attrs(def_id.to_def_id()).contains_extern_indicator()) { Some(def_id) } else { diff --git a/src/librustc_middle/mir/mono.rs b/src/librustc_middle/mir/mono.rs index d8dcf0dea8a5f..886690da212d3 100644 --- a/src/librustc_middle/mir/mono.rs +++ b/src/librustc_middle/mir/mono.rs @@ -92,10 +92,10 @@ impl<'tcx> MonoItem<'tcx> { MonoItem::Fn(ref instance) => { let entry_def_id = tcx.entry_fn(LOCAL_CRATE).map(|(id, _)| id); // If this function isn't inlined or otherwise has explicit - // linkage, then we'll be creating a globally shared version. + // linkage or an extern indicator, then we'll be creating a + // globally shared version. if self.explicit_linkage(tcx).is_some() || !instance.def.generates_cgu_internal_copy(tcx) - || tcx.inline_exportable(instance.def_id()) || Some(instance.def_id()) == entry_def_id.map(LocalDefId::to_def_id) { return InstantiationMode::GloballyShared { may_conflict: false }; @@ -103,8 +103,12 @@ impl<'tcx> MonoItem<'tcx> { // At this point we don't have explicit linkage and we're an // inlined function. If we're inlining into all CGUs then we'll - // be creating a local copy per CGU - if generate_cgu_internal_copies { + // be creating a local copy per CGU. We need to watch out here + // for an extern indicator as we don't want to optimise away + // inlined functions that should be exported. + if generate_cgu_internal_copies + && !tcx.codegen_fn_attrs(instance.def_id()).contains_extern_indicator() + { return InstantiationMode::LocalCopy; } diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index 20487fdb6696d..be15e6c576f69 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -697,10 +697,6 @@ rustc_queries! { storage(ArenaCacheSelector<'tcx>) cache_on_disk_if { true } } - - query inline_exportable(def_id: DefId) -> bool { - desc { |tcx| "computing whether `{}` should be explicitly exported", tcx.def_path_str(def_id) } - } } Other { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 08a6330e718e6..1d59d749634ee 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -40,7 +40,6 @@ use rustc_middle::ty::util::Discr; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, AdtKind, Const, ToPolyTraitRef, Ty, TyCtxt}; use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness}; -use rustc_session::config::CrateType; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -80,7 +79,6 @@ pub fn provide(providers: &mut Providers<'_>) { static_mutability, generator_kind, codegen_fn_attrs, - inline_exportable, collect_mod_item_types, ..*providers }; @@ -2601,16 +2599,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { codegen_fn_attrs } -fn inline_exportable(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - // Functions marked with #[inline] are only ever codegened - // with "internal" linkage and are never exported unless we're - // building a `staticlib` or `cdylib` and they are marked - // `#[no_mangle]`. - tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NO_MANGLE) - && (tcx.sess.crate_types().contains(&CrateType::Cdylib) - || tcx.sess.crate_types().contains(&CrateType::Staticlib)) -} - /// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller /// applied to the method prototype. fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool { diff --git a/src/test/codegen/cdylib-external-inline-fns.rs b/src/test/codegen/cdylib-external-inline-fns.rs new file mode 100644 index 0000000000000..58f806b5a1f34 --- /dev/null +++ b/src/test/codegen/cdylib-external-inline-fns.rs @@ -0,0 +1,23 @@ +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "cdylib"] + +// CHECK: define void @a() +#[no_mangle] +#[inline] +pub extern "C" fn a() {} + +// CHECK: define void @b() +#[export_name = "b"] +#[inline] +pub extern "C" fn b() {} + +// CHECK: define void @c() +#[no_mangle] +#[inline] +extern "C" fn c() {} + +// CHECK: define void @d() +#[export_name = "d"] +#[inline] +extern "C" fn d() {} diff --git a/src/test/codegen/cdylib-external-no-mangle-fns.rs b/src/test/codegen/cdylib-external-no-mangle-fns.rs deleted file mode 100644 index 827de7e5c11d9..0000000000000 --- a/src/test/codegen/cdylib-external-no-mangle-fns.rs +++ /dev/null @@ -1,13 +0,0 @@ -// compile-flags: -C no-prepopulate-passes - -#![crate_type = "cdylib"] - -// CHECK: define void @a() -#[no_mangle] -#[inline] -pub extern "C" fn a() { - // side effect to keep `a` around - unsafe { - core::ptr::read_volatile(&42); - } -} diff --git a/src/test/codegen/export-no-mangle.rs b/src/test/codegen/export-no-mangle.rs index 78d41e4be0ae9..793636bb1b030 100644 --- a/src/test/codegen/export-no-mangle.rs +++ b/src/test/codegen/export-no-mangle.rs @@ -18,4 +18,9 @@ mod private { // CHECK: void @bar() #[export_name = "bar"] extern fn bar() {} + + // CHECK: void @baz() + #[export_name = "baz"] + #[inline] + extern fn baz() {} } diff --git a/src/test/codegen/external-no-mangle-fns.rs b/src/test/codegen/external-no-mangle-fns.rs index 902882144996f..aefa9ce21c3ee 100644 --- a/src/test/codegen/external-no-mangle-fns.rs +++ b/src/test/codegen/external-no-mangle-fns.rs @@ -53,3 +53,13 @@ fn x() { core::ptr::read_volatile(&42); } } + +// CHECK: define void @i() +#[no_mangle] +#[inline] +fn i() {} + +// CHECK: define void @j() +#[no_mangle] +#[inline] +pub fn j() {} diff --git a/src/test/codegen/staticlib-external-inline-fns.rs b/src/test/codegen/staticlib-external-inline-fns.rs new file mode 100644 index 0000000000000..8f55a5303311c --- /dev/null +++ b/src/test/codegen/staticlib-external-inline-fns.rs @@ -0,0 +1,23 @@ +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "staticlib"] + +// CHECK: define void @a() +#[no_mangle] +#[inline] +pub extern "C" fn a() {} + +// CHECK: define void @b() +#[export_name = "b"] +#[inline] +pub extern "C" fn b() {} + +// CHECK: define void @c() +#[no_mangle] +#[inline] +extern "C" fn c() {} + +// CHECK: define void @d() +#[export_name = "d"] +#[inline] +extern "C" fn d() {} diff --git a/src/test/codegen/staticlib-external-no-mangle-fns.rs b/src/test/codegen/staticlib-external-no-mangle-fns.rs deleted file mode 100644 index 0b4a37febb209..0000000000000 --- a/src/test/codegen/staticlib-external-no-mangle-fns.rs +++ /dev/null @@ -1,13 +0,0 @@ -// compile-flags: -C no-prepopulate-passes - -#![crate_type = "staticlib"] - -// CHECK: define void @a() -#[no_mangle] -#[inline] -pub extern "C" fn a() { - // side effect to keep `a` around - unsafe { - core::ptr::read_volatile(&42); - } -} From d23bedd13d70597a7db70ef5ea549fc7a4063d10 Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Mon, 8 Jun 2020 09:54:33 +0100 Subject: [PATCH 19/60] Fix whitespace --- src/test/codegen/export-no-mangle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/codegen/export-no-mangle.rs b/src/test/codegen/export-no-mangle.rs index 793636bb1b030..a52fac37021dd 100644 --- a/src/test/codegen/export-no-mangle.rs +++ b/src/test/codegen/export-no-mangle.rs @@ -18,7 +18,7 @@ mod private { // CHECK: void @bar() #[export_name = "bar"] extern fn bar() {} - + // CHECK: void @baz() #[export_name = "baz"] #[inline] From ee810a75e41368387918759ed191657f05650f05 Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Tue, 9 Jun 2020 15:49:59 +0100 Subject: [PATCH 20/60] Fix exports with `#[inline(always)]` --- src/librustc_middle/mir/mono.rs | 15 +++++-------- .../codegen/cdylib-external-inline-fns.rs | 20 ++++++++++++++++++ src/test/codegen/export-no-mangle.rs | 21 ++++++++++++------- src/test/codegen/external-no-mangle-fns.rs | 10 +++++++++ .../codegen/staticlib-external-inline-fns.rs | 20 ++++++++++++++++++ 5 files changed, 68 insertions(+), 18 deletions(-) diff --git a/src/librustc_middle/mir/mono.rs b/src/librustc_middle/mir/mono.rs index 886690da212d3..24d324ff09c4c 100644 --- a/src/librustc_middle/mir/mono.rs +++ b/src/librustc_middle/mir/mono.rs @@ -91,10 +91,9 @@ impl<'tcx> MonoItem<'tcx> { match *self { MonoItem::Fn(ref instance) => { let entry_def_id = tcx.entry_fn(LOCAL_CRATE).map(|(id, _)| id); - // If this function isn't inlined or otherwise has explicit - // linkage or an extern indicator, then we'll be creating a - // globally shared version. - if self.explicit_linkage(tcx).is_some() + // If this function isn't inlined or otherwise has an extern + // indicator, then we'll be creating a globally shared version. + if tcx.codegen_fn_attrs(instance.def_id()).contains_extern_indicator() || !instance.def.generates_cgu_internal_copy(tcx) || Some(instance.def_id()) == entry_def_id.map(LocalDefId::to_def_id) { @@ -103,12 +102,8 @@ impl<'tcx> MonoItem<'tcx> { // At this point we don't have explicit linkage and we're an // inlined function. If we're inlining into all CGUs then we'll - // be creating a local copy per CGU. We need to watch out here - // for an extern indicator as we don't want to optimise away - // inlined functions that should be exported. - if generate_cgu_internal_copies - && !tcx.codegen_fn_attrs(instance.def_id()).contains_extern_indicator() - { + // be creating a local copy per CGU. + if generate_cgu_internal_copies { return InstantiationMode::LocalCopy; } diff --git a/src/test/codegen/cdylib-external-inline-fns.rs b/src/test/codegen/cdylib-external-inline-fns.rs index 58f806b5a1f34..519be6b6a99a4 100644 --- a/src/test/codegen/cdylib-external-inline-fns.rs +++ b/src/test/codegen/cdylib-external-inline-fns.rs @@ -21,3 +21,23 @@ extern "C" fn c() {} #[export_name = "d"] #[inline] extern "C" fn d() {} + +// CHECK: define void @e() +#[no_mangle] +#[inline(always)] +pub extern "C" fn e() {} + +// CHECK: define void @f() +#[export_name = "f"] +#[inline(always)] +pub extern "C" fn f() {} + +// CHECK: define void @g() +#[no_mangle] +#[inline(always)] +extern "C" fn g() {} + +// CHECK: define void @h() +#[export_name = "h"] +#[inline(always)] +extern "C" fn h() {} diff --git a/src/test/codegen/export-no-mangle.rs b/src/test/codegen/export-no-mangle.rs index a52fac37021dd..11427ae38822f 100644 --- a/src/test/codegen/export-no-mangle.rs +++ b/src/test/codegen/export-no-mangle.rs @@ -11,16 +11,21 @@ mod private { #[export_name = "BAR"] static BAR: u32 = 3; - // CHECK: void @foo() + // CHECK: void @a() #[no_mangle] - pub extern fn foo() {} + pub extern fn a() {} - // CHECK: void @bar() - #[export_name = "bar"] - extern fn bar() {} + // CHECK: void @b() + #[export_name = "b"] + extern fn b() {} - // CHECK: void @baz() - #[export_name = "baz"] + // CHECK: void @c() + #[export_name = "c"] #[inline] - extern fn baz() {} + extern fn c() {} + + // CHECK: void @d() + #[export_name = "d"] + #[inline(always)] + extern fn d() {} } diff --git a/src/test/codegen/external-no-mangle-fns.rs b/src/test/codegen/external-no-mangle-fns.rs index aefa9ce21c3ee..41820b057f1ef 100644 --- a/src/test/codegen/external-no-mangle-fns.rs +++ b/src/test/codegen/external-no-mangle-fns.rs @@ -63,3 +63,13 @@ fn i() {} #[no_mangle] #[inline] pub fn j() {} + +// CHECK: define void @k() +#[no_mangle] +#[inline(always)] +fn k() {} + +// CHECK: define void @l() +#[no_mangle] +#[inline(always)] +pub fn l() {} diff --git a/src/test/codegen/staticlib-external-inline-fns.rs b/src/test/codegen/staticlib-external-inline-fns.rs index 8f55a5303311c..8876ab7376afe 100644 --- a/src/test/codegen/staticlib-external-inline-fns.rs +++ b/src/test/codegen/staticlib-external-inline-fns.rs @@ -21,3 +21,23 @@ extern "C" fn c() {} #[export_name = "d"] #[inline] extern "C" fn d() {} + +// CHECK: define void @e() +#[no_mangle] +#[inline(always)] +pub extern "C" fn e() {} + +// CHECK: define void @f() +#[export_name = "f"] +#[inline(always)] +pub extern "C" fn f() {} + +// CHECK: define void @g() +#[no_mangle] +#[inline(always)] +extern "C" fn g() {} + +// CHECK: define void @h() +#[export_name = "h"] +#[inline(always)] +extern "C" fn h() {} From 11b56fbfb63ef8e2494b8631488e478794c80ed4 Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Tue, 9 Jun 2020 15:54:34 +0100 Subject: [PATCH 21/60] Fix whitespace --- src/librustc_middle/mir/mono.rs | 2 +- src/test/codegen/export-no-mangle.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_middle/mir/mono.rs b/src/librustc_middle/mir/mono.rs index 24d324ff09c4c..f1c1b962ab997 100644 --- a/src/librustc_middle/mir/mono.rs +++ b/src/librustc_middle/mir/mono.rs @@ -102,7 +102,7 @@ impl<'tcx> MonoItem<'tcx> { // At this point we don't have explicit linkage and we're an // inlined function. If we're inlining into all CGUs then we'll - // be creating a local copy per CGU. + // be creating a local copy per CGU. if generate_cgu_internal_copies { return InstantiationMode::LocalCopy; } diff --git a/src/test/codegen/export-no-mangle.rs b/src/test/codegen/export-no-mangle.rs index 11427ae38822f..59e97601c838d 100644 --- a/src/test/codegen/export-no-mangle.rs +++ b/src/test/codegen/export-no-mangle.rs @@ -23,7 +23,7 @@ mod private { #[export_name = "c"] #[inline] extern fn c() {} - + // CHECK: void @d() #[export_name = "d"] #[inline(always)] From babda9470ea1e5932d238b7f805e76379f01d37c Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Mon, 15 Jun 2020 10:21:19 +0100 Subject: [PATCH 22/60] Fix sanitizer test --- src/test/codegen/sanitizer-no-sanitize-inlining.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/codegen/sanitizer-no-sanitize-inlining.rs b/src/test/codegen/sanitizer-no-sanitize-inlining.rs index d96e76618d325..86e58c3c9bb17 100644 --- a/src/test/codegen/sanitizer-no-sanitize-inlining.rs +++ b/src/test/codegen/sanitizer-no-sanitize-inlining.rs @@ -13,7 +13,7 @@ #![feature(no_sanitize)] // ASAN-LABEL: define void @test -// ASAN: tail call fastcc void @random_inline +// ASAN: tail call fastcc // ASAN: } // // LSAN-LABEL: define void @test @@ -26,7 +26,6 @@ pub fn test(n: &mut u32) { #[no_sanitize(address)] #[inline] -#[no_mangle] pub fn random_inline(n: &mut u32) { *n = 42; } From e8e0a0e4e220533db31bc6a572ed9f1b99b31289 Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Mon, 15 Jun 2020 11:12:19 +0100 Subject: [PATCH 23/60] Update sanitizer test --- src/test/codegen/sanitizer-no-sanitize-inlining.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/codegen/sanitizer-no-sanitize-inlining.rs b/src/test/codegen/sanitizer-no-sanitize-inlining.rs index 86e58c3c9bb17..48231d6f7208d 100644 --- a/src/test/codegen/sanitizer-no-sanitize-inlining.rs +++ b/src/test/codegen/sanitizer-no-sanitize-inlining.rs @@ -13,7 +13,7 @@ #![feature(no_sanitize)] // ASAN-LABEL: define void @test -// ASAN: tail call fastcc +// ASAN: call {{.*}} @random_inline // ASAN: } // // LSAN-LABEL: define void @test @@ -26,6 +26,7 @@ pub fn test(n: &mut u32) { #[no_sanitize(address)] #[inline] +#[no_mangle] pub fn random_inline(n: &mut u32) { *n = 42; } From 9e510085ecaedaee86b44410a4b3e4c85d97d6e0 Mon Sep 17 00:00:00 2001 From: Alexis Bourget Date: Mon, 15 Jun 2020 15:19:02 +0200 Subject: [PATCH 24/60] 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 81c909488eebcba16610402349563380772e0d1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 29 May 2020 15:09:43 -0700 Subject: [PATCH 25/60] Suggest substituting `'static` lifetime in impl/dyn `Trait + 'static` return types --- .../nice_region_error/static_impl_trait.rs | 64 ++++++++-- src/librustc_middle/ty/context.rs | 13 +- src/librustc_middle/ty/diagnostics.rs | 8 +- ...t_outlive_least_region_or_bound.nll.stderr | 38 +++++- .../must_outlive_least_region_or_bound.rs | 21 ++++ .../must_outlive_least_region_or_bound.stderr | 117 ++++++++++++++++-- 6 files changed, 232 insertions(+), 29 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index f4c86ddae604e..88d6c23d51441 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -4,6 +4,7 @@ use crate::infer::error_reporting::msg_span_from_free_region; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use rustc_errors::{Applicability, ErrorReported}; +use rustc_hir::{GenericBound, ItemKind, Lifetime, LifetimeName, TyKind}; use rustc_middle::ty::RegionKind; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { @@ -20,8 +21,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ) = error.clone() { let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?; - let (fn_return_span, is_dyn) = - self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?; + let fn_return = self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?; + let is_dyn = matches!(fn_return.kind, TyKind::TraitObject(..)); + let fn_return_span = fn_return.span; if sub_r == &RegionKind::ReStatic { let sp = var_origin.span(); let return_sp = sub_origin.span(); @@ -67,12 +69,58 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { lifetime, ); // FIXME: account for the need of parens in `&(dyn Trait + '_)` - err.span_suggestion_verbose( - fn_return_span.shrink_to_hi(), - &msg, - format!(" + {}", lifetime_name), - Applicability::MaybeIncorrect, - ); + match fn_return.kind { + TyKind::Def(item_id, _) => { + let item = self.tcx().hir().item(item_id.id); + let opaque = if let ItemKind::OpaqueTy(opaque) = &item.kind { + opaque + } else { + err.emit(); + return Some(ErrorReported); + }; + let (span, sugg) = opaque + .bounds + .iter() + .filter_map(|arg| match arg { + GenericBound::Outlives(Lifetime { + name: LifetimeName::Static, + span, + .. + }) => Some((*span, lifetime_name.clone())), + _ => None, + }) + .next() + .unwrap_or_else(|| { + ( + fn_return_span.shrink_to_hi(), + format!(" + {}", lifetime_name), + ) + }); + + err.span_suggestion_verbose( + span, + &msg, + sugg, + Applicability::MaybeIncorrect, + ); + } + TyKind::TraitObject(_, lt) => { + let (span, sugg) = match lt.name { + LifetimeName::ImplicitObjectLifetimeDefault => ( + fn_return_span.shrink_to_hi(), + format!(" + {}", lifetime_name), + ), + _ => (lt.span, lifetime_name), + }; + err.span_suggestion_verbose( + span, + &msg, + sugg, + Applicability::MaybeIncorrect, + ); + } + _ => {} + } } err.emit(); return Some(ErrorReported); diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index d5be3508d2d80..4770993d9cb07 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -1383,7 +1383,10 @@ impl<'tcx> TyCtxt<'tcx> { }) } - pub fn return_type_impl_or_dyn_trait(&self, scope_def_id: DefId) -> Option<(Span, bool)> { + pub fn return_type_impl_or_dyn_trait( + &self, + scope_def_id: DefId, + ) -> Option<&'tcx hir::Ty<'tcx>> { let hir_id = self.hir().as_local_hir_id(scope_def_id.expect_local()); let hir_output = match self.hir().get(hir_id) { Node::Item(hir::Item { @@ -1429,15 +1432,17 @@ impl<'tcx> TyCtxt<'tcx> { let output = self.erase_late_bound_regions(&sig.output()); if output.is_impl_trait() { let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap(); - Some((fn_decl.output.span(), false)) + if let hir::FnRetTy::Return(ty) = fn_decl.output { + return Some(ty); + } } else { let mut v = TraitObjectVisitor(vec![]); rustc_hir::intravisit::walk_ty(&mut v, hir_output); if v.0.len() == 1 { - return Some((v.0[0], true)); + return Some(v.0[0]); } - None } + None } _ => None, } diff --git a/src/librustc_middle/ty/diagnostics.rs b/src/librustc_middle/ty/diagnostics.rs index 2e9aa724ac5af..3ca506fe0d590 100644 --- a/src/librustc_middle/ty/diagnostics.rs +++ b/src/librustc_middle/ty/diagnostics.rs @@ -236,21 +236,21 @@ pub fn suggest_constraining_type_param( } } -pub struct TraitObjectVisitor(pub Vec); -impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor { +pub struct TraitObjectVisitor<'tcx>(pub Vec<&'tcx hir::Ty<'tcx>>); +impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> { type Map = rustc_hir::intravisit::ErasedMap<'v>; fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap { hir::intravisit::NestedVisitorMap::None } - fn visit_ty(&mut self, ty: &hir::Ty<'_>) { + fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { if let hir::TyKind::TraitObject( _, hir::Lifetime { name: hir::LifetimeName::ImplicitObjectLifetimeDefault, .. }, ) = ty.kind { - self.0.push(ty.span); + self.0.push(ty); } } } diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr index 1806d2607a3ac..ca9ca8a9debe2 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr @@ -26,7 +26,34 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^^^^^^^^^^^ error: lifetime may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:12:69 + --> $DIR/must_outlive_least_region_or_bound.rs:9:46 + | +LL | fn elided2(x: &i32) -> impl Copy + 'static { x } + | - ^ returning this value requires that `'1` must outlive `'static` + | | + | let's call the lifetime of this reference `'1` + | + = help: consider replacing `'1` with `'static` + +error: lifetime may not live long enough + --> $DIR/must_outlive_least_region_or_bound.rs:12:55 + | +LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } + | -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static` + | + = help: consider replacing `'a` with `'static` + = help: consider replacing `'a` with `'static` + +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/must_outlive_least_region_or_bound.rs:15:41 + | +LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } + | ---- ^ lifetime `'a` required + | | + | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` + +error: lifetime may not live long enough + --> $DIR/must_outlive_least_region_or_bound.rs:33:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static` @@ -35,7 +62,7 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } = help: consider replacing `'a` with `'static` error: lifetime may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:17:61 + --> $DIR/must_outlive_least_region_or_bound.rs:38:61 | LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { | -- -- lifetime `'b` defined here ^^^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a` @@ -45,13 +72,14 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32 = help: consider adding the following bound: `'b: 'a` error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:22:51 + --> $DIR/must_outlive_least_region_or_bound.rs:43:51 | LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { | ^^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `T: 'static`... -error: aborting due to 5 previous errors +error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0310`. +Some errors have detailed explanations: E0310, E0621. +For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs index 00f3490991b52..beafe9258209d 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs @@ -6,6 +6,27 @@ fn elided(x: &i32) -> impl Copy { x } fn explicit<'a>(x: &'a i32) -> impl Copy { x } //~^ ERROR cannot infer an appropriate lifetime +fn elided2(x: &i32) -> impl Copy + 'static { x } +//~^ ERROR cannot infer an appropriate lifetime + +fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } +//~^ ERROR cannot infer an appropriate lifetime + +fn foo<'a>(x: &i32) -> impl Copy + 'a { x } +//~^ ERROR explicit lifetime required in the type of `x` + +fn elided3(x: &i32) -> Box { Box::new(x) } +//~^ ERROR cannot infer an appropriate lifetime + +fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } +//~^ ERROR cannot infer an appropriate lifetime + +fn elided4(x: &i32) -> Box { Box::new(x) } +//~^ ERROR explicit lifetime required in the type of `x` + +fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } +//~^ ERROR cannot infer an appropriate lifetime + trait LifetimeTrait<'a> {} impl<'a> LifetimeTrait<'a> for &'a i32 {} diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index d7dae6a08a7b9..525e271bea9c3 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -27,7 +27,43 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^ error: cannot infer an appropriate lifetime - --> $DIR/must_outlive_least_region_or_bound.rs:12:69 + --> $DIR/must_outlive_least_region_or_bound.rs:9:46 + | +LL | fn elided2(x: &i32) -> impl Copy + 'static { x } + | ---- ------------------- ^ ...and is captured here + | | | + | | ...is required to be `'static` by this... + | data with this lifetime... + | +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 9:1 + | +LL | fn elided2(x: &i32) -> impl Copy + '_ { x } + | ^^ + +error: cannot infer an appropriate lifetime + --> $DIR/must_outlive_least_region_or_bound.rs:12:55 + | +LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } + | ------- ------------------- ^ ...and is captured here + | | | + | | ...is required to be `'static` by this... + | data with this lifetime... + | +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 12:14 + | +LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } + | ^^ + +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/must_outlive_least_region_or_bound.rs:15:24 + | +LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } + | ---- ^^^^^^^^^^^^^^ lifetime `'a` required + | | + | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` + +error: cannot infer an appropriate lifetime + --> $DIR/must_outlive_least_region_or_bound.rs:33:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | ------- -------------------------------- ^ ...and is captured here @@ -35,13 +71,13 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | | ...is required to be `'static` by this... | data with this lifetime... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 12:15 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 33:15 | -LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static + 'a { x } - | ^^^^ +LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } + | ^^ error[E0623]: lifetime mismatch - --> $DIR/must_outlive_least_region_or_bound.rs:17:61 + --> $DIR/must_outlive_least_region_or_bound.rs:38:61 | LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { | ------- ^^^^^^^^^^^^^^^^ @@ -50,14 +86,79 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32 | this parameter and the return type are declared with different lifetimes... error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:22:51 + --> $DIR/must_outlive_least_region_or_bound.rs:43:51 | LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { | -- ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | | | help: consider adding an explicit lifetime bound...: `T: 'static +` -error: aborting due to 5 previous errors +error: cannot infer an appropriate lifetime + --> $DIR/must_outlive_least_region_or_bound.rs:18:50 + | +LL | fn elided3(x: &i32) -> Box { Box::new(x) } + | ---- ---------^- + | | | | + | | | ...and is captured here + | | ...is required to be `'static` by this... + | data with this lifetime... + | +help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1 + | +LL | fn elided3(x: &i32) -> Box { Box::new(x) } + | ^^^^ + +error: cannot infer an appropriate lifetime + --> $DIR/must_outlive_least_region_or_bound.rs:21:59 + | +LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } + | ------- ---------^- + | | | | + | | | ...and is captured here + | | ...is required to be `'static` by this... + | data with this lifetime... + | +help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14 + | +LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^^^ + +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/must_outlive_least_region_or_bound.rs:24:51 + | +LL | fn elided4(x: &i32) -> Box { Box::new(x) } + | ---- ^^^^^^^^^^^ lifetime `'static` required + | | + | help: add explicit lifetime `'static` to the type of `x`: `&'static i32` + +error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements + --> $DIR/must_outlive_least_region_or_bound.rs:27:69 + | +LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^ + | +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 27:14... + --> $DIR/must_outlive_least_region_or_bound.rs:27:14 + | +LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^ +note: ...so that the expression is assignable + --> $DIR/must_outlive_least_region_or_bound.rs:27:69 + | +LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^ + = note: expected `&i32` + found `&'a i32` + = note: but, the lifetime must be valid for the static lifetime... +note: ...so that the expression is assignable + --> $DIR/must_outlive_least_region_or_bound.rs:27:60 + | +LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^ + = note: expected `std::boxed::Box<(dyn std::fmt::Debug + 'static)>` + found `std::boxed::Box` + +error: aborting due to 12 previous errors -Some errors have detailed explanations: E0310, E0623. +Some errors have detailed explanations: E0310, E0495, E0621, E0623. For more information about an error, try `rustc --explain E0310`. From 4e90f177cc530371a314f51f522a4c2e70885e03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 29 May 2020 18:05:20 -0700 Subject: [PATCH 26/60] When `'static` is explicit, suggest constraining argument with it --- .../infer/error_reporting/mod.rs | 3 +- .../nice_region_error/static_impl_trait.rs | 115 +++++++++++------- src/librustc_middle/ty/diagnostics.rs | 5 +- .../must_outlive_least_region_or_bound.rs | 2 +- .../must_outlive_least_region_or_bound.stderr | 75 +++++++----- src/test/ui/issues/issue-16922.stderr | 2 +- ...ect-lifetime-default-from-box-error.stderr | 2 +- ...ion-object-lifetime-in-coercion.nll.stderr | 19 ++- .../region-object-lifetime-in-coercion.rs | 5 +- .../region-object-lifetime-in-coercion.stderr | 61 +++++++--- .../regions-close-object-into-object-2.stderr | 32 ++--- .../regions-close-object-into-object-4.stderr | 32 ++--- .../regions-proc-bound-capture.nll.stderr | 11 ++ .../ui/regions/regions-proc-bound-capture.rs | 4 +- .../regions/regions-proc-bound-capture.stderr | 25 ++-- .../dyn-trait-underscore.stderr | 2 +- 16 files changed, 237 insertions(+), 158 deletions(-) create mode 100644 src/test/ui/regions/regions-proc-bound-capture.nll.stderr diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs index 12f7a9c0ca502..9cfa11dd7c813 100644 --- a/src/librustc_infer/infer/error_reporting/mod.rs +++ b/src/librustc_infer/infer/error_reporting/mod.rs @@ -2035,8 +2035,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.tcx.sess, var_origin.span(), E0495, - "cannot infer an appropriate lifetime{} \ - due to conflicting requirements", + "cannot infer an appropriate lifetime{} due to conflicting requirements", var_description ) } diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 88d6c23d51441..e24535bba5fdc 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -10,6 +10,7 @@ use rustc_middle::ty::RegionKind; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// Print the error message for lifetime errors when the return type is a static impl Trait. pub(super) fn try_report_static_impl_trait(&self) -> Option { + debug!("try_report_static_impl_trait(error={:?})", self.error); if let Some(ref error) = self.error { if let RegionResolutionError::SubSupConflict( _, @@ -18,19 +19,24 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { sub_r, sup_origin, sup_r, - ) = error.clone() + ) = error { + debug!( + "try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})", + var_origin, sub_origin, sub_r, sup_origin, sup_r + ); let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?; + debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup); let fn_return = self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?; - let is_dyn = matches!(fn_return.kind, TyKind::TraitObject(..)); - let fn_return_span = fn_return.span; - if sub_r == &RegionKind::ReStatic { + debug!("try_report_static_impl_trait: fn_return={:?}", fn_return); + if **sub_r == RegionKind::ReStatic { let sp = var_origin.span(); let return_sp = sub_origin.span(); + let param_info = self.find_param_with_region(sup_r, sub_r)?; let mut err = self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime"); - let param_info = self.find_param_with_region(sup_r, sub_r)?; err.span_label(param_info.param_ty_span, "data with this lifetime..."); + debug!("try_report_static_impl_trait: param_info={:?}", param_info); // We try to make the output have fewer overlapping spans if possible. if (sp == sup_origin.span() || !return_sp.overlaps(sup_origin.span())) @@ -60,14 +66,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { if sup_r.has_name() { sup_r.to_string() } else { "'_".to_owned() }; // only apply this suggestion onto functions with // explicit non-desugar'able return. - if fn_return_span.desugaring_kind().is_none() { - let msg = format!( - "to permit non-static references in {} `{} Trait` value, you can add \ - an explicit bound for {}", - if is_dyn { "a" } else { "an" }, - if is_dyn { "dyn" } else { "impl" }, - lifetime, - ); + if fn_return.span.desugaring_kind().is_none() { // FIXME: account for the need of parens in `&(dyn Trait + '_)` match fn_return.kind { TyKind::Def(item_id, _) => { @@ -78,7 +77,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { err.emit(); return Some(ErrorReported); }; - let (span, sugg) = opaque + + if let Some(span) = opaque .bounds .iter() .filter_map(|arg| match arg { @@ -86,38 +86,71 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { name: LifetimeName::Static, span, .. - }) => Some((*span, lifetime_name.clone())), + }) => Some(*span), _ => None, }) .next() - .unwrap_or_else(|| { - ( - fn_return_span.shrink_to_hi(), - format!(" + {}", lifetime_name), - ) - }); - - err.span_suggestion_verbose( - span, - &msg, - sugg, - Applicability::MaybeIncorrect, - ); - } - TyKind::TraitObject(_, lt) => { - let (span, sugg) = match lt.name { - LifetimeName::ImplicitObjectLifetimeDefault => ( - fn_return_span.shrink_to_hi(), + { + err.span_suggestion_verbose( + span, + "consider changing the `impl Trait`'s explicit \ + `'static` bound", + lifetime_name, + Applicability::MaybeIncorrect, + ); + err.span_suggestion_verbose( + param_info.param_ty_span, + "alternatively, set an explicit `'static` lifetime to \ + this parameter", + param_info.param_ty.to_string(), + Applicability::MaybeIncorrect, + ); + } else { + err.span_suggestion_verbose( + fn_return.span.shrink_to_hi(), + &format!( + "to permit non-static references in an `impl Trait` \ + value, you can add an explicit bound for {}", + lifetime, + ), format!(" + {}", lifetime_name), - ), - _ => (lt.span, lifetime_name), + Applicability::MaybeIncorrect, + ); }; - err.span_suggestion_verbose( - span, - &msg, - sugg, - Applicability::MaybeIncorrect, - ); + } + TyKind::TraitObject(_, lt) => { + match lt.name { + LifetimeName::ImplicitObjectLifetimeDefault => { + err.span_suggestion_verbose( + fn_return.span.shrink_to_hi(), + &format!( + "to permit non-static references in a trait object \ + value, you can add an explicit bound for {}", + lifetime, + ), + format!(" + {}", lifetime_name), + Applicability::MaybeIncorrect, + ); + } + _ => { + err.span_suggestion_verbose( + lt.span, + "consider changing the trait object's explicit \ + `'static` bound", + lifetime_name, + Applicability::MaybeIncorrect, + ); + err.span_suggestion_verbose( + param_info.param_ty_span, + &format!( + "alternatively, set an explicit `'static` lifetime \ + in this parameter", + ), + param_info.param_ty.to_string(), + Applicability::MaybeIncorrect, + ); + } + } } _ => {} } diff --git a/src/librustc_middle/ty/diagnostics.rs b/src/librustc_middle/ty/diagnostics.rs index 3ca506fe0d590..a2812e117ed39 100644 --- a/src/librustc_middle/ty/diagnostics.rs +++ b/src/librustc_middle/ty/diagnostics.rs @@ -247,7 +247,10 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> { fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { if let hir::TyKind::TraitObject( _, - hir::Lifetime { name: hir::LifetimeName::ImplicitObjectLifetimeDefault, .. }, + hir::Lifetime { + name: hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static, + .. + }, ) = ty.kind { self.0.push(ty); diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs index beafe9258209d..837244b022721 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs @@ -22,7 +22,7 @@ fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } //~^ ERROR cannot infer an appropriate lifetime fn elided4(x: &i32) -> Box { Box::new(x) } -//~^ ERROR explicit lifetime required in the type of `x` +//~^ ERROR cannot infer an appropriate lifetime fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } //~^ ERROR cannot infer an appropriate lifetime diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 525e271bea9c3..96d4a121c16af 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -35,10 +35,14 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | | ...is required to be `'static` by this... | data with this lifetime... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 9:1 +help: consider changing the `impl Trait`'s explicit `'static` bound | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } | ^^ +help: alternatively, set an explicit `'static` lifetime to this parameter + | +LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x } + | ^^^^^^^^^^^^ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:12:55 @@ -49,10 +53,14 @@ LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | | ...is required to be `'static` by this... | data with this lifetime... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 12:14 +help: consider changing the `impl Trait`'s explicit `'static` bound | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^ +help: alternatively, set an explicit `'static` lifetime to this parameter + | +LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x } + | ^^^^^^^^^^^^ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/must_outlive_least_region_or_bound.rs:15:24 @@ -71,10 +79,14 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | | ...is required to be `'static` by this... | data with this lifetime... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 33:15 +help: consider changing the `impl Trait`'s explicit `'static` bound | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } | ^^ +help: alternatively, set an explicit `'static` lifetime to this parameter + | +LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x } + | ^^^^^^^^^^^^ error[E0623]: lifetime mismatch --> $DIR/must_outlive_least_region_or_bound.rs:38:61 @@ -103,7 +115,7 @@ LL | fn elided3(x: &i32) -> Box { Box::new(x) } | | ...is required to be `'static` by this... | data with this lifetime... | -help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } | ^^^^ @@ -118,47 +130,48 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | | ...is required to be `'static` by this... | data with this lifetime... | -help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14 +help: to permit non-static references in a trait object value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^^^ -error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/must_outlive_least_region_or_bound.rs:24:51 +error: cannot infer an appropriate lifetime + --> $DIR/must_outlive_least_region_or_bound.rs:24:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ---- ^^^^^^^^^^^ lifetime `'static` required - | | - | help: add explicit lifetime `'static` to the type of `x`: `&'static i32` - -error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/must_outlive_least_region_or_bound.rs:27:69 + | ---- ---------^- + | | | | + | | | ...and is captured here + | data with this lifetime... ...is required to be `'static` by this... | -LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^ +help: consider changing the trait object's explicit `'static` bound | -note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 27:14... - --> $DIR/must_outlive_least_region_or_bound.rs:27:14 +LL | fn elided4(x: &i32) -> Box { Box::new(x) } + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter | -LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^^ -note: ...so that the expression is assignable +LL | fn elided4(x: &'static i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^^ + +error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:27:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^ - = note: expected `&i32` - found `&'a i32` - = note: but, the lifetime must be valid for the static lifetime... -note: ...so that the expression is assignable - --> $DIR/must_outlive_least_region_or_bound.rs:27:60 + | ------- ---------^- + | | | | + | | | ...and is captured here + | data with this lifetime... ...is required to be `'static` by this... | -LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^ - = note: expected `std::boxed::Box<(dyn std::fmt::Debug + 'static)>` - found `std::boxed::Box` +help: consider changing the trait object's explicit `'static` bound + | +LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter + | +LL | fn explicit4<'a>(x: &'static i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^^ error: aborting due to 12 previous errors -Some errors have detailed explanations: E0310, E0495, E0621, E0623. +Some errors have detailed explanations: E0310, E0621, E0623. For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index 02d33aae023ff..038df47e1bd98 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -9,7 +9,7 @@ LL | Box::new(value) as Box | | ...and is captured here | ...is required to be `'static` by this... | -help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1 | LL | fn foo(value: &T) -> Box { | ^^^^ diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index 70a9bf22b8db3..555622c9d13c1 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -7,7 +7,7 @@ LL | fn load(ss: &mut SomeStruct) -> Box { LL | ss.r | ^^^^ ...is captured and required to be `'static` here | -help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1 | LL | fn load(ss: &mut SomeStruct) -> Box { | ^^^^ diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr index bf02ba8eb9199..7e8f78067e08a 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr @@ -1,21 +1,21 @@ -error[E0621]: explicit lifetime required in the type of `v` +error: lifetime may not live long enough --> $DIR/region-object-lifetime-in-coercion.rs:8:12 | LL | fn a(v: &[u8]) -> Box { - | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]` + | - let's call the lifetime of this reference `'1` LL | let x: Box = Box::new(v); - | ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required + | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static` -error[E0621]: explicit lifetime required in the type of `v` - --> $DIR/region-object-lifetime-in-coercion.rs:14:5 +error: lifetime may not live long enough + --> $DIR/region-object-lifetime-in-coercion.rs:13:5 | LL | fn b(v: &[u8]) -> Box { - | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]` + | - let's call the lifetime of this reference `'1` LL | Box::new(v) - | ^^^^^^^^^^^ lifetime `'static` required + | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` error: lifetime may not live long enough - --> $DIR/region-object-lifetime-in-coercion.rs:20:5 + --> $DIR/region-object-lifetime-in-coercion.rs:19:5 | LL | fn c(v: &[u8]) -> Box { | - let's call the lifetime of this reference `'1` @@ -24,7 +24,7 @@ LL | Box::new(v) | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` error: lifetime may not live long enough - --> $DIR/region-object-lifetime-in-coercion.rs:24:5 + --> $DIR/region-object-lifetime-in-coercion.rs:23:5 | LL | fn d<'a,'b>(v: &'a [u8]) -> Box { | -- -- lifetime `'b` defined here @@ -37,4 +37,3 @@ LL | Box::new(v) error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.rs b/src/test/ui/regions/region-object-lifetime-in-coercion.rs index d56eaf77b6646..5d199149c39b8 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.rs +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.rs @@ -5,13 +5,12 @@ trait Foo {} impl<'a> Foo for &'a [u8] {} fn a(v: &[u8]) -> Box { - let x: Box = Box::new(v); - //~^ ERROR explicit lifetime required in the type of `v` [E0621] + let x: Box = Box::new(v); //~ ERROR cannot infer an appropriate lifetime x } fn b(v: &[u8]) -> Box { - Box::new(v) //~ ERROR explicit lifetime required in the type of `v` [E0621] + Box::new(v) //~ ERROR cannot infer an appropriate lifetime } fn c(v: &[u8]) -> Box { diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 1462af44cb15a..673300cebc26c 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -1,21 +1,45 @@ -error[E0621]: explicit lifetime required in the type of `v` - --> $DIR/region-object-lifetime-in-coercion.rs:8:37 +error: cannot infer an appropriate lifetime + --> $DIR/region-object-lifetime-in-coercion.rs:8:46 | LL | fn a(v: &[u8]) -> Box { - | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]` + | ----- data with this lifetime... LL | let x: Box = Box::new(v); - | ^^^^^^^^^^^ lifetime `'static` required + | ---------^- + | | | + | | ...and is captured here + | ...is required to be `'static` by this... + | +help: consider changing the trait object's explicit `'static` bound + | +LL | fn a(v: &[u8]) -> Box { + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter + | +LL | fn a(v: &'static [u8]) -> Box { + | ^^^^^^^^^^^^^ -error[E0621]: explicit lifetime required in the type of `v` - --> $DIR/region-object-lifetime-in-coercion.rs:14:5 +error: cannot infer an appropriate lifetime + --> $DIR/region-object-lifetime-in-coercion.rs:13:14 | LL | fn b(v: &[u8]) -> Box { - | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]` + | ----- data with this lifetime... LL | Box::new(v) - | ^^^^^^^^^^^ lifetime `'static` required + | ---------^- + | | | + | | ...and is captured here + | ...is required to be `'static` by this... + | +help: consider changing the trait object's explicit `'static` bound + | +LL | fn b(v: &[u8]) -> Box { + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter + | +LL | fn b(v: &'static [u8]) -> Box { + | ^^^^^^^^^^^^^ error: cannot infer an appropriate lifetime - --> $DIR/region-object-lifetime-in-coercion.rs:20:14 + --> $DIR/region-object-lifetime-in-coercion.rs:19:14 | LL | fn c(v: &[u8]) -> Box { | ----- data with this lifetime... @@ -26,36 +50,36 @@ LL | Box::new(v) | | ...and is captured here | ...is required to be `'static` by this... | -help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 17:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 16:1 | LL | fn c(v: &[u8]) -> Box { | ^^^^ error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/region-object-lifetime-in-coercion.rs:24:14 + --> $DIR/region-object-lifetime-in-coercion.rs:23:14 | LL | Box::new(v) | ^ | -note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 23:6... - --> $DIR/region-object-lifetime-in-coercion.rs:23:6 +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 22:6... + --> $DIR/region-object-lifetime-in-coercion.rs:22:6 | LL | fn d<'a,'b>(v: &'a [u8]) -> Box { | ^^ note: ...so that the expression is assignable - --> $DIR/region-object-lifetime-in-coercion.rs:24:14 + --> $DIR/region-object-lifetime-in-coercion.rs:23:14 | LL | Box::new(v) | ^ = note: expected `&[u8]` found `&'a [u8]` -note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 23:9... - --> $DIR/region-object-lifetime-in-coercion.rs:23:9 +note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 22:9... + --> $DIR/region-object-lifetime-in-coercion.rs:22:9 | LL | fn d<'a,'b>(v: &'a [u8]) -> Box { | ^^ note: ...so that the expression is assignable - --> $DIR/region-object-lifetime-in-coercion.rs:24:5 + --> $DIR/region-object-lifetime-in-coercion.rs:23:5 | LL | Box::new(v) | ^^^^^^^^^^^ @@ -64,5 +88,4 @@ LL | Box::new(v) error: aborting due to 4 previous errors -Some errors have detailed explanations: E0495, E0621. -For more information about an error, try `rustc --explain E0495`. +For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 147f7f3541816..982ed07232a80 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -1,28 +1,22 @@ -error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements +error: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-2.rs:10:11 | +LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { + | ------------------ data with this lifetime... LL | box B(&*v) as Box - | ^^^ - | -note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6... - --> $DIR/regions-close-object-into-object-2.rs:9:6 + | ------^^^--------------- + | | | + | | ...and is captured here + | ...is required to be `'static` by this... | -LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { - | ^^ -note: ...so that the type `(dyn A + 'a)` is not borrowed for too long - --> $DIR/regions-close-object-into-object-2.rs:10:11 +help: consider changing the trait object's explicit `'static` bound | -LL | box B(&*v) as Box - | ^^^ - = note: but, the lifetime must be valid for the static lifetime... -note: ...so that the expression is assignable - --> $DIR/regions-close-object-into-object-2.rs:10:5 +LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter | -LL | box B(&*v) as Box - | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `std::boxed::Box<(dyn X + 'static)>` - found `std::boxed::Box` +LL | fn g<'a, T: 'static>(v: std::boxed::Box<(dyn A + 'static)>) -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 6e7d6152cd09a..1b82098ee13c2 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -1,28 +1,22 @@ -error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements +error: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-4.rs:10:11 | +LL | fn i<'a, T, U>(v: Box+'a>) -> Box { + | ---------------- data with this lifetime... LL | box B(&*v) as Box - | ^^^ - | -note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6... - --> $DIR/regions-close-object-into-object-4.rs:9:6 + | ------^^^--------------- + | | | + | | ...and is captured here + | ...is required to be `'static` by this... | -LL | fn i<'a, T, U>(v: Box+'a>) -> Box { - | ^^ -note: ...so that the type `(dyn A + 'a)` is not borrowed for too long - --> $DIR/regions-close-object-into-object-4.rs:10:11 +help: consider changing the trait object's explicit `'static` bound | -LL | box B(&*v) as Box - | ^^^ - = note: but, the lifetime must be valid for the static lifetime... -note: ...so that the expression is assignable - --> $DIR/regions-close-object-into-object-4.rs:10:5 +LL | fn i<'a, T, U>(v: Box+'a>) -> Box { + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter | -LL | box B(&*v) as Box - | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `std::boxed::Box<(dyn X + 'static)>` - found `std::boxed::Box` +LL | fn i<'a, T, U>(v: std::boxed::Box<(dyn A + 'static)>) -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/regions/regions-proc-bound-capture.nll.stderr b/src/test/ui/regions/regions-proc-bound-capture.nll.stderr new file mode 100644 index 0000000000000..75890b8581537 --- /dev/null +++ b/src/test/ui/regions/regions-proc-bound-capture.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/regions-proc-bound-capture.rs:9:5 + | +LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { + | - let's call the lifetime of this reference `'1` +LL | // This is illegal, because the region bound on `proc` is 'static. +LL | Box::new(move || { *x }) + | ^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-proc-bound-capture.rs b/src/test/ui/regions/regions-proc-bound-capture.rs index 0c903b7384992..8617c0e9da8f7 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.rs +++ b/src/test/ui/regions/regions-proc-bound-capture.rs @@ -4,9 +4,9 @@ fn borrowed_proc<'a>(x: &'a isize) -> Box(isize) + 'a> { Box::new(move|| { *x }) } -fn static_proc(x: &isize) -> Box(isize) + 'static> { +fn static_proc(x: &isize) -> Box (isize) + 'static> { // This is illegal, because the region bound on `proc` is 'static. - Box::new(move|| { *x }) //~ ERROR explicit lifetime required in the type of `x` [E0621] + Box::new(move || { *x }) //~ ERROR cannot infer an appropriate lifetime } fn main() { } diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index c53af34456ef3..e7bbfaababe8a 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -1,12 +1,23 @@ -error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/regions-proc-bound-capture.rs:9:5 +error: cannot infer an appropriate lifetime + --> $DIR/regions-proc-bound-capture.rs:9:14 | -LL | fn static_proc(x: &isize) -> Box(isize) + 'static> { - | ------ help: add explicit lifetime `'static` to the type of `x`: `&'static isize` +LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { + | ------ data with this lifetime... LL | // This is illegal, because the region bound on `proc` is 'static. -LL | Box::new(move|| { *x }) - | ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required +LL | Box::new(move || { *x }) + | ---------^^^^^^^^^^^^^^- + | | | + | | ...and is captured here + | ...is required to be `'static` by this... + | +help: consider changing the trait object's explicit `'static` bound + | +LL | fn static_proc(x: &isize) -> Box (isize) + '_> { + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter + | +LL | fn static_proc(x: &'static isize) -> Box (isize) + 'static> { + | ^^^^^^^^^^^^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index 3577dd59289e5..4dc4aac6ceac4 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -7,7 +7,7 @@ LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to LL | Box::new(items.iter()) | ---------------^^^^--- ...is captured and required to be `'static` here | -help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1 | LL | fn a(items: &[T]) -> Box + '_> { | ^^^^ From 921f35fe73e8749dee8531f7fbaf2cb4958fa799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 29 May 2020 18:59:42 -0700 Subject: [PATCH 27/60] Reduce verbosity of suggestion message and mention lifetime in label --- .../nice_region_error/static_impl_trait.rs | 87 ++++++++++--------- .../ui/async-await/issues/issue-62097.stderr | 2 +- .../must_outlive_least_region_or_bound.stderr | 38 ++++---- .../static-return-lifetime-infered.stderr | 8 +- src/test/ui/issues/issue-16922.stderr | 4 +- ...ect-lifetime-default-from-box-error.stderr | 4 +- .../region-object-lifetime-in-coercion.stderr | 12 +-- .../regions-close-object-into-object-2.stderr | 4 +- .../regions-close-object-into-object-4.stderr | 4 +- .../regions/regions-proc-bound-capture.stderr | 4 +- ...types_pin_lifetime_impl_trait-async.stderr | 2 +- ..._self_types_pin_lifetime_impl_trait.stderr | 4 +- .../missing-lifetimes-in-signature.stderr | 4 +- .../dyn-trait-underscore.stderr | 4 +- 14 files changed, 95 insertions(+), 86 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index e24535bba5fdc..e9f165d309f8f 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -1,6 +1,5 @@ //! Error Reporting for static impl Traits. -use crate::infer::error_reporting::msg_span_from_free_region; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use rustc_errors::{Applicability, ErrorReported}; @@ -33,9 +32,17 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let sp = var_origin.span(); let return_sp = sub_origin.span(); let param_info = self.find_param_with_region(sup_r, sub_r)?; + let (lifetime_name, lifetime) = if sup_r.has_name() { + (sup_r.to_string(), format!("lifetime `{}`", sup_r)) + } else { + ("'_".to_owned(), "the anonymous lifetime `'_`".to_string()) + }; let mut err = self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime"); - err.span_label(param_info.param_ty_span, "data with this lifetime..."); + err.span_label( + param_info.param_ty_span, + &format!("this data with {}...", lifetime), + ); debug!("try_report_static_impl_trait: param_info={:?}", param_info); // We try to make the output have fewer overlapping spans if possible. @@ -60,10 +67,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ); } - let (lifetime, _) = msg_span_from_free_region(self.tcx(), sup_r); - - let lifetime_name = - if sup_r.has_name() { sup_r.to_string() } else { "'_".to_owned() }; // only apply this suggestion onto functions with // explicit non-desugar'able return. if fn_return.span.desugaring_kind().is_none() { @@ -93,8 +96,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { { err.span_suggestion_verbose( span, - "consider changing the `impl Trait`'s explicit \ - `'static` bound", + &format!( + "consider changing the `impl Trait`'s explicit \ + `'static` bound to {}", + lifetime, + ), lifetime_name, Applicability::MaybeIncorrect, ); @@ -118,40 +124,41 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ); }; } - TyKind::TraitObject(_, lt) => { - match lt.name { - LifetimeName::ImplicitObjectLifetimeDefault => { - err.span_suggestion_verbose( - fn_return.span.shrink_to_hi(), - &format!( - "to permit non-static references in a trait object \ - value, you can add an explicit bound for {}", - lifetime, - ), - format!(" + {}", lifetime_name), - Applicability::MaybeIncorrect, - ); - } - _ => { - err.span_suggestion_verbose( - lt.span, + TyKind::TraitObject(_, lt) => match lt.name { + LifetimeName::ImplicitObjectLifetimeDefault => { + err.span_suggestion_verbose( + fn_return.span.shrink_to_hi(), + &format!( + "to permit non-static references in a trait object \ + value, you can add an explicit bound for {}", + lifetime, + ), + format!(" + {}", lifetime_name), + Applicability::MaybeIncorrect, + ); + } + _ => { + err.span_suggestion_verbose( + lt.span, + &format!( "consider changing the trait object's explicit \ - `'static` bound", - lifetime_name, - Applicability::MaybeIncorrect, - ); - err.span_suggestion_verbose( - param_info.param_ty_span, - &format!( - "alternatively, set an explicit `'static` lifetime \ - in this parameter", - ), - param_info.param_ty.to_string(), - Applicability::MaybeIncorrect, - ); - } + `'static` bound to {}", + lifetime, + ), + lifetime_name, + Applicability::MaybeIncorrect, + ); + err.span_suggestion_verbose( + param_info.param_ty_span, + &format!( + "alternatively, set an explicit `'static` lifetime \ + in this parameter", + ), + param_info.param_ty.to_string(), + Applicability::MaybeIncorrect, + ); } - } + }, _ => {} } } diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index af8fc2cd2ab45..fff43ae9f47bc 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -4,7 +4,7 @@ error: cannot infer an appropriate lifetime LL | pub async fn run_dummy_fn(&self) { | ^^^^^ | | - | data with this lifetime... + | this data with the anonymous lifetime `'_`... | ...is captured here... LL | foo(|| self.bar()).await; | --- ...and required to be `'static` by this diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 96d4a121c16af..00b6ec38323c3 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -5,9 +5,9 @@ LL | fn elided(x: &i32) -> impl Copy { x } | ---- --------- ^ ...and is captured here | | | | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with the anonymous lifetime `'_`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ^^^^ @@ -19,9 +19,9 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } | ------- --------- ^ ...and is captured here | | | | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with lifetime `'a`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 6:13 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for lifetime `'a` | LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^ @@ -33,9 +33,9 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | ---- ------------------- ^ ...and is captured here | | | | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with the anonymous lifetime `'_`... | -help: consider changing the `impl Trait`'s explicit `'static` bound +help: consider changing the `impl Trait`'s explicit `'static` bound to the anonymous lifetime `'_` | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } | ^^ @@ -51,9 +51,9 @@ LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | ------- ------------------- ^ ...and is captured here | | | | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with lifetime `'a`... | -help: consider changing the `impl Trait`'s explicit `'static` bound +help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a` | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^ @@ -77,9 +77,9 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | ------- -------------------------------- ^ ...and is captured here | | | | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with lifetime `'a`... | -help: consider changing the `impl Trait`'s explicit `'static` bound +help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a` | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } | ^^ @@ -113,9 +113,9 @@ LL | fn elided3(x: &i32) -> Box { Box::new(x) } | | | | | | | ...and is captured here | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with the anonymous lifetime `'_`... | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn elided3(x: &i32) -> Box { Box::new(x) } | ^^^^ @@ -128,9 +128,9 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | | | | | | | ...and is captured here | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with lifetime `'a`... | -help: to permit non-static references in a trait object value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14 +help: to permit non-static references in a trait object value, you can add an explicit bound for lifetime `'a` | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^^^ @@ -142,9 +142,10 @@ LL | fn elided4(x: &i32) -> Box { Box::new(x) } | ---- ---------^- | | | | | | | ...and is captured here - | data with this lifetime... ...is required to be `'static` by this... + | | ...is required to be `'static` by this... + | this data with the anonymous lifetime `'_`... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } | ^^ @@ -160,9 +161,10 @@ LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ------- ---------^- | | | | | | | ...and is captured here - | data with this lifetime... ...is required to be `'static` by this... + | | ...is required to be `'static` by this... + | this data with lifetime `'a`... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^ diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index 1c3a5979ee55b..67d4f60dff6f1 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -4,13 +4,13 @@ error: cannot infer an appropriate lifetime LL | fn iter_values_anon(&self) -> impl Iterator { | ----- ----------------------- ...is required to be `'static` by this... | | - | data with this lifetime... + | this data with the anonymous lifetime `'_`... LL | self.x.iter().map(|a| a.0) | ------ ^^^^ | | | ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the method body at 6:5 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn iter_values_anon(&self) -> impl Iterator + '_ { | ^^^^ @@ -21,13 +21,13 @@ error: cannot infer an appropriate lifetime LL | fn iter_values<'a>(&'a self) -> impl Iterator { | -------- ----------------------- ...is required to be `'static` by this... | | - | data with this lifetime... + | this data with lifetime `'a`... LL | self.x.iter().map(|a| a.0) | ------ ^^^^ | | | ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the method body at 10:20 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for lifetime `'a` | LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { | ^^^^ diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index 038df47e1bd98..c533a72dfc014 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -2,14 +2,14 @@ error: cannot infer an appropriate lifetime --> $DIR/issue-16922.rs:4:14 | LL | fn foo(value: &T) -> Box { - | -- data with this lifetime... + | -- this data with the anonymous lifetime `'_`... LL | Box::new(value) as Box | ---------^^^^^- | | | | | ...and is captured here | ...is required to be `'static` by this... | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn foo(value: &T) -> Box { | ^^^^ diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index 555622c9d13c1..6edef8086b937 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -2,12 +2,12 @@ error: cannot infer an appropriate lifetime --> $DIR/object-lifetime-default-from-box-error.rs:18:5 | LL | fn load(ss: &mut SomeStruct) -> Box { - | --------------- data with this lifetime... + | --------------- this data with the anonymous lifetime `'_`... ... LL | ss.r | ^^^^ ...is captured and required to be `'static` here | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn load(ss: &mut SomeStruct) -> Box { | ^^^^ diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 673300cebc26c..4b08c4bff2ebc 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -2,14 +2,14 @@ error: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:8:46 | LL | fn a(v: &[u8]) -> Box { - | ----- data with this lifetime... + | ----- this data with the anonymous lifetime `'_`... LL | let x: Box = Box::new(v); | ---------^- | | | | | ...and is captured here | ...is required to be `'static` by this... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn a(v: &[u8]) -> Box { | ^^ @@ -22,14 +22,14 @@ error: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:13:14 | LL | fn b(v: &[u8]) -> Box { - | ----- data with this lifetime... + | ----- this data with the anonymous lifetime `'_`... LL | Box::new(v) | ---------^- | | | | | ...and is captured here | ...is required to be `'static` by this... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn b(v: &[u8]) -> Box { | ^^ @@ -42,7 +42,7 @@ error: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:19:14 | LL | fn c(v: &[u8]) -> Box { - | ----- data with this lifetime... + | ----- this data with the anonymous lifetime `'_`... ... LL | Box::new(v) | ---------^- @@ -50,7 +50,7 @@ LL | Box::new(v) | | ...and is captured here | ...is required to be `'static` by this... | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 16:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn c(v: &[u8]) -> Box { | ^^^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 982ed07232a80..894be310fd14b 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -2,14 +2,14 @@ error: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-2.rs:10:11 | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { - | ------------------ data with this lifetime... + | ------------------ this data with lifetime `'a`... LL | box B(&*v) as Box | ------^^^--------------- | | | | | ...and is captured here | ...is required to be `'static` by this... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 1b82098ee13c2..ce261d78c2909 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -2,14 +2,14 @@ error: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-4.rs:10:11 | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { - | ---------------- data with this lifetime... + | ---------------- this data with lifetime `'a`... LL | box B(&*v) as Box | ------^^^--------------- | | | | | ...and is captured here | ...is required to be `'static` by this... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ^^ diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index e7bbfaababe8a..a0df1815247c3 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -2,7 +2,7 @@ error: cannot infer an appropriate lifetime --> $DIR/regions-proc-bound-capture.rs:9:14 | LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { - | ------ data with this lifetime... + | ------ this data with the anonymous lifetime `'_`... LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) | ---------^^^^^^^^^^^^^^- @@ -10,7 +10,7 @@ LL | Box::new(move || { *x }) | | ...and is captured here | ...is required to be `'static` by this... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn static_proc(x: &isize) -> Box (isize) + '_> { | ^^ diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 1aeabce5e8aaf..5520341b5b1c3 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -4,7 +4,7 @@ error: cannot infer an appropriate lifetime LL | async fn f(self: Pin<&Self>) -> impl Clone { self } | ^^^^ ---------- ---------- ...and required to be `'static` by this | | | - | | data with this lifetime... + | | this data with the anonymous lifetime `'_`... | ...is captured here... error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index 04c475be787b8..5374929f3a45f 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -5,9 +5,9 @@ LL | fn f(self: Pin<&Self>) -> impl Clone { self } | ---------- ---------- ^^^^ ...and is captured here | | | | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with the anonymous lifetime `'_`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the method body at 6:5 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } | ^^^^ diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index 5cf170d566ca9..471f3cd14aa3e 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -12,14 +12,14 @@ error: cannot infer an appropriate lifetime LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() | ------ ------------- ...is required to be `'static` by this... | | - | data with this lifetime... + | this data with the anonymous lifetime `'_`... ... LL | / move || { LL | | *dest = g.get(); LL | | } | |_____^ ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 15:1 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() + '_ | ^^^^ diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index 4dc4aac6ceac4..5fd03f9770e5d 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -2,12 +2,12 @@ error: cannot infer an appropriate lifetime --> $DIR/dyn-trait-underscore.rs:8:20 | LL | fn a(items: &[T]) -> Box> { - | ---- data with this lifetime... + | ---- this data with the anonymous lifetime `'_`... LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` LL | Box::new(items.iter()) | ---------------^^^^--- ...is captured and required to be `'static` here | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn a(items: &[T]) -> Box + '_> { | ^^^^ From e75588934c01d6bc9abb02979eb61168a7b5c598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 29 May 2020 19:46:22 -0700 Subject: [PATCH 28/60] Move overlapping span to a note --- .../nice_region_error/static_impl_trait.rs | 31 ++++++++++++- .../must_outlive_least_region_or_bound.stderr | 44 ++++++++++++------- src/test/ui/issues/issue-16922.stderr | 10 +++-- .../region-object-lifetime-in-coercion.stderr | 30 ++++++++----- .../regions-close-object-into-object-2.stderr | 10 +++-- .../regions-close-object-into-object-4.stderr | 10 +++-- .../regions/regions-proc-bound-capture.stderr | 10 +++-- 7 files changed, 99 insertions(+), 46 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index e9f165d309f8f..cc95441b68a03 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -53,7 +53,36 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // Customize the spans and labels depending on their relative order so // that split sentences flow correctly. - if sup_origin.span().shrink_to_hi() <= return_sp.shrink_to_lo() { + if sup_origin.span().overlaps(return_sp) && sp == sup_origin.span() { + // Avoid the following: + // + // error: cannot infer an appropriate lifetime + // --> $DIR/must_outlive_least_region_or_bound.rs:18:50 + // | + // LL | fn foo(x: &i32) -> Box { Box::new(x) } + // | ---- ---------^- + // | | | | + // | | | ...and is captured here + // | | ...is required to be `'static` by this... + // | this data with the anonymous lifetime `'_`... + // + // and instead show: + // + // error: cannot infer an appropriate lifetime + // --> $DIR/must_outlive_least_region_or_bound.rs:18:50 + // | + // LL | fn foo(x: &i32) -> Box { Box::new(x) } + // | ---- ^ ...is captured here with a `'static` requirement + // | | + // | this data with the anonymous lifetime `'_`... + // | + // note: ...is required to be `'static` by this + // | + // LL | fn elided3(x: &i32) -> Box { Box::new(x) } + // | ^^^^^^^^^^^ + err.span_label(sup_origin.span(), "...is captured here..."); + err.span_note(return_sp, "...and required to be `'static` by this"); + } else if sup_origin.span() <= return_sp { err.span_label(sup_origin.span(), "...is captured here..."); err.span_label(return_sp, "...and required to be `'static` by this"); } else { diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 00b6ec38323c3..2da49379ea8c2 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -109,12 +109,15 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:18:50 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } - | ---- ---------^- - | | | | - | | | ...and is captured here - | | ...is required to be `'static` by this... + | ---- ^ ...is captured here... + | | | this data with the anonymous lifetime `'_`... | +note: ...and required to be `'static` by this + --> $DIR/must_outlive_least_region_or_bound.rs:18:41 + | +LL | fn elided3(x: &i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn elided3(x: &i32) -> Box { Box::new(x) } @@ -124,12 +127,15 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:21:59 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- ---------^- - | | | | - | | | ...and is captured here - | | ...is required to be `'static` by this... + | ------- ^ ...is captured here... + | | | this data with lifetime `'a`... | +note: ...and required to be `'static` by this + --> $DIR/must_outlive_least_region_or_bound.rs:21:50 + | +LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for lifetime `'a` | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } @@ -139,12 +145,15 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:24:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ---- ---------^- - | | | | - | | | ...and is captured here - | | ...is required to be `'static` by this... + | ---- ^ ...is captured here... + | | | this data with the anonymous lifetime `'_`... | +note: ...and required to be `'static` by this + --> $DIR/must_outlive_least_region_or_bound.rs:24:51 + | +LL | fn elided4(x: &i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } @@ -158,12 +167,13 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:27:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- ---------^- - | | | | - | | | ...and is captured here - | | ...is required to be `'static` by this... - | this data with lifetime `'a`... + | ------- this data with lifetime `'a`... ^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/must_outlive_least_region_or_bound.rs:27:60 + | +LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index c533a72dfc014..6c0b26a86b651 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -4,11 +4,13 @@ error: cannot infer an appropriate lifetime LL | fn foo(value: &T) -> Box { | -- this data with the anonymous lifetime `'_`... LL | Box::new(value) as Box - | ---------^^^^^- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^^^^^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/issue-16922.rs:4:5 + | +LL | Box::new(value) as Box + | ^^^^^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn foo(value: &T) -> Box { diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 4b08c4bff2ebc..b333c314c57c9 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -4,11 +4,13 @@ error: cannot infer an appropriate lifetime LL | fn a(v: &[u8]) -> Box { | ----- this data with the anonymous lifetime `'_`... LL | let x: Box = Box::new(v); - | ---------^- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/region-object-lifetime-in-coercion.rs:8:37 + | +LL | let x: Box = Box::new(v); + | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn a(v: &[u8]) -> Box { @@ -24,11 +26,13 @@ error: cannot infer an appropriate lifetime LL | fn b(v: &[u8]) -> Box { | ----- this data with the anonymous lifetime `'_`... LL | Box::new(v) - | ---------^- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/region-object-lifetime-in-coercion.rs:13:5 + | +LL | Box::new(v) + | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn b(v: &[u8]) -> Box { @@ -45,11 +49,13 @@ LL | fn c(v: &[u8]) -> Box { | ----- this data with the anonymous lifetime `'_`... ... LL | Box::new(v) - | ---------^- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^ ...is captured here... + | +note: ...and required to be `'static` by this + --> $DIR/region-object-lifetime-in-coercion.rs:19:5 | +LL | Box::new(v) + | ^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn c(v: &[u8]) -> Box { diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 894be310fd14b..3127ae65ace7d 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -4,11 +4,13 @@ error: cannot infer an appropriate lifetime LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ------------------ this data with lifetime `'a`... LL | box B(&*v) as Box - | ------^^^--------------- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^^^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/regions-close-object-into-object-2.rs:10:5 + | +LL | box B(&*v) as Box + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index ce261d78c2909..b18c61f137694 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -4,11 +4,13 @@ error: cannot infer an appropriate lifetime LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ---------------- this data with lifetime `'a`... LL | box B(&*v) as Box - | ------^^^--------------- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^^^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/regions-close-object-into-object-4.rs:10:5 + | +LL | box B(&*v) as Box + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index a0df1815247c3..5cb9506afd351 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -5,11 +5,13 @@ LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { | ------ this data with the anonymous lifetime `'_`... LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) - | ---------^^^^^^^^^^^^^^- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^^^^^^^^^^^^^^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/regions-proc-bound-capture.rs:9:5 + | +LL | Box::new(move || { *x }) + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn static_proc(x: &isize) -> Box (isize) + '_> { From bc1579060981b5e95a18409e876c92bf0c9307e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 30 May 2020 09:54:05 -0700 Subject: [PATCH 29/60] Tweak output for overlapping required/captured spans --- .../nice_region_error/static_impl_trait.rs | 10 +++---- .../must_outlive_least_region_or_bound.stderr | 28 +++---------------- src/test/ui/issues/issue-16922.stderr | 7 +---- .../region-object-lifetime-in-coercion.stderr | 21 ++------------ .../regions-close-object-into-object-2.stderr | 7 +---- .../regions-close-object-into-object-4.stderr | 7 +---- .../regions/regions-proc-bound-capture.stderr | 7 +---- 7 files changed, 15 insertions(+), 72 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index cc95441b68a03..253057536f133 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -76,12 +76,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // | | // | this data with the anonymous lifetime `'_`... // | - // note: ...is required to be `'static` by this - // | - // LL | fn elided3(x: &i32) -> Box { Box::new(x) } - // | ^^^^^^^^^^^ - err.span_label(sup_origin.span(), "...is captured here..."); - err.span_note(return_sp, "...and required to be `'static` by this"); + err.span_label( + sup_origin.span(), + "...is captured here with a `'static` requirement", + ); } else if sup_origin.span() <= return_sp { err.span_label(sup_origin.span(), "...is captured here..."); err.span_label(return_sp, "...and required to be `'static` by this"); diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 2da49379ea8c2..82e44cff9cc44 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -109,15 +109,10 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:18:50 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here... + | ---- ^ ...is captured here with a `'static` requirement | | | this data with the anonymous lifetime `'_`... | -note: ...and required to be `'static` by this - --> $DIR/must_outlive_least_region_or_bound.rs:18:41 - | -LL | fn elided3(x: &i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn elided3(x: &i32) -> Box { Box::new(x) } @@ -127,15 +122,10 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:21:59 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- ^ ...is captured here... + | ------- ^ ...is captured here with a `'static` requirement | | | this data with lifetime `'a`... | -note: ...and required to be `'static` by this - --> $DIR/must_outlive_least_region_or_bound.rs:21:50 - | -LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for lifetime `'a` | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } @@ -145,15 +135,10 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:24:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here... + | ---- ^ ...is captured here with a `'static` requirement | | | this data with the anonymous lifetime `'_`... | -note: ...and required to be `'static` by this - --> $DIR/must_outlive_least_region_or_bound.rs:24:51 - | -LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } @@ -167,13 +152,8 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:27:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- this data with lifetime `'a`... ^ ...is captured here... + | ------- this data with lifetime `'a`... ^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/must_outlive_least_region_or_bound.rs:27:60 - | -LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index 6c0b26a86b651..a254343cd1bb7 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -4,13 +4,8 @@ error: cannot infer an appropriate lifetime LL | fn foo(value: &T) -> Box { | -- this data with the anonymous lifetime `'_`... LL | Box::new(value) as Box - | ^^^^^ ...is captured here... + | ^^^^^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/issue-16922.rs:4:5 - | -LL | Box::new(value) as Box - | ^^^^^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn foo(value: &T) -> Box { diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index b333c314c57c9..97d1f3579fcd8 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -4,13 +4,8 @@ error: cannot infer an appropriate lifetime LL | fn a(v: &[u8]) -> Box { | ----- this data with the anonymous lifetime `'_`... LL | let x: Box = Box::new(v); - | ^ ...is captured here... + | ^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/region-object-lifetime-in-coercion.rs:8:37 - | -LL | let x: Box = Box::new(v); - | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn a(v: &[u8]) -> Box { @@ -26,13 +21,8 @@ error: cannot infer an appropriate lifetime LL | fn b(v: &[u8]) -> Box { | ----- this data with the anonymous lifetime `'_`... LL | Box::new(v) - | ^ ...is captured here... + | ^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/region-object-lifetime-in-coercion.rs:13:5 - | -LL | Box::new(v) - | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn b(v: &[u8]) -> Box { @@ -49,13 +39,8 @@ LL | fn c(v: &[u8]) -> Box { | ----- this data with the anonymous lifetime `'_`... ... LL | Box::new(v) - | ^ ...is captured here... - | -note: ...and required to be `'static` by this - --> $DIR/region-object-lifetime-in-coercion.rs:19:5 + | ^ ...is captured here with a `'static` requirement | -LL | Box::new(v) - | ^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn c(v: &[u8]) -> Box { diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 3127ae65ace7d..3d707f2d99941 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -4,13 +4,8 @@ error: cannot infer an appropriate lifetime LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ------------------ this data with lifetime `'a`... LL | box B(&*v) as Box - | ^^^ ...is captured here... + | ^^^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/regions-close-object-into-object-2.rs:10:5 - | -LL | box B(&*v) as Box - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index b18c61f137694..70282c8cbdb30 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -4,13 +4,8 @@ error: cannot infer an appropriate lifetime LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ---------------- this data with lifetime `'a`... LL | box B(&*v) as Box - | ^^^ ...is captured here... + | ^^^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/regions-close-object-into-object-4.rs:10:5 - | -LL | box B(&*v) as Box - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index 5cb9506afd351..8f93fad7fe9d8 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -5,13 +5,8 @@ LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { | ------ this data with the anonymous lifetime `'_`... LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) - | ^^^^^^^^^^^^^^ ...is captured here... + | ^^^^^^^^^^^^^^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/regions-proc-bound-capture.rs:9:5 - | -LL | Box::new(move || { *x }) - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn static_proc(x: &isize) -> Box (isize) + '_> { From 539e9783dfb713b3af0a9967af8fd0639d700555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 30 May 2020 10:15:58 -0700 Subject: [PATCH 30/60] Tweak wording and add error code --- .../nice_region_error/static_impl_trait.rs | 35 +++++++------ .../ui/async-await/issues/issue-62097.stderr | 6 +-- .../must_outlive_least_region_or_bound.stderr | 52 +++++++++---------- .../static-return-lifetime-infered.stderr | 12 ++--- src/test/ui/issues/issue-16922.stderr | 8 +-- ...ect-lifetime-default-from-box-error.stderr | 8 +-- .../region-object-lifetime-in-coercion.stderr | 24 ++++----- .../regions-close-object-into-object-2.stderr | 4 +- .../regions-close-object-into-object-4.stderr | 4 +- .../regions/regions-proc-bound-capture.stderr | 8 +-- ...types_pin_lifetime_impl_trait-async.stderr | 6 +-- ..._self_types_pin_lifetime_impl_trait.stderr | 8 +-- .../missing-lifetimes-in-signature.stderr | 8 +-- .../dyn-trait-underscore.stderr | 8 +-- 14 files changed, 97 insertions(+), 94 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 253057536f133..4e16e8c2c5717 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -2,7 +2,7 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; -use rustc_errors::{Applicability, ErrorReported}; +use rustc_errors::{struct_span_err, Applicability, ErrorReported}; use rustc_hir::{GenericBound, ItemKind, Lifetime, LifetimeName, TyKind}; use rustc_middle::ty::RegionKind; @@ -35,10 +35,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let (lifetime_name, lifetime) = if sup_r.has_name() { (sup_r.to_string(), format!("lifetime `{}`", sup_r)) } else { - ("'_".to_owned(), "the anonymous lifetime `'_`".to_string()) + ("'_".to_owned(), "an anonymous lifetime `'_`".to_string()) }; - let mut err = - self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime"); + let mut err = struct_span_err!( + self.tcx().sess, + sp, + E0758, + "cannot infer an appropriate lifetime" + ); err.span_label( param_info.param_ty_span, &format!("this data with {}...", lifetime), @@ -61,10 +65,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // | // LL | fn foo(x: &i32) -> Box { Box::new(x) } // | ---- ---------^- - // | | | | - // | | | ...and is captured here - // | | ...is required to be `'static` by this... - // | this data with the anonymous lifetime `'_`... // // and instead show: // @@ -72,25 +72,28 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // --> $DIR/must_outlive_least_region_or_bound.rs:18:50 // | // LL | fn foo(x: &i32) -> Box { Box::new(x) } - // | ---- ^ ...is captured here with a `'static` requirement - // | | - // | this data with the anonymous lifetime `'_`... - // | + // | ---- ^ err.span_label( sup_origin.span(), - "...is captured here with a `'static` requirement", + "...is captured here requiring it to live as long as `'static`", ); } else if sup_origin.span() <= return_sp { err.span_label(sup_origin.span(), "...is captured here..."); - err.span_label(return_sp, "...and required to be `'static` by this"); + err.span_label( + return_sp, + "...and required to live as long as `'static` by this", + ); } else { - err.span_label(return_sp, "...is required to be `'static` by this..."); + err.span_label( + return_sp, + "...is required to live as long as `'static` by this...", + ); err.span_label(sup_origin.span(), "...and is captured here"); } } else { err.span_label( return_sp, - "...is captured and required to be `'static` here", + "...is captured and required live as long as `'static` here", ); } diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index fff43ae9f47bc..558d89f928945 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -1,13 +1,13 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/issue-62097.rs:12:31 | LL | pub async fn run_dummy_fn(&self) { | ^^^^^ | | - | this data with the anonymous lifetime `'_`... + | this data with an anonymous lifetime `'_`... | ...is captured here... LL | foo(|| self.bar()).await; - | --- ...and required to be `'static` by this + | --- ...and required to live as long as `'static` by this error: aborting due to previous error diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 82e44cff9cc44..eff56ddc440d4 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -1,24 +1,24 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:3:35 | LL | fn elided(x: &i32) -> impl Copy { x } | ---- --------- ^ ...and is captured here | | | - | | ...is required to be `'static` by this... - | this data with the anonymous lifetime `'_`... + | | ...is required to live as long as `'static` by this... + | this data with an anonymous lifetime `'_`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:6:44 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } | ------- --------- ^ ...and is captured here | | | - | | ...is required to be `'static` by this... + | | ...is required to live as long as `'static` by this... | this data with lifetime `'a`... | help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for lifetime `'a` @@ -26,16 +26,16 @@ help: to permit non-static references in an `impl Trait` value, you can add an e LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:9:46 | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | ---- ------------------- ^ ...and is captured here | | | - | | ...is required to be `'static` by this... - | this data with the anonymous lifetime `'_`... + | | ...is required to live as long as `'static` by this... + | this data with an anonymous lifetime `'_`... | -help: consider changing the `impl Trait`'s explicit `'static` bound to the anonymous lifetime `'_` +help: consider changing the `impl Trait`'s explicit `'static` bound to an anonymous lifetime `'_` | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } | ^^ @@ -44,13 +44,13 @@ help: alternatively, set an explicit `'static` lifetime to this parameter LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:12:55 | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | ------- ------------------- ^ ...and is captured here | | | - | | ...is required to be `'static` by this... + | | ...is required to live as long as `'static` by this... | this data with lifetime `'a`... | help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a` @@ -70,13 +70,13 @@ LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } | | | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:33:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | ------- -------------------------------- ^ ...and is captured here | | | - | | ...is required to be `'static` by this... + | | ...is required to live as long as `'static` by this... | this data with lifetime `'a`... | help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a` @@ -105,24 +105,24 @@ LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { | | | help: consider adding an explicit lifetime bound...: `T: 'static +` -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:18:50 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here with a `'static` requirement + | ---- ^ ...is captured here requiring it to live as long as `'static` | | - | this data with the anonymous lifetime `'_`... + | this data with an anonymous lifetime `'_`... | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn elided3(x: &i32) -> Box { Box::new(x) } | ^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:21:59 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- ^ ...is captured here with a `'static` requirement + | ------- ^ ...is captured here requiring it to live as long as `'static` | | | this data with lifetime `'a`... | @@ -131,15 +131,15 @@ help: to permit non-static references in a trait object value, you can add an ex LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:24:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here with a `'static` requirement + | ---- ^ ...is captured here requiring it to live as long as `'static` | | - | this data with the anonymous lifetime `'_`... + | this data with an anonymous lifetime `'_`... | -help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } | ^^ @@ -148,11 +148,11 @@ help: alternatively, set an explicit `'static` lifetime in this parameter LL | fn elided4(x: &'static i32) -> Box { Box::new(x) } | ^^^^^^^^^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:27:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- this data with lifetime `'a`... ^ ...is captured here with a `'static` requirement + | ------- this data with lifetime `'a`... ^ ...is captured here requiring it to live as long as `'static` | help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index 67d4f60dff6f1..a48580ee2d2fc 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -1,25 +1,25 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:7:16 | LL | fn iter_values_anon(&self) -> impl Iterator { - | ----- ----------------------- ...is required to be `'static` by this... + | ----- ----------------------- ...is required to live as long as `'static` by this... | | - | this data with the anonymous lifetime `'_`... + | this data with an anonymous lifetime `'_`... LL | self.x.iter().map(|a| a.0) | ------ ^^^^ | | | ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn iter_values_anon(&self) -> impl Iterator + '_ { | ^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:11:16 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | -------- ----------------------- ...is required to be `'static` by this... + | -------- ----------------------- ...is required to live as long as `'static` by this... | | | this data with lifetime `'a`... LL | self.x.iter().map(|a| a.0) diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index a254343cd1bb7..53fd658800a7a 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -1,12 +1,12 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/issue-16922.rs:4:14 | LL | fn foo(value: &T) -> Box { - | -- this data with the anonymous lifetime `'_`... + | -- this data with an anonymous lifetime `'_`... LL | Box::new(value) as Box - | ^^^^^ ...is captured here with a `'static` requirement + | ^^^^^ ...is captured here requiring it to live as long as `'static` | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn foo(value: &T) -> Box { | ^^^^ diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index 6edef8086b937..04a06104faf99 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -1,13 +1,13 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/object-lifetime-default-from-box-error.rs:18:5 | LL | fn load(ss: &mut SomeStruct) -> Box { - | --------------- this data with the anonymous lifetime `'_`... + | --------------- this data with an anonymous lifetime `'_`... ... LL | ss.r - | ^^^^ ...is captured and required to be `'static` here + | ^^^^ ...is captured and required live as long as `'static` here | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn load(ss: &mut SomeStruct) -> Box { | ^^^^ diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 97d1f3579fcd8..34cf131319a1c 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -1,12 +1,12 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:8:46 | LL | fn a(v: &[u8]) -> Box { - | ----- this data with the anonymous lifetime `'_`... + | ----- this data with an anonymous lifetime `'_`... LL | let x: Box = Box::new(v); - | ^ ...is captured here with a `'static` requirement + | ^ ...is captured here requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` | LL | fn a(v: &[u8]) -> Box { | ^^ @@ -15,15 +15,15 @@ help: alternatively, set an explicit `'static` lifetime in this parameter LL | fn a(v: &'static [u8]) -> Box { | ^^^^^^^^^^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:13:14 | LL | fn b(v: &[u8]) -> Box { - | ----- this data with the anonymous lifetime `'_`... + | ----- this data with an anonymous lifetime `'_`... LL | Box::new(v) - | ^ ...is captured here with a `'static` requirement + | ^ ...is captured here requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` | LL | fn b(v: &[u8]) -> Box { | ^^ @@ -32,16 +32,16 @@ help: alternatively, set an explicit `'static` lifetime in this parameter LL | fn b(v: &'static [u8]) -> Box { | ^^^^^^^^^^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:19:14 | LL | fn c(v: &[u8]) -> Box { - | ----- this data with the anonymous lifetime `'_`... + | ----- this data with an anonymous lifetime `'_`... ... LL | Box::new(v) - | ^ ...is captured here with a `'static` requirement + | ^ ...is captured here requiring it to live as long as `'static` | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn c(v: &[u8]) -> Box { | ^^^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 3d707f2d99941..be47ef589af8c 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -1,10 +1,10 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-2.rs:10:11 | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ------------------ this data with lifetime `'a`... LL | box B(&*v) as Box - | ^^^ ...is captured here with a `'static` requirement + | ^^^ ...is captured here requiring it to live as long as `'static` | help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 70282c8cbdb30..1b099c7d8bdf0 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -1,10 +1,10 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-4.rs:10:11 | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ---------------- this data with lifetime `'a`... LL | box B(&*v) as Box - | ^^^ ...is captured here with a `'static` requirement + | ^^^ ...is captured here requiring it to live as long as `'static` | help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index 8f93fad7fe9d8..e8baf44bd10aa 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -1,13 +1,13 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/regions-proc-bound-capture.rs:9:14 | LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { - | ------ this data with the anonymous lifetime `'_`... + | ------ this data with an anonymous lifetime `'_`... LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) - | ^^^^^^^^^^^^^^ ...is captured here with a `'static` requirement + | ^^^^^^^^^^^^^^ ...is captured here requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` | LL | fn static_proc(x: &isize) -> Box (isize) + '_> { | ^^ diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 5520341b5b1c3..92e1473a5da73 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -1,10 +1,10 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | ^^^^ ---------- ---------- ...and required to be `'static` by this + | ^^^^ ---------- ---------- ...and required to live as long as `'static` by this | | | - | | this data with the anonymous lifetime `'_`... + | | this data with an anonymous lifetime `'_`... | ...is captured here... error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index 5374929f3a45f..6721d41bb73c9 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -1,13 +1,13 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44 | LL | fn f(self: Pin<&Self>) -> impl Clone { self } | ---------- ---------- ^^^^ ...and is captured here | | | - | | ...is required to be `'static` by this... - | this data with the anonymous lifetime `'_`... + | | ...is required to live as long as `'static` by this... + | this data with an anonymous lifetime `'_`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } | ^^^^ diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index 471f3cd14aa3e..ba56255af5b0c 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -6,20 +6,20 @@ LL | fn baz(g: G, dest: &mut T) -> impl FnOnce() + '_ | | | help: consider introducing lifetime `'a` here: `'a,` -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/missing-lifetimes-in-signature.rs:19:5 | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() - | ------ ------------- ...is required to be `'static` by this... + | ------ ------------- ...is required to live as long as `'static` by this... | | - | this data with the anonymous lifetime `'_`... + | this data with an anonymous lifetime `'_`... ... LL | / move || { LL | | *dest = g.get(); LL | | } | |_____^ ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() + '_ | ^^^^ diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index 5fd03f9770e5d..20d3640d4118e 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -1,13 +1,13 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/dyn-trait-underscore.rs:8:20 | LL | fn a(items: &[T]) -> Box> { - | ---- this data with the anonymous lifetime `'_`... + | ---- this data with an anonymous lifetime `'_`... LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` LL | Box::new(items.iter()) - | ---------------^^^^--- ...is captured and required to be `'static` here + | ---------------^^^^--- ...is captured and required live as long as `'static` here | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn a(items: &[T]) -> Box + '_> { | ^^^^ From 31ea589a06e336a3d596e20e3a3f4327c8356aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 1 Jun 2020 16:15:10 -0700 Subject: [PATCH 31/60] review comments: wording --- .../nice_region_error/static_impl_trait.rs | 58 ++++++++++--------- .../ui/async-await/issues/issue-62097.stderr | 2 +- .../must_outlive_least_region_or_bound.stderr | 46 +++++++-------- .../static-return-lifetime-infered.stderr | 8 +-- src/test/ui/issues/issue-16922.stderr | 4 +- ...ect-lifetime-default-from-box-error.stderr | 2 +- .../region-object-lifetime-in-coercion.stderr | 16 ++--- .../regions-close-object-into-object-2.stderr | 6 +- .../regions-close-object-into-object-4.stderr | 6 +- .../regions/regions-proc-bound-capture.stderr | 6 +- ...types_pin_lifetime_impl_trait-async.stderr | 2 +- ..._self_types_pin_lifetime_impl_trait.stderr | 4 +- .../missing-lifetimes-in-signature.stderr | 4 +- .../dyn-trait-underscore.stderr | 2 +- 14 files changed, 85 insertions(+), 81 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 4e16e8c2c5717..86f310eb71d76 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -75,18 +75,18 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // | ---- ^ err.span_label( sup_origin.span(), - "...is captured here requiring it to live as long as `'static`", + "...is captured here, requiring it to live as long as `'static`", ); } else if sup_origin.span() <= return_sp { err.span_label(sup_origin.span(), "...is captured here..."); err.span_label( return_sp, - "...and required to live as long as `'static` by this", + "...and is required to live as long as `'static` here", ); } else { err.span_label( return_sp, - "...is required to live as long as `'static` by this...", + "...is required to live as long as `'static` here...", ); err.span_label(sup_origin.span(), "...and is captured here"); } @@ -101,6 +101,20 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // explicit non-desugar'able return. if fn_return.span.desugaring_kind().is_none() { // FIXME: account for the need of parens in `&(dyn Trait + '_)` + + let consider = "consider changing the"; + let declare = "to declare that the"; + let arg = match param_info.param.pat.simple_ident() { + Some(simple_ident) => format!("argument `{}`", simple_ident), + None => "the argument".to_string(), + }; + let explicit = + format!("you can add an explicit `{}` lifetime bound", lifetime_name); + let explicit_static = format!("explicit `'static` bound to {}", arg); + let captures = format!("captures data from {}", arg); + let add_static_bound = + "alternatively, add an explicit `'static` bound to this reference"; + let plus_lt = format!(" + {}", lifetime_name); match fn_return.kind { TyKind::Def(item_id, _) => { let item = self.tcx().hir().item(item_id.id); @@ -126,18 +140,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { { err.span_suggestion_verbose( span, - &format!( - "consider changing the `impl Trait`'s explicit \ - `'static` bound to {}", - lifetime, - ), + &format!("{} `impl Trait`'s {}", consider, explicit_static), lifetime_name, Applicability::MaybeIncorrect, ); err.span_suggestion_verbose( param_info.param_ty_span, - "alternatively, set an explicit `'static` lifetime to \ - this parameter", + add_static_bound, param_info.param_ty.to_string(), Applicability::MaybeIncorrect, ); @@ -145,11 +154,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { err.span_suggestion_verbose( fn_return.span.shrink_to_hi(), &format!( - "to permit non-static references in an `impl Trait` \ - value, you can add an explicit bound for {}", - lifetime, + "{declare} `impl Trait` {captures}, {explicit}", + declare = declare, + captures = captures, + explicit = explicit, ), - format!(" + {}", lifetime_name), + plus_lt, Applicability::MaybeIncorrect, ); }; @@ -159,31 +169,25 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { err.span_suggestion_verbose( fn_return.span.shrink_to_hi(), &format!( - "to permit non-static references in a trait object \ - value, you can add an explicit bound for {}", - lifetime, + "{declare} trait object {captures}, {explicit}", + declare = declare, + captures = captures, + explicit = explicit, ), - format!(" + {}", lifetime_name), + plus_lt, Applicability::MaybeIncorrect, ); } _ => { err.span_suggestion_verbose( lt.span, - &format!( - "consider changing the trait object's explicit \ - `'static` bound to {}", - lifetime, - ), + &format!("{} trait object's {}", consider, explicit_static), lifetime_name, Applicability::MaybeIncorrect, ); err.span_suggestion_verbose( param_info.param_ty_span, - &format!( - "alternatively, set an explicit `'static` lifetime \ - in this parameter", - ), + add_static_bound, param_info.param_ty.to_string(), Applicability::MaybeIncorrect, ); diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index 558d89f928945..e9f155c6ced31 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -7,7 +7,7 @@ LL | pub async fn run_dummy_fn(&self) { | this data with an anonymous lifetime `'_`... | ...is captured here... LL | foo(|| self.bar()).await; - | --- ...and required to live as long as `'static` by this + | --- ...and is required to live as long as `'static` here error: aborting due to previous error diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index eff56ddc440d4..a9fa0e93fed61 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -4,10 +4,10 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn elided(x: &i32) -> impl Copy { x } | ---- --------- ^ ...and is captured here | | | - | | ...is required to live as long as `'static` by this... + | | ...is required to live as long as `'static` here... | this data with an anonymous lifetime `'_`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound | LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ^^^^ @@ -18,10 +18,10 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } | ------- --------- ^ ...and is captured here | | | - | | ...is required to live as long as `'static` by this... + | | ...is required to live as long as `'static` here... | this data with lifetime `'a`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for lifetime `'a` +help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'a` lifetime bound | LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^ @@ -32,14 +32,14 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | ---- ------------------- ^ ...and is captured here | | | - | | ...is required to live as long as `'static` by this... + | | ...is required to live as long as `'static` here... | this data with an anonymous lifetime `'_`... | -help: consider changing the `impl Trait`'s explicit `'static` bound to an anonymous lifetime `'_` +help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } | ^^ -help: alternatively, set an explicit `'static` lifetime to this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^ @@ -50,14 +50,14 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | ------- ------------------- ^ ...and is captured here | | | - | | ...is required to live as long as `'static` by this... + | | ...is required to live as long as `'static` here... | this data with lifetime `'a`... | -help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a` +help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^ -help: alternatively, set an explicit `'static` lifetime to this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^ @@ -76,14 +76,14 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | ------- -------------------------------- ^ ...and is captured here | | | - | | ...is required to live as long as `'static` by this... + | | ...is required to live as long as `'static` here... | this data with lifetime `'a`... | -help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a` +help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } | ^^ -help: alternatively, set an explicit `'static` lifetime to this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x } | ^^^^^^^^^^^^ @@ -109,11 +109,11 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:18:50 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here requiring it to live as long as `'static` + | ---- ^ ...is captured here, requiring it to live as long as `'static` | | | this data with an anonymous lifetime `'_`... | -help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound | LL | fn elided3(x: &i32) -> Box { Box::new(x) } | ^^^^ @@ -122,11 +122,11 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:21:59 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- ^ ...is captured here requiring it to live as long as `'static` + | ------- ^ ...is captured here, requiring it to live as long as `'static` | | | this data with lifetime `'a`... | -help: to permit non-static references in a trait object value, you can add an explicit bound for lifetime `'a` +help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^^^ @@ -135,15 +135,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:24:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here requiring it to live as long as `'static` + | ---- ^ ...is captured here, requiring it to live as long as `'static` | | | this data with an anonymous lifetime `'_`... | -help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to argument `x` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn elided4(x: &'static i32) -> Box { Box::new(x) } | ^^^^^^^^^^^^ @@ -152,13 +152,13 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:27:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- this data with lifetime `'a`... ^ ...is captured here requiring it to live as long as `'static` + | ------- this data with lifetime `'a`... ^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to lifetime `'a` +help: consider changing the trait object's explicit `'static` bound to argument `x` | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn explicit4<'a>(x: &'static i32) -> Box { Box::new(x) } | ^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index a48580ee2d2fc..6681eaa909ee0 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -2,7 +2,7 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:7:16 | LL | fn iter_values_anon(&self) -> impl Iterator { - | ----- ----------------------- ...is required to live as long as `'static` by this... + | ----- ----------------------- ...is required to live as long as `'static` here... | | | this data with an anonymous lifetime `'_`... LL | self.x.iter().map(|a| a.0) @@ -10,7 +10,7 @@ LL | self.x.iter().map(|a| a.0) | | | ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound | LL | fn iter_values_anon(&self) -> impl Iterator + '_ { | ^^^^ @@ -19,7 +19,7 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:11:16 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | -------- ----------------------- ...is required to live as long as `'static` by this... + | -------- ----------------------- ...is required to live as long as `'static` here... | | | this data with lifetime `'a`... LL | self.x.iter().map(|a| a.0) @@ -27,7 +27,7 @@ LL | self.x.iter().map(|a| a.0) | | | ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for lifetime `'a` +help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound | LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { | ^^^^ diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index 53fd658800a7a..95f46bd7f3eb6 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -4,9 +4,9 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn foo(value: &T) -> Box { | -- this data with an anonymous lifetime `'_`... LL | Box::new(value) as Box - | ^^^^^ ...is captured here requiring it to live as long as `'static` + | ^^^^^ ...is captured here, requiring it to live as long as `'static` | -help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the trait object captures data from argument `value`, you can add an explicit `'_` lifetime bound | LL | fn foo(value: &T) -> Box { | ^^^^ diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index 04a06104faf99..e585db262f2d8 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -7,7 +7,7 @@ LL | fn load(ss: &mut SomeStruct) -> Box { LL | ss.r | ^^^^ ...is captured and required live as long as `'static` here | -help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the trait object captures data from argument `ss`, you can add an explicit `'_` lifetime bound | LL | fn load(ss: &mut SomeStruct) -> Box { | ^^^^ diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 34cf131319a1c..8d048d90cb345 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -4,13 +4,13 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn a(v: &[u8]) -> Box { | ----- this data with an anonymous lifetime `'_`... LL | let x: Box = Box::new(v); - | ^ ...is captured here requiring it to live as long as `'static` + | ^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to argument `v` | LL | fn a(v: &[u8]) -> Box { | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn a(v: &'static [u8]) -> Box { | ^^^^^^^^^^^^^ @@ -21,13 +21,13 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn b(v: &[u8]) -> Box { | ----- this data with an anonymous lifetime `'_`... LL | Box::new(v) - | ^ ...is captured here requiring it to live as long as `'static` + | ^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to argument `v` | LL | fn b(v: &[u8]) -> Box { | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn b(v: &'static [u8]) -> Box { | ^^^^^^^^^^^^^ @@ -39,9 +39,9 @@ LL | fn c(v: &[u8]) -> Box { | ----- this data with an anonymous lifetime `'_`... ... LL | Box::new(v) - | ^ ...is captured here requiring it to live as long as `'static` + | ^ ...is captured here, requiring it to live as long as `'static` | -help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the trait object captures data from argument `v`, you can add an explicit `'_` lifetime bound | LL | fn c(v: &[u8]) -> Box { | ^^^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index be47ef589af8c..5dfe384112b2a 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -4,13 +4,13 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ------------------ this data with lifetime `'a`... LL | box B(&*v) as Box - | ^^^ ...is captured here requiring it to live as long as `'static` + | ^^^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to lifetime `'a` +help: consider changing the trait object's explicit `'static` bound to argument `v` | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn g<'a, T: 'static>(v: std::boxed::Box<(dyn A + 'static)>) -> Box { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 1b099c7d8bdf0..4d23118ba06f0 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -4,13 +4,13 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ---------------- this data with lifetime `'a`... LL | box B(&*v) as Box - | ^^^ ...is captured here requiring it to live as long as `'static` + | ^^^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to lifetime `'a` +help: consider changing the trait object's explicit `'static` bound to argument `v` | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn i<'a, T, U>(v: std::boxed::Box<(dyn A + 'static)>) -> Box { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index e8baf44bd10aa..e36f77ec1da96 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -5,13 +5,13 @@ LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { | ------ this data with an anonymous lifetime `'_`... LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) - | ^^^^^^^^^^^^^^ ...is captured here requiring it to live as long as `'static` + | ^^^^^^^^^^^^^^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to argument `x` | LL | fn static_proc(x: &isize) -> Box (isize) + '_> { | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn static_proc(x: &'static isize) -> Box (isize) + 'static> { | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 92e1473a5da73..365e38515b12c 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -2,7 +2,7 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | ^^^^ ---------- ---------- ...and required to live as long as `'static` by this + | ^^^^ ---------- ---------- ...and is required to live as long as `'static` here | | | | | this data with an anonymous lifetime `'_`... | ...is captured here... diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index 6721d41bb73c9..bd3f3efad82f2 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -4,10 +4,10 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn f(self: Pin<&Self>) -> impl Clone { self } | ---------- ---------- ^^^^ ...and is captured here | | | - | | ...is required to live as long as `'static` by this... + | | ...is required to live as long as `'static` here... | this data with an anonymous lifetime `'_`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound | LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } | ^^^^ diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index ba56255af5b0c..d96a5f961bdb8 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -10,7 +10,7 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/missing-lifetimes-in-signature.rs:19:5 | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() - | ------ ------------- ...is required to live as long as `'static` by this... + | ------ ------------- ...is required to live as long as `'static` here... | | | this data with an anonymous lifetime `'_`... ... @@ -19,7 +19,7 @@ LL | | *dest = g.get(); LL | | } | |_____^ ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the `impl Trait` captures data from argument `dest`, you can add an explicit `'_` lifetime bound | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() + '_ | ^^^^ diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index 20d3640d4118e..7c649f9c08d64 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -7,7 +7,7 @@ LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to LL | Box::new(items.iter()) | ---------------^^^^--- ...is captured and required live as long as `'static` here | -help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the trait object captures data from argument `items`, you can add an explicit `'_` lifetime bound | LL | fn a(items: &[T]) -> Box + '_> { | ^^^^ From 10d9bf17671ed1d3099f2b2e25b418931075cda7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 1 Jun 2020 17:51:12 -0700 Subject: [PATCH 32/60] Use note for requirement source span --- .../nice_region_error/static_impl_trait.rs | 10 +--- .../ui/async-await/issues/issue-62097.stderr | 6 ++- .../must_outlive_least_region_or_bound.stderr | 50 +++++++++++++------ .../static-return-lifetime-infered.stderr | 22 +++++--- ...types_pin_lifetime_impl_trait-async.stderr | 11 ++-- ..._self_types_pin_lifetime_impl_trait.stderr | 10 ++-- .../missing-lifetimes-in-signature.stderr | 11 ++-- 7 files changed, 77 insertions(+), 43 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 86f310eb71d76..74267a8dec059 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -77,18 +77,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { sup_origin.span(), "...is captured here, requiring it to live as long as `'static`", ); - } else if sup_origin.span() <= return_sp { + } else { err.span_label(sup_origin.span(), "...is captured here..."); - err.span_label( + err.span_note( return_sp, "...and is required to live as long as `'static` here", ); - } else { - err.span_label( - return_sp, - "...is required to live as long as `'static` here...", - ); - err.span_label(sup_origin.span(), "...and is captured here"); } } else { err.span_label( diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index e9f155c6ced31..ff7007dd30b1b 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -6,8 +6,12 @@ LL | pub async fn run_dummy_fn(&self) { | | | this data with an anonymous lifetime `'_`... | ...is captured here... + | +note: ...and is required to live as long as `'static` here + --> $DIR/issue-62097.rs:13:9 + | LL | foo(|| self.bar()).await; - | --- ...and is required to live as long as `'static` here + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index a9fa0e93fed61..698464b4971a7 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -2,11 +2,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:3:35 | LL | fn elided(x: &i32) -> impl Copy { x } - | ---- --------- ^ ...and is captured here - | | | - | | ...is required to live as long as `'static` here... + | ---- ^ ...is captured here... + | | | this data with an anonymous lifetime `'_`... | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:3:23 + | +LL | fn elided(x: &i32) -> impl Copy { x } + | ^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound | LL | fn elided(x: &i32) -> impl Copy + '_ { x } @@ -16,11 +20,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:6:44 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } - | ------- --------- ^ ...and is captured here - | | | - | | ...is required to live as long as `'static` here... + | ------- ^ ...is captured here... + | | | this data with lifetime `'a`... | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:6:32 + | +LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } + | ^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'a` lifetime bound | LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } @@ -30,11 +38,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:9:46 | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } - | ---- ------------------- ^ ...and is captured here - | | | - | | ...is required to live as long as `'static` here... + | ---- ^ ...is captured here... + | | | this data with an anonymous lifetime `'_`... | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:9:24 + | +LL | fn elided2(x: &i32) -> impl Copy + 'static { x } + | ^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } @@ -48,11 +60,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:12:55 | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } - | ------- ------------------- ^ ...and is captured here - | | | - | | ...is required to live as long as `'static` here... + | ------- ^ ...is captured here... + | | | this data with lifetime `'a`... | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:12:33 + | +LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } + | ^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } @@ -74,11 +90,13 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:33:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } - | ------- -------------------------------- ^ ...and is captured here - | | | - | | ...is required to live as long as `'static` here... - | this data with lifetime `'a`... + | ------- this data with lifetime `'a`... ^ ...is captured here... + | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:33:34 | +LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index 6681eaa909ee0..bcc46785c5918 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -2,14 +2,17 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:7:16 | LL | fn iter_values_anon(&self) -> impl Iterator { - | ----- ----------------------- ...is required to live as long as `'static` here... - | | - | this data with an anonymous lifetime `'_`... + | ----- this data with an anonymous lifetime `'_`... LL | self.x.iter().map(|a| a.0) | ------ ^^^^ | | - | ...and is captured here + | ...is captured here... | +note: ...and is required to live as long as `'static` here + --> $DIR/static-return-lifetime-infered.rs:6:35 + | +LL | fn iter_values_anon(&self) -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound | LL | fn iter_values_anon(&self) -> impl Iterator + '_ { @@ -19,14 +22,17 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:11:16 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | -------- ----------------------- ...is required to live as long as `'static` here... - | | - | this data with lifetime `'a`... + | -------- this data with lifetime `'a`... LL | self.x.iter().map(|a| a.0) | ------ ^^^^ | | - | ...and is captured here + | ...is captured here... | +note: ...and is required to live as long as `'static` here + --> $DIR/static-return-lifetime-infered.rs:10:37 + | +LL | fn iter_values<'a>(&'a self) -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound | LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 365e38515b12c..2ffbf6e08158e 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -2,10 +2,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | ^^^^ ---------- ---------- ...and is required to live as long as `'static` here - | | | - | | this data with an anonymous lifetime `'_`... + | ^^^^ ---------- this data with an anonymous lifetime `'_`... + | | | ...is captured here... + | +note: ...and is required to live as long as `'static` here + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:37 + | +LL | async fn f(self: Pin<&Self>) -> impl Clone { self } + | ^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index bd3f3efad82f2..2da7bcf543d66 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -2,11 +2,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44 | LL | fn f(self: Pin<&Self>) -> impl Clone { self } - | ---------- ---------- ^^^^ ...and is captured here - | | | - | | ...is required to live as long as `'static` here... + | ---------- ^^^^ ...is captured here... + | | | this data with an anonymous lifetime `'_`... | +note: ...and is required to live as long as `'static` here + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:31 + | +LL | fn f(self: Pin<&Self>) -> impl Clone { self } + | ^^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound | LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index d96a5f961bdb8..95d905af05089 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -10,15 +10,18 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/missing-lifetimes-in-signature.rs:19:5 | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() - | ------ ------------- ...is required to live as long as `'static` here... - | | - | this data with an anonymous lifetime `'_`... + | ------ this data with an anonymous lifetime `'_`... ... LL | / move || { LL | | *dest = g.get(); LL | | } - | |_____^ ...and is captured here + | |_____^ ...is captured here... | +note: ...and is required to live as long as `'static` here + --> $DIR/missing-lifetimes-in-signature.rs:15:37 + | +LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() + | ^^^^^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `dest`, you can add an explicit `'_` lifetime bound | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() + '_ From 34d8692262a8299025379e5178041d0d52a0329e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 2 Jun 2020 10:47:58 -0700 Subject: [PATCH 33/60] Register new eror code --- src/test/ui/async-await/issues/issue-62097.stderr | 1 + .../ui/impl-trait/must_outlive_least_region_or_bound.stderr | 2 +- src/test/ui/impl-trait/static-return-lifetime-infered.stderr | 1 + src/test/ui/issues/issue-16922.stderr | 1 + .../object-lifetime-default-from-box-error.stderr | 3 ++- src/test/ui/regions/region-object-lifetime-in-coercion.stderr | 3 ++- src/test/ui/regions/regions-close-object-into-object-2.stderr | 1 + src/test/ui/regions/regions-close-object-into-object-4.stderr | 1 + src/test/ui/regions/regions-proc-bound-capture.stderr | 1 + .../arbitrary_self_types_pin_lifetime_impl_trait-async.stderr | 1 + .../self/arbitrary_self_types_pin_lifetime_impl_trait.stderr | 1 + .../lifetimes/missing-lifetimes-in-signature.stderr | 2 +- src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr | 1 + 13 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index ff7007dd30b1b..b3754cce40833 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -15,3 +15,4 @@ LL | foo(|| self.bar()).await; error: aborting due to previous error +For more information about this error, try `rustc --explain E0758`. diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 698464b4971a7..5ab450a85d9e1 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -183,5 +183,5 @@ LL | fn explicit4<'a>(x: &'static i32) -> Box { Box::new(x) error: aborting due to 12 previous errors -Some errors have detailed explanations: E0310, E0621, E0623. +Some errors have detailed explanations: E0310, E0621, E0623, E0758. For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index bcc46785c5918..90aada01d9917 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -40,3 +40,4 @@ LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0758`. diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index 95f46bd7f3eb6..ec80f6569f5ac 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -13,3 +13,4 @@ LL | fn foo(value: &T) -> Box { error: aborting due to previous error +For more information about this error, try `rustc --explain E0758`. diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index e585db262f2d8..ac7502e004c44 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -23,4 +23,5 @@ LL | ss.r = b; error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0621`. +Some errors have detailed explanations: E0621, E0758. +For more information about an error, try `rustc --explain E0621`. diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 8d048d90cb345..fe191e9b69565 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -79,4 +79,5 @@ LL | Box::new(v) error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0495`. +Some errors have detailed explanations: E0495, E0758. +For more information about an error, try `rustc --explain E0495`. diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 5dfe384112b2a..2ea970afcede2 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -17,3 +17,4 @@ LL | fn g<'a, T: 'static>(v: std::boxed::Box<(dyn A + 'static)>) -> Box(v: std::boxed::Box<(dyn A + 'static)>) -> Box Box (isize) + 'static> error: aborting due to previous error +For more information about this error, try `rustc --explain E0758`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 2ffbf6e08158e..69022607bd19e 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -14,3 +14,4 @@ LL | async fn f(self: Pin<&Self>) -> impl Clone { self } error: aborting due to previous error +For more information about this error, try `rustc --explain E0758`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index 2da7bcf543d66..c37eb2d136ef1 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -18,3 +18,4 @@ LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } error: aborting due to previous error +For more information about this error, try `rustc --explain E0758`. diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index 95d905af05089..7e8ab1bfe1633 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -125,5 +125,5 @@ LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a error: aborting due to 7 previous errors -Some errors have detailed explanations: E0261, E0309, E0621. +Some errors have detailed explanations: E0261, E0309, E0621, E0758. For more information about an error, try `rustc --explain E0261`. diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index 7c649f9c08d64..e768d7c8ab99f 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -14,3 +14,4 @@ LL | fn a(items: &[T]) -> Box + '_> { error: aborting due to previous error +For more information about this error, try `rustc --explain E0758`. From e31367de6b5ed3878711cdd1761828587b9639fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 2 Jun 2020 16:05:48 -0700 Subject: [PATCH 34/60] small tweaks --- .../nice_region_error/static_impl_trait.rs | 20 +++++++++++++------ .../ui/async-await/issues/issue-62097.stderr | 6 +----- .../must_outlive_least_region_or_bound.stderr | 10 +++++----- ...ect-lifetime-default-from-box-error.stderr | 2 +- .../region-object-lifetime-in-coercion.stderr | 4 ++-- .../regions-close-object-into-object-2.stderr | 2 +- .../regions-close-object-into-object-4.stderr | 2 +- .../regions/regions-proc-bound-capture.stderr | 2 +- ...types_pin_lifetime_impl_trait-async.stderr | 11 +++------- .../dyn-trait-underscore.stderr | 2 +- 10 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 74267a8dec059..5ad76e3964038 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -79,15 +79,22 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ); } else { err.span_label(sup_origin.span(), "...is captured here..."); - err.span_note( - return_sp, - "...and is required to live as long as `'static` here", - ); + if return_sp < sup_origin.span() { + err.span_note( + return_sp, + "...and is required to live as long as `'static` here", + ); + } else { + err.span_label( + return_sp, + "...and is required to live as long as `'static` here", + ); + } } } else { err.span_label( return_sp, - "...is captured and required live as long as `'static` here", + "...is captured and required to live as long as `'static` here", ); } @@ -104,7 +111,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { }; let explicit = format!("you can add an explicit `{}` lifetime bound", lifetime_name); - let explicit_static = format!("explicit `'static` bound to {}", arg); + let explicit_static = + format!("explicit `'static` bound to the lifetime of {}", arg); let captures = format!("captures data from {}", arg); let add_static_bound = "alternatively, add an explicit `'static` bound to this reference"; diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index b3754cce40833..aa443b9d2fc16 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -6,12 +6,8 @@ LL | pub async fn run_dummy_fn(&self) { | | | this data with an anonymous lifetime `'_`... | ...is captured here... - | -note: ...and is required to live as long as `'static` here - --> $DIR/issue-62097.rs:13:9 - | LL | foo(|| self.bar()).await; - | ^^^ + | --- ...and is required to live as long as `'static` here error: aborting due to previous error diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 5ab450a85d9e1..baed43783a13c 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -47,7 +47,7 @@ note: ...and is required to live as long as `'static` here | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^^^^^^^^ -help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` +help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } | ^^ @@ -69,7 +69,7 @@ note: ...and is required to live as long as `'static` here | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^^^^^^^^ -help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` +help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^ @@ -97,7 +97,7 @@ note: ...and is required to live as long as `'static` here | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` +help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } | ^^ @@ -157,7 +157,7 @@ LL | fn elided4(x: &i32) -> Box { Box::new(x) } | | | this data with an anonymous lifetime `'_`... | -help: consider changing the trait object's explicit `'static` bound to argument `x` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } | ^^ @@ -172,7 +172,7 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ------- this data with lifetime `'a`... ^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to argument `x` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^ diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index ac7502e004c44..d461001adead9 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -5,7 +5,7 @@ LL | fn load(ss: &mut SomeStruct) -> Box { | --------------- this data with an anonymous lifetime `'_`... ... LL | ss.r - | ^^^^ ...is captured and required live as long as `'static` here + | ^^^^ ...is captured and required to live as long as `'static` here | help: to declare that the trait object captures data from argument `ss`, you can add an explicit `'_` lifetime bound | diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index fe191e9b69565..c684373c67e9d 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -6,7 +6,7 @@ LL | fn a(v: &[u8]) -> Box { LL | let x: Box = Box::new(v); | ^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to argument `v` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | LL | fn a(v: &[u8]) -> Box { | ^^ @@ -23,7 +23,7 @@ LL | fn b(v: &[u8]) -> Box { LL | Box::new(v) | ^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to argument `v` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | LL | fn b(v: &[u8]) -> Box { | ^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 2ea970afcede2..c4ba395179831 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -6,7 +6,7 @@ LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { LL | box B(&*v) as Box | ^^^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to argument `v` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 493b7a1df9920..e45930bd95710 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -6,7 +6,7 @@ LL | fn i<'a, T, U>(v: Box+'a>) -> Box { LL | box B(&*v) as Box | ^^^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to argument `v` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ^^ diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index c10b9850a4e99..69c7256364d70 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -7,7 +7,7 @@ LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) | ^^^^^^^^^^^^^^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to argument `x` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` | LL | fn static_proc(x: &isize) -> Box (isize) + '_> { | ^^ diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 69022607bd19e..9b04069136be2 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -2,15 +2,10 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | ^^^^ ---------- this data with an anonymous lifetime `'_`... - | | + | ^^^^ ---------- ---------- ...and is required to live as long as `'static` here + | | | + | | this data with an anonymous lifetime `'_`... | ...is captured here... - | -note: ...and is required to live as long as `'static` here - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:37 - | -LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | ^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index e768d7c8ab99f..fc4c801949512 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -5,7 +5,7 @@ LL | fn a(items: &[T]) -> Box> { | ---- this data with an anonymous lifetime `'_`... LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` LL | Box::new(items.iter()) - | ---------------^^^^--- ...is captured and required live as long as `'static` here + | ---------------^^^^--- ...is captured and required to live as long as `'static` here | help: to declare that the trait object captures data from argument `items`, you can add an explicit `'_` lifetime bound | From f7a1f97307e2f878297c6096f3afcc6fc2a31f22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 3 Jun 2020 11:34:04 -0700 Subject: [PATCH 35/60] Change E0758 to E0759 to avoid conflict with #72912 --- src/librustc_error_codes/error_codes.rs | 1 + src/librustc_error_codes/error_codes/E0759.md | 67 +++++++++++++++++++ .../nice_region_error/static_impl_trait.rs | 2 +- .../ui/async-await/issues/issue-62097.stderr | 4 +- .../must_outlive_least_region_or_bound.stderr | 20 +++--- .../static-return-lifetime-infered.stderr | 6 +- src/test/ui/issues/issue-16922.stderr | 4 +- ...ect-lifetime-default-from-box-error.stderr | 4 +- .../region-object-lifetime-in-coercion.stderr | 8 +-- .../regions-close-object-into-object-2.stderr | 4 +- .../regions-close-object-into-object-4.stderr | 4 +- .../regions/regions-proc-bound-capture.stderr | 4 +- ...types_pin_lifetime_impl_trait-async.stderr | 4 +- ..._self_types_pin_lifetime_impl_trait.stderr | 4 +- .../missing-lifetimes-in-signature.stderr | 4 +- .../dyn-trait-underscore.stderr | 4 +- 16 files changed, 106 insertions(+), 38 deletions(-) create mode 100644 src/librustc_error_codes/error_codes/E0759.md diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 3fb5e04efc922..99ef226f94aae 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -439,6 +439,7 @@ E0752: include_str!("./error_codes/E0752.md"), E0753: include_str!("./error_codes/E0753.md"), E0754: include_str!("./error_codes/E0754.md"), E0758: include_str!("./error_codes/E0758.md"), +E0759: include_str!("./error_codes/E0759.md"), E0760: include_str!("./error_codes/E0760.md"), E0761: include_str!("./error_codes/E0761.md"), E0762: include_str!("./error_codes/E0762.md"), diff --git a/src/librustc_error_codes/error_codes/E0759.md b/src/librustc_error_codes/error_codes/E0759.md new file mode 100644 index 0000000000000..a74759bdf634b --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0759.md @@ -0,0 +1,67 @@ +A `'static` requirement in a return type involving a trait is not fulfilled. + +Erroneous code examples: + +```compile_fail,E0759 +use std::fmt::Debug; + +fn foo(x: &i32) -> impl Debug { + x +} +``` + +```compile_fail,E0759 +# use std::fmt::Debug; +fn bar(x: &i32) -> Box { + Box::new(x) +} +``` + +These examples have the same semantics as the following: + +```compile_fail,E0759 +# use std::fmt::Debug; +fn foo(x: &i32) -> impl Debug + 'static { + x +} +``` + +```compile_fail,E0759 +# use std::fmt::Debug; +fn bar(x: &i32) -> Box { + Box::new(x) +} +``` + +Both [`dyn Trait`] and [`impl Trait`] in return types have a an implicit +`'static` requirement, meaning that the value implementing them that is being +returned has to be either a `'static` borrow or an owned value. + +In order to change the requirement from `'static` to be a lifetime derived from +its arguments, you can add an explicit bound, either to an anonymous lifetime +`'_` or some appropriate named lifetime. + +``` +# use std::fmt::Debug; +fn foo(x: &i32) -> impl Debug + '_ { + x +} +fn bar(x: &i32) -> Box { + Box::new(x) +} +``` + +These are equivalent to the following explicit lifetime annotations: + +``` +# use std::fmt::Debug; +fn foo<'a>(x: &'a i32) -> impl Debug + 'a { + x +} +fn bar<'a>(x: &'a i32) -> Box { + Box::new(x) +} +``` + +[`dyn Trait`]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types +[`impl Trait`]: https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 5ad76e3964038..853a414290704 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -40,7 +40,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let mut err = struct_span_err!( self.tcx().sess, sp, - E0758, + E0759, "cannot infer an appropriate lifetime" ); err.span_label( diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index aa443b9d2fc16..0f58b158904db 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/issue-62097.rs:12:31 | LL | pub async fn run_dummy_fn(&self) { @@ -11,4 +11,4 @@ LL | foo(|| self.bar()).await; error: aborting due to previous error -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index baed43783a13c..e1fa4f02b6fcf 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:3:35 | LL | fn elided(x: &i32) -> impl Copy { x } @@ -16,7 +16,7 @@ help: to declare that the `impl Trait` captures data from argument `x`, you can LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:6:44 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } @@ -34,7 +34,7 @@ help: to declare that the `impl Trait` captures data from argument `x`, you can LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:9:46 | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } @@ -56,7 +56,7 @@ help: alternatively, add an explicit `'static` bound to this reference LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:12:55 | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } @@ -86,7 +86,7 @@ LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } | | | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:33:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } @@ -123,7 +123,7 @@ LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { | | | help: consider adding an explicit lifetime bound...: `T: 'static +` -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:18:50 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } @@ -136,7 +136,7 @@ help: to declare that the trait object captures data from argument `x`, you can LL | fn elided3(x: &i32) -> Box { Box::new(x) } | ^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:21:59 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } @@ -149,7 +149,7 @@ help: to declare that the trait object captures data from argument `x`, you can LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:24:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } @@ -166,7 +166,7 @@ help: alternatively, add an explicit `'static` bound to this reference LL | fn elided4(x: &'static i32) -> Box { Box::new(x) } | ^^^^^^^^^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:27:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } @@ -183,5 +183,5 @@ LL | fn explicit4<'a>(x: &'static i32) -> Box { Box::new(x) error: aborting due to 12 previous errors -Some errors have detailed explanations: E0310, E0621, E0623, E0758. +Some errors have detailed explanations: E0310, E0621, E0623, E0759. For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index 90aada01d9917..df0db6e4fc6df 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:7:16 | LL | fn iter_values_anon(&self) -> impl Iterator { @@ -18,7 +18,7 @@ help: to declare that the `impl Trait` captures data from argument `self`, you c LL | fn iter_values_anon(&self) -> impl Iterator + '_ { | ^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:11:16 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { @@ -40,4 +40,4 @@ LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index ec80f6569f5ac..919594fc9af4b 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/issue-16922.rs:4:14 | LL | fn foo(value: &T) -> Box { @@ -13,4 +13,4 @@ LL | fn foo(value: &T) -> Box { error: aborting due to previous error -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index d461001adead9..1b1e0d9610724 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/object-lifetime-default-from-box-error.rs:18:5 | LL | fn load(ss: &mut SomeStruct) -> Box { @@ -23,5 +23,5 @@ LL | ss.r = b; error: aborting due to 2 previous errors -Some errors have detailed explanations: E0621, E0758. +Some errors have detailed explanations: E0621, E0759. For more information about an error, try `rustc --explain E0621`. diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index c684373c67e9d..7f5a3a47976c7 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:8:46 | LL | fn a(v: &[u8]) -> Box { @@ -15,7 +15,7 @@ help: alternatively, add an explicit `'static` bound to this reference LL | fn a(v: &'static [u8]) -> Box { | ^^^^^^^^^^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:13:14 | LL | fn b(v: &[u8]) -> Box { @@ -32,7 +32,7 @@ help: alternatively, add an explicit `'static` bound to this reference LL | fn b(v: &'static [u8]) -> Box { | ^^^^^^^^^^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:19:14 | LL | fn c(v: &[u8]) -> Box { @@ -79,5 +79,5 @@ LL | Box::new(v) error: aborting due to 4 previous errors -Some errors have detailed explanations: E0495, E0758. +Some errors have detailed explanations: E0495, E0759. For more information about an error, try `rustc --explain E0495`. diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index c4ba395179831..114e4052aae09 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-2.rs:10:11 | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { @@ -17,4 +17,4 @@ LL | fn g<'a, T: 'static>(v: std::boxed::Box<(dyn A + 'static)>) -> Box $DIR/regions-close-object-into-object-4.rs:10:11 | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { @@ -17,4 +17,4 @@ LL | fn i<'a, T, U>(v: std::boxed::Box<(dyn A + 'static)>) -> Box $DIR/regions-proc-bound-capture.rs:9:14 | LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { @@ -18,4 +18,4 @@ LL | fn static_proc(x: &'static isize) -> Box (isize) + 'static> error: aborting due to previous error -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 9b04069136be2..88bd990b1e81b 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } @@ -9,4 +9,4 @@ LL | async fn f(self: Pin<&Self>) -> impl Clone { self } error: aborting due to previous error -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index c37eb2d136ef1..2e10ab3d3f9b8 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44 | LL | fn f(self: Pin<&Self>) -> impl Clone { self } @@ -18,4 +18,4 @@ LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } error: aborting due to previous error -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index 7e8ab1bfe1633..9ab060328537b 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -6,7 +6,7 @@ LL | fn baz(g: G, dest: &mut T) -> impl FnOnce() + '_ | | | help: consider introducing lifetime `'a` here: `'a,` -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/missing-lifetimes-in-signature.rs:19:5 | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() @@ -125,5 +125,5 @@ LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a error: aborting due to 7 previous errors -Some errors have detailed explanations: E0261, E0309, E0621, E0758. +Some errors have detailed explanations: E0261, E0309, E0621, E0759. For more information about an error, try `rustc --explain E0261`. diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index fc4c801949512..dda5de431d309 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/dyn-trait-underscore.rs:8:20 | LL | fn a(items: &[T]) -> Box> { @@ -14,4 +14,4 @@ LL | fn a(items: &[T]) -> Box + '_> { error: aborting due to previous error -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. From bfe1434d3bb849d3eb993c42fb57aa0819f9be65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 15 Jun 2020 09:09:20 -0700 Subject: [PATCH 36/60] fix rebase --- .../error_reporting/nice_region_error/static_impl_trait.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 853a414290704..82feebc80292a 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -118,7 +118,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { "alternatively, add an explicit `'static` bound to this reference"; let plus_lt = format!(" + {}", lifetime_name); match fn_return.kind { - TyKind::Def(item_id, _) => { + TyKind::OpaqueDef(item_id, _) => { let item = self.tcx().hir().item(item_id.id); let opaque = if let ItemKind::OpaqueTy(opaque) = &item.kind { opaque From 10c8d2afb8b90e03e2d1563df021146150338c45 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 15 Jun 2020 19:12:14 +0200 Subject: [PATCH 37/60] add FIXME to EnumTagInfo --- src/librustc_codegen_llvm/debuginfo/metadata.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 01f630a31a18b..b7e7489cba0ab 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1637,6 +1637,9 @@ impl VariantMemberDescriptionFactory<'ll, 'tcx> { } } +// FIXME: terminology here should be aligned with `abi::TagEncoding`. +// `OptimizedTag` is `TagEncoding::Niche`, `RegularTag` is `TagEncoding::Direct`. +// `NoTag` should be removed; users should use `Option` instead. #[derive(Copy, Clone)] enum EnumTagInfo<'ll> { RegularTag { tag_field: Field, tag_type_metadata: &'ll DIType }, 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 38/60] 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 39/60] 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 268decbac8bad298299702a0d17c9213f0a14f2e Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 5 May 2020 23:02:09 -0500 Subject: [PATCH 40/60] make all uses of ty::Error or ConstKind::Error delay a span bug --- .../debuginfo/type_names.rs | 2 +- .../infer/canonical/canonicalizer.rs | 2 +- src/librustc_infer/infer/canonical/mod.rs | 2 +- src/librustc_infer/infer/freshen.rs | 4 +- src/librustc_infer/infer/mod.rs | 3 +- src/librustc_infer/infer/resolve.rs | 8 +-- src/librustc_infer/infer/sub.rs | 4 +- src/librustc_lint/types.rs | 2 +- src/librustc_middle/traits/query.rs | 2 +- src/librustc_middle/ty/_match.rs | 2 +- src/librustc_middle/ty/context.rs | 49 +++++++++++++++-- src/librustc_middle/ty/error.rs | 4 +- src/librustc_middle/ty/fast_reject.rs | 2 +- src/librustc_middle/ty/flags.rs | 4 +- src/librustc_middle/ty/layout.rs | 4 +- src/librustc_middle/ty/outlives.rs | 2 +- src/librustc_middle/ty/print/mod.rs | 2 +- src/librustc_middle/ty/print/obsolete.rs | 2 +- src/librustc_middle/ty/print/pretty.rs | 4 +- src/librustc_middle/ty/query/values.rs | 4 +- src/librustc_middle/ty/relate.rs | 4 +- src/librustc_middle/ty/structural_impls.rs | 8 +-- src/librustc_middle/ty/sty.rs | 33 ++++++++---- src/librustc_middle/ty/util.rs | 8 +-- src/librustc_middle/ty/walk.rs | 4 +- .../type_check/free_region_relations.rs | 2 +- .../borrow_check/type_check/mod.rs | 4 +- .../interpret/intrinsics/type_name.rs | 2 +- src/librustc_mir/interpret/operand.rs | 2 +- src/librustc_mir/interpret/validity.rs | 2 +- src/librustc_mir_build/build/mod.rs | 6 ++- src/librustc_mir_build/hair/cx/expr.rs | 2 +- src/librustc_mir_build/hair/pattern/mod.rs | 6 +-- src/librustc_passes/intrinsicck.rs | 4 +- src/librustc_privacy/lib.rs | 2 +- src/librustc_save_analysis/lib.rs | 2 +- src/librustc_symbol_mangling/v0.rs | 4 +- src/librustc_trait_selection/opaque_types.rs | 6 +-- .../traits/coherence.rs | 2 +- .../traits/error_reporting/mod.rs | 2 +- .../traits/error_reporting/suggestions.rs | 2 +- .../traits/project.rs | 20 +++---- .../traits/query/dropck_outlives.rs | 2 +- .../traits/select/mod.rs | 6 +-- .../traits/structural_match.rs | 2 +- src/librustc_trait_selection/traits/wf.rs | 4 +- src/librustc_traits/chalk/lowering.rs | 4 +- src/librustc_traits/dropck_outlives.rs | 2 +- src/librustc_ty/ty.rs | 2 +- src/librustc_typeck/astconv.rs | 22 ++++---- src/librustc_typeck/check/_match.rs | 2 +- src/librustc_typeck/check/callee.rs | 2 +- src/librustc_typeck/check/cast.rs | 2 +- src/librustc_typeck/check/closure.rs | 4 +- src/librustc_typeck/check/coercion.rs | 8 +-- src/librustc_typeck/check/expr.rs | 52 +++++++++---------- src/librustc_typeck/check/method/confirm.rs | 3 +- src/librustc_typeck/check/method/probe.rs | 4 +- src/librustc_typeck/check/mod.rs | 28 +++++----- src/librustc_typeck/check/op.rs | 4 +- src/librustc_typeck/check/pat.rs | 43 ++++++++------- src/librustc_typeck/check/upvar.rs | 2 +- src/librustc_typeck/check/writeback.rs | 9 ++-- src/librustc_typeck/coherence/builtin.rs | 2 +- .../coherence/inherent_impls.rs | 2 +- src/librustc_typeck/collect.rs | 15 +++--- src/librustc_typeck/collect/type_of.rs | 35 ++++++------- src/librustc_typeck/variance/constraints.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- .../internal-lints/ty_tykind_usage.rs | 2 +- .../internal-lints/ty_tykind_usage.stderr | 2 +- 71 files changed, 279 insertions(+), 225 deletions(-) diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs index 57a3d8b5edcaf..a64489c04c81d 100644 --- a/src/librustc_codegen_ssa/debuginfo/type_names.rs +++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs @@ -195,7 +195,7 @@ pub fn push_debuginfo_type_name<'tcx>( tcx.def_key(def_id).disambiguated_data.disambiguator )); } - ty::Error + ty::Error(_) | ty::Infer(_) | ty::Placeholder(..) | ty::Projection(..) diff --git a/src/librustc_infer/infer/canonical/canonicalizer.rs b/src/librustc_infer/infer/canonical/canonicalizer.rs index c2dae6ba4f83d..427cc55a428ae 100644 --- a/src/librustc_infer/infer/canonical/canonicalizer.rs +++ b/src/librustc_infer/infer/canonical/canonicalizer.rs @@ -403,7 +403,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { | ty::Float(..) | ty::Adt(..) | ty::Str - | ty::Error + | ty::Error(_) | ty::Array(..) | ty::Slice(..) | ty::RawPtr(..) diff --git a/src/librustc_infer/infer/canonical/mod.rs b/src/librustc_infer/infer/canonical/mod.rs index 7310d2c3bdcf8..2b8c46f1de42d 100644 --- a/src/librustc_infer/infer/canonical/mod.rs +++ b/src/librustc_infer/infer/canonical/mod.rs @@ -154,7 +154,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { self.tcx .mk_const(ty::Const { val: ty::ConstKind::Placeholder(placeholder_mapped), - ty: self.tcx.types.err, // FIXME(const_generics) + ty: self.tcx.ty_error(), // FIXME(const_generics) }) .into() } diff --git a/src/librustc_infer/infer/freshen.rs b/src/librustc_infer/infer/freshen.rs index b4cfcb3a1c325..02bebe10ed04a 100644 --- a/src/librustc_infer/infer/freshen.rs +++ b/src/librustc_infer/infer/freshen.rs @@ -192,7 +192,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { | ty::Float(..) | ty::Adt(..) | ty::Str - | ty::Error + | ty::Error(_) | ty::Array(..) | ty::Slice(..) | ty::RawPtr(..) @@ -250,7 +250,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { ty::ConstKind::Param(_) | ty::ConstKind::Value(_) | ty::ConstKind::Unevaluated(..) - | ty::ConstKind::Error => {} + | ty::ConstKind::Error(_) => {} } ct.super_fold_with(self) diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs index 92387f753f55e..91f4b3323f30e 100644 --- a/src/librustc_infer/infer/mod.rs +++ b/src/librustc_infer/infer/mod.rs @@ -1751,9 +1751,10 @@ impl<'tcx> TypeTrace<'tcx> { } pub fn dummy(tcx: TyCtxt<'tcx>) -> TypeTrace<'tcx> { + let err = tcx.ty_error(); TypeTrace { cause: ObligationCause::dummy(), - values: Types(ExpectedFound { expected: tcx.types.err, found: tcx.types.err }), + values: Types(ExpectedFound { expected: err, found: err }), } } } diff --git a/src/librustc_infer/infer/resolve.rs b/src/librustc_infer/infer/resolve.rs index e28cf49c7f253..df166d21a36c3 100644 --- a/src/librustc_infer/infer/resolve.rs +++ b/src/librustc_infer/infer/resolve.rs @@ -189,15 +189,15 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { match t.kind { ty::Infer(ty::TyVar(vid)) => { self.err = Some(FixupError::UnresolvedTy(vid)); - self.tcx().types.err + self.tcx().ty_error() } ty::Infer(ty::IntVar(vid)) => { self.err = Some(FixupError::UnresolvedIntTy(vid)); - self.tcx().types.err + self.tcx().ty_error() } ty::Infer(ty::FloatVar(vid)) => { self.err = Some(FixupError::UnresolvedFloatTy(vid)); - self.tcx().types.err + self.tcx().ty_error() } ty::Infer(_) => { bug!("Unexpected type in full type resolver: {:?}", t); @@ -228,7 +228,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { match c.val { ty::ConstKind::Infer(InferConst::Var(vid)) => { self.err = Some(FixupError::UnresolvedConst(vid)); - return self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: c.ty }); + return self.tcx().const_error(c.ty); } ty::ConstKind::Infer(InferConst::Fresh(_)) => { bug!("Unexpected const in full const resolver: {:?}", c); diff --git a/src/librustc_infer/infer/sub.rs b/src/librustc_infer/infer/sub.rs index b51af19883fdd..90962d210b5b4 100644 --- a/src/librustc_infer/infer/sub.rs +++ b/src/librustc_infer/infer/sub.rs @@ -119,9 +119,9 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> { Ok(a) } - (&ty::Error, _) | (_, &ty::Error) => { + (&ty::Error(_), _) | (_, &ty::Error(_)) => { infcx.set_tainted_by_errors(); - Ok(self.tcx().types.err) + Ok(self.tcx().ty_error()) } _ => { diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index a8ecfdd0f3d45..1dd6d837d4eaf 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -889,7 +889,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ty::Param(..) | ty::Infer(..) | ty::Bound(..) - | ty::Error + | ty::Error(_) | ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) diff --git a/src/librustc_middle/traits/query.rs b/src/librustc_middle/traits/query.rs index e030125b5b15c..69696ac9e93c0 100644 --- a/src/librustc_middle/traits/query.rs +++ b/src/librustc_middle/traits/query.rs @@ -221,7 +221,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { | ty::Ref(..) | ty::Str | ty::Foreign(..) - | ty::Error => true, + | ty::Error(_) => true, // [T; N] and [T] have same properties as T. ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, ty), diff --git a/src/librustc_middle/ty/_match.rs b/src/librustc_middle/ty/_match.rs index 02abe868f3943..db9229ae3d214 100644 --- a/src/librustc_middle/ty/_match.rs +++ b/src/librustc_middle/ty/_match.rs @@ -79,7 +79,7 @@ impl TypeRelation<'tcx> for Match<'tcx> { Err(TypeError::Sorts(relate::expected_found(self, &a, &b))) } - (&ty::Error, _) | (_, &ty::Error) => Ok(self.tcx().types.err), + (&ty::Error(_), _) | (_, &ty::Error(_)) => Ok(self.tcx().ty_error()), _ => relate::super_relate_tys(self, a, b), } diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index d5be3508d2d80..4fe8173becff9 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -46,7 +46,7 @@ use rustc_session::lint::{Level, Lint}; use rustc_session::Session; use rustc_span::source_map::MultiSpan; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{Layout, TargetDataLayout, VariantIdx}; use rustc_target::spec::abi; @@ -145,7 +145,6 @@ pub struct CommonTypes<'tcx> { pub f64: Ty<'tcx>, pub never: Ty<'tcx>, pub self_param: Ty<'tcx>, - pub err: Ty<'tcx>, /// Dummy type used for the `Self` of a `TraitRef` created for converting /// a trait object, and which gets removed in `ExistentialTraitRef`. @@ -804,7 +803,6 @@ impl<'tcx> CommonTypes<'tcx> { bool: mk(Bool), char: mk(Char), never: mk(Never), - err: mk(Error), isize: mk(Int(ast::IntTy::Isize)), i8: mk(Int(ast::IntTy::I8)), i16: mk(Int(ast::IntTy::I16)), @@ -1143,6 +1141,49 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used. + #[track_caller] + pub fn ty_error(self) -> Ty<'tcx> { + self.err_with_message_and_location( + DUMMY_SP, + "TyKind::Error constructed but no error reported", + std::panic::Location::caller(), + ) + } + + /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to + /// ensure it gets used. + #[track_caller] + pub fn ty_error_with_message>(self, span: S, msg: &str) -> Ty<'tcx> { + self.err_with_message_and_location(span, msg, std::panic::Location::caller()) + } + + pub fn err_with_message_and_location>( + self, + span: S, + msg: &str, + loc: &'static std::panic::Location<'static>, + ) -> Ty<'tcx> { + self.sess.delay_span_bug(span, &format!("{}: {}", loc, msg)); + self.mk_ty(Error(super::sty::DelaySpanBugEmitted(()))) + } + + /// Like `err` but for constants. + #[track_caller] + pub fn const_error(self, ty: Ty<'tcx>) -> &'tcx Const<'tcx> { + self.sess.delay_span_bug( + DUMMY_SP, + &format!( + "ty::ConstKind::Error constructed but no error reported. {}", + std::panic::Location::caller() + ), + ); + self.mk_const(ty::Const { + val: ty::ConstKind::Error(super::sty::DelaySpanBugEmitted(())), + ty, + }) + } + pub fn consider_optimizing String>(&self, msg: T) -> bool { let cname = self.crate_name(LOCAL_CRATE).as_str(); self.sess.consider_optimizing(&cname, msg) @@ -1846,7 +1887,7 @@ macro_rules! sty_debug_print { let variant = match t.kind { ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) | ty::Float(..) | ty::Str | ty::Never => continue, - ty::Error => /* unimportant */ continue, + ty::Error(_) => /* unimportant */ continue, $(ty::$variant(..) => &mut $variant,)* }; let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER); diff --git a/src/librustc_middle/ty/error.rs b/src/librustc_middle/ty/error.rs index be3bf748225b9..6113359ca93a7 100644 --- a/src/librustc_middle/ty/error.rs +++ b/src/librustc_middle/ty/error.rs @@ -286,14 +286,14 @@ impl<'tcx> ty::TyS<'tcx> { ty::Projection(_) => "associated type".into(), ty::Param(p) => format!("type parameter `{}`", p).into(), ty::Opaque(..) => "opaque type".into(), - ty::Error => "type error".into(), + ty::Error(_) => "type error".into(), } } pub fn prefix_string(&self) -> Cow<'static, str> { match self.kind { ty::Infer(_) - | ty::Error + | ty::Error(_) | ty::Bool | ty::Char | ty::Int(_) diff --git a/src/librustc_middle/ty/fast_reject.rs b/src/librustc_middle/ty/fast_reject.rs index 16d8e37940763..b0fb179b18bdf 100644 --- a/src/librustc_middle/ty/fast_reject.rs +++ b/src/librustc_middle/ty/fast_reject.rs @@ -104,7 +104,7 @@ pub fn simplify_type( } ty::Opaque(def_id, _) => Some(OpaqueSimplifiedType(def_id)), ty::Foreign(def_id) => Some(ForeignSimplifiedType(def_id)), - ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) | ty::Error => None, + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) | ty::Error(_) => None, } } diff --git a/src/librustc_middle/ty/flags.rs b/src/librustc_middle/ty/flags.rs index edcb69c5e8cbd..bee42be8a5388 100644 --- a/src/librustc_middle/ty/flags.rs +++ b/src/librustc_middle/ty/flags.rs @@ -70,7 +70,7 @@ impl FlagComputation { | &ty::Str | &ty::Foreign(..) => {} - &ty::Error => self.add_flags(TypeFlags::HAS_ERROR), + &ty::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), &ty::Param(_) => { self.add_flags(TypeFlags::HAS_TY_PARAM); @@ -227,7 +227,7 @@ impl FlagComputation { self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } ty::ConstKind::Value(_) => {} - ty::ConstKind::Error => self.add_flags(TypeFlags::HAS_ERROR), + ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), } } diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs index f5bca90c2bd52..d58ebdc8dfc4d 100644 --- a/src/librustc_middle/ty/layout.rs +++ b/src/librustc_middle/ty/layout.rs @@ -1245,7 +1245,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { bug!("Layout::compute: unexpected type `{}`", ty) } - ty::Param(_) | ty::Error => { + ty::Param(_) | ty::Error(_) => { return Err(LayoutError::Unknown(ty)); } }) @@ -2141,7 +2141,7 @@ where | ty::Opaque(..) | ty::Param(_) | ty::Infer(_) - | ty::Error => bug!("TyAndLayout::field_type: unexpected type `{}`", this.ty), + | ty::Error(_) => bug!("TyAndLayout::field_type: unexpected type `{}`", this.ty), }) } diff --git a/src/librustc_middle/ty/outlives.rs b/src/librustc_middle/ty/outlives.rs index 1da042e161737..1a8693b8df711 100644 --- a/src/librustc_middle/ty/outlives.rs +++ b/src/librustc_middle/ty/outlives.rs @@ -171,7 +171,7 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo ty::Dynamic(..) | // OutlivesObject, OutlivesFragment (*) ty::Placeholder(..) | ty::Bound(..) | - ty::Error => { + ty::Error(_) => { // (*) Function pointers and trait objects are both binders. // In the RFC, this means we would add the bound regions to // the "bound regions list". In our representation, no such diff --git a/src/librustc_middle/ty/print/mod.rs b/src/librustc_middle/ty/print/mod.rs index 69b36980bd73c..6c8f23c139f6e 100644 --- a/src/librustc_middle/ty/print/mod.rs +++ b/src/librustc_middle/ty/print/mod.rs @@ -298,7 +298,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { | ty::Opaque(..) | ty::Infer(_) | ty::Bound(..) - | ty::Error + | ty::Error(_) | ty::GeneratorWitness(..) | ty::Never | ty::Float(_) => None, diff --git a/src/librustc_middle/ty/print/obsolete.rs b/src/librustc_middle/ty/print/obsolete.rs index 7d9943ab07902..67b6433b61143 100644 --- a/src/librustc_middle/ty/print/obsolete.rs +++ b/src/librustc_middle/ty/print/obsolete.rs @@ -144,7 +144,7 @@ impl DefPathBasedNames<'tcx> { let substs = substs.truncate_to(self.tcx, generics); self.push_generic_params(substs, iter::empty(), output, debug); } - ty::Error + ty::Error(_) | ty::Bound(..) | ty::Infer(_) | ty::Placeholder(..) diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs index d782dd07a6588..17203fcce5e59 100644 --- a/src/librustc_middle/ty/print/pretty.rs +++ b/src/librustc_middle/ty/print/pretty.rs @@ -518,7 +518,7 @@ pub trait PrettyPrinter<'tcx>: p!(write("{}", infer_ty)) } } - ty::Error => p!(write("[type error]")), + ty::Error(_) => p!(write("[type error]")), ty::Param(ref param_ty) => p!(write("{}", param_ty)), ty::Bound(debruijn, bound_ty) => match bound_ty.kind { ty::BoundTyKind::Anon => self.pretty_print_bound_var(debruijn, bound_ty.var)?, @@ -919,7 +919,7 @@ pub trait PrettyPrinter<'tcx>: self.pretty_print_bound_var(debruijn, bound_var)? } ty::ConstKind::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)), - ty::ConstKind::Error => p!(write("[const error]")), + ty::ConstKind::Error(_) => p!(write("[const error]")), }; Ok(self) } diff --git a/src/librustc_middle/ty/query/values.rs b/src/librustc_middle/ty/query/values.rs index b1f76ff6a03bd..0a0ff101b5203 100644 --- a/src/librustc_middle/ty/query/values.rs +++ b/src/librustc_middle/ty/query/values.rs @@ -17,7 +17,7 @@ impl<'tcx> Value<'tcx> for &'_ TyS<'_> { fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self { // SAFETY: This is never called when `Self` is not `Ty<'tcx>`. // FIXME: Represent the above fact in the trait system somehow. - unsafe { std::mem::transmute::, Ty<'_>>(tcx.types.err) } + unsafe { std::mem::transmute::, Ty<'_>>(tcx.ty_error()) } } } @@ -33,7 +33,7 @@ impl<'tcx> Value<'tcx> for AdtSizedConstraint<'_> { // FIXME: Represent the above fact in the trait system somehow. unsafe { std::mem::transmute::, AdtSizedConstraint<'_>>( - AdtSizedConstraint(tcx.intern_type_list(&[tcx.types.err])), + AdtSizedConstraint(tcx.intern_type_list(&[tcx.ty_error()])), ) } } diff --git a/src/librustc_middle/ty/relate.rs b/src/librustc_middle/ty/relate.rs index cddd7081ca375..14cddd11c438d 100644 --- a/src/librustc_middle/ty/relate.rs +++ b/src/librustc_middle/ty/relate.rs @@ -354,7 +354,7 @@ pub fn super_relate_tys>( bug!("bound types encountered in super_relate_tys") } - (&ty::Error, _) | (_, &ty::Error) => Ok(tcx.types.err), + (&ty::Error(_), _) | (_, &ty::Error(_)) => Ok(tcx.ty_error()), (&ty::Never, _) | (&ty::Char, _) @@ -524,7 +524,7 @@ pub fn super_relate_consts>( bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b) } - (ty::ConstKind::Error, _) | (_, ty::ConstKind::Error) => Ok(ty::ConstKind::Error), + (ty::ConstKind::Error(d), _) | (_, ty::ConstKind::Error(d)) => Ok(ty::ConstKind::Error(d)), (ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) if a_p.index == b_p.index => { return Ok(a); diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs index f6f5dfd651612..f04d31601ea5b 100644 --- a/src/librustc_middle/ty/structural_impls.rs +++ b/src/librustc_middle/ty/structural_impls.rs @@ -911,7 +911,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { | ty::Int(_) | ty::Uint(_) | ty::Float(_) - | ty::Error + | ty::Error(_) | ty::Infer(_) | ty::Param(..) | ty::Bound(..) @@ -952,7 +952,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { | ty::Int(_) | ty::Uint(_) | ty::Float(_) - | ty::Error + | ty::Error(_) | ty::Infer(_) | ty::Bound(..) | ty::Placeholder(..) @@ -1051,7 +1051,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) - | ty::ConstKind::Error => *self, + | ty::ConstKind::Error(_) => *self, } } @@ -1063,7 +1063,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) - | ty::ConstKind::Error => false, + | ty::ConstKind::Error(_) => false, } } } diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index fad96aa86cc0a..656c05b5520e8 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -203,9 +203,26 @@ pub enum TyKind<'tcx> { /// A placeholder for a type which could not be computed; this is /// propagated to avoid useless error messages. - Error, + Error(DelaySpanBugEmitted), } +/// A type that is not publicly constructable. This prevents people from making `TyKind::Error` +/// except through `tcx.err*()`. +#[derive( + Copy, + Clone, + Debug, + Eq, + Hash, + PartialEq, + PartialOrd, + Ord, + RustcEncodable, + RustcDecodable, + HashStable +)] +pub struct DelaySpanBugEmitted(pub(super) ()); + // `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_arch = "x86_64")] static_assert_size!(TyKind<'_>, 24); @@ -1984,7 +2001,7 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn has_concrete_skeleton(&self) -> bool { match self.kind { - Param(_) | Infer(_) | Error => false, + Param(_) | Infer(_) | Error(_) => false, _ => true, } } @@ -2016,7 +2033,7 @@ impl<'tcx> TyS<'tcx> { match self.kind { FnDef(def_id, substs) => tcx.fn_sig(def_id).subst(tcx, substs), FnPtr(f) => f, - Error => { + Error(_) => { // ignore errors (#54954) ty::Binder::dummy(FnSig::fake()) } @@ -2140,7 +2157,7 @@ impl<'tcx> TyS<'tcx> { // closure type is not yet known Bound(..) | Infer(_) => None, - Error => Some(ty::ClosureKind::Fn), + Error(_) => Some(ty::ClosureKind::Fn), _ => bug!("cannot convert type `{:?}` to a closure kind", self), } @@ -2167,7 +2184,7 @@ impl<'tcx> TyS<'tcx> { | ty::Array(..) | ty::Closure(..) | ty::Never - | ty::Error => true, + | ty::Error(_) => true, ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => false, @@ -2372,9 +2389,7 @@ impl<'tcx> Const<'tcx> { // can leak through `val` into the const we return. Ok(val) => Const::from_value(tcx, val, self.ty), Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => self, - Err(ErrorHandled::Reported(ErrorReported)) => { - tcx.mk_const(ty::Const { val: ty::ConstKind::Error, ty: self.ty }) - } + Err(ErrorHandled::Reported(ErrorReported)) => tcx.const_error(self.ty), } } else { self @@ -2434,7 +2449,7 @@ pub enum ConstKind<'tcx> { /// A placeholder for a const which could not be computed; this is /// propagated to avoid useless error messages. - Error, + Error(DelaySpanBugEmitted), } #[cfg(target_arch = "x86_64")] diff --git a/src/librustc_middle/ty/util.rs b/src/librustc_middle/ty/util.rs index ff284b709c2cf..47110be53b252 100644 --- a/src/librustc_middle/ty/util.rs +++ b/src/librustc_middle/ty/util.rs @@ -176,7 +176,7 @@ impl<'tcx> TyCtxt<'tcx> { if let ty::Adt(def, substs) = ty.kind { for field in def.all_fields() { let field_ty = field.ty(self, substs); - if let Error = field_ty.kind { + if let Error(_) = field_ty.kind { return true; } } @@ -731,7 +731,7 @@ impl<'tcx> ty::TyS<'tcx> { | ty::Ref(..) | ty::RawPtr(_) | ty::FnDef(..) - | ty::Error + | ty::Error(_) | ty::FnPtr(_) => true, ty::Tuple(_) => self.tuple_fields().all(Self::is_trivially_freeze), ty::Slice(elem_ty) | ty::Array(elem_ty, _) => elem_ty.is_trivially_freeze(), @@ -826,7 +826,7 @@ impl<'tcx> ty::TyS<'tcx> { // called for known, fully-monomorphized types. Projection(_) | Opaque(..) | Param(_) | Bound(..) | Placeholder(_) | Infer(_) => false, - Foreign(_) | GeneratorWitness(..) | Error => false, + Foreign(_) | GeneratorWitness(..) | Error(_) => false, } } @@ -1109,7 +1109,7 @@ pub fn needs_drop_components( // Foreign types can never have destructors. ty::Foreign(..) => Ok(SmallVec::new()), - ty::Dynamic(..) | ty::Error => Err(AlwaysRequiresDrop), + ty::Dynamic(..) | ty::Error(_) => Err(AlwaysRequiresDrop), ty::Slice(ty) => needs_drop_components(ty, target_layout), ty::Array(elem_ty, size) => { diff --git a/src/librustc_middle/ty/walk.rs b/src/librustc_middle/ty/walk.rs index bf988a4302633..d6f504fdb338b 100644 --- a/src/librustc_middle/ty/walk.rs +++ b/src/librustc_middle/ty/walk.rs @@ -108,7 +108,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::Infer(_) | ty::Param(_) | ty::Never - | ty::Error + | ty::Error(_) | ty::Placeholder(..) | ty::Bound(..) | ty::Foreign(..) => {} @@ -171,7 +171,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::ConstKind::Placeholder(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Value(_) - | ty::ConstKind::Error => {} + | ty::ConstKind::Error(_) => {} ty::ConstKind::Unevaluated(_, substs, _) => { stack.extend(substs.iter().rev()); diff --git a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs index 5707127340d87..beee31812563e 100644 --- a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs +++ b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs @@ -264,7 +264,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { .tcx .sess .delay_span_bug(DUMMY_SP, &format!("failed to normalize {:?}", ty)); - (self.infcx.tcx.types.err, None) + (self.infcx.tcx.ty_error(), None) }); let constraints2 = self.add_implied_bounds(ty); normalized_inputs_and_output.push(ty); diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index 168612f9beec0..011aeb4b8162b 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -498,7 +498,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { if place_ty.variant_index.is_none() { if place_ty.ty.references_error() { assert!(self.errors_reported); - return PlaceTy::from_ty(self.tcx().types.err); + return PlaceTy::from_ty(self.tcx().ty_error()); } } place_ty = self.sanitize_projection(place_ty, elem, place, location) @@ -725,7 +725,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { fn error(&mut self) -> Ty<'tcx> { self.errors_reported = true; - self.tcx().types.err + self.tcx().ty_error() } fn field_ty( diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index 71cca725982f5..379117f3b846a 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -50,7 +50,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { | ty::Dynamic(_, _) => self.pretty_print_type(ty), // Placeholders (all printed as `_` to uniformize them). - ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error => { + ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => { write!(self, "_")?; Ok(self) } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 38f5988d0eb3f..0cb878a49dcf1 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -527,7 +527,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Early-return cases. let val_val = match val.val { ty::ConstKind::Param(_) => throw_inval!(TooGeneric), - ty::ConstKind::Error => throw_inval!(TypeckError(ErrorReported)), + ty::ConstKind::Error(_) => throw_inval!(TypeckError(ErrorReported)), ty::ConstKind::Unevaluated(def_id, substs, promoted) => { let instance = self.resolve(def_id, substs)?; // We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation. diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 7e3b6c08e08f4..999f2fe76b4da 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -561,7 +561,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' | ty::Generator(..) => Ok(false), // Some types only occur during typechecking, they have no layout. // We should not see them here and we could not check them anyway. - ty::Error + ty::Error(_) | ty::Infer(..) | ty::Placeholder(..) | ty::Bound(..) diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index 2efe93d057b9b..e2cf1bce733d6 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -687,7 +687,7 @@ fn construct_error<'a, 'tcx>(hir: Cx<'a, 'tcx>, body_id: hir::BodyId) -> Body<'t let tcx = hir.tcx(); let owner_id = tcx.hir().body_owner(body_id); let span = tcx.hir().span(owner_id); - let ty = tcx.types.err; + let ty = tcx.ty_error(); let num_params = match hir.body_owner_kind { hir::BodyOwnerKind::Fn => tcx.hir().fn_decl_by_hir_id(owner_id).unwrap().inputs.len(), hir::BodyOwnerKind::Closure => { @@ -909,7 +909,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.local_decls[local].mutability = mutability; self.local_decls[local].source_info.scope = self.source_scope; self.local_decls[local].local_info = if let Some(kind) = self_binding { - Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(*kind)))) + Some(box LocalInfo::User(ClearCrossCrate::Set( + BindingForm::ImplicitSelf(*kind), + ))) } else { let binding_mode = ty::BindingMode::BindByValue(mutability); Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var( diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs index 703f6ef8dc41e..a1796c9433eac 100644 --- a/src/librustc_mir_build/hair/cx/expr.rs +++ b/src/librustc_mir_build/hair/cx/expr.rs @@ -478,7 +478,7 @@ fn make_mirror_unadjusted<'a, 'tcx>( ); // Not a real fn, but we're not reaching codegen anyways... - ty = cx.tcx.types.err; + ty = cx.tcx.ty_error(); InlineAsmOperand::SymFn { expr: Expr { ty, diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs index e9aa7f597beb6..5c30b2a448c6d 100644 --- a/src/librustc_mir_build/hair/pattern/mod.rs +++ b/src/librustc_mir_build/hair/pattern/mod.rs @@ -509,7 +509,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Pat<'tcx> { let mut ty = self.tables.node_type(pat.hir_id); - if let ty::Error = ty.kind { + if let ty::Error(_) = ty.kind { // Avoid ICEs (e.g., #50577 and #50585). return Pat { span: pat.span, ty, kind: Box::new(PatKind::Wild) }; } @@ -708,7 +708,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { if adt_def.is_enum() { let substs = match ty.kind { ty::Adt(_, substs) | ty::FnDef(_, substs) => substs, - ty::Error => { + ty::Error(_) => { // Avoid ICE (#50585) return PatKind::Wild; } @@ -1051,7 +1051,7 @@ crate fn compare_const_vals<'tcx>( let b_bits = b.try_eval_bits(tcx, param_env, ty); if let (Some(a), Some(b)) = (a_bits, b_bits) { - use ::rustc_apfloat::Float; + use rustc_apfloat::Float; return match ty.kind { ty::Float(ast::FloatTy::F32) => { let l = ::rustc_apfloat::ieee::Single::from_bits(a); diff --git a/src/librustc_passes/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs index e2bfcf18edb17..88fb78f85e423 100644 --- a/src/librustc_passes/intrinsicck.rs +++ b/src/librustc_passes/intrinsicck.rs @@ -150,7 +150,7 @@ impl ExprVisitor<'tcx> { _ => unreachable!(), }; let asm_ty = match ty.kind { - ty::Never | ty::Error => return None, + ty::Never | ty::Error(_) => return None, ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8), ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Some(InlineAsmType::I16), ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Some(InlineAsmType::I32), @@ -167,7 +167,7 @@ impl ExprVisitor<'tcx> { let fields = &adt.non_enum_variant().fields; let elem_ty = fields[0].ty(self.tcx, substs); match elem_ty.kind { - ty::Never | ty::Error => return None, + ty::Never | ty::Error(_) => return None, ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => { Some(InlineAsmType::VecI8(fields.len() as u64)) } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 3c1b56a9ef40a..9e6e7ea962bc3 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -220,7 +220,7 @@ where | ty::Ref(..) | ty::FnPtr(..) | ty::Param(..) - | ty::Error + | ty::Error(_) | ty::GeneratorWitness(..) => {} ty::Bound(..) | ty::Placeholder(..) | ty::Infer(..) => { bug!("unexpected type: {:?}", ty) diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 12d2c8c7eb9a4..cae501e942b65 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -520,7 +520,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { pub fn get_expr_data(&self, expr: &hir::Expr<'_>) -> Option { let hir_node = self.tcx.hir().expect_expr(expr.hir_id); let ty = self.tables.expr_ty_adjusted_opt(&hir_node); - if ty.is_none() || ty.unwrap().kind == ty::Error { + if ty.is_none() || matches!(ty.unwrap().kind, ty::Error(_)) { return None; } match expr.kind { diff --git a/src/librustc_symbol_mangling/v0.rs b/src/librustc_symbol_mangling/v0.rs index 1a536b6a4294f..7d117b77cf5e5 100644 --- a/src/librustc_symbol_mangling/v0.rs +++ b/src/librustc_symbol_mangling/v0.rs @@ -345,7 +345,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { ty::Never => "z", // Placeholders (should be demangled as `_`). - ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error => "p", + ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => "p", _ => "", }; @@ -367,7 +367,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { ty::Tuple(_) if ty.is_unit() => unreachable!(), // Placeholders, also handled as part of basic types. - ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error => { + ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => { unreachable!() } diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs index d53a0ec9ef884..adccdd0b2617a 100644 --- a/src/librustc_trait_selection/opaque_types.rs +++ b/src/librustc_trait_selection/opaque_types.rs @@ -941,7 +941,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); - self.tcx().types.err + self.tcx().ty_error() } } } @@ -974,7 +974,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); - self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: ct.ty }) + self.tcx().const_error(ct.ty) } } } @@ -1002,7 +1002,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { tcx, ty_op: |ty| { if ty.references_error() { - return tcx.types.err; + return tcx.ty_error(); } else if let ty::Opaque(def_id, substs) = ty.kind { // Check that this is `impl Trait` type is // declared by `parent_def_id` -- i.e., one whose diff --git a/src/librustc_trait_selection/traits/coherence.rs b/src/librustc_trait_selection/traits/coherence.rs index 85c2f9246afcc..706cbf058b713 100644 --- a/src/librustc_trait_selection/traits/coherence.rs +++ b/src/librustc_trait_selection/traits/coherence.rs @@ -565,7 +565,7 @@ fn ty_is_non_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> Option> } } - ty::Error => None, + ty::Error(_) => None, ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) => { bug!("ty_is_local invoked on unexpected type: {:?}", ty) diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs index d31e04cffd55f..e5a6c9a2e391a 100644 --- a/src/librustc_trait_selection/traits/error_reporting/mod.rs +++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs @@ -1246,7 +1246,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { ty::Generator(..) => Some(18), ty::Foreign(..) => Some(19), ty::GeneratorWitness(..) => Some(20), - ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error => None, + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None, } } diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index 8796cfb52165d..f4da25debd7cc 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -948,7 +948,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ty| { let ty = self.resolve_vars_if_possible(&ty); same &= - ty.kind != ty::Error + !matches!(ty.kind, ty::Error(_)) && last_ty.map_or(true, |last_ty| { // FIXME: ideally we would use `can_coerce` here instead, but `typeck` comes // *after* in the dependency graph. diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs index 9492c3c340995..ed108613bfa23 100644 --- a/src/librustc_trait_selection/traits/project.rs +++ b/src/librustc_trait_selection/traits/project.rs @@ -784,7 +784,7 @@ struct Progress<'tcx> { impl<'tcx> Progress<'tcx> { fn error(tcx: TyCtxt<'tcx>) -> Self { - Progress { ty: tcx.types.err, obligations: vec![] } + Progress { ty: tcx.ty_error(), obligations: vec![] } } fn with_addl_obligations(mut self, mut obligations: Vec>) -> Self { @@ -1085,7 +1085,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( | ty::Bound(..) | ty::Placeholder(..) | ty::Infer(..) - | ty::Error => false, + | ty::Error(_) => false, } } super::ImplSourceParam(..) => { @@ -1440,8 +1440,8 @@ fn confirm_param_env_candidate<'cx, 'tcx>( obligation, poly_cache_entry, e, ); debug!("confirm_param_env_candidate: {}", msg); - infcx.tcx.sess.delay_span_bug(obligation.cause.span, &msg); - Progress { ty: infcx.tcx.types.err, obligations: vec![] } + let err = infcx.tcx.ty_error_with_message(obligation.cause.span, &msg); + Progress { ty: err, obligations: vec![] } } } } @@ -1460,7 +1460,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( let param_env = obligation.param_env; let assoc_ty = match assoc_ty_def(selcx, impl_def_id, assoc_item_id) { Ok(assoc_ty) => assoc_ty, - Err(ErrorReported) => return Progress { ty: tcx.types.err, obligations: nested }, + Err(ErrorReported) => return Progress { ty: tcx.ty_error(), obligations: nested }, }; if !assoc_ty.item.defaultness.has_value() { @@ -1472,16 +1472,18 @@ fn confirm_impl_candidate<'cx, 'tcx>( "confirm_impl_candidate: no associated type {:?} for {:?}", assoc_ty.item.ident, obligation.predicate ); - return Progress { ty: tcx.types.err, obligations: nested }; + return Progress { ty: tcx.ty_error(), obligations: nested }; } let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs); let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.defining_node); let ty = tcx.type_of(assoc_ty.item.def_id); if substs.len() != tcx.generics_of(assoc_ty.item.def_id).count() { - tcx.sess - .delay_span_bug(DUMMY_SP, "impl item and trait item have different parameter counts"); - Progress { ty: tcx.types.err, obligations: nested } + let err = tcx.ty_error_with_message( + DUMMY_SP, + "impl item and trait item have different parameter counts", + ); + Progress { ty: err, obligations: nested } } else { Progress { ty: ty.subst(tcx, substs), obligations: nested } } diff --git a/src/librustc_trait_selection/traits/query/dropck_outlives.rs b/src/librustc_trait_selection/traits/query/dropck_outlives.rs index 856a2111fc82c..d07c95270e004 100644 --- a/src/librustc_trait_selection/traits/query/dropck_outlives.rs +++ b/src/librustc_trait_selection/traits/query/dropck_outlives.rs @@ -101,7 +101,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { | ty::Ref(..) | ty::Str | ty::Foreign(..) - | ty::Error => true, + | ty::Error(_) => true, // [T; N] and [T] have same properties as T. ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, ty), diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs index 7ebf30f61c095..3fd566eab437e 100644 --- a/src/librustc_trait_selection/traits/select/mod.rs +++ b/src/librustc_trait_selection/traits/select/mod.rs @@ -1569,7 +1569,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Array(..) | ty::Closure(..) | ty::Never - | ty::Error => { + | ty::Error(_) => { // safe for everything Where(ty::Binder::dummy(Vec::new())) } @@ -1613,7 +1613,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Infer(ty::FloatVar(_)) | ty::FnDef(..) | ty::FnPtr(_) - | ty::Error => Where(ty::Binder::dummy(Vec::new())), + | ty::Error(_) => Where(ty::Binder::dummy(Vec::new())), ty::Uint(_) | ty::Int(_) @@ -1690,7 +1690,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::FnDef(..) | ty::FnPtr(_) | ty::Str - | ty::Error + | ty::Error(_) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Never | ty::Char => Vec::new(), diff --git a/src/librustc_trait_selection/traits/structural_match.rs b/src/librustc_trait_selection/traits/structural_match.rs index c4deb639140ca..201edf27a655c 100644 --- a/src/librustc_trait_selection/traits/structural_match.rs +++ b/src/librustc_trait_selection/traits/structural_match.rs @@ -219,7 +219,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> { ty::Infer(_) | ty::Placeholder(_) | ty::Bound(..) => { bug!("unexpected type during structural-match checking: {:?}", ty); } - ty::Error => { + ty::Error(_) => { self.tcx().sess.delay_span_bug(self.span, "ty::Error in structural-match check"); // We still want to check other types after encountering an error, // as this may still emit relevant errors. diff --git a/src/librustc_trait_selection/traits/wf.rs b/src/librustc_trait_selection/traits/wf.rs index 5024392a0f98d..e2e5f4e7c58bf 100644 --- a/src/librustc_trait_selection/traits/wf.rs +++ b/src/librustc_trait_selection/traits/wf.rs @@ -391,7 +391,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { )); } } - ty::ConstKind::Error + ty::ConstKind::Error(_) | ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) => { @@ -411,7 +411,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { | ty::Int(..) | ty::Uint(..) | ty::Float(..) - | ty::Error + | ty::Error(_) | ty::Str | ty::GeneratorWitness(..) | ty::Never diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index 9530b07e47cdb..c9dd06e9f1ba2 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -168,7 +168,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi ty::PredicateKind::WellFormed(arg) => match arg.unpack() { GenericArgKind::Type(ty) => match ty.kind { // These types are always WF. - ty::Str | ty::Placeholder(..) | ty::Error | ty::Never => { + ty::Str | ty::Placeholder(..) | ty::Error(_) | ty::Never => { chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)) } @@ -376,7 +376,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { }) .intern(interner), Infer(_infer) => unimplemented!(), - Error => unimplemented!(), + Error(_) => unimplemented!(), } } } diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 11c48559bd683..6339f8288d54e 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -271,7 +271,7 @@ fn dtorck_constraint_for_ty<'tcx>( constraints.dtorck_types.push(ty); } - ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error => { + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => { // By the time this code runs, all type variables ought to // be fully resolved. return Err(NoSolution); diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index 99094246a6378..cf70a845af0aa 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -20,7 +20,7 @@ fn sized_constraint_for_ty<'tcx>( Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..) | FnPtr(_) | Array(..) | Closure(..) | Generator(..) | Never => vec![], - Str | Dynamic(..) | Slice(_) | Foreign(..) | Error | GeneratorWitness(..) => { + Str | Dynamic(..) | Slice(_) | Foreign(..) | Error(_) | GeneratorWitness(..) => { // these are never sized - return the target type vec![ty] } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 267f3d9f3ef6e..7cdcb2face823 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -819,7 +819,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => { if let (hir::TyKind::Infer, false) = (&ty.kind, self.allow_ty_infer()) { inferred_params.push(ty.span); - tcx.types.err.into() + tcx.ty_error().into() } else { self.ast_ty_to_ty(&ty).into() } @@ -845,7 +845,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // careful! if default_needs_object_self(param) { missing_type_params.push(param.name.to_string()); - tcx.types.err.into() + tcx.ty_error().into() } else { // This is a default type parameter. self.normalize_ty( @@ -865,7 +865,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.ty_infer(param, span).into() } else { // We've already errored above about the mismatch. - tcx.types.err.into() + tcx.ty_error().into() } } GenericParamDefKind::Const => { @@ -876,7 +876,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.ct_infer(ty, Some(param), span).into() } else { // We've already errored above about the mismatch. - tcx.mk_const(ty::Const { val: ty::ConstKind::Error, ty }).into() + tcx.const_error(ty).into() } } } @@ -1607,7 +1607,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "at least one trait is required for an object type" ) .emit(); - return tcx.types.err; + return tcx.ty_error(); } // Check that there are no gross object safety violations; @@ -1624,7 +1624,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &object_safety_violations[..], ) .emit(); - return tcx.types.err; + return tcx.ty_error(); } } @@ -2434,7 +2434,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &path_str, item_segment.ident.name, ); - return tcx.types.err; + return tcx.ty_error(); }; debug!("qpath_to_ty: self_type={:?}", self_ty); @@ -2792,7 +2792,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } Res::Err => { self.set_tainted_by_errors(); - self.tcx().types.err + self.tcx().ty_error() } _ => span_bug!(span, "unexpected resolution: {:?}", path.res), } @@ -2860,7 +2860,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }; self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, res, segment, false) .map(|(ty, _, _)| ty) - .unwrap_or(tcx.types.err) + .unwrap_or_else(|_| tcx.ty_error()) } hir::TyKind::Array(ref ty, ref length) => { let length_def_id = tcx.hir().local_def_id(length.hir_id); @@ -2878,7 +2878,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .span_label(ast_ty.span, "reserved keyword") .emit(); - tcx.types.err + tcx.ty_error() } hir::TyKind::Infer => { // Infer also appears as the type of arguments or return @@ -2887,7 +2887,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // handled specially and will not descend into this routine. self.ty_infer(None, ast_ty.span) } - hir::TyKind::Err => tcx.types.err, + hir::TyKind::Err => tcx.ty_error(), }; debug!("ast_ty_to_ty: result_ty={:?}", result_ty); diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index fb139b5033b3b..9e23f5df3c6a8 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -105,7 +105,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && i != 0 && self.if_fallback_coercion(expr.span, &arms[0].body, &mut coercion) { - tcx.types.err + tcx.ty_error() } else { // Only call this if this is not an `if` expr with an expected type and no `else` // clause to avoid duplicated type errors. (#60254) diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index aa316105f7f11..13695be83a9da 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -383,7 +383,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ( ty::Binder::bind(self.tcx.mk_fn_sig( self.err_args(arg_exprs.len()).into_iter(), - self.tcx.types.err, + self.tcx.ty_error(), false, hir::Unsafety::Normal, abi::Abi::Rust, diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 46d6706cbf429..c55f0cf1fcb68 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -135,7 +135,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Generator(..) | ty::Adt(..) | ty::Never - | ty::Error => { + | ty::Error(_) => { self.tcx .sess .delay_span_bug(span, &format!("`{:?}` should be sized but is not?", t)); diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 206619588c71d..6d09ddc925ffe 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -700,7 +700,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let supplied_arguments = decl.inputs.iter().map(|a| { // Convert the types that the user supplied (if any), but ignore them. astconv.ast_ty_to_ty(a); - self.tcx.types.err + self.tcx.ty_error() }); if let hir::FnRetTy::Return(ref output) = decl.output { @@ -709,7 +709,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let result = ty::Binder::bind(self.tcx.mk_fn_sig( supplied_arguments, - self.tcx.types.err, + self.tcx.ty_error(), decl.c_variadic, hir::Unsafety::Normal, Abi::RustCall, diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 15ec92568fb4d..dd3f292fb5684 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -162,7 +162,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Just ignore error types. if a.references_error() || b.references_error() { - return success(vec![], self.fcx.tcx.types.err, vec![]); + return success(vec![], self.fcx.tcx.ty_error(), vec![]); } if a.is_never() { @@ -864,7 +864,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (adjustments, _) = self.register_infer_ok_obligations(ok); self.apply_adjustments(expr, adjustments); - Ok(if expr_ty.references_error() { self.tcx.types.err } else { target }) + Ok(if expr_ty.references_error() { self.tcx.ty_error() } else { target }) } /// Same as `try_coerce()`, but without side-effects. @@ -1239,7 +1239,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // If we see any error types, just propagate that error // upwards. if expression_ty.references_error() || self.merged_ty().references_error() { - self.final_ty = Some(fcx.tcx.types.err); + self.final_ty = Some(fcx.tcx.ty_error()); return; } @@ -1396,7 +1396,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { err.emit_unless(assign_to_bool || unsized_return); - self.final_ty = Some(fcx.tcx.types.err); + self.final_ty = Some(fcx.tcx.ty_error()); } } } diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index bc3ef73d851eb..69cfafc21648f 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -248,7 +248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx.types.never } else { // There was an error; make type-check fail. - tcx.types.err + tcx.ty_error() } } ExprKind::Ret(ref expr_opt) => self.check_expr_return(expr_opt.as_deref(), expr), @@ -284,7 +284,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ExprKind::Field(ref base, field) => self.check_field(expr, needs, &base, field), ExprKind::Index(ref base, ref idx) => self.check_expr_index(base, idx, needs, expr), ExprKind::Yield(ref value, ref src) => self.check_expr_yield(value, expr, src), - hir::ExprKind::Err => tcx.types.err, + hir::ExprKind::Err => tcx.ty_error(), } } @@ -360,7 +360,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp, None); } err.emit(); - oprnd_t = tcx.types.err; + oprnd_t = tcx.ty_error(); } } hir::UnOp::UnNot => { @@ -410,7 +410,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tm = ty::TypeAndMut { ty, mutbl }; match kind { - _ if tm.ty.references_error() => self.tcx.types.err, + _ if tm.ty.references_error() => self.tcx.ty_error(), hir::BorrowKind::Raw => { self.check_named_place_expr(oprnd); self.tcx.mk_ptr(tm) @@ -476,11 +476,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = match res { Res::Err => { self.set_tainted_by_errors(); - tcx.types.err + tcx.ty_error() } Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => { report_unexpected_variant_res(tcx, res, expr.span); - tcx.types.err + tcx.ty_error() } _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0, }; @@ -560,11 +560,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(ctxt) => ctxt.coerce.as_ref().map(|coerce| coerce.expected_ty()), None => { // Avoid ICE when `break` is inside a closure (#65383). - self.tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( expr.span, "break was outside loop, but no error was emitted", ); - return tcx.types.err; } } }; @@ -572,7 +571,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the loop context is not a `loop { }`, then break with // a value is illegal, and `opt_coerce_to` will be `None`. // Just set expectation to error in that case. - let coerce_to = opt_coerce_to.unwrap_or(tcx.types.err); + let coerce_to = opt_coerce_to.unwrap_or_else(|| tcx.ty_error()); // Recurse without `enclosing_breakables` borrowed. e_ty = self.check_expr_with_hint(e, coerce_to); @@ -592,11 +591,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(ctxt) => ctxt, None => { // Avoid ICE when `break` is inside a closure (#65383). - self.tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( expr.span, "break was outside loop, but no error was emitted", ); - return tcx.types.err; } }; @@ -649,14 +647,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // this can only happen if the `break` was not // inside a loop at all, which is caught by the // loop-checking pass. - self.tcx - .sess - .delay_span_bug(expr.span, "break was outside loop, but no error was emitted"); + let err = self.tcx.ty_error_with_message( + expr.span, + "break was outside loop, but no error was emitted", + ); // We still need to assign a type to the inner expression to // prevent the ICE in #43162. if let Some(ref e) = expr_opt { - self.check_expr_with_hint(e, tcx.types.err); + self.check_expr_with_hint(e, err); // ... except when we try to 'break rust;'. // ICE this expression in particular (see #43162). @@ -666,8 +665,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } + // There was an error; make type-check fail. - tcx.types.err + err } } @@ -803,7 +803,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized); if lhs_ty.references_error() || rhs_ty.references_error() { - self.tcx.types.err + self.tcx.ty_error() } else { self.tcx.mk_unit() } @@ -957,7 +957,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Eagerly check for some obvious errors. if t_expr.references_error() || t_cast.references_error() { - self.tcx.types.err + self.tcx.ty_error() } else { // Defer other checks until we're done type checking. let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut(); @@ -966,7 +966,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { deferred_cast_checks.push(cast_check); t_cast } - Err(ErrorReported) => self.tcx.types.err, + Err(ErrorReported) => self.tcx.ty_error(), } } } @@ -1041,7 +1041,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; if element_ty.references_error() { - return tcx.types.err; + return tcx.ty_error(); } tcx.mk_ty(ty::Array(t, count)) @@ -1071,7 +1071,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); let tuple = self.tcx.mk_tup(elt_ts_iter); if tuple.references_error() { - self.tcx.types.err + self.tcx.ty_error() } else { self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized); tuple @@ -1092,7 +1092,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { variant_ty } else { self.check_struct_fields_on_error(fields, base_expr); - return self.tcx.types.err; + return self.tcx.ty_error(); }; let path_span = match *qpath { @@ -1233,7 +1233,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name, span); } - tcx.types.err + tcx.ty_error() }; // Make sure to give a type to the field even if there's @@ -1519,7 +1519,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .emit(); } - self.tcx().types.err + self.tcx().ty_error() } fn ban_nonexisting_field( @@ -1775,7 +1775,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } err.emit(); - self.tcx.types.err + self.tcx.ty_error() } } } @@ -1887,7 +1887,7 @@ pub(super) fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> { ty::Char => "'a'", ty::Int(_) | ty::Uint(_) => "42", ty::Float(_) => "3.14159", - ty::Error | ty::Never => return None, + ty::Error(_) | ty::Never => return None, _ => "value", }) } diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 007794ce1b7ff..8651c643cee87 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -141,11 +141,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { let (_, n) = match autoderef.nth(pick.autoderefs) { Some(n) => n, None => { - self.tcx.sess.delay_span_bug( + return self.tcx.ty_error_with_message( rustc_span::DUMMY_SP, &format!("failed autoderef {}", pick.autoderefs), ); - return self.tcx.types.err; } }; assert_eq!(n, pick.autoderefs); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 37652330108c9..93bcd5cf29149 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -400,7 +400,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .probe_instantiate_query_response(span, &orig_values, ty) .unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty)); let ty = self.structurally_resolved_type(span, ty.value); - assert_eq!(ty, self.tcx.types.err); + assert!(matches!(ty.kind, ty::Error(_))); return Err(MethodError::NoMatch(NoMatchData::new( Vec::new(), Vec::new(), @@ -478,7 +478,7 @@ fn method_autoderef_steps<'tcx>( let final_ty = autoderef.maybe_ambiguous_final_ty(); let opt_bad_ty = match final_ty.kind { - ty::Infer(ty::TyVar(_)) | ty::Error => Some(MethodAutoderefBadTy { + ty::Infer(ty::TyVar(_)) | ty::Error(_) => Some(MethodAutoderefBadTy { reached_raw_pointer, ty: infcx .make_query_response_ignoring_pending_obligations(inference_vars, final_ty), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a409e20953da1..96f1c6ff16104 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -967,8 +967,7 @@ fn diagnostic_only_typeck_tables_of<'tcx>( ) -> &ty::TypeckTables<'tcx> { let fallback = move || { let span = tcx.hir().span(tcx.hir().as_local_hir_id(def_id)); - tcx.sess.delay_span_bug(span, "diagnostic only typeck table used"); - tcx.types.err + tcx.ty_error_with_message(span, "diagnostic only typeck table used") }; typeck_tables_of_with_fallback(tcx, def_id, fallback) } @@ -3387,7 +3386,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> { match self.tables.borrow().node_types().get(id) { Some(&t) => t, - None if self.is_tainted_by_errors() => self.tcx.types.err, + None if self.is_tainted_by_errors() => self.tcx.ty_error(), None => { bug!( "no type for node {}: {} in fcx {}", @@ -3501,7 +3500,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { assert!(ty.is_ty_infer()); let fallback = match self.type_is_unconstrained_numeric(ty) { - _ if self.is_tainted_by_errors() => self.tcx().types.err, + _ if self.is_tainted_by_errors() => self.tcx().ty_error(), UnconstrainedInt => self.tcx.types.i32, UnconstrainedFloat => self.tcx.types.f64, Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(), @@ -3774,7 +3773,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tuple_arguments, None, ); - return self.tcx.types.err; + return self.tcx.ty_error(); } let method = method.unwrap(); @@ -4161,7 +4160,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } fn err_args(&self, len: usize) -> Vec> { - vec![self.tcx.types.err; len] + vec![self.tcx.ty_error(); len] } /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk @@ -4305,7 +4304,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { opt_ty.unwrap_or_else(|| self.next_float_var()) } ast::LitKind::Bool(_) => tcx.types.bool, - ast::LitKind::Err(_) => tcx.types.err, + ast::LitKind::Err(_) => tcx.ty_error(), } } @@ -4442,7 +4441,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let result = AstConv::associated_path_to_ty(self, hir_id, path_span, ty, res, segment, true); - let ty = result.map(|(ty, _, _)| ty).unwrap_or(self.tcx().types.err); + let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error()); let result = result.map(|(_, kind, def_id)| (kind, def_id)); // Write back the new resolution. @@ -4570,7 +4569,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty: Ty<'tcx>, ) { if ty.references_error() { - // Override the types everywhere with `types.err` to avoid knock on errors. + // Override the types everywhere with `err()` to avoid knock on errors. self.write_ty(local.hir_id, ty); self.write_ty(local.pat.hir_id, ty); let local_ty = LocalTy { decl_ty, revealed_ty: ty }; @@ -4790,7 +4789,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut ty = ctxt.coerce.unwrap().complete(self); if self.has_errors.get() || ty.references_error() { - ty = self.tcx.types.err + ty = self.tcx.ty_error() } self.write_ty(blk.hir_id, ty); @@ -5378,7 +5377,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => return None, }; let last_expr_ty = self.node_ty(last_expr.hir_id); - if matches!(last_expr_ty.kind, ty::Error) + if matches!(last_expr_ty.kind, ty::Error(_)) || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() { return None; @@ -5538,7 +5537,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } err.emit(); - return (tcx.types.err, res); + return (tcx.ty_error(), res); } } } else { @@ -5731,8 +5730,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .note("type must be known at this point") .emit(); } - self.demand_suptype(sp, self.tcx.types.err, ty); - self.tcx.types.err + let err = self.tcx.ty_error(); + self.demand_suptype(sp, err, ty); + err } } diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index a3a27dc138be9..fe50870911647 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -497,7 +497,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - self.tcx.types.err + self.tcx.ty_error() } }; @@ -709,7 +709,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } err.emit(); } - self.tcx.types.err + self.tcx.ty_error() } } } diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 8a10427260eee..7965c9c9ce12a 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -442,7 +442,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // There exists a side that didn't meet our criteria that the end-point // be of a numeric or char type, as checked in `calc_side` above. self.emit_err_pat_range(span, lhs, rhs); - return self.tcx.types.err; + return self.tcx.ty_error(); } // Now that we know the types can be unified we find the unified type @@ -673,11 +673,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { variant_ty } else { + let err = self.tcx.ty_error(); for field in fields { let ti = TopInfo { parent_pat: Some(&pat), ..ti }; - self.check_pat(&field.pat, self.tcx.types.err, def_bm, ti); + self.check_pat(&field.pat, err, def_bm, ti); } - return self.tcx.types.err; + return err; }; // Type-check the path. @@ -687,7 +688,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.check_struct_pat_fields(pat_ty, &pat, variant, fields, etc, def_bm, ti) { pat_ty } else { - self.tcx.types.err + self.tcx.ty_error() } } @@ -705,11 +706,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match res { Res::Err => { self.set_tainted_by_errors(); - return tcx.types.err; + return tcx.ty_error(); } Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fictive | CtorKind::Fn), _) => { report_unexpected_variant_res(tcx, res, pat.span); - return tcx.types.err; + return tcx.ty_error(); } Res::SelfCtor(..) | Res::Def( @@ -788,7 +789,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let on_error = || { let parent_pat = Some(pat); for pat in subpats { - self.check_pat(&pat, tcx.types.err, def_bm, TopInfo { parent_pat, ..ti }); + self.check_pat(&pat, tcx.ty_error(), def_bm, TopInfo { parent_pat, ..ti }); } }; let report_unexpected_res = |res: Res| { @@ -824,7 +825,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if res == Res::Err { self.set_tainted_by_errors(); on_error(); - return self.tcx.types.err; + return self.tcx.ty_error(); } // Type-check the path. @@ -832,18 +833,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id); if !pat_ty.is_fn() { report_unexpected_res(res); - return tcx.types.err; + return tcx.ty_error(); } let variant = match res { Res::Err => { self.set_tainted_by_errors(); on_error(); - return tcx.types.err; + return tcx.ty_error(); } Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => { report_unexpected_res(res); - return tcx.types.err; + return tcx.ty_error(); } Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res), _ => bug!("unexpected pattern resolution: {:?}", res), @@ -880,7 +881,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Pattern has wrong number of fields. self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err); on_error(); - return tcx.types.err; + return tcx.ty_error(); } pat_ty } @@ -1001,9 +1002,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); // Walk subpatterns with an expected type of `err` in this case to silence // further errors being emitted when using the bindings. #50333 - let element_tys_iter = (0..max_len).map(|_| tcx.types.err); + let element_tys_iter = (0..max_len).map(|_| tcx.ty_error()); for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { - self.check_pat(elem, &tcx.types.err, def_bm, ti); + self.check_pat(elem, &tcx.ty_error(), def_bm, ti); } tcx.mk_tup(element_tys_iter) } else { @@ -1052,7 +1053,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Occupied(occupied) => { self.error_field_already_bound(span, field.ident, *occupied.get()); no_field_errors = false; - tcx.types.err + tcx.ty_error() } Vacant(vacant) => { vacant.insert(span); @@ -1066,7 +1067,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or_else(|| { inexistent_fields.push(field.ident); no_field_errors = false; - tcx.types.err + tcx.ty_error() }) } }; @@ -1281,7 +1282,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.demand_eqtype_pat(span, expected, box_ty, ti); (box_ty, inner_ty) } else { - (tcx.types.err, tcx.types.err) + let err = tcx.ty_error(); + (err, err) }; self.check_pat(&inner, inner_ty, def_bm, ti); box_ty @@ -1327,7 +1329,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } else { - (tcx.types.err, tcx.types.err) + let err = tcx.ty_error(); + (err, err) }; self.check_pat(&inner, inner_ty, def_bm, TopInfo { parent_pat: Some(&pat), ..ti }); rptr_ty @@ -1378,7 +1381,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !expected.references_error() { self.error_expected_array_or_slice(span, expected); } - let err = self.tcx.types.err; + let err = self.tcx.ty_error(); (err, Some(err), err) } }; @@ -1445,7 +1448,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // If we get here, we must have emitted an error. - (Some(self.tcx.types.err), arr_ty) + (Some(self.tcx.ty_error()), arr_ty) } fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) { diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 19a23e5a59478..8403c99f01bb5 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -91,7 +91,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (closure_def_id, substs) = match ty.kind { ty::Closure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs)), ty::Generator(def_id, substs, _) => (def_id, UpvarSubsts::Generator(substs)), - ty::Error => { + ty::Error(_) => { // #51714: skip analysis when we have already encountered type errors return; } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 159d3d7a538a6..ba806430f17fd 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -208,11 +208,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // to access an unexistend index. We assume that more relevant errors will // already have been emitted, so we only gate on this with an ICE if no // error has been emitted. (#64638) - self.tcx().sess.delay_span_bug( + self.fcx.tcx.ty_error_with_message( e.span, &format!("bad index {:?} for base: `{:?}`", index, base), - ); - self.fcx.tcx.types.err + ) }); let index_ty = self.fcx.resolve_vars_if_possible(&index_ty); @@ -681,7 +680,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> { debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t); self.report_type_error(t); self.replaced_with_error = true; - self.tcx().types.err + self.tcx().ty_error() } } } @@ -698,7 +697,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> { debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct); self.report_const_error(ct); self.replaced_with_error = true; - self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: ct.ty }) + self.tcx().const_error(ct.ty) } } } diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index c5dd314dc6558..8c6161a626473 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -50,7 +50,7 @@ impl<'tcx> Checker<'tcx> { fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) { // Destructors only work on nominal types. - if let ty::Adt(..) | ty::Error = tcx.type_of(impl_did).kind { + if let ty::Adt(..) | ty::Error(_) = tcx.type_of(impl_did).kind { return; } diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 653b7b8f2a5ba..93ee87f6c572e 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -296,7 +296,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { item.span, ); } - ty::Error => {} + ty::Error(_) => {} _ => { struct_span_err!( self.tcx.sess, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1d59d749634ee..3bd75095bb602 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -307,8 +307,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { } fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { - self.tcx().sess.delay_span_bug(span, "bad placeholder type"); - self.tcx().types.err + self.tcx().ty_error_with_message(span, "bad_placeholder_type") } fn ct_infer( @@ -318,8 +317,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { span: Span, ) -> &'tcx Const<'tcx> { bad_placeholder_type(self.tcx(), vec![span]).emit(); - - self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty }) + self.tcx().const_error(ty) } fn projected_ty_from_poly_trait_ref( @@ -419,7 +417,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { _ => {} } err.emit(); - self.tcx().types.err + self.tcx().ty_error() } } @@ -1465,7 +1463,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { visitor.visit_ty(ty); let mut diag = bad_placeholder_type(tcx, visitor.0); let ret_ty = fn_sig.output(); - if ret_ty != tcx.types.err { + if ret_ty != tcx.ty_error() { diag.span_suggestion( ty.span, "replace with the correct return type", @@ -2004,12 +2002,11 @@ fn associated_item_predicates( // once they are handled by the trait system. ty::GenericParamDefKind::Type { .. } => { unimplemented_error("type"); - tcx.types.err.into() + tcx.ty_error().into() } ty::GenericParamDefKind::Const => { unimplemented_error("const"); - tcx.mk_const(ty::Const { val: ty::ConstKind::Error, ty: tcx.type_of(param.def_id) }) - .into() + tcx.const_error(tcx.type_of(param.def_id)).into() } } }; diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index 549a20531e299..cf5f2ec69d8d8 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -127,7 +127,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { // Some error in the // owner fn prevented us from populating // the `concrete_opaque_types` table. - tcx.types.err + tcx.ty_error() } else { // We failed to resolve the opaque type or it // resolves to itself. Return the non-revealed @@ -217,11 +217,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { }) | Node::TraitRef(&TraitRef { path, .. }) => &*path, _ => { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( DUMMY_SP, &format!("unexpected const parent path {:?}", parent_node), ); - return tcx.types.err; } }; @@ -254,14 +253,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } Res::Def(_, def_id) => tcx.generics_of(def_id), res => { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( DUMMY_SP, &format!( "unexpected anon const res {:?} in path: {:?}", res, path, ), - ); - return tcx.types.err; + ); } }; @@ -283,24 +281,21 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } else { // This is no generic parameter associated with the arg. This is // probably from an extra arg where one is not needed. - tcx.sess.delay_span_bug( + tcx.ty_error_with_message( DUMMY_SP, &format!( - "missing generic parameter for `AnonConst`, parent: {:?}, res: {:?}", + "missing generic parameter for `AnonConst`, \ + parent: {:?}, res: {:?}", parent_node, res ), - ); - tcx.types.err + ) } } - x => { - tcx.sess.delay_span_bug( - DUMMY_SP, - &format!("unexpected const parent in type_of_def_id(): {:?}", x), - ); - tcx.types.err - } + x => tcx.ty_error_with_message( + DUMMY_SP, + &format!("unexpected const parent in type_of_def_id(): {:?}", x), + ), } } @@ -568,7 +563,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { None => { let span = tcx.def_span(def_id); tcx.sess.span_err(span, "could not find defining uses"); - tcx.types.err + tcx.ty_error() } } } @@ -605,7 +600,7 @@ fn let_position_impl_trait_type(tcx: TyCtxt<'_>, opaque_ty_id: LocalDefId) -> Ty if let Some(ErrorReported) = owner_tables.tainted_by_errors { // Some error in the owner fn prevented us from populating the // `concrete_opaque_types` table. - tcx.types.err + tcx.ty_error() } else { // We failed to resolve the opaque type or it resolves to // itself. Return the non-revealed type, which should result in @@ -655,7 +650,7 @@ fn infer_placeholder_type( } None => { let mut diag = bad_placeholder_type(tcx, vec![span]); - if ty != tcx.types.err { + if !matches!(ty.kind, ty::Error(_)) { diag.span_suggestion( span, "replace `_` with the correct type", diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index eee0f764373a4..cae09267994e3 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -339,7 +339,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_sig(current, sig, variance); } - ty::Error => { + ty::Error(_) => { // we encounter this when walking the trait references for object // types, where we use Error as the Self type } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index adb2ae9a5d660..73fe87b05d477 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1717,7 +1717,7 @@ impl<'tcx> Clean for Ty<'tcx> { ty::Placeholder(..) => panic!("Placeholder"), ty::GeneratorWitness(..) => panic!("GeneratorWitness"), ty::Infer(..) => panic!("Infer"), - ty::Error => panic!("Error"), + ty::Error(_) => panic!("Error"), } } } diff --git a/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.rs b/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.rs index 27fe432e96ded..973294e985f7a 100644 --- a/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.rs +++ b/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.rs @@ -37,7 +37,7 @@ fn main() { TyKind::Bound(..) => (), //~ ERROR usage of `ty::TyKind::` TyKind::Placeholder(..) => (), //~ ERROR usage of `ty::TyKind::` TyKind::Infer(..) => (), //~ ERROR usage of `ty::TyKind::` - TyKind::Error => (), //~ ERROR usage of `ty::TyKind::` + TyKind::Error(_) => (), //~ ERROR usage of `ty::TyKind::` } if let ty::Int(int_ty) = kind {} diff --git a/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.stderr b/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.stderr index 0486c90a5a07a..d6e4c85c190d5 100644 --- a/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.stderr +++ b/src/test/ui-fulldeps/internal-lints/ty_tykind_usage.stderr @@ -169,7 +169,7 @@ LL | TyKind::Infer(..) => (), error: usage of `ty::TyKind::` --> $DIR/ty_tykind_usage.rs:40:9 | -LL | TyKind::Error => (), +LL | TyKind::Error(_) => (), | ^^^^^^ help: try using ty:: directly: `ty` error: usage of `ty::TyKind::` From e855b90a8e159d27e014847ef50d9536aa1249d0 Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 26 May 2020 12:49:11 -0500 Subject: [PATCH 41/60] track caller for delay_span_bug --- src/librustc_errors/lib.rs | 4 ++++ src/librustc_middle/ty/context.rs | 26 ++++---------------------- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 7261c638ce013..0c1418d3cad27 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -5,6 +5,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(crate_visibility_modifier)] #![feature(nll)] +#![feature(track_caller)] pub use emitter::ColorConfig; @@ -621,6 +622,7 @@ impl Handler { self.inner.borrow_mut().span_bug(span, msg) } + #[track_caller] pub fn delay_span_bug(&self, span: impl Into, msg: &str) { self.inner.borrow_mut().delay_span_bug(span, msg) } @@ -873,6 +875,7 @@ impl HandlerInner { self.emit_diagnostic(diag.set_span(sp)); } + #[track_caller] fn delay_span_bug(&mut self, sp: impl Into, msg: &str) { // This is technically `self.treat_err_as_bug()` but `delay_span_bug` is called before // incrementing `err_count` by one, so we need to +1 the comparing. @@ -883,6 +886,7 @@ impl HandlerInner { } let mut diagnostic = Diagnostic::new(Level::Bug, msg); diagnostic.set_span(sp.into()); + diagnostic.note(&format!("delayed at {}", std::panic::Location::caller())); self.delay_as_bug(diagnostic) } diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index 4fe8173becff9..1715b545662b8 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -1144,40 +1144,22 @@ impl<'tcx> TyCtxt<'tcx> { /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used. #[track_caller] pub fn ty_error(self) -> Ty<'tcx> { - self.err_with_message_and_location( - DUMMY_SP, - "TyKind::Error constructed but no error reported", - std::panic::Location::caller(), - ) + self.ty_error_with_message(DUMMY_SP, "TyKind::Error constructed but no error reported") } /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg to /// ensure it gets used. #[track_caller] pub fn ty_error_with_message>(self, span: S, msg: &str) -> Ty<'tcx> { - self.err_with_message_and_location(span, msg, std::panic::Location::caller()) - } - - pub fn err_with_message_and_location>( - self, - span: S, - msg: &str, - loc: &'static std::panic::Location<'static>, - ) -> Ty<'tcx> { - self.sess.delay_span_bug(span, &format!("{}: {}", loc, msg)); + self.sess.delay_span_bug(span, msg); self.mk_ty(Error(super::sty::DelaySpanBugEmitted(()))) } /// Like `err` but for constants. #[track_caller] pub fn const_error(self, ty: Ty<'tcx>) -> &'tcx Const<'tcx> { - self.sess.delay_span_bug( - DUMMY_SP, - &format!( - "ty::ConstKind::Error constructed but no error reported. {}", - std::panic::Location::caller() - ), - ); + self.sess + .delay_span_bug(DUMMY_SP, "ty::ConstKind::Error constructed but no error reported."); self.mk_const(ty::Const { val: ty::ConstKind::Error(super::sty::DelaySpanBugEmitted(())), ty, From 0bcefd9b5e68eb3a026843ed7b624761bea2de1e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 31 May 2020 12:13:29 +0200 Subject: [PATCH 42/60] 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 43/60] 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 44/60] 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 45/60] 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 46/60] 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? } } From f0d36891b6681c0833747d6188f0b194aee7fac8 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Tue, 16 Jun 2020 06:55:24 -0700 Subject: [PATCH 47/60] fixup! Note numeric literals that can never fit in an expected type --- src/test/ui/numeric/numeric-cast-no-fix.rs | 65 ++++ .../ui/numeric/numeric-cast-no-fix.stderr | 352 +++++++++++++++++- 2 files changed, 416 insertions(+), 1 deletion(-) diff --git a/src/test/ui/numeric/numeric-cast-no-fix.rs b/src/test/ui/numeric/numeric-cast-no-fix.rs index 8bfd833354164..63e5f098a25d3 100644 --- a/src/test/ui/numeric/numeric-cast-no-fix.rs +++ b/src/test/ui/numeric/numeric-cast-no-fix.rs @@ -19,4 +19,69 @@ fn main() { //~^ ERROR mismatched types x_u8 > -1_isize; //~^ ERROR mismatched types + + x_usize > -1_i128; + //~^ ERROR mismatched types + x_u128 > -1_i128; + //~^ ERROR mismatched types + x_u64 > -1_i128; + //~^ ERROR mismatched types + x_u32 > -1_i128; + //~^ ERROR mismatched types + x_u16 > -1_i128; + //~^ ERROR mismatched types + x_u8 > -1_i128; + //~^ ERROR mismatched types + + x_usize > -1_i64; + //~^ ERROR mismatched types + x_u128 > -1_i64; + //~^ ERROR mismatched types + x_u64 > -1_i64; + //~^ ERROR mismatched types + x_u32 > -1_i64; + //~^ ERROR mismatched types + x_u16 > -1_i64; + //~^ ERROR mismatched types + x_u8 > -1_i64; + //~^ ERROR mismatched types + + x_usize > -1_i32; + //~^ ERROR mismatched types + x_u128 > -1_i32; + //~^ ERROR mismatched types + x_u64 > -1_i32; + //~^ ERROR mismatched types + x_u32 > -1_i32; + //~^ ERROR mismatched types + x_u16 > -1_i32; + //~^ ERROR mismatched types + x_u8 > -1_i32; + //~^ ERROR mismatched types + + x_usize > -1_i16; + //~^ ERROR mismatched types + x_u128 > -1_i16; + //~^ ERROR mismatched types + x_u64 > -1_i16; + //~^ ERROR mismatched types + x_u32 > -1_i16; + //~^ ERROR mismatched types + x_u16 > -1_i16; + //~^ ERROR mismatched types + x_u8 > -1_i16; + //~^ ERROR mismatched types + + x_usize > -1_i8; + //~^ ERROR mismatched types + x_u128 > -1_i8; + //~^ ERROR mismatched types + x_u64 > -1_i8; + //~^ ERROR mismatched types + x_u32 > -1_i8; + //~^ ERROR mismatched types + x_u16 > -1_i8; + //~^ ERROR mismatched types + x_u8 > -1_i8; + //~^ ERROR mismatched types } diff --git a/src/test/ui/numeric/numeric-cast-no-fix.stderr b/src/test/ui/numeric/numeric-cast-no-fix.stderr index 63b563aafb6de..6501e11fc64d6 100644 --- a/src/test/ui/numeric/numeric-cast-no-fix.stderr +++ b/src/test/ui/numeric/numeric-cast-no-fix.stderr @@ -69,6 +69,356 @@ help: you can convert `x_u8` from `u8` to `isize`, matching the type of `-1_isiz LL | isize::from(x_u8) > -1_isize; | ^^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:23:15 + | +LL | x_usize > -1_i128; + | ^^^^^^^ expected `usize`, found `i128` + | +note: `-1_i128` cannot fit into type `usize` + --> $DIR/numeric-cast-no-fix.rs:23:15 + | +LL | x_usize > -1_i128; + | ^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:25:14 + | +LL | x_u128 > -1_i128; + | ^^^^^^^ expected `u128`, found `i128` + | +note: `-1_i128` cannot fit into type `u128` + --> $DIR/numeric-cast-no-fix.rs:25:14 + | +LL | x_u128 > -1_i128; + | ^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:27:13 + | +LL | x_u64 > -1_i128; + | ^^^^^^^ expected `u64`, found `i128` + | +help: you can convert `x_u64` from `u64` to `i128`, matching the type of `-1_i128` + | +LL | i128::from(x_u64) > -1_i128; + | ^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:29:13 + | +LL | x_u32 > -1_i128; + | ^^^^^^^ expected `u32`, found `i128` + | +help: you can convert `x_u32` from `u32` to `i128`, matching the type of `-1_i128` + | +LL | i128::from(x_u32) > -1_i128; + | ^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:31:13 + | +LL | x_u16 > -1_i128; + | ^^^^^^^ expected `u16`, found `i128` + | +help: you can convert `x_u16` from `u16` to `i128`, matching the type of `-1_i128` + | +LL | i128::from(x_u16) > -1_i128; + | ^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:33:12 + | +LL | x_u8 > -1_i128; + | ^^^^^^^ expected `u8`, found `i128` + | +help: you can convert `x_u8` from `u8` to `i128`, matching the type of `-1_i128` + | +LL | i128::from(x_u8) > -1_i128; + | ^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:36:15 + | +LL | x_usize > -1_i64; + | ^^^^^^ expected `usize`, found `i64` + | +note: `-1_i64` cannot fit into type `usize` + --> $DIR/numeric-cast-no-fix.rs:36:15 + | +LL | x_usize > -1_i64; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:38:14 + | +LL | x_u128 > -1_i64; + | ^^^^^^ expected `u128`, found `i64` + | +note: `-1_i64` cannot fit into type `u128` + --> $DIR/numeric-cast-no-fix.rs:38:14 + | +LL | x_u128 > -1_i64; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:40:13 + | +LL | x_u64 > -1_i64; + | ^^^^^^ expected `u64`, found `i64` + | +note: `-1_i64` cannot fit into type `u64` + --> $DIR/numeric-cast-no-fix.rs:40:13 + | +LL | x_u64 > -1_i64; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:42:13 + | +LL | x_u32 > -1_i64; + | ^^^^^^ expected `u32`, found `i64` + | +help: you can convert `x_u32` from `u32` to `i64`, matching the type of `-1_i64` + | +LL | i64::from(x_u32) > -1_i64; + | ^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:44:13 + | +LL | x_u16 > -1_i64; + | ^^^^^^ expected `u16`, found `i64` + | +help: you can convert `x_u16` from `u16` to `i64`, matching the type of `-1_i64` + | +LL | i64::from(x_u16) > -1_i64; + | ^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:46:12 + | +LL | x_u8 > -1_i64; + | ^^^^^^ expected `u8`, found `i64` + | +help: you can convert `x_u8` from `u8` to `i64`, matching the type of `-1_i64` + | +LL | i64::from(x_u8) > -1_i64; + | ^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:49:15 + | +LL | x_usize > -1_i32; + | ^^^^^^ expected `usize`, found `i32` + | +note: `-1_i32` cannot fit into type `usize` + --> $DIR/numeric-cast-no-fix.rs:49:15 + | +LL | x_usize > -1_i32; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:51:14 + | +LL | x_u128 > -1_i32; + | ^^^^^^ expected `u128`, found `i32` + | +note: `-1_i32` cannot fit into type `u128` + --> $DIR/numeric-cast-no-fix.rs:51:14 + | +LL | x_u128 > -1_i32; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:53:13 + | +LL | x_u64 > -1_i32; + | ^^^^^^ expected `u64`, found `i32` + | +note: `-1_i32` cannot fit into type `u64` + --> $DIR/numeric-cast-no-fix.rs:53:13 + | +LL | x_u64 > -1_i32; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:55:13 + | +LL | x_u32 > -1_i32; + | ^^^^^^ expected `u32`, found `i32` + | +note: `-1_i32` cannot fit into type `u32` + --> $DIR/numeric-cast-no-fix.rs:55:13 + | +LL | x_u32 > -1_i32; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:57:13 + | +LL | x_u16 > -1_i32; + | ^^^^^^ expected `u16`, found `i32` + | +help: you can convert `x_u16` from `u16` to `i32`, matching the type of `-1_i32` + | +LL | i32::from(x_u16) > -1_i32; + | ^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:59:12 + | +LL | x_u8 > -1_i32; + | ^^^^^^ expected `u8`, found `i32` + | +help: you can convert `x_u8` from `u8` to `i32`, matching the type of `-1_i32` + | +LL | i32::from(x_u8) > -1_i32; + | ^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:62:15 + | +LL | x_usize > -1_i16; + | ^^^^^^ expected `usize`, found `i16` + | +note: `-1_i16` cannot fit into type `usize` + --> $DIR/numeric-cast-no-fix.rs:62:15 + | +LL | x_usize > -1_i16; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:64:14 + | +LL | x_u128 > -1_i16; + | ^^^^^^ expected `u128`, found `i16` + | +note: `-1_i16` cannot fit into type `u128` + --> $DIR/numeric-cast-no-fix.rs:64:14 + | +LL | x_u128 > -1_i16; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:66:13 + | +LL | x_u64 > -1_i16; + | ^^^^^^ expected `u64`, found `i16` + | +note: `-1_i16` cannot fit into type `u64` + --> $DIR/numeric-cast-no-fix.rs:66:13 + | +LL | x_u64 > -1_i16; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:68:13 + | +LL | x_u32 > -1_i16; + | ^^^^^^ expected `u32`, found `i16` + | +note: `-1_i16` cannot fit into type `u32` + --> $DIR/numeric-cast-no-fix.rs:68:13 + | +LL | x_u32 > -1_i16; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:70:13 + | +LL | x_u16 > -1_i16; + | ^^^^^^ expected `u16`, found `i16` + | +note: `-1_i16` cannot fit into type `u16` + --> $DIR/numeric-cast-no-fix.rs:70:13 + | +LL | x_u16 > -1_i16; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:72:12 + | +LL | x_u8 > -1_i16; + | ^^^^^^ expected `u8`, found `i16` + | +help: you can convert `x_u8` from `u8` to `i16`, matching the type of `-1_i16` + | +LL | i16::from(x_u8) > -1_i16; + | ^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:75:15 + | +LL | x_usize > -1_i8; + | ^^^^^ expected `usize`, found `i8` + | +note: `-1_i8` cannot fit into type `usize` + --> $DIR/numeric-cast-no-fix.rs:75:15 + | +LL | x_usize > -1_i8; + | ^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:77:14 + | +LL | x_u128 > -1_i8; + | ^^^^^ expected `u128`, found `i8` + | +note: `-1_i8` cannot fit into type `u128` + --> $DIR/numeric-cast-no-fix.rs:77:14 + | +LL | x_u128 > -1_i8; + | ^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:79:13 + | +LL | x_u64 > -1_i8; + | ^^^^^ expected `u64`, found `i8` + | +note: `-1_i8` cannot fit into type `u64` + --> $DIR/numeric-cast-no-fix.rs:79:13 + | +LL | x_u64 > -1_i8; + | ^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:81:13 + | +LL | x_u32 > -1_i8; + | ^^^^^ expected `u32`, found `i8` + | +note: `-1_i8` cannot fit into type `u32` + --> $DIR/numeric-cast-no-fix.rs:81:13 + | +LL | x_u32 > -1_i8; + | ^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:83:13 + | +LL | x_u16 > -1_i8; + | ^^^^^ expected `u16`, found `i8` + | +note: `-1_i8` cannot fit into type `u16` + --> $DIR/numeric-cast-no-fix.rs:83:13 + | +LL | x_u16 > -1_i8; + | ^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:85:12 + | +LL | x_u8 > -1_i8; + | ^^^^^ expected `u8`, found `i8` + | +note: `-1_i8` cannot fit into type `u8` + --> $DIR/numeric-cast-no-fix.rs:85:12 + | +LL | x_u8 > -1_i8; + | ^^^^^ + +error: aborting due to 36 previous errors For more information about this error, try `rustc --explain E0308`. From cfdbbb5600c0a9f95dd662ce98f463d921e30cf0 Mon Sep 17 00:00:00 2001 From: Who? Me?! Date: Tue, 16 Jun 2020 09:41:05 -0500 Subject: [PATCH 48/60] format derives Co-authored-by: lzutao --- src/librustc_middle/ty/sty.rs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index 656c05b5520e8..cf11adb0285ac 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -208,19 +208,8 @@ pub enum TyKind<'tcx> { /// A type that is not publicly constructable. This prevents people from making `TyKind::Error` /// except through `tcx.err*()`. -#[derive( - Copy, - Clone, - Debug, - Eq, - Hash, - PartialEq, - PartialOrd, - Ord, - RustcEncodable, - RustcDecodable, - HashStable -)] +#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] +#[derive(RustcEncodable, RustcDecodable, HashStable)] pub struct DelaySpanBugEmitted(pub(super) ()); // `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger. From 4506a358ca4be0b3f7a1f320a677168d964ca9f7 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 16 Jun 2020 17:36:04 +0000 Subject: [PATCH 49/60] add header for rust specific feature --- src/rustllvm/PassWrapper.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 7586dd91ab68b..47c03069182a5 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -424,8 +424,7 @@ extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) { printf("Available features for this target:\n"); for (auto &Feature : FeatTable) printf(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc); - printf("\n"); - // Rust specific target features + printf("Rust-specific features:\n"); printf(" %-*s - %s.\n", MaxFeatLen, "crt-static", "Enables libraries with C Run-time Libraries(CRT) to be statically linked"); printf("\n"); From 9f50f84ef106c7f521d1322ec39562610339f74d Mon Sep 17 00:00:00 2001 From: root Date: Tue, 16 Jun 2020 18:14:32 +0000 Subject: [PATCH 50/60] break long line for formatting --- src/rustllvm/PassWrapper.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 47c03069182a5..16c2ac3322787 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -425,7 +425,11 @@ extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) { for (auto &Feature : FeatTable) printf(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc); printf("Rust-specific features:\n"); - printf(" %-*s - %s.\n", MaxFeatLen, "crt-static", "Enables libraries with C Run-time Libraries(CRT) to be statically linked"); + printf(" %-*s - %s.\n", + MaxFeatLen, + "crt-static", + "Enables libraries with C Run-time Libraries(CRT) to be statically linked" + ); printf("\n"); printf("Use +feature to enable a feature, or -feature to disable it.\n" From 457acbd5a80153fc06bca12663405c175fd9453f Mon Sep 17 00:00:00 2001 From: root Date: Tue, 16 Jun 2020 18:53:30 +0000 Subject: [PATCH 51/60] trim whitespace --- src/rustllvm/PassWrapper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 16c2ac3322787..28caf61a0197e 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -425,9 +425,9 @@ extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) { for (auto &Feature : FeatTable) printf(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc); printf("Rust-specific features:\n"); - printf(" %-*s - %s.\n", - MaxFeatLen, - "crt-static", + printf(" %-*s - %s.\n", + MaxFeatLen, + "crt-static", "Enables libraries with C Run-time Libraries(CRT) to be statically linked" ); printf("\n"); From af45d8a5bb4909e6908c4d7bba80eedcdcd7f961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 13 Jun 2020 12:08:32 -0700 Subject: [PATCH 52/60] Suggest new type param on single char ident Suggest new type parameter on single char uppercase ident even if it doesn't appear in a field's type parameter. Address comment in #72641. --- src/librustc_resolve/late/diagnostics.rs | 41 +++++++++++++++---- .../associated-types-eq-1.stderr | 11 ++++- .../type-not-found-in-adt-field.rs | 8 +++- .../type-not-found-in-adt-field.stderr | 16 ++++++-- 4 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 28ff89f66925e..694e2ac2a36a9 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -919,20 +919,45 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { &self, path: &[Segment], ) -> Option<(Span, &'static str, String, Applicability)> { - let ident = match path { - [segment] if !segment.has_args => segment.ident, + let (ident, span) = match path { + [segment] if !segment.has_args => (segment.ident.to_string(), segment.ident.span), _ => return None, }; - match ( - self.diagnostic_metadata.current_item, - self.diagnostic_metadata.currently_processing_generics, - ) { - (Some(Item { kind: ItemKind::Fn(..), ident, .. }), true) if ident.name == sym::main => { + let mut iter = ident.chars().map(|c| c.is_uppercase()); + let single_uppercase_char = + matches!(iter.next(), Some(true)) && matches!(iter.next(), None); + if !self.diagnostic_metadata.currently_processing_generics && !single_uppercase_char { + return None; + } + match (self.diagnostic_metadata.current_item, single_uppercase_char) { + (Some(Item { kind: ItemKind::Fn(..), ident, .. }), _) if ident.name == sym::main => { // Ignore `fn main()` as we don't want to suggest `fn main()` } - (Some(Item { kind, .. }), true) => { + ( + Some(Item { + kind: + kind @ ItemKind::Fn(..) + | kind @ ItemKind::Enum(..) + | kind @ ItemKind::Struct(..) + | kind @ ItemKind::Union(..), + .. + }), + true, + ) + | (Some(Item { kind, .. }), false) => { // Likely missing type parameter. if let Some(generics) = kind.generics() { + if span.overlaps(generics.span) { + // Avoid the following: + // error[E0405]: cannot find trait `A` in this scope + // --> $DIR/typo-suggestion-named-underscore.rs:CC:LL + // | + // L | fn foo(x: T) {} // Shouldn't suggest underscore + // | ^- help: you might be missing a type parameter: `, A` + // | | + // | not found in this scope + return None; + } let msg = "you might be missing a type parameter"; let (span, sugg) = if let [.., param] = &generics.params[..] { let span = if let [.., bound] = ¶m.bounds[..] { diff --git a/src/test/ui/associated-types/associated-types-eq-1.stderr b/src/test/ui/associated-types/associated-types-eq-1.stderr index 66c5f34644c01..53a45cf4e4f4d 100644 --- a/src/test/ui/associated-types/associated-types-eq-1.stderr +++ b/src/test/ui/associated-types/associated-types-eq-1.stderr @@ -4,7 +4,16 @@ error[E0412]: cannot find type `A` in this scope LL | fn foo2(x: I) { | - similarly named type parameter `I` defined here LL | let _: A = x.boo(); - | ^ help: a type parameter with a similar name exists: `I` + | ^ + | +help: a type parameter with a similar name exists + | +LL | let _: I = x.boo(); + | ^ +help: you might be missing a type parameter + | +LL | fn foo2(x: I) { + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/suggestions/type-not-found-in-adt-field.rs b/src/test/ui/suggestions/type-not-found-in-adt-field.rs index 6bd42472f5a55..4cbfe58d35703 100644 --- a/src/test/ui/suggestions/type-not-found-in-adt-field.rs +++ b/src/test/ui/suggestions/type-not-found-in-adt-field.rs @@ -1,5 +1,9 @@ -struct S { - m: Vec>, //~ ERROR cannot find type `Hashmap` in this scope +struct Struct { + m: Vec>, //~ ERROR cannot find type `Someunknownname` in this scope + //~^ NOTE not found in this scope +} +struct OtherStruct { //~ HELP you might be missing a type parameter + m: K, //~ ERROR cannot find type `K` in this scope //~^ NOTE not found in this scope } fn main() {} diff --git a/src/test/ui/suggestions/type-not-found-in-adt-field.stderr b/src/test/ui/suggestions/type-not-found-in-adt-field.stderr index cfad8c689d038..e990fb5ba1210 100644 --- a/src/test/ui/suggestions/type-not-found-in-adt-field.stderr +++ b/src/test/ui/suggestions/type-not-found-in-adt-field.stderr @@ -1,9 +1,17 @@ -error[E0412]: cannot find type `Hashmap` in this scope +error[E0412]: cannot find type `Someunknownname` in this scope --> $DIR/type-not-found-in-adt-field.rs:2:12 | -LL | m: Vec>, - | ^^^^^^^ not found in this scope +LL | m: Vec>, + | ^^^^^^^^^^^^^^^ not found in this scope -error: aborting due to previous error +error[E0412]: cannot find type `K` in this scope + --> $DIR/type-not-found-in-adt-field.rs:6:8 + | +LL | struct OtherStruct { + | - help: you might be missing a type parameter: `` +LL | m: K, + | ^ not found in this scope + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0412`. From d7277df3acc47d3bcf9e580e8991e0ebb7e66664 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Tue, 16 Jun 2020 20:05:55 -0700 Subject: [PATCH 53/60] fixup! Note numeric literals that can never fit in an expected type --- src/librustc_typeck/check/demand.rs | 2 +- .../ui/numeric/numeric-cast-no-fix.stderr | 150 +++--------------- 2 files changed, 26 insertions(+), 126 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 79fc9772423fd..bcfc0cf347cbc 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -834,7 +834,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // suggest a fallible conversion, check if the value can never fit in the // expected type. let msg = format!("`{}` cannot fit into type `{}`", src, expected_ty); - err.span_note(expr.span, &msg); + err.note(&msg); return; } else if in_const_context { // Do not recommend `into` or `try_into` in const contexts. diff --git a/src/test/ui/numeric/numeric-cast-no-fix.stderr b/src/test/ui/numeric/numeric-cast-no-fix.stderr index 6501e11fc64d6..4852e7047b47a 100644 --- a/src/test/ui/numeric/numeric-cast-no-fix.stderr +++ b/src/test/ui/numeric/numeric-cast-no-fix.stderr @@ -4,11 +4,7 @@ error[E0308]: mismatched types LL | x_usize > -1_isize; | ^^^^^^^^ expected `usize`, found `isize` | -note: `-1_isize` cannot fit into type `usize` - --> $DIR/numeric-cast-no-fix.rs:10:15 - | -LL | x_usize > -1_isize; - | ^^^^^^^^ + = note: `-1_isize` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:12:14 @@ -16,11 +12,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_isize; | ^^^^^^^^ expected `u128`, found `isize` | -note: `-1_isize` cannot fit into type `u128` - --> $DIR/numeric-cast-no-fix.rs:12:14 - | -LL | x_u128 > -1_isize; - | ^^^^^^^^ + = note: `-1_isize` cannot fit into type `u128` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:14:13 @@ -28,11 +20,7 @@ error[E0308]: mismatched types LL | x_u64 > -1_isize; | ^^^^^^^^ expected `u64`, found `isize` | -note: `-1_isize` cannot fit into type `u64` - --> $DIR/numeric-cast-no-fix.rs:14:13 - | -LL | x_u64 > -1_isize; - | ^^^^^^^^ + = note: `-1_isize` cannot fit into type `u64` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:16:13 @@ -40,11 +28,7 @@ error[E0308]: mismatched types LL | x_u32 > -1_isize; | ^^^^^^^^ expected `u32`, found `isize` | -note: `-1_isize` cannot fit into type `u32` - --> $DIR/numeric-cast-no-fix.rs:16:13 - | -LL | x_u32 > -1_isize; - | ^^^^^^^^ + = note: `-1_isize` cannot fit into type `u32` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:18:13 @@ -52,11 +36,7 @@ error[E0308]: mismatched types LL | x_u16 > -1_isize; | ^^^^^^^^ expected `u16`, found `isize` | -note: `-1_isize` cannot fit into type `u16` - --> $DIR/numeric-cast-no-fix.rs:18:13 - | -LL | x_u16 > -1_isize; - | ^^^^^^^^ + = note: `-1_isize` cannot fit into type `u16` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:20:12 @@ -75,11 +55,7 @@ error[E0308]: mismatched types LL | x_usize > -1_i128; | ^^^^^^^ expected `usize`, found `i128` | -note: `-1_i128` cannot fit into type `usize` - --> $DIR/numeric-cast-no-fix.rs:23:15 - | -LL | x_usize > -1_i128; - | ^^^^^^^ + = note: `-1_i128` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:25:14 @@ -87,11 +63,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_i128; | ^^^^^^^ expected `u128`, found `i128` | -note: `-1_i128` cannot fit into type `u128` - --> $DIR/numeric-cast-no-fix.rs:25:14 - | -LL | x_u128 > -1_i128; - | ^^^^^^^ + = note: `-1_i128` cannot fit into type `u128` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:27:13 @@ -143,11 +115,7 @@ error[E0308]: mismatched types LL | x_usize > -1_i64; | ^^^^^^ expected `usize`, found `i64` | -note: `-1_i64` cannot fit into type `usize` - --> $DIR/numeric-cast-no-fix.rs:36:15 - | -LL | x_usize > -1_i64; - | ^^^^^^ + = note: `-1_i64` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:38:14 @@ -155,11 +123,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_i64; | ^^^^^^ expected `u128`, found `i64` | -note: `-1_i64` cannot fit into type `u128` - --> $DIR/numeric-cast-no-fix.rs:38:14 - | -LL | x_u128 > -1_i64; - | ^^^^^^ + = note: `-1_i64` cannot fit into type `u128` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:40:13 @@ -167,11 +131,7 @@ error[E0308]: mismatched types LL | x_u64 > -1_i64; | ^^^^^^ expected `u64`, found `i64` | -note: `-1_i64` cannot fit into type `u64` - --> $DIR/numeric-cast-no-fix.rs:40:13 - | -LL | x_u64 > -1_i64; - | ^^^^^^ + = note: `-1_i64` cannot fit into type `u64` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:42:13 @@ -212,11 +172,7 @@ error[E0308]: mismatched types LL | x_usize > -1_i32; | ^^^^^^ expected `usize`, found `i32` | -note: `-1_i32` cannot fit into type `usize` - --> $DIR/numeric-cast-no-fix.rs:49:15 - | -LL | x_usize > -1_i32; - | ^^^^^^ + = note: `-1_i32` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:51:14 @@ -224,11 +180,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_i32; | ^^^^^^ expected `u128`, found `i32` | -note: `-1_i32` cannot fit into type `u128` - --> $DIR/numeric-cast-no-fix.rs:51:14 - | -LL | x_u128 > -1_i32; - | ^^^^^^ + = note: `-1_i32` cannot fit into type `u128` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:53:13 @@ -236,11 +188,7 @@ error[E0308]: mismatched types LL | x_u64 > -1_i32; | ^^^^^^ expected `u64`, found `i32` | -note: `-1_i32` cannot fit into type `u64` - --> $DIR/numeric-cast-no-fix.rs:53:13 - | -LL | x_u64 > -1_i32; - | ^^^^^^ + = note: `-1_i32` cannot fit into type `u64` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:55:13 @@ -248,11 +196,7 @@ error[E0308]: mismatched types LL | x_u32 > -1_i32; | ^^^^^^ expected `u32`, found `i32` | -note: `-1_i32` cannot fit into type `u32` - --> $DIR/numeric-cast-no-fix.rs:55:13 - | -LL | x_u32 > -1_i32; - | ^^^^^^ + = note: `-1_i32` cannot fit into type `u32` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:57:13 @@ -282,11 +226,7 @@ error[E0308]: mismatched types LL | x_usize > -1_i16; | ^^^^^^ expected `usize`, found `i16` | -note: `-1_i16` cannot fit into type `usize` - --> $DIR/numeric-cast-no-fix.rs:62:15 - | -LL | x_usize > -1_i16; - | ^^^^^^ + = note: `-1_i16` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:64:14 @@ -294,11 +234,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_i16; | ^^^^^^ expected `u128`, found `i16` | -note: `-1_i16` cannot fit into type `u128` - --> $DIR/numeric-cast-no-fix.rs:64:14 - | -LL | x_u128 > -1_i16; - | ^^^^^^ + = note: `-1_i16` cannot fit into type `u128` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:66:13 @@ -306,11 +242,7 @@ error[E0308]: mismatched types LL | x_u64 > -1_i16; | ^^^^^^ expected `u64`, found `i16` | -note: `-1_i16` cannot fit into type `u64` - --> $DIR/numeric-cast-no-fix.rs:66:13 - | -LL | x_u64 > -1_i16; - | ^^^^^^ + = note: `-1_i16` cannot fit into type `u64` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:68:13 @@ -318,11 +250,7 @@ error[E0308]: mismatched types LL | x_u32 > -1_i16; | ^^^^^^ expected `u32`, found `i16` | -note: `-1_i16` cannot fit into type `u32` - --> $DIR/numeric-cast-no-fix.rs:68:13 - | -LL | x_u32 > -1_i16; - | ^^^^^^ + = note: `-1_i16` cannot fit into type `u32` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:70:13 @@ -330,11 +258,7 @@ error[E0308]: mismatched types LL | x_u16 > -1_i16; | ^^^^^^ expected `u16`, found `i16` | -note: `-1_i16` cannot fit into type `u16` - --> $DIR/numeric-cast-no-fix.rs:70:13 - | -LL | x_u16 > -1_i16; - | ^^^^^^ + = note: `-1_i16` cannot fit into type `u16` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:72:12 @@ -353,11 +277,7 @@ error[E0308]: mismatched types LL | x_usize > -1_i8; | ^^^^^ expected `usize`, found `i8` | -note: `-1_i8` cannot fit into type `usize` - --> $DIR/numeric-cast-no-fix.rs:75:15 - | -LL | x_usize > -1_i8; - | ^^^^^ + = note: `-1_i8` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:77:14 @@ -365,11 +285,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_i8; | ^^^^^ expected `u128`, found `i8` | -note: `-1_i8` cannot fit into type `u128` - --> $DIR/numeric-cast-no-fix.rs:77:14 - | -LL | x_u128 > -1_i8; - | ^^^^^ + = note: `-1_i8` cannot fit into type `u128` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:79:13 @@ -377,11 +293,7 @@ error[E0308]: mismatched types LL | x_u64 > -1_i8; | ^^^^^ expected `u64`, found `i8` | -note: `-1_i8` cannot fit into type `u64` - --> $DIR/numeric-cast-no-fix.rs:79:13 - | -LL | x_u64 > -1_i8; - | ^^^^^ + = note: `-1_i8` cannot fit into type `u64` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:81:13 @@ -389,11 +301,7 @@ error[E0308]: mismatched types LL | x_u32 > -1_i8; | ^^^^^ expected `u32`, found `i8` | -note: `-1_i8` cannot fit into type `u32` - --> $DIR/numeric-cast-no-fix.rs:81:13 - | -LL | x_u32 > -1_i8; - | ^^^^^ + = note: `-1_i8` cannot fit into type `u32` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:83:13 @@ -401,11 +309,7 @@ error[E0308]: mismatched types LL | x_u16 > -1_i8; | ^^^^^ expected `u16`, found `i8` | -note: `-1_i8` cannot fit into type `u16` - --> $DIR/numeric-cast-no-fix.rs:83:13 - | -LL | x_u16 > -1_i8; - | ^^^^^ + = note: `-1_i8` cannot fit into type `u16` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:85:12 @@ -413,11 +317,7 @@ error[E0308]: mismatched types LL | x_u8 > -1_i8; | ^^^^^ expected `u8`, found `i8` | -note: `-1_i8` cannot fit into type `u8` - --> $DIR/numeric-cast-no-fix.rs:85:12 - | -LL | x_u8 > -1_i8; - | ^^^^^ + = note: `-1_i8` cannot fit into type `u8` error: aborting due to 36 previous errors From caffb28ece818ce87f1c7573992cae4210544015 Mon Sep 17 00:00:00 2001 From: asrar Date: Wed, 17 Jun 2020 10:31:46 +0530 Subject: [PATCH 54/60] add blank line bw sections Separate target features from rust ones with a blank line Co-authored-by: Josh Stone --- src/rustllvm/PassWrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 28caf61a0197e..323bd26c698a3 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -424,7 +424,7 @@ extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) { printf("Available features for this target:\n"); for (auto &Feature : FeatTable) printf(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc); - printf("Rust-specific features:\n"); + printf("\nRust-specific features:\n"); printf(" %-*s - %s.\n", MaxFeatLen, "crt-static", From 7a89a338239c0d551279b9183b9c2c1a1e7d7e74 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Tue, 16 Jun 2020 23:10:41 -0700 Subject: [PATCH 55/60] fixup! Note numeric literals that can never fit in an expected type --- src/test/ui/repeat_count.stderr | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr index 34641be22150f..2eab3ebc7687d 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat_count.stderr @@ -40,11 +40,7 @@ error[E0308]: mismatched types LL | let f = [0; -4_isize]; | ^^^^^^^^ expected `usize`, found `isize` | -note: `-4_isize` cannot fit into type `usize` - --> $DIR/repeat_count.rs:19:17 - | -LL | let f = [0; -4_isize]; - | ^^^^^^^^ + = note: `-4_isize` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/repeat_count.rs:22:23 @@ -52,11 +48,7 @@ error[E0308]: mismatched types LL | let f = [0_usize; -1_isize]; | ^^^^^^^^ expected `usize`, found `isize` | -note: `-1_isize` cannot fit into type `usize` - --> $DIR/repeat_count.rs:22:23 - | -LL | let f = [0_usize; -1_isize]; - | ^^^^^^^^ + = note: `-1_isize` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/repeat_count.rs:25:17 From b60cefee0addb02b5bd146893d358bb52bc829e2 Mon Sep 17 00:00:00 2001 From: Nathan West Date: Wed, 17 Jun 2020 17:56:25 -0400 Subject: [PATCH 56/60] Removed write_fmt forwarding, to fix recursive borrow issues --- src/libstd/io/stdio.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index cce9a0dc7a43b..b41f0c2f82d0d 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -652,9 +652,6 @@ impl Write for Stdout { fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { self.lock().write_all(buf) } - fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> { - self.lock().write_fmt(args) - } fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { self.lock().write_all_vectored(bufs) } @@ -680,9 +677,6 @@ impl Write for StdoutLock<'_> { fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { self.inner.borrow_mut().write_all_vectored(bufs) } - fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { - self.inner.borrow_mut().write_fmt(fmt) - } } #[stable(feature = "std_debug", since = "1.16.0")] @@ -838,9 +832,6 @@ impl Write for Stderr { fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { self.lock().write_all(buf) } - fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> { - self.lock().write_fmt(args) - } fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { self.lock().write_all_vectored(bufs) } @@ -866,9 +857,6 @@ impl Write for StderrLock<'_> { fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { self.inner.borrow_mut().write_all_vectored(bufs) } - fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { - self.inner.borrow_mut().write_fmt(fmt) - } } #[stable(feature = "std_debug", since = "1.16.0")] From 8d1a3801faa199acb2a86580247afd672bd838f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 17 Jun 2020 16:29:03 -0700 Subject: [PATCH 57/60] review comments --- src/librustc_resolve/build_reduced_graph.rs | 2 +- src/librustc_resolve/late/diagnostics.rs | 4 +++- src/librustc_resolve/lib.rs | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 8661af6d7a1de..ef2389fcefafc 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -485,7 +485,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { module_path.push(Segment { ident: Ident { name: kw::PathRoot, span: source.ident.span }, id: Some(self.r.next_node_id()), - has_args: false, + has_generic_args: false, }); source.ident.name = crate_name; } diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 694e2ac2a36a9..a6e016e9e6a22 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -920,7 +920,9 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { path: &[Segment], ) -> Option<(Span, &'static str, String, Applicability)> { let (ident, span) = match path { - [segment] if !segment.has_args => (segment.ident.to_string(), segment.ident.span), + [segment] if !segment.has_generic_args => { + (segment.ident.to_string(), segment.ident.span) + } _ => return None, }; let mut iter = ident.chars().map(|c| c.is_uppercase()); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index f7ec919fa04e3..a30e5cc1ab601 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -233,7 +233,7 @@ pub struct Segment { id: Option, /// Signals whether this `PathSegment` has generic arguments. Used to avoid providing /// nonsensical suggestions. - has_args: bool, + has_generic_args: bool, } impl Segment { @@ -242,7 +242,7 @@ impl Segment { } fn from_ident(ident: Ident) -> Segment { - Segment { ident, id: None, has_args: false } + Segment { ident, id: None, has_generic_args: false } } fn names_to_string(segments: &[Segment]) -> String { @@ -252,7 +252,7 @@ impl Segment { impl<'a> From<&'a ast::PathSegment> for Segment { fn from(seg: &'a ast::PathSegment) -> Segment { - Segment { ident: seg.ident, id: Some(seg.id), has_args: seg.args.is_some() } + Segment { ident: seg.ident, id: Some(seg.id), has_generic_args: seg.args.is_some() } } } @@ -2019,7 +2019,7 @@ impl<'a> Resolver<'a> { path, opt_ns, record_used, path_span, crate_lint, ); - for (i, &Segment { ident, id, has_args: _ }) in path.iter().enumerate() { + for (i, &Segment { ident, id, has_generic_args: _ }) in path.iter().enumerate() { debug!("resolve_path ident {} {:?} {:?}", i, ident, id); let record_segment_res = |this: &mut Self, res| { if record_used { From 14d385bedeeec7fcb48f4c9bb881b1cdae011da0 Mon Sep 17 00:00:00 2001 From: Nathan West Date: Wed, 17 Jun 2020 19:48:51 -0400 Subject: [PATCH 58/60] Restore some write_fmts --- src/libstd/io/stdio.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index b41f0c2f82d0d..d6b7ad6254a8c 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -655,6 +655,9 @@ impl Write for Stdout { fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { self.lock().write_all_vectored(bufs) } + fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> { + self.lock().write_fmt(args) + } } #[stable(feature = "rust1", since = "1.0.0")] impl Write for StdoutLock<'_> { @@ -835,6 +838,9 @@ impl Write for Stderr { fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { self.lock().write_all_vectored(bufs) } + fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> io::Result<()> { + self.lock().write_fmt(args) + } } #[stable(feature = "rust1", since = "1.0.0")] impl Write for StderrLock<'_> { From e5c5df8f9c395e340d25ae70f828504148807af4 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Thu, 18 Jun 2020 02:54:35 +0000 Subject: [PATCH 59/60] Add specialization of `ToString for char` --- src/liballoc/string.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 0378ff5362a8b..fa5757a0b1138 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -2228,6 +2228,14 @@ impl ToString for T { } } +#[stable(feature = "char_to_string_specialization", since = "1.46.0")] +impl ToString for char { + #[inline] + fn to_string(&self) -> String { + String::from(self.encode_utf8(&mut [0; 4])) + } +} + #[stable(feature = "str_to_string_specialization", since = "1.9.0")] impl ToString for str { #[inline] From d134870bd4bedefaeb07c88a8d24a520bce639cf Mon Sep 17 00:00:00 2001 From: qy3u <65523321+qy3u@users.noreply.github.com> Date: Thu, 18 Jun 2020 10:13:35 +0800 Subject: [PATCH 60/60] Document format correction --- src/libstd/sys/unix/ext/fs.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index 732cd677a1859..e4d714936047e 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -242,7 +242,8 @@ pub trait PermissionsExt { /// let permissions = metadata.permissions(); /// /// println!("permissions: {:o}", permissions.mode()); - /// Ok(()) } + /// Ok(()) + /// } /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn mode(&self) -> u32; @@ -262,7 +263,8 @@ pub trait PermissionsExt { /// /// permissions.set_mode(0o644); // Read/write for owner and read for others. /// assert_eq!(permissions.mode(), 0o644); - /// Ok(()) } + /// Ok(()) + /// } /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn set_mode(&mut self, mode: u32);