From aff4cd5ce725602249c2554b04b1066d09acd31e Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 14 Jun 2021 01:49:37 +0800 Subject: [PATCH 01/24] Report Layout of enum variants Followup of #83501, Fixes #86253. --- src/librustdoc/html/render/print_item.rs | 36 +++++++++++++++++++++++- src/test/rustdoc/type-layout.rs | 6 ++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 8f4857a693928..f362a288bcbf9 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -7,11 +7,13 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; +use rustc_middle::bug; use rustc_middle::middle::stability; use rustc_middle::ty::layout::LayoutError; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{Adt, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; +use rustc_target::abi::Variants; use super::{ collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_strs, notable_traits_decl, @@ -1636,6 +1638,38 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { pl = if bytes == 1 { "" } else { "s" }, ); } + if let Variants::Multiple { variants, .. } = &ty_layout.layout.variants { + if !variants.is_empty() { + w.write_str( + "

\ + Size for each variant:\ +

"); + } + } } // This kind of layout error can occur with valid code, e.g. if you try to // get the layout of a generic type such as `Vec`. diff --git a/src/test/rustdoc/type-layout.rs b/src/test/rustdoc/type-layout.rs index 272911de6815b..f398dd776d9c6 100644 --- a/src/test/rustdoc/type-layout.rs +++ b/src/test/rustdoc/type-layout.rs @@ -52,3 +52,9 @@ pub struct Unsized([u8]); // @!has type_layout/trait.MyTrait.html 'Size: ' pub trait MyTrait {} + +// @has type_layout/enum.Variants.html '1 byte' +pub enum Variants { + A, + B(u8), +} From c349b79029770e39963fadf5021cfa6a6cfe5472 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 9 Jul 2021 22:25:46 +0800 Subject: [PATCH 02/24] Apply suggestions --- src/librustdoc/html/render/print_item.rs | 44 ++++++++++-------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index f362a288bcbf9..b25323c4e0a74 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -7,13 +7,13 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; -use rustc_middle::bug; use rustc_middle::middle::stability; +use rustc_middle::span_bug; use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::{Adt, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_target::abi::Variants; +use rustc_target::abi::{Layout, Variants}; use super::{ collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_strs, notable_traits_decl, @@ -1606,6 +1606,15 @@ fn document_non_exhaustive(w: &mut Buffer, item: &clean::Item) { } fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { + fn write_size_of_layout(w: &mut Buffer, layout: &Layout) { + if layout.abi.is_unsized() { + write!(w, "(unsized)"); + } else { + let bytes = layout.size.bytes(); + write!(w, "{size} byte{pl}", size = bytes, pl = if bytes == 1 { "" } else { "s" },); + } + } + if !cx.shared.show_type_layout { return; } @@ -1627,17 +1636,9 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { “Type Layout” \ chapter for details on type layout guarantees.

" ); - if ty_layout.layout.abi.is_unsized() { - writeln!(w, "

Size: (unsized)

"); - } else { - let bytes = ty_layout.layout.size.bytes(); - writeln!( - w, - "

Size: {size} byte{pl}

", - size = bytes, - pl = if bytes == 1 { "" } else { "s" }, - ); - } + w.write_str("

Size: "); + write_size_of_layout(w, ty_layout.layout); + writeln!(w, "

"); if let Variants::Multiple { variants, .. } = &ty_layout.layout.variants { if !variants.is_empty() { w.write_str( @@ -1649,23 +1650,14 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { let adt = if let Adt(adt, _) = ty_layout.ty.kind() { adt } else { - bug!("not an adt") + span_bug!(tcx.def_span(ty_def_id), "not an adt") }; for (index, layout) in variants.iter_enumerated() { let ident = adt.variants[index].ident; - if layout.abi.is_unsized() { - writeln!(w, "
  • {name} (unsized)
  • ", name = ident); - } else { - let bytes = layout.size.bytes(); - writeln!( - w, - "
  • {name}: {size} byte{pl}
  • ", - name = ident, - size = bytes, - pl = if bytes == 1 { "" } else { "s" }, - ); - } + write!(w, "
  • {name} ", name = ident); + write_size_of_layout(w, layout); + writeln!(w, "
  • "); } w.write_str("

    "); } From 8096910b54920f4c3334de555ee9dd265ed6f49d Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 10 Jul 2021 21:35:40 +0800 Subject: [PATCH 03/24] Report variant size without the discriminant --- src/librustdoc/html/render/print_item.rs | 20 +++++++++++++------- src/test/rustdoc/type-layout.rs | 3 ++- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index b25323c4e0a74..4e90e611a16ae 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::{Adt, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_target::abi::{Layout, Variants}; +use rustc_target::abi::{Layout, Primitive, Variants}; use super::{ collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_strs, notable_traits_decl, @@ -1606,11 +1606,11 @@ fn document_non_exhaustive(w: &mut Buffer, item: &clean::Item) { } fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { - fn write_size_of_layout(w: &mut Buffer, layout: &Layout) { + fn write_size_of_layout(w: &mut Buffer, layout: &Layout, tag_size: u64) { if layout.abi.is_unsized() { write!(w, "(unsized)"); } else { - let bytes = layout.size.bytes(); + let bytes = layout.size.bytes() - tag_size; write!(w, "{size} byte{pl}", size = bytes, pl = if bytes == 1 { "" } else { "s" },); } } @@ -1637,9 +1637,9 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { chapter for details on type layout guarantees.

    " ); w.write_str("

    Size: "); - write_size_of_layout(w, ty_layout.layout); + write_size_of_layout(w, ty_layout.layout, 0); writeln!(w, "

    "); - if let Variants::Multiple { variants, .. } = &ty_layout.layout.variants { + if let Variants::Multiple { variants, tag, .. } = &ty_layout.layout.variants { if !variants.is_empty() { w.write_str( "

    \ @@ -1653,10 +1653,16 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { span_bug!(tcx.def_span(ty_def_id), "not an adt") }; + let tag_size = if let Primitive::Int(i, _) = tag.value { + i.size().bytes() + } else { + span_bug!(tcx.def_span(ty_def_id), "tag is not int") + }; + for (index, layout) in variants.iter_enumerated() { let ident = adt.variants[index].ident; - write!(w, "

  • {name} ", name = ident); - write_size_of_layout(w, layout); + write!(w, "
  • {name}: ", name = ident); + write_size_of_layout(w, layout, tag_size); writeln!(w, "
  • "); } w.write_str("

    "); diff --git a/src/test/rustdoc/type-layout.rs b/src/test/rustdoc/type-layout.rs index f398dd776d9c6..bc1b65c46e24a 100644 --- a/src/test/rustdoc/type-layout.rs +++ b/src/test/rustdoc/type-layout.rs @@ -53,7 +53,8 @@ pub struct Unsized([u8]); // @!has type_layout/trait.MyTrait.html 'Size: ' pub trait MyTrait {} -// @has type_layout/enum.Variants.html '1 byte' +// @has type_layout/enum.Variants.html 'A: 0 bytes' +// @has - 'B: 1 byte' pub enum Variants { A, B(u8), From 5f1505e7f13fdea3f2d626059010cf26edfce4f8 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 31 Aug 2021 05:24:08 +0000 Subject: [PATCH 04/24] Apply suggestions --- src/librustdoc/html/render/print_item.rs | 5 ++--- src/test/rustdoc/type-layout.rs | 4 +++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 4e90e611a16ae..6054073bf79b2 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1642,8 +1642,7 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { if let Variants::Multiple { variants, tag, .. } = &ty_layout.layout.variants { if !variants.is_empty() { w.write_str( - "

    \ - Size for each variant:\ + "

    Size for each variant:

    \
      ", ); @@ -1665,7 +1664,7 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { write_size_of_layout(w, layout, tag_size); writeln!(w, ""); } - w.write_str("

    "); + w.write_str(""); } } } diff --git a/src/test/rustdoc/type-layout.rs b/src/test/rustdoc/type-layout.rs index bc1b65c46e24a..8c4f4f8fc98e6 100644 --- a/src/test/rustdoc/type-layout.rs +++ b/src/test/rustdoc/type-layout.rs @@ -53,7 +53,9 @@ pub struct Unsized([u8]); // @!has type_layout/trait.MyTrait.html 'Size: ' pub trait MyTrait {} -// @has type_layout/enum.Variants.html 'A: 0 bytes' +// @has type_layout/enum.Variants.html 'Size: ' +// @has - '2 bytes' +// @has - 'A: 0 bytes' // @has - 'B: 1 byte' pub enum Variants { A, From 6cfe98f1962c442504a0b56f260620f1bccd7601 Mon Sep 17 00:00:00 2001 From: Theodore Luo Wang Date: Tue, 31 Aug 2021 23:07:58 -0400 Subject: [PATCH 05/24] Improve error checking on unary plus --- compiler/rustc_parse/src/parser/expr.rs | 12 +++ .../did_you_mean/issue-88276-unary-plus.fixed | 13 +++ .../ui/did_you_mean/issue-88276-unary-plus.rs | 13 +++ .../issue-88276-unary-plus.stderr | 83 +++++++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 src/test/ui/did_you_mean/issue-88276-unary-plus.fixed create mode 100644 src/test/ui/did_you_mean/issue-88276-unary-plus.rs create mode 100644 src/test/ui/did_you_mean/issue-88276-unary-plus.stderr diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 326c8f81ffbf9..88dae48a9013d 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -23,6 +23,8 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Pos}; use std::mem; +use tracing::debug; + /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression /// dropped into the token stream, which happens while parsing the result of /// macro expansion). Placement of these is not as complex as I feared it would @@ -355,6 +357,7 @@ impl<'a> Parser<'a> { /// but the next token implies this should be parsed as an expression. /// For example: `if let Some(x) = x { x } else { 0 } / 2`. fn error_found_expr_would_be_stmt(&self, lhs: &Expr) { + debug!("error_found_expr_would_be_stmt(lhs: {:?})", lhs); let mut err = self.struct_span_err( self.token.span, &format!("expected expression, found `{}`", pprust::token_to_string(&self.token),), @@ -516,6 +519,15 @@ impl<'a> Parser<'a> { token::BinOp(token::And) | token::AndAnd => { make_it!(this, attrs, |this, _| this.parse_borrow_expr(lo)) } + token::BinOp(token::Plus) => { + this.struct_span_err(lo, "leading `+` is not supported") + .span_label(lo, "unexpected `+`") + .span_suggestion_short(lo, "remove the `+`", "".to_string(), Applicability::MachineApplicable) + .emit(); + this.bump(); + + this.parse_prefix_expr(None) + } // `+expr` token::Ident(..) if this.token.is_keyword(kw::Box) => { make_it!(this, attrs, |this, _| this.parse_box_expr(lo)) } diff --git a/src/test/ui/did_you_mean/issue-88276-unary-plus.fixed b/src/test/ui/did_you_mean/issue-88276-unary-plus.fixed new file mode 100644 index 0000000000000..4bd248663b884 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-88276-unary-plus.fixed @@ -0,0 +1,13 @@ +// run-rustfix +#[allow(unused_parens)] +fn main() { + let _ = 1; //~ ERROR leading `+` is not supported + let _ = -(1+2)*3; //~ ERROR leading `+` is not supported + let _ = -(1+2)*3; //~ ERROR leading `+` is not supported + //~| ERROR leading `+` is not supported + let _ = --(1+2)*3; //~ ERROR leading `+` is not supported + //~| ERROR leading `+` is not supported + let _ = (&"hello"); //~ ERROR leading `+` is not supported + let _ = [3, 4+6]; //~ ERROR leading `+` is not supported + //~| ERROR leading `+` is not supported +} diff --git a/src/test/ui/did_you_mean/issue-88276-unary-plus.rs b/src/test/ui/did_you_mean/issue-88276-unary-plus.rs new file mode 100644 index 0000000000000..e2cce677b4755 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-88276-unary-plus.rs @@ -0,0 +1,13 @@ +// run-rustfix +#[allow(unused_parens)] +fn main() { + let _ = +1; //~ ERROR leading `+` is not supported + let _ = -+(1+2)*3; //~ ERROR leading `+` is not supported + let _ = +-+(1+2)*3; //~ ERROR leading `+` is not supported + //~| ERROR leading `+` is not supported + let _ = -+-+(1+2)*3; //~ ERROR leading `+` is not supported + //~| ERROR leading `+` is not supported + let _ = (+&"hello"); //~ ERROR leading `+` is not supported + let _ = +[+3, 4+6]; //~ ERROR leading `+` is not supported + //~| ERROR leading `+` is not supported +} diff --git a/src/test/ui/did_you_mean/issue-88276-unary-plus.stderr b/src/test/ui/did_you_mean/issue-88276-unary-plus.stderr new file mode 100644 index 0000000000000..9c1227d7c351a --- /dev/null +++ b/src/test/ui/did_you_mean/issue-88276-unary-plus.stderr @@ -0,0 +1,83 @@ +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:4:13 + | +LL | let _ = +1; + | ^ + | | + | unexpected `+` + | help: remove the `+` + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:5:14 + | +LL | let _ = -+(1+2)*3; + | ^ + | | + | unexpected `+` + | help: remove the `+` + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:6:13 + | +LL | let _ = +-+(1+2)*3; + | ^ + | | + | unexpected `+` + | help: remove the `+` + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:6:15 + | +LL | let _ = +-+(1+2)*3; + | ^ + | | + | unexpected `+` + | help: remove the `+` + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:8:14 + | +LL | let _ = -+-+(1+2)*3; + | ^ + | | + | unexpected `+` + | help: remove the `+` + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:8:16 + | +LL | let _ = -+-+(1+2)*3; + | ^ + | | + | unexpected `+` + | help: remove the `+` + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:10:14 + | +LL | let _ = (+&"hello"); + | ^ + | | + | unexpected `+` + | help: remove the `+` + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:11:13 + | +LL | let _ = +[+3, 4+6]; + | ^ + | | + | unexpected `+` + | help: remove the `+` + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:11:15 + | +LL | let _ = +[+3, 4+6]; + | ^ + | | + | unexpected `+` + | help: remove the `+` + +error: aborting due to 9 previous errors + From e7fb98e7258557034f0d0caf81a53b0070a87297 Mon Sep 17 00:00:00 2001 From: Theodore Luo Wang Date: Tue, 31 Aug 2021 23:09:43 -0400 Subject: [PATCH 06/24] Apply formatting --- compiler/rustc_parse/src/parser/expr.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 88dae48a9013d..43de53e87231f 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -522,7 +522,12 @@ impl<'a> Parser<'a> { token::BinOp(token::Plus) => { this.struct_span_err(lo, "leading `+` is not supported") .span_label(lo, "unexpected `+`") - .span_suggestion_short(lo, "remove the `+`", "".to_string(), Applicability::MachineApplicable) + .span_suggestion_short( + lo, + "remove the `+`", + "".to_string(), + Applicability::MachineApplicable, + ) .emit(); this.bump(); From 5a863d594c725d09ab8f0df5caba374d72200976 Mon Sep 17 00:00:00 2001 From: Theodore Luo Wang Date: Wed, 1 Sep 2021 11:54:06 -0400 Subject: [PATCH 07/24] Add checks for a block before a unary plus. Fix failing tests --- compiler/rustc_parse/src/parser/expr.rs | 30 ++++++++--- compiler/rustc_parse/src/parser/stmt.rs | 3 ++ .../ui/associated-types/issue-36499.stderr | 7 ++- src/test/ui/parser/expr-as-stmt.fixed | 6 +-- src/test/ui/parser/expr-as-stmt.rs | 6 +-- src/test/ui/parser/expr-as-stmt.stderr | 12 ++--- .../issue-88276-unary-plus.fixed | 4 +- .../issue-88276-unary-plus.rs | 4 +- .../issue-88276-unary-plus.stderr | 54 +++++++++---------- 9 files changed, 73 insertions(+), 53 deletions(-) rename src/test/ui/{did_you_mean => parser}/issue-88276-unary-plus.fixed (78%) rename src/test/ui/{did_you_mean => parser}/issue-88276-unary-plus.rs (78%) rename src/test/ui/{did_you_mean => parser}/issue-88276-unary-plus.stderr (61%) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 43de53e87231f..c887f9fe0cf59 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -165,9 +165,12 @@ impl<'a> Parser<'a> { if [token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token.kind) { return self.parse_prefix_range_expr(attrs); } else { - self.parse_prefix_expr(attrs)? + let result = self.parse_prefix_expr(attrs); + debug!("parse_prefix_expr result: {:?}", &result); + result? } }; + debug!("parse_assoc_expr_with(lhs = {:?})", &lhs); let last_type_ascription_set = self.last_type_ascription.is_some(); if !self.should_continue_as_assoc_expr(&lhs) { @@ -175,8 +178,11 @@ impl<'a> Parser<'a> { return Ok(lhs); } + debug!("continue_as_assoc_expr"); + self.expected_tokens.push(TokenType::Operator); while let Some(op) = self.check_assoc_op() { + debug!("op: {:?}", op); // Adjust the span for interpolated LHS to point to the `$lhs` token // and not to what it refers to. let lhs_span = match self.prev_token.kind { @@ -520,17 +526,25 @@ impl<'a> Parser<'a> { make_it!(this, attrs, |this, _| this.parse_borrow_expr(lo)) } token::BinOp(token::Plus) => { - this.struct_span_err(lo, "leading `+` is not supported") - .span_label(lo, "unexpected `+`") - .span_suggestion_short( + debug!("leading + detected: {:?}", lo); + let mut err = this.struct_span_err(lo, "leading `+` is not supported"); + err.span_label(lo, "unexpected `+`"); + + // a block on the LHS might have been intended to be an expression instead + let sp = this.sess.source_map().start_point(lo); + if let Some(sp) = this.sess.ambiguous_block_expr_parse.borrow().get(&sp) { + this.sess.expr_parentheses_needed(&mut err, *sp); + } else { + err.span_suggestion( lo, - "remove the `+`", + "try removing the `+`", "".to_string(), Applicability::MachineApplicable, - ) - .emit(); - this.bump(); + ); + } + err.emit(); + this.bump(); this.parse_prefix_expr(None) } // `+expr` token::Ident(..) if this.token.is_keyword(kw::Box) => { diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 85515bd2a6314..329b60f9a8711 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -21,6 +21,8 @@ use rustc_span::symbol::{kw, sym}; use std::mem; +use tracing::debug; + impl<'a> Parser<'a> { /// Parses a statement. This stops just before trailing semicolons on everything but items. /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed. @@ -418,6 +420,7 @@ impl<'a> Parser<'a> { if self.token == token::Eof { break; } + debug!("parsing statements, stmts: {:?}", &stmts); let stmt = match self.parse_full_stmt(recover) { Err(mut err) if recover.yes() => { self.maybe_annotate_with_ascription(&mut err, false); diff --git a/src/test/ui/associated-types/issue-36499.stderr b/src/test/ui/associated-types/issue-36499.stderr index ff450f60acc68..990ef09e3f742 100644 --- a/src/test/ui/associated-types/issue-36499.stderr +++ b/src/test/ui/associated-types/issue-36499.stderr @@ -1,8 +1,11 @@ -error: expected expression, found `+` +error: leading `+` is not supported --> $DIR/issue-36499.rs:4:9 | LL | 2 + +2; - | ^ expected expression + | ^ + | | + | unexpected `+` + | help: try removing the `+` error: aborting due to previous error diff --git a/src/test/ui/parser/expr-as-stmt.fixed b/src/test/ui/parser/expr-as-stmt.fixed index c217ab9774fd2..79d73090a0420 100644 --- a/src/test/ui/parser/expr-as-stmt.fixed +++ b/src/test/ui/parser/expr-as-stmt.fixed @@ -5,18 +5,18 @@ #![allow(unused_must_use)] fn foo() -> i32 { - ({2}) + {2} //~ ERROR expected expression, found `+` + ({2}) + {2} //~ ERROR leading `+` is not supported //~^ ERROR mismatched types } fn bar() -> i32 { - ({2}) + 2 //~ ERROR expected expression, found `+` + ({2}) + 2 //~ ERROR leading `+` is not supported //~^ ERROR mismatched types } fn zul() -> u32 { let foo = 3; - ({ 42 }) + foo; //~ ERROR expected expression, found `+` + ({ 42 }) + foo; //~ ERROR leading `+` is not supported //~^ ERROR mismatched types 32 } diff --git a/src/test/ui/parser/expr-as-stmt.rs b/src/test/ui/parser/expr-as-stmt.rs index b04025faaec63..8698f99b81a41 100644 --- a/src/test/ui/parser/expr-as-stmt.rs +++ b/src/test/ui/parser/expr-as-stmt.rs @@ -5,18 +5,18 @@ #![allow(unused_must_use)] fn foo() -> i32 { - {2} + {2} //~ ERROR expected expression, found `+` + {2} + {2} //~ ERROR leading `+` is not supported //~^ ERROR mismatched types } fn bar() -> i32 { - {2} + 2 //~ ERROR expected expression, found `+` + {2} + 2 //~ ERROR leading `+` is not supported //~^ ERROR mismatched types } fn zul() -> u32 { let foo = 3; - { 42 } + foo; //~ ERROR expected expression, found `+` + { 42 } + foo; //~ ERROR leading `+` is not supported //~^ ERROR mismatched types 32 } diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr index ba5cd01abfcc7..91f97c4662a97 100644 --- a/src/test/ui/parser/expr-as-stmt.stderr +++ b/src/test/ui/parser/expr-as-stmt.stderr @@ -1,30 +1,30 @@ -error: expected expression, found `+` +error: leading `+` is not supported --> $DIR/expr-as-stmt.rs:8:9 | LL | {2} + {2} - | ^ expected expression + | ^ unexpected `+` | help: parentheses are required to parse this as an expression | LL | ({2}) + {2} | + + -error: expected expression, found `+` +error: leading `+` is not supported --> $DIR/expr-as-stmt.rs:13:9 | LL | {2} + 2 - | ^ expected expression + | ^ unexpected `+` | help: parentheses are required to parse this as an expression | LL | ({2}) + 2 | + + -error: expected expression, found `+` +error: leading `+` is not supported --> $DIR/expr-as-stmt.rs:19:12 | LL | { 42 } + foo; - | ^ expected expression + | ^ unexpected `+` | help: parentheses are required to parse this as an expression | diff --git a/src/test/ui/did_you_mean/issue-88276-unary-plus.fixed b/src/test/ui/parser/issue-88276-unary-plus.fixed similarity index 78% rename from src/test/ui/did_you_mean/issue-88276-unary-plus.fixed rename to src/test/ui/parser/issue-88276-unary-plus.fixed index 4bd248663b884..279cdb5060a42 100644 --- a/src/test/ui/did_you_mean/issue-88276-unary-plus.fixed +++ b/src/test/ui/parser/issue-88276-unary-plus.fixed @@ -3,10 +3,10 @@ fn main() { let _ = 1; //~ ERROR leading `+` is not supported let _ = -(1+2)*3; //~ ERROR leading `+` is not supported - let _ = -(1+2)*3; //~ ERROR leading `+` is not supported - //~| ERROR leading `+` is not supported let _ = --(1+2)*3; //~ ERROR leading `+` is not supported //~| ERROR leading `+` is not supported + let _ = (1 + 2) * 3; //~ ERROR leading `+` is not supported + //~| ERROR leading `+` is not supported let _ = (&"hello"); //~ ERROR leading `+` is not supported let _ = [3, 4+6]; //~ ERROR leading `+` is not supported //~| ERROR leading `+` is not supported diff --git a/src/test/ui/did_you_mean/issue-88276-unary-plus.rs b/src/test/ui/parser/issue-88276-unary-plus.rs similarity index 78% rename from src/test/ui/did_you_mean/issue-88276-unary-plus.rs rename to src/test/ui/parser/issue-88276-unary-plus.rs index e2cce677b4755..a72dad4dc7198 100644 --- a/src/test/ui/did_you_mean/issue-88276-unary-plus.rs +++ b/src/test/ui/parser/issue-88276-unary-plus.rs @@ -3,10 +3,10 @@ fn main() { let _ = +1; //~ ERROR leading `+` is not supported let _ = -+(1+2)*3; //~ ERROR leading `+` is not supported - let _ = +-+(1+2)*3; //~ ERROR leading `+` is not supported - //~| ERROR leading `+` is not supported let _ = -+-+(1+2)*3; //~ ERROR leading `+` is not supported //~| ERROR leading `+` is not supported + let _ = (1 + +2) * +3; //~ ERROR leading `+` is not supported + //~| ERROR leading `+` is not supported let _ = (+&"hello"); //~ ERROR leading `+` is not supported let _ = +[+3, 4+6]; //~ ERROR leading `+` is not supported //~| ERROR leading `+` is not supported diff --git a/src/test/ui/did_you_mean/issue-88276-unary-plus.stderr b/src/test/ui/parser/issue-88276-unary-plus.stderr similarity index 61% rename from src/test/ui/did_you_mean/issue-88276-unary-plus.stderr rename to src/test/ui/parser/issue-88276-unary-plus.stderr index 9c1227d7c351a..255839bc684b5 100644 --- a/src/test/ui/did_you_mean/issue-88276-unary-plus.stderr +++ b/src/test/ui/parser/issue-88276-unary-plus.stderr @@ -5,7 +5,7 @@ LL | let _ = +1; | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` error: leading `+` is not supported --> $DIR/issue-88276-unary-plus.rs:5:14 @@ -14,43 +14,43 @@ LL | let _ = -+(1+2)*3; | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:6:13 - | -LL | let _ = +-+(1+2)*3; - | ^ - | | - | unexpected `+` - | help: remove the `+` - -error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:6:15 - | -LL | let _ = +-+(1+2)*3; - | ^ - | | - | unexpected `+` - | help: remove the `+` - -error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:8:14 + --> $DIR/issue-88276-unary-plus.rs:6:14 | LL | let _ = -+-+(1+2)*3; | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:8:16 + --> $DIR/issue-88276-unary-plus.rs:6:16 | LL | let _ = -+-+(1+2)*3; | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:8:18 + | +LL | let _ = (1 + +2) * +3; + | ^ + | | + | unexpected `+` + | help: try removing the `+` + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:8:24 + | +LL | let _ = (1 + +2) * +3; + | ^ + | | + | unexpected `+` + | help: try removing the `+` error: leading `+` is not supported --> $DIR/issue-88276-unary-plus.rs:10:14 @@ -59,7 +59,7 @@ LL | let _ = (+&"hello"); | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` error: leading `+` is not supported --> $DIR/issue-88276-unary-plus.rs:11:13 @@ -68,7 +68,7 @@ LL | let _ = +[+3, 4+6]; | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` error: leading `+` is not supported --> $DIR/issue-88276-unary-plus.rs:11:15 @@ -77,7 +77,7 @@ LL | let _ = +[+3, 4+6]; | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` error: aborting due to 9 previous errors From ce9e76528abea4d5bc8d360e3c6d40e61cffb889 Mon Sep 17 00:00:00 2001 From: Theodore Luo Wang Date: Wed, 1 Sep 2021 11:55:36 -0400 Subject: [PATCH 08/24] Update formatting --- compiler/rustc_parse/src/parser/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c887f9fe0cf59..b0f29601417cb 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -535,7 +535,7 @@ impl<'a> Parser<'a> { if let Some(sp) = this.sess.ambiguous_block_expr_parse.borrow().get(&sp) { this.sess.expr_parentheses_needed(&mut err, *sp); } else { - err.span_suggestion( + err.span_suggestion( lo, "try removing the `+`", "".to_string(), From bc9877c5af5155174f1a517d41d997b446cc074e Mon Sep 17 00:00:00 2001 From: Theodore Luo Wang Date: Wed, 1 Sep 2021 12:02:11 -0400 Subject: [PATCH 09/24] Undo debug statements --- compiler/rustc_parse/src/parser/expr.rs | 12 +----------- compiler/rustc_parse/src/parser/stmt.rs | 3 --- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b0f29601417cb..4463d2fc6c8da 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -23,8 +23,6 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Pos}; use std::mem; -use tracing::debug; - /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression /// dropped into the token stream, which happens while parsing the result of /// macro expansion). Placement of these is not as complex as I feared it would @@ -165,12 +163,9 @@ impl<'a> Parser<'a> { if [token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token.kind) { return self.parse_prefix_range_expr(attrs); } else { - let result = self.parse_prefix_expr(attrs); - debug!("parse_prefix_expr result: {:?}", &result); - result? + self.parse_prefix_expr(attrs)? } }; - debug!("parse_assoc_expr_with(lhs = {:?})", &lhs); let last_type_ascription_set = self.last_type_ascription.is_some(); if !self.should_continue_as_assoc_expr(&lhs) { @@ -178,11 +173,8 @@ impl<'a> Parser<'a> { return Ok(lhs); } - debug!("continue_as_assoc_expr"); - self.expected_tokens.push(TokenType::Operator); while let Some(op) = self.check_assoc_op() { - debug!("op: {:?}", op); // Adjust the span for interpolated LHS to point to the `$lhs` token // and not to what it refers to. let lhs_span = match self.prev_token.kind { @@ -363,7 +355,6 @@ impl<'a> Parser<'a> { /// but the next token implies this should be parsed as an expression. /// For example: `if let Some(x) = x { x } else { 0 } / 2`. fn error_found_expr_would_be_stmt(&self, lhs: &Expr) { - debug!("error_found_expr_would_be_stmt(lhs: {:?})", lhs); let mut err = self.struct_span_err( self.token.span, &format!("expected expression, found `{}`", pprust::token_to_string(&self.token),), @@ -526,7 +517,6 @@ impl<'a> Parser<'a> { make_it!(this, attrs, |this, _| this.parse_borrow_expr(lo)) } token::BinOp(token::Plus) => { - debug!("leading + detected: {:?}", lo); let mut err = this.struct_span_err(lo, "leading `+` is not supported"); err.span_label(lo, "unexpected `+`"); diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 329b60f9a8711..85515bd2a6314 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -21,8 +21,6 @@ use rustc_span::symbol::{kw, sym}; use std::mem; -use tracing::debug; - impl<'a> Parser<'a> { /// Parses a statement. This stops just before trailing semicolons on everything but items. /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed. @@ -420,7 +418,6 @@ impl<'a> Parser<'a> { if self.token == token::Eof { break; } - debug!("parsing statements, stmts: {:?}", &stmts); let stmt = match self.parse_full_stmt(recover) { Err(mut err) if recover.yes() => { self.maybe_annotate_with_ascription(&mut err, false); From 49c680ada001a4c296d1c00f58be8d8b535d50f6 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Thu, 2 Sep 2021 17:19:43 +0200 Subject: [PATCH 10/24] Add "!" doc alias for `std::ops::Not` --- library/core/src/ops/bit.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs index 51f8043817345..92f45ac9e7ea9 100644 --- a/library/core/src/ops/bit.rs +++ b/library/core/src/ops/bit.rs @@ -30,6 +30,7 @@ /// ``` #[lang = "not"] #[stable(feature = "rust1", since = "1.0.0")] +#[doc(alias = "!")] pub trait Not { /// The resulting type after applying the `!` operator. #[stable(feature = "rust1", since = "1.0.0")] From ab89c88faadbc5a4063c8473c9ce28af16324d79 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Thu, 2 Sep 2021 17:21:05 +0200 Subject: [PATCH 11/24] =?UTF-8?q?Consistent=20placement=20of=20doc=20alias?= =?UTF-8?q?=20for=20primitives=20below=20the=20`doc(primitive=E2=80=A6)`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/std/src/primitive_docs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index dc4572cd9363b..045c1303b133f 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -385,8 +385,8 @@ mod prim_char {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_unit {} -#[doc(alias = "ptr")] #[doc(primitive = "pointer")] +#[doc(alias = "ptr")] // /// Raw, unsafe pointers, `*const T`, and `*mut T`. /// @@ -499,10 +499,10 @@ mod prim_unit {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_pointer {} +#[doc(primitive = "array")] #[doc(alias = "[]")] #[doc(alias = "[T;N]")] // unfortunately, rustdoc doesn't have fuzzy search for aliases #[doc(alias = "[T; N]")] -#[doc(primitive = "array")] /// A fixed-size array, denoted `[T; N]`, for the element type, `T`, and the /// non-negative compile-time constant size, `N`. /// From 34c1fce50be88eb4a0b81eb486b47e1f929b1ce3 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Sat, 4 Sep 2021 11:05:36 -0700 Subject: [PATCH 12/24] =?UTF-8?q?=E2=80=9CMoves=E2=80=9D=20instead=20of=20?= =?UTF-8?q?=E2=80=9Ccopies=E2=80=9D=20in=20`=20as=20From>::fr?= =?UTF-8?q?om`=20doc.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This implementation has no `Copy` or `Clone` bound, so its operation is guaranteed to be a move. The call site might copy, but the function itself cannot. Also linkify `Some` while we're touching the line anyway. --- library/core/src/option.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 9d5e03dd0de79..899a3b83df60b 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1701,7 +1701,7 @@ impl<'a, T> IntoIterator for &'a mut Option { #[stable(since = "1.12.0", feature = "option_from")] impl From for Option { - /// Copies `val` into a new `Some`. + /// Moves `val` into a new [`Some`]. /// /// # Examples /// From c2f432058c8dcf3d210ea673d178b3768815f80d Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Sat, 4 Sep 2021 11:17:34 -0700 Subject: [PATCH 13/24] Add sentence punctuation and links in `Option` docs. --- library/core/src/option.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 899a3b83df60b..64333a82387a1 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1173,7 +1173,7 @@ impl Option { // Entry-like operations to insert a value and return a reference ///////////////////////////////////////////////////////////////////////// - /// Inserts `value` into the option then returns a mutable reference to it. + /// Inserts `value` into the option, then returns a mutable reference to it. /// /// If the option already contains a value, the old value is dropped. /// @@ -1397,7 +1397,7 @@ impl Option { } impl Option<(T, U)> { - /// Unzips an option containing a tuple of two options + /// Unzips an option containing a tuple of two options. /// /// If `self` is `Some((a, b))` this method returns `(Some(a), Some(b))`. /// Otherwise, `(None, None)` is returned. @@ -1500,7 +1500,7 @@ impl Option<&mut T> { } impl Option { - /// Returns the contained [`Some`] value or a default + /// Returns the contained [`Some`] value or a default. /// /// Consumes the `self` argument then, if [`Some`], returns the contained /// value, otherwise if [`None`], returns the [default value] for that @@ -1561,7 +1561,7 @@ impl Option { /// Converts from `Option` (or `&mut Option`) to `Option<&mut T::Target>`. /// /// Leaves the original `Option` in-place, creating a new one containing a mutable reference to - /// the inner type's `Deref::Target` type. + /// the inner type's [`Deref::Target`] type. /// /// # Examples /// @@ -2039,7 +2039,7 @@ impl ops::FromResidual for Option { } impl Option> { - /// Converts from `Option>` to `Option` + /// Converts from `Option>` to `Option`. /// /// # Examples /// From 9a3a2a1c3784905eee405becdbd2e5c7ebd5dbce Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Sat, 4 Sep 2021 11:19:59 -0700 Subject: [PATCH 14/24] =?UTF-8?q?Clarify=20what=20=E2=80=9Ca=20container?= =?UTF-8?q?=E2=80=9D=20is=20in=20`FromIterator>=20for=20Option`=20doc.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/core/src/option.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 64333a82387a1..907726f0c345c 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1942,8 +1942,8 @@ unsafe impl TrustedLen for IntoIter {} impl> FromIterator> for Option { /// Takes each element in the [`Iterator`]: if it is [`None`][Option::None], /// no further elements are taken, and the [`None`][Option::None] is - /// returned. Should no [`None`][Option::None] occur, a container with the - /// values of each [`Option`] is returned. + /// returned. Should no [`None`][Option::None] occur, a container of type + /// `V` containing the values of each [`Option`] is returned. /// /// # Examples /// From 65eb7e516c798a9447dbfe1d02aeeb314d4fec54 Mon Sep 17 00:00:00 2001 From: Theodore Luo Wang Date: Sat, 4 Sep 2021 22:35:59 -0400 Subject: [PATCH 15/24] Use verbose suggestions and only match if the + is seen before a numeric literal --- compiler/rustc_ast/src/token.rs | 4 + compiler/rustc_parse/src/parser/expr.rs | 7 +- .../ui/associated-types/issue-36499.stderr | 11 ++- src/test/ui/parser/expr-as-stmt.fixed | 4 +- src/test/ui/parser/expr-as-stmt.rs | 4 +- src/test/ui/parser/expr-as-stmt.stderr | 8 +- .../ui/parser/issue-88276-unary-plus.fixed | 7 +- src/test/ui/parser/issue-88276-unary-plus.rs | 9 +- .../ui/parser/issue-88276-unary-plus.stderr | 93 ++++++------------- 9 files changed, 55 insertions(+), 92 deletions(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 710a592e258b4..e467bd963bf3c 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -586,6 +586,10 @@ impl Token { self.is_non_raw_ident_where(|id| id.name.is_bool_lit()) } + pub fn is_numeric_lit(&self) -> bool { + matches!(self.kind, Literal(Lit { kind: LitKind::Integer, ..}) | Literal(Lit { kind: LitKind::Float, ..})) + } + /// Returns `true` if the token is a non-raw identifier for which `pred` holds. pub fn is_non_raw_ident_where(&self, pred: impl FnOnce(Ident) -> bool) -> bool { match self.ident() { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 4463d2fc6c8da..83e1c5ff753a8 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -516,16 +516,15 @@ impl<'a> Parser<'a> { token::BinOp(token::And) | token::AndAnd => { make_it!(this, attrs, |this, _| this.parse_borrow_expr(lo)) } - token::BinOp(token::Plus) => { + token::BinOp(token::Plus) if this.look_ahead(1, |tok| tok.is_numeric_lit()) => { let mut err = this.struct_span_err(lo, "leading `+` is not supported"); err.span_label(lo, "unexpected `+`"); // a block on the LHS might have been intended to be an expression instead - let sp = this.sess.source_map().start_point(lo); - if let Some(sp) = this.sess.ambiguous_block_expr_parse.borrow().get(&sp) { + if let Some(sp) = this.sess.ambiguous_block_expr_parse.borrow().get(&lo) { this.sess.expr_parentheses_needed(&mut err, *sp); } else { - err.span_suggestion( + err.span_suggestion_verbose( lo, "try removing the `+`", "".to_string(), diff --git a/src/test/ui/associated-types/issue-36499.stderr b/src/test/ui/associated-types/issue-36499.stderr index 990ef09e3f742..610798d880f0a 100644 --- a/src/test/ui/associated-types/issue-36499.stderr +++ b/src/test/ui/associated-types/issue-36499.stderr @@ -2,10 +2,13 @@ error: leading `+` is not supported --> $DIR/issue-36499.rs:4:9 | LL | 2 + +2; - | ^ - | | - | unexpected `+` - | help: try removing the `+` + | ^ unexpected `+` + | +help: try removing the `+` + | +LL - 2 + +2; +LL + 2 + 2; + | error: aborting due to previous error diff --git a/src/test/ui/parser/expr-as-stmt.fixed b/src/test/ui/parser/expr-as-stmt.fixed index 79d73090a0420..5f5e25991e0cc 100644 --- a/src/test/ui/parser/expr-as-stmt.fixed +++ b/src/test/ui/parser/expr-as-stmt.fixed @@ -5,7 +5,7 @@ #![allow(unused_must_use)] fn foo() -> i32 { - ({2}) + {2} //~ ERROR leading `+` is not supported + ({2}) + {2} //~ ERROR expected expression, found `+` //~^ ERROR mismatched types } @@ -16,7 +16,7 @@ fn bar() -> i32 { fn zul() -> u32 { let foo = 3; - ({ 42 }) + foo; //~ ERROR leading `+` is not supported + ({ 42 }) + foo; //~ ERROR expected expression, found `+` //~^ ERROR mismatched types 32 } diff --git a/src/test/ui/parser/expr-as-stmt.rs b/src/test/ui/parser/expr-as-stmt.rs index 8698f99b81a41..5428e1c32fed3 100644 --- a/src/test/ui/parser/expr-as-stmt.rs +++ b/src/test/ui/parser/expr-as-stmt.rs @@ -5,7 +5,7 @@ #![allow(unused_must_use)] fn foo() -> i32 { - {2} + {2} //~ ERROR leading `+` is not supported + {2} + {2} //~ ERROR expected expression, found `+` //~^ ERROR mismatched types } @@ -16,7 +16,7 @@ fn bar() -> i32 { fn zul() -> u32 { let foo = 3; - { 42 } + foo; //~ ERROR leading `+` is not supported + { 42 } + foo; //~ ERROR expected expression, found `+` //~^ ERROR mismatched types 32 } diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr index 91f97c4662a97..d99e9be0000c3 100644 --- a/src/test/ui/parser/expr-as-stmt.stderr +++ b/src/test/ui/parser/expr-as-stmt.stderr @@ -1,8 +1,8 @@ -error: leading `+` is not supported +error: expected expression, found `+` --> $DIR/expr-as-stmt.rs:8:9 | LL | {2} + {2} - | ^ unexpected `+` + | ^ expected expression | help: parentheses are required to parse this as an expression | @@ -20,11 +20,11 @@ help: parentheses are required to parse this as an expression LL | ({2}) + 2 | + + -error: leading `+` is not supported +error: expected expression, found `+` --> $DIR/expr-as-stmt.rs:19:12 | LL | { 42 } + foo; - | ^ unexpected `+` + | ^ expected expression | help: parentheses are required to parse this as an expression | diff --git a/src/test/ui/parser/issue-88276-unary-plus.fixed b/src/test/ui/parser/issue-88276-unary-plus.fixed index 279cdb5060a42..25b7c340f600d 100644 --- a/src/test/ui/parser/issue-88276-unary-plus.fixed +++ b/src/test/ui/parser/issue-88276-unary-plus.fixed @@ -2,12 +2,7 @@ #[allow(unused_parens)] fn main() { let _ = 1; //~ ERROR leading `+` is not supported - let _ = -(1+2)*3; //~ ERROR leading `+` is not supported - let _ = --(1+2)*3; //~ ERROR leading `+` is not supported - //~| ERROR leading `+` is not supported - let _ = (1 + 2) * 3; //~ ERROR leading `+` is not supported + let _ = (1.0 + 2.0) * 3.0; //~ ERROR leading `+` is not supported //~| ERROR leading `+` is not supported - let _ = (&"hello"); //~ ERROR leading `+` is not supported let _ = [3, 4+6]; //~ ERROR leading `+` is not supported - //~| ERROR leading `+` is not supported } diff --git a/src/test/ui/parser/issue-88276-unary-plus.rs b/src/test/ui/parser/issue-88276-unary-plus.rs index a72dad4dc7198..11b2e9d601653 100644 --- a/src/test/ui/parser/issue-88276-unary-plus.rs +++ b/src/test/ui/parser/issue-88276-unary-plus.rs @@ -2,12 +2,7 @@ #[allow(unused_parens)] fn main() { let _ = +1; //~ ERROR leading `+` is not supported - let _ = -+(1+2)*3; //~ ERROR leading `+` is not supported - let _ = -+-+(1+2)*3; //~ ERROR leading `+` is not supported - //~| ERROR leading `+` is not supported - let _ = (1 + +2) * +3; //~ ERROR leading `+` is not supported + let _ = (1.0 + +2.0) * +3.0; //~ ERROR leading `+` is not supported //~| ERROR leading `+` is not supported - let _ = (+&"hello"); //~ ERROR leading `+` is not supported - let _ = +[+3, 4+6]; //~ ERROR leading `+` is not supported - //~| ERROR leading `+` is not supported + let _ = [+3, 4+6]; //~ ERROR leading `+` is not supported } diff --git a/src/test/ui/parser/issue-88276-unary-plus.stderr b/src/test/ui/parser/issue-88276-unary-plus.stderr index 255839bc684b5..b26761729a837 100644 --- a/src/test/ui/parser/issue-88276-unary-plus.stderr +++ b/src/test/ui/parser/issue-88276-unary-plus.stderr @@ -2,82 +2,49 @@ error: leading `+` is not supported --> $DIR/issue-88276-unary-plus.rs:4:13 | LL | let _ = +1; - | ^ - | | - | unexpected `+` - | help: try removing the `+` - -error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:5:14 + | ^ unexpected `+` | -LL | let _ = -+(1+2)*3; - | ^ - | | - | unexpected `+` - | help: try removing the `+` - -error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:6:14 +help: try removing the `+` | -LL | let _ = -+-+(1+2)*3; - | ^ - | | - | unexpected `+` - | help: try removing the `+` +LL - let _ = +1; +LL + let _ = 1; + | error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:6:16 + --> $DIR/issue-88276-unary-plus.rs:5:20 | -LL | let _ = -+-+(1+2)*3; - | ^ - | | - | unexpected `+` - | help: try removing the `+` - -error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:8:18 +LL | let _ = (1.0 + +2.0) * +3.0; + | ^ unexpected `+` | -LL | let _ = (1 + +2) * +3; - | ^ - | | - | unexpected `+` - | help: try removing the `+` - -error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:8:24 +help: try removing the `+` | -LL | let _ = (1 + +2) * +3; - | ^ - | | - | unexpected `+` - | help: try removing the `+` +LL - let _ = (1.0 + +2.0) * +3.0; +LL + let _ = (1.0 + 2.0) * +3.0; + | error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:10:14 + --> $DIR/issue-88276-unary-plus.rs:5:28 | -LL | let _ = (+&"hello"); - | ^ - | | - | unexpected `+` - | help: try removing the `+` - -error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:11:13 +LL | let _ = (1.0 + +2.0) * +3.0; + | ^ unexpected `+` | -LL | let _ = +[+3, 4+6]; - | ^ - | | - | unexpected `+` - | help: try removing the `+` +help: try removing the `+` + | +LL - let _ = (1.0 + +2.0) * +3.0; +LL + let _ = (1.0 + +2.0) * 3.0; + | error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:11:15 + --> $DIR/issue-88276-unary-plus.rs:7:14 + | +LL | let _ = [+3, 4+6]; + | ^ unexpected `+` + | +help: try removing the `+` | -LL | let _ = +[+3, 4+6]; - | ^ - | | - | unexpected `+` - | help: try removing the `+` +LL - let _ = [+3, 4+6]; +LL + let _ = [3, 4+6]; + | -error: aborting due to 9 previous errors +error: aborting due to 4 previous errors From 20eba43283d59849627042d67413d32e08ace0f1 Mon Sep 17 00:00:00 2001 From: Theodore Luo Wang Date: Sat, 4 Sep 2021 22:38:39 -0400 Subject: [PATCH 16/24] Fix formatting --- compiler/rustc_ast/src/token.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index e467bd963bf3c..3a65ffe41ae87 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -587,7 +587,10 @@ impl Token { } pub fn is_numeric_lit(&self) -> bool { - matches!(self.kind, Literal(Lit { kind: LitKind::Integer, ..}) | Literal(Lit { kind: LitKind::Float, ..})) + matches!( + self.kind, + Literal(Lit { kind: LitKind::Integer, .. }) | Literal(Lit { kind: LitKind::Float, .. }) + ) } /// Returns `true` if the token is a non-raw identifier for which `pred` holds. From 2b69171dc2f0dec24478598abf844a8ff789ff86 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Thu, 2 Sep 2021 17:37:53 +0200 Subject: [PATCH 17/24] Additional aliases for pointers --- library/std/src/primitive_docs.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 045c1303b133f..09a6b932b960e 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -387,6 +387,9 @@ mod prim_unit {} #[doc(primitive = "pointer")] #[doc(alias = "ptr")] +#[doc(alias = "*")] +#[doc(alias = "*const")] +#[doc(alias = "*mut")] // /// Raw, unsafe pointers, `*const T`, and `*mut T`. /// From 5135d8692023359f4f04ca627a2571d6b8a0446a Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Thu, 2 Sep 2021 17:47:28 +0200 Subject: [PATCH 18/24] Mention usage of `const` in raw pointer types at the top of the keyword's documentation page. --- library/std/src/keyword_docs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index 749a441d18263..3af941f59b689 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -119,7 +119,7 @@ mod break_keyword {} #[doc(keyword = "const")] // -/// Compile-time constants and compile-time evaluable functions. +/// Compile-time constants, compile-time evaluable functions, and raw pointers. /// /// ## Compile-time constants /// From fe7bcd6e4044f760f90aa2309c76d3a75899126a Mon Sep 17 00:00:00 2001 From: Bram van den Heuvel Date: Tue, 31 Aug 2021 11:03:49 +0200 Subject: [PATCH 19/24] Add regression test for #74400 --- .../lifetime-errors/issue_74400.nll.stderr | 30 +++++++++++++++++++ .../lifetimes/lifetime-errors/issue_74400.rs | 13 ++++++++ .../lifetime-errors/issue_74400.stderr | 11 +++++++ 3 files changed, 54 insertions(+) create mode 100644 src/test/ui/lifetimes/lifetime-errors/issue_74400.nll.stderr create mode 100644 src/test/ui/lifetimes/lifetime-errors/issue_74400.rs create mode 100644 src/test/ui/lifetimes/lifetime-errors/issue_74400.stderr diff --git a/src/test/ui/lifetimes/lifetime-errors/issue_74400.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/issue_74400.nll.stderr new file mode 100644 index 0000000000000..5a1294f948f1c --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/issue_74400.nll.stderr @@ -0,0 +1,30 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/issue_74400.rs:12:5 + | +LL | f(data, identity) + | ^^^^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `T: 'static`... + +error[E0308]: mismatched types + --> $DIR/issue_74400.rs:12:5 + | +LL | f(data, identity) + | ^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected type `for<'r> Fn<(&'r T,)>` + found type `Fn<(&T,)>` + +error: implementation of `FnOnce` is not general enough + --> $DIR/issue_74400.rs:12:5 + | +LL | f(data, identity) + | ^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: `fn(&'2 T) -> &'2 T {identity::<&'2 T>}` must implement `FnOnce<(&'1 T,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 T,)>`, for some specific lifetime `'2` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0310. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/lifetimes/lifetime-errors/issue_74400.rs b/src/test/ui/lifetimes/lifetime-errors/issue_74400.rs new file mode 100644 index 0000000000000..f83384524f718 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/issue_74400.rs @@ -0,0 +1,13 @@ +//! Regression test for #74400: Type mismatch in function arguments E0631, E0271 are falsely +//! recognized as E0308 mismatched types. + +use std::convert::identity; + +fn main() {} + +fn f(data: &[T], key: impl Fn(&T) -> S) { +} + +fn g(data: &[T]) { + f(data, identity) //~ ERROR implementation of `FnOnce` is not general +} diff --git a/src/test/ui/lifetimes/lifetime-errors/issue_74400.stderr b/src/test/ui/lifetimes/lifetime-errors/issue_74400.stderr new file mode 100644 index 0000000000000..d972861a2b567 --- /dev/null +++ b/src/test/ui/lifetimes/lifetime-errors/issue_74400.stderr @@ -0,0 +1,11 @@ +error: implementation of `FnOnce` is not general enough + --> $DIR/issue_74400.rs:12:5 + | +LL | f(data, identity) + | ^ implementation of `FnOnce` is not general enough + | + = note: `fn(&'2 T) -> &'2 T {identity::<&'2 T>}` must implement `FnOnce<(&'1 T,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 T,)>`, for some specific lifetime `'2` + +error: aborting due to previous error + From c0451f73b2094d7edccb77d7ea8be48f64887e67 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 6 Sep 2021 07:09:32 +0000 Subject: [PATCH 20/24] Correctly handle niche of enum --- src/librustdoc/html/render/print_item.rs | 12 ++++++++---- src/test/rustdoc/type-layout.rs | 9 +++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 6054073bf79b2..aac631a1cfcdd 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::{Adt, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_target::abi::{Layout, Primitive, Variants}; +use rustc_target::abi::{Layout, Primitive, TagEncoding, Variants}; use super::{ collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_strs, notable_traits_decl, @@ -1639,7 +1639,9 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { w.write_str("

    Size: "); write_size_of_layout(w, ty_layout.layout, 0); writeln!(w, "

    "); - if let Variants::Multiple { variants, tag, .. } = &ty_layout.layout.variants { + if let Variants::Multiple { variants, tag, tag_encoding, .. } = + &ty_layout.layout.variants + { if !variants.is_empty() { w.write_str( "

    Size for each variant:

    \ @@ -1652,10 +1654,12 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) { span_bug!(tcx.def_span(ty_def_id), "not an adt") }; - let tag_size = if let Primitive::Int(i, _) = tag.value { + let tag_size = if let TagEncoding::Niche { .. } = tag_encoding { + 0 + } else if let Primitive::Int(i, _) = tag.value { i.size().bytes() } else { - span_bug!(tcx.def_span(ty_def_id), "tag is not int") + span_bug!(tcx.def_span(ty_def_id), "tag is neither niche nor int") }; for (index, layout) in variants.iter_enumerated() { diff --git a/src/test/rustdoc/type-layout.rs b/src/test/rustdoc/type-layout.rs index 8c4f4f8fc98e6..0868486fa59cd 100644 --- a/src/test/rustdoc/type-layout.rs +++ b/src/test/rustdoc/type-layout.rs @@ -61,3 +61,12 @@ pub enum Variants { A, B(u8), } + +// @has type_layout/enum.WithNiche.html 'Size: ' +// @has - //p '4 bytes' +// @has - 'None: 0 bytes' +// @has - 'Some: 4 bytes' +pub enum WithNiche { + None, + Some(std::num::NonZeroU32), +} From 214eef043501a896ec375fc831891cf1dc09219f Mon Sep 17 00:00:00 2001 From: hyd-dev Date: Mon, 6 Sep 2021 23:58:10 +0800 Subject: [PATCH 21/24] Add a regression test for https://github.com/rust-lang/rust/issues/88649 --- src/test/ui/consts/issue-88649.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/test/ui/consts/issue-88649.rs diff --git a/src/test/ui/consts/issue-88649.rs b/src/test/ui/consts/issue-88649.rs new file mode 100644 index 0000000000000..43e562b5a7da4 --- /dev/null +++ b/src/test/ui/consts/issue-88649.rs @@ -0,0 +1,18 @@ +// check-pass +#![crate_type = "lib"] + +enum Foo { + Variant1(bool), + Variant2(bool), +} + +const _: () = { + let mut n = 0; + while n < 2 { + match Foo::Variant1(true) { + Foo::Variant1(x) | Foo::Variant2(x) if x => {} + _ => {} + } + n += 1; + } +}; From 56bb6f5a25e8babe1cba540f9935032b0f4941ce Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Tue, 7 Sep 2021 02:14:04 -0400 Subject: [PATCH 22/24] Fix docs for `uX::checked_next_multiple_of` --- library/core/src/num/uint_macros.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 02a5ed4ca800e..7264088bb95fd 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1927,7 +1927,8 @@ macro_rules! uint_impl { } /// Calculates the smallest value greater than or equal to `self` that - /// is a multiple of `rhs`. If `rhs` is negative, + /// is a multiple of `rhs`. Returns `None` is `rhs` is zero or the + /// operation would result in overflow. /// /// # Examples /// From f8cbb1935cf6d641dc4ef7024b50a601e501d250 Mon Sep 17 00:00:00 2001 From: Mingwei Samuel Date: Tue, 7 Sep 2021 09:27:30 -0700 Subject: [PATCH 23/24] Fix typo in `const_generics` replaced with `adt_const_params` note --- compiler/rustc_feature/src/removed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 8e498a5446ea8..efab0200ff502 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -104,7 +104,7 @@ declare_features! ( (removed, quote, "1.33.0", Some(29601), None, None), /// Allows const generic types (e.g. `struct Foo(...);`). (removed, const_generics, "1.34.0", Some(44580), None, - Some("removed in favor of `#![feature(adt_const_params]` and `#![feature(generic_const_exprs)]`")), + Some("removed in favor of `#![feature(adt_const_params)]` and `#![feature(generic_const_exprs)]`")), /// Allows `[x; N]` where `x` is a constant (RFC 2203). (removed, const_in_array_repeat_expressions, "1.37.0", Some(49147), None, Some("removed due to causing promotable bugs")), From daf6f9951e25561cc97ae8715807b880f496da90 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 6 Sep 2021 12:55:11 -0400 Subject: [PATCH 24/24] Drop 1.56 stabilizations from 1.55 release notes --- RELEASES.md | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 2124195bcb209..c0851a1506e13 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -10,8 +10,7 @@ Language Compiler -------- -- [Added tier 3\* support for `powerpc-unknown-freebsd`.][87370] -- [Added tier 3 support for `powerpc64le-unknown-freebsd`.][83572] +- [Added tier 3\* support for `powerpc64le-unknown-freebsd`.][83572] \* Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. @@ -24,17 +23,6 @@ Libraries no longer reject certain valid floating point values, and reduce the produced code size for non-stripped artifacts. - [`string::Drain` now implements `AsRef` and `AsRef<[u8]>`.][86858] -- [`collections::{BinaryHeap, BTreeSet, HashSet, LinkedList, VecDeque}` now - implement `From<[T; N]>`.][84111] -- [`collections::{BTreeMap, HashMap}` now implement `From<[(K, V); N]>`.][84111] - This allows you to write the following; - ```rust - let highscores = std::collections::HashMap::from([ - ("Alice", 9000u32), - ("Bob", 7250), - ("Charlie", 5500), - ]); - ``` Stabilised APIs --------------- @@ -60,7 +48,6 @@ Stabilised APIs The following previously stable functions are now `const`. - [`str::from_utf8_unchecked`] -- [`mem::transmute`] Cargo @@ -131,7 +118,6 @@ Compatibility Notes [`MaybeUninit::assume_init_ref`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_ref [`MaybeUninit::write`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.write [`Seek::rewind`]: https://doc.rust-lang.org/stable/std/io/trait.Seek.html#method.rewind -[`mem::transmute`]: https://doc.rust-lang.org/stable/std/mem/fn.transmute.html [`ops::ControlFlow`]: https://doc.rust-lang.org/stable/std/ops/enum.ControlFlow.html [`str::from_utf8_unchecked`]: https://doc.rust-lang.org/stable/std/str/fn.from_utf8_unchecked.html [`x86::_bittest`]: https://doc.rust-lang.org/stable/core/arch/x86/fn._bittest.html