From 3e477c1772d977589b28e09677d68a86fa4644cd Mon Sep 17 00:00:00 2001 From: terrarier2111 <58695553+terrarier2111@users.noreply.github.com> Date: Sat, 28 Aug 2021 20:20:22 +0200 Subject: [PATCH 1/4] Fix a typo in raw_vec --- library/alloc/src/raw_vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 3caada06f6b58..be21018512d8b 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -323,7 +323,7 @@ impl RawVec { pub fn reserve(&mut self, len: usize, additional: usize) { // Callers expect this function to be very cheap when there is already sufficient capacity. // Therefore, we move all the resizing and error-handling logic from grow_amortized and - // handle_reserve behind a call, while making sure that the this function is likely to be + // handle_reserve behind a call, while making sure that this function is likely to be // inlined as just a comparison and a call if the comparison fails. #[cold] fn do_reserve_and_handle( From 5538be5d80c0ec92918f4a57c5a94e9cb5287164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 30 Aug 2021 23:32:57 +0200 Subject: [PATCH 2/4] x.py clippy: don't run with --all-targets by default this caused a lot of noise because benchmarks and tests were also checked --- src/bootstrap/check.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 4eb335979b983..f5fad4b413684 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -107,6 +107,11 @@ impl Step for Std { add_to_sysroot(&builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target)); } + // don't run on std twice with x.py clippy + if builder.kind == Kind::Clippy { + return; + } + // Then run cargo again, once we've put the rmeta files for the library // crates into the sysroot. This is needed because e.g., core's tests // depend on `libtest` -- Cargo presumes it will exist, but it doesn't @@ -120,6 +125,7 @@ impl Step for Std { target, cargo_subcommand(builder.kind), ); + cargo.arg("--all-targets"); std_cargo(builder, target, compiler.stage, &mut cargo); @@ -192,7 +198,12 @@ impl Step for Rustc { cargo_subcommand(builder.kind), ); rustc_cargo(builder, &mut cargo, target); - cargo.arg("--all-targets"); + + // For ./x.py clippy, don't run with --all-targets because + // linting tests and benchmarks can produce very noisy results + if builder.kind != Kind::Clippy { + cargo.arg("--all-targets"); + } // Explicitly pass -p for all compiler krates -- this will force cargo // to also check the tests/benches/examples for these crates, rather @@ -313,7 +324,12 @@ macro_rules! tool_check_step { $source_type, &[], ); - cargo.arg("--all-targets"); + + // For ./x.py clippy, don't run with --all-targets because + // linting tests and benchmarks can produce very noisy results + if builder.kind != Kind::Clippy { + cargo.arg("--all-targets"); + } // Enable internal lints for clippy and rustdoc // NOTE: this doesn't enable lints for any other tools unless they explicitly add `#![warn(rustc::internal)]` From 39ceab02a6b5d08e1543c6ad6ebe04d57dd10078 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Mon, 23 Aug 2021 10:49:31 +0000 Subject: [PATCH 3/4] Provide more context on incorrect inner attribute Suggest changing an inner attribute into an outer attribute if followed by an item. --- compiler/rustc_parse/src/parser/attr.rs | 140 +++++++++++++++--- .../ui/parser/attr-stmt-expr-attr-bad.stderr | 96 ++++++++---- src/test/ui/parser/attr.stderr | 10 +- .../parser/doc-comment-in-if-statement.stderr | 5 + .../inner-attr-after-doc-comment.stderr | 10 +- src/test/ui/parser/inner-attr.stderr | 9 +- src/test/ui/parser/issue-30318.fixed | 27 ++++ src/test/ui/parser/issue-30318.rs | 22 ++- src/test/ui/parser/issue-30318.stderr | 74 ++++++++- src/test/ui/parser/issue-45296.rs | 1 + src/test/ui/parser/issue-45296.stderr | 9 +- .../parser/stmt_expr_attrs_placement.stderr | 21 ++- .../issue-86781-bad-inner-doc.fixed | 12 ++ .../proc-macro/issue-86781-bad-inner-doc.rs | 3 +- .../issue-86781-bad-inner-doc.stderr | 10 +- 15 files changed, 382 insertions(+), 67 deletions(-) create mode 100644 src/test/ui/parser/issue-30318.fixed create mode 100644 src/test/ui/proc-macro/issue-86781-bad-inner-doc.fixed diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index e9f0038b2d65d..b402b8ba53ada 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -1,10 +1,10 @@ -use super::{AttrWrapper, Capturing, Parser, PathStyle}; +use super::{AttrWrapper, Capturing, ForceCollect, Parser, PathStyle}; use rustc_ast as ast; use rustc_ast::attr; use rustc_ast::token::{self, Nonterminal}; use rustc_ast_pretty::pprust; -use rustc_errors::{error_code, PResult}; -use rustc_span::{sym, Span}; +use rustc_errors::{error_code, DiagnosticBuilder, PResult}; +use rustc_span::{sym, BytePos, Span}; use std::convert::TryInto; use tracing::debug; @@ -25,6 +25,12 @@ pub(super) const DEFAULT_INNER_ATTR_FORBIDDEN: InnerAttrPolicy<'_> = InnerAttrPo prev_attr_sp: None, }; +enum OuterAttributeType { + DocComment, + DocBlockComment, + Attribute, +} + impl<'a> Parser<'a> { /// Parses attributes that appear before an item. pub(super) fn parse_outer_attributes(&mut self) -> PResult<'a, AttrWrapper> { @@ -49,18 +55,32 @@ impl<'a> Parser<'a> { Some(self.parse_attribute(inner_parse_policy)?) } else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind { if attr_style != ast::AttrStyle::Outer { - self.sess - .span_diagnostic - .struct_span_err_with_code( - self.token.span, - "expected outer doc comment", - error_code!(E0753), - ) - .note( - "inner doc comments like this (starting with \ - `//!` or `/*!`) can only appear before items", - ) - .emit(); + let span = self.token.span; + let mut err = self.sess.span_diagnostic.struct_span_err_with_code( + span, + "expected outer doc comment", + error_code!(E0753), + ); + if let Some(replacement_span) = self.annotate_following_item_if_applicable( + &mut err, + span, + match comment_kind { + token::CommentKind::Line => OuterAttributeType::DocComment, + token::CommentKind::Block => OuterAttributeType::DocBlockComment, + }, + ) { + err.note( + "inner doc comments like this (starting with `//!` or `/*!`) can \ + only appear before items", + ); + err.span_suggestion_verbose( + replacement_span, + "you might have meant to write a regular comment", + String::new(), + rustc_errors::Applicability::MachineApplicable, + ); + } + err.emit(); } self.bump(); just_parsed_doc_comment = true; @@ -97,7 +117,7 @@ impl<'a> Parser<'a> { inner_parse_policy, self.token ); let lo = self.token.span; - // Attributse can't have attributes of their own + // Attributes can't have attributes of their own [Editor's note: not with that attitude] self.collect_tokens_no_attrs(|this| { if this.eat(&token::Pound) { let style = if this.eat(&token::Not) { @@ -125,6 +145,75 @@ impl<'a> Parser<'a> { }) } + fn annotate_following_item_if_applicable( + &self, + err: &mut DiagnosticBuilder<'_>, + span: Span, + attr_type: OuterAttributeType, + ) -> Option { + let mut snapshot = self.clone(); + let lo = span.lo() + + BytePos(match attr_type { + OuterAttributeType::Attribute => 1, + _ => 2, + }); + let hi = lo + BytePos(1); + let replacement_span = span.with_lo(lo).with_hi(hi); + if let OuterAttributeType::DocBlockComment | OuterAttributeType::DocComment = attr_type { + snapshot.bump(); + } + loop { + // skip any other attributes, we want the item + if snapshot.token.kind == token::Pound { + if let Err(mut err) = snapshot.parse_attribute(InnerAttrPolicy::Permitted) { + err.cancel(); + return Some(replacement_span); + } + } else { + break; + } + } + match snapshot.parse_item_common( + AttrWrapper::empty(), + true, + false, + |_| true, + ForceCollect::No, + ) { + Ok(Some(item)) => { + let attr_name = match attr_type { + OuterAttributeType::Attribute => "attribute", + _ => "doc comment", + }; + err.span_label( + item.span, + &format!("the inner {} doesn't annotate this {}", attr_name, item.kind.descr()), + ); + err.span_suggestion_verbose( + replacement_span, + &format!( + "to annotate the {}, change the {} from inner to outer style", + item.kind.descr(), + attr_name + ), + (match attr_type { + OuterAttributeType::Attribute => "", + OuterAttributeType::DocBlockComment => "*", + OuterAttributeType::DocComment => "/", + }) + .to_string(), + rustc_errors::Applicability::MachineApplicable, + ); + return None; + } + Err(mut item_err) => { + item_err.cancel(); + } + Ok(None) => {} + } + Some(replacement_span) + } + pub(super) fn error_on_forbidden_inner_attr(&self, attr_sp: Span, policy: InnerAttrPolicy<'_>) { if let InnerAttrPolicy::Forbidden { reason, saw_doc_comment, prev_attr_sp } = policy { let prev_attr_note = @@ -138,11 +227,20 @@ impl<'a> Parser<'a> { } diag.note( - "inner attributes, like `#![no_std]`, annotate the item enclosing them, \ - and are usually found at the beginning of source files. \ - Outer attributes, like `#[test]`, annotate the item following them.", - ) - .emit(); + "inner attributes, like `#![no_std]`, annotate the item enclosing them, and \ + are usually found at the beginning of source files", + ); + if self + .annotate_following_item_if_applicable( + &mut diag, + attr_sp, + OuterAttributeType::Attribute, + ) + .is_some() + { + diag.note("outer attributes, like `#[test]`, annotate the item following them"); + }; + diag.emit(); } } diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr index cec6980c008c4..d38b98a190117 100644 --- a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr +++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr @@ -4,7 +4,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = box #![attr] 0; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected expression, found `]` --> $DIR/attr-stmt-expr-attr-bad.rs:7:40 @@ -24,7 +25,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected expression, found `)` --> $DIR/attr-stmt-expr-attr-bad.rs:11:44 @@ -38,7 +40,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected expression, found `)` --> $DIR/attr-stmt-expr-attr-bad.rs:14:46 @@ -52,7 +55,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:19:33 @@ -60,7 +64,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = !#![attr] 0; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:21:33 @@ -68,7 +73,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = -#![attr] 0; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `#` --> $DIR/attr-stmt-expr-attr-bad.rs:23:34 @@ -82,7 +88,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] foo; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:27:40 @@ -90,7 +97,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:29:35 @@ -98,7 +106,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:31:40 @@ -106,7 +115,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected expression, found `..` --> $DIR/attr-stmt-expr-attr-bad.rs:33:40 @@ -126,7 +136,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:39:45 @@ -134,7 +145,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: outer attributes are not allowed on `if` and `else` branches --> $DIR/attr-stmt-expr-attr-bad.rs:41:37 @@ -151,7 +163,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` --> $DIR/attr-stmt-expr-attr-bad.rs:45:40 @@ -174,7 +187,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: outer attributes are not allowed on `if` and `else` branches --> $DIR/attr-stmt-expr-attr-bad.rs:51:45 @@ -200,7 +214,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: outer attributes are not allowed on `if` and `else` branches --> $DIR/attr-stmt-expr-attr-bad.rs:57:45 @@ -217,7 +232,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: expected one of `.`, `;`, `?`, `else`, or an operator, found `#` --> $DIR/attr-stmt-expr-attr-bad.rs:61:48 @@ -240,7 +256,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: outer attributes are not allowed on `if` and `else` branches --> $DIR/attr-stmt-expr-attr-bad.rs:67:53 @@ -266,7 +283,8 @@ error: an inner attribute is not permitted in this context LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; } | ^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted following an outer attribute --> $DIR/attr-stmt-expr-attr-bad.rs:74:32 @@ -276,7 +294,8 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; } | | | previous outer attribute | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted following an outer attribute --> $DIR/attr-stmt-expr-attr-bad.rs:76:32 @@ -286,37 +305,56 @@ LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } | | | previous outer attribute | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted following an outer attribute --> $DIR/attr-stmt-expr-attr-bad.rs:78:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } - | ------- ^^^^^^^^ not permitted following an outer attribute - | | + | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation + | | | + | | not permitted following an outer attribute | previous outer attribute | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the item macro invocation, change the attribute from inner to outer style + | +LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } +LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!(); } + | error: an inner attribute is not permitted following an outer attribute --> $DIR/attr-stmt-expr-attr-bad.rs:80:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } - | ------- ^^^^^^^^ not permitted following an outer attribute - | | + | ------- ^^^^^^^^ ------- the inner attribute doesn't annotate this item macro invocation + | | | + | | not permitted following an outer attribute | previous outer attribute | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the item macro invocation, change the attribute from inner to outer style + | +LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } +LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo![]; } + | error: an inner attribute is not permitted following an outer attribute --> $DIR/attr-stmt-expr-attr-bad.rs:82:32 | LL | #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } - | ------- ^^^^^^^^ not permitted following an outer attribute - | | + | ------- ^^^^^^^^ ------ the inner attribute doesn't annotate this item macro invocation + | | | + | | not permitted following an outer attribute | previous outer attribute | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the item macro invocation, change the attribute from inner to outer style + | +LL - #[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } +LL + #[cfg(FALSE)] fn s() { #[attr] #[attr] foo!{}; } + | error[E0586]: inclusive range with no end --> $DIR/attr-stmt-expr-attr-bad.rs:88:35 diff --git a/src/test/ui/parser/attr.stderr b/src/test/ui/parser/attr.stderr index 400a0276b3b60..3cec61fe41eea 100644 --- a/src/test/ui/parser/attr.stderr +++ b/src/test/ui/parser/attr.stderr @@ -3,8 +3,16 @@ error: an inner attribute is not permitted in this context | LL | #![lang = "foo"] | ^^^^^^^^^^^^^^^^ +LL | +LL | fn foo() {} + | ----------- the inner attribute doesn't annotate this function | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![lang = "foo"] +LL + #[lang = "foo"] + | error[E0522]: definition of an unknown language item: `foo` --> $DIR/attr.rs:5:1 diff --git a/src/test/ui/parser/doc-comment-in-if-statement.stderr b/src/test/ui/parser/doc-comment-in-if-statement.stderr index be52a0afd46b7..b7c1847fc7c0d 100644 --- a/src/test/ui/parser/doc-comment-in-if-statement.stderr +++ b/src/test/ui/parser/doc-comment-in-if-statement.stderr @@ -5,6 +5,11 @@ LL | if true /*!*/ {} | ^^^^^ | = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +help: you might have meant to write a regular comment + | +LL - if true /*!*/ {} +LL + if true /**/ {} + | error: outer attributes are not allowed on `if` and `else` branches --> $DIR/doc-comment-in-if-statement.rs:2:13 diff --git a/src/test/ui/parser/inner-attr-after-doc-comment.stderr b/src/test/ui/parser/inner-attr-after-doc-comment.stderr index c1e9e7a427f89..404800ee15bdd 100644 --- a/src/test/ui/parser/inner-attr-after-doc-comment.stderr +++ b/src/test/ui/parser/inner-attr-after-doc-comment.stderr @@ -8,8 +8,16 @@ LL | | */ LL | LL | #![recursion_limit="100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ not permitted following an outer attribute +LL | +LL | fn main() {} + | ------------ the inner attribute doesn't annotate this function | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![recursion_limit="100"] +LL + #[recursion_limit="100"] + | error: aborting due to previous error diff --git a/src/test/ui/parser/inner-attr.stderr b/src/test/ui/parser/inner-attr.stderr index e1bf2cca1c963..1adac74590881 100644 --- a/src/test/ui/parser/inner-attr.stderr +++ b/src/test/ui/parser/inner-attr.stderr @@ -6,8 +6,15 @@ LL | #[feature(lang_items)] LL | LL | #![recursion_limit="100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ not permitted following an outer attribute +LL | fn main() {} + | ------------ the inner attribute doesn't annotate this function | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![recursion_limit="100"] +LL + #[recursion_limit="100"] + | error: aborting due to previous error diff --git a/src/test/ui/parser/issue-30318.fixed b/src/test/ui/parser/issue-30318.fixed new file mode 100644 index 0000000000000..71fc82172a54d --- /dev/null +++ b/src/test/ui/parser/issue-30318.fixed @@ -0,0 +1,27 @@ +// run-rustfix +#![allow(unused)] +fn foo() { } + +/// Misplaced comment... +//~^ ERROR expected outer doc comment +fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function + +#[test] //~ ERROR an inner attribute is not permitted in this context +fn baz() { } //~ NOTE the inner attribute doesn't annotate this function +//~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually + +/** Misplaced comment... */ +//~^ ERROR expected outer doc comment +fn bat() { } //~ NOTE the inner doc comment doesn't annotate this function + +fn main() { } + +// Misplaced comment... +//~^ ERROR expected outer doc comment +//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +//~| NOTE other attributes here +/* Misplaced comment... */ +//~^ ERROR expected outer doc comment +//~| NOTE this doc comment doesn't document anything +//~| ERROR expected item after doc comment +//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items diff --git a/src/test/ui/parser/issue-30318.rs b/src/test/ui/parser/issue-30318.rs index 38e30de716d0a..465dca2ff8224 100644 --- a/src/test/ui/parser/issue-30318.rs +++ b/src/test/ui/parser/issue-30318.rs @@ -1,7 +1,27 @@ +// run-rustfix +#![allow(unused)] fn foo() { } //! Misplaced comment... //~^ ERROR expected outer doc comment -//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +fn bar() { } //~ NOTE the inner doc comment doesn't annotate this function + +#![test] //~ ERROR an inner attribute is not permitted in this context +fn baz() { } //~ NOTE the inner attribute doesn't annotate this function +//~^^ NOTE inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually + +/*! Misplaced comment... */ +//~^ ERROR expected outer doc comment +fn bat() { } //~ NOTE the inner doc comment doesn't annotate this function fn main() { } + +//! Misplaced comment... +//~^ ERROR expected outer doc comment +//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +//~| NOTE other attributes here +/*! Misplaced comment... */ +//~^ ERROR expected outer doc comment +//~| NOTE this doc comment doesn't document anything +//~| ERROR expected item after doc comment +//~| NOTE inner doc comments like this (starting with `//!` or `/*!`) can only appear before items diff --git a/src/test/ui/parser/issue-30318.stderr b/src/test/ui/parser/issue-30318.stderr index b3a27f1985171..7e7108845546a 100644 --- a/src/test/ui/parser/issue-30318.stderr +++ b/src/test/ui/parser/issue-30318.stderr @@ -1,11 +1,81 @@ error[E0753]: expected outer doc comment - --> $DIR/issue-30318.rs:3:1 + --> $DIR/issue-30318.rs:5:1 + | +LL | //! Misplaced comment... + | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | fn bar() { } + | ------------ the inner doc comment doesn't annotate this function + | +help: to annotate the function, change the doc comment from inner to outer style + | +LL | /// Misplaced comment... + | ~ + +error: an inner attribute is not permitted in this context + --> $DIR/issue-30318.rs:9:1 + | +LL | #![test] + | ^^^^^^^^ +LL | fn baz() { } + | ------------ the inner attribute doesn't annotate this function + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![test] +LL + #[test] + | + +error[E0753]: expected outer doc comment + --> $DIR/issue-30318.rs:13:1 + | +LL | /*! Misplaced comment... */ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | fn bat() { } + | ------------ the inner doc comment doesn't annotate this function + | +help: to annotate the function, change the doc comment from inner to outer style + | +LL | /** Misplaced comment... */ + | ~ + +error[E0753]: expected outer doc comment + --> $DIR/issue-30318.rs:19:1 | LL | //! Misplaced comment... | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +help: you might have meant to write a regular comment + | +LL - //! Misplaced comment... +LL + // Misplaced comment... + | + +error[E0753]: expected outer doc comment + --> $DIR/issue-30318.rs:23:1 + | +LL | /*! Misplaced comment... */ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +help: you might have meant to write a regular comment + | +LL - /*! Misplaced comment... */ +LL + /* Misplaced comment... */ + | + +error: expected item after doc comment + --> $DIR/issue-30318.rs:23:1 + | +LL | //! Misplaced comment... + | ------------------------ other attributes here +... +LL | /*! Misplaced comment... */ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment doesn't document anything -error: aborting due to previous error +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0753`. diff --git a/src/test/ui/parser/issue-45296.rs b/src/test/ui/parser/issue-45296.rs index f242c1d29372f..d3a97e89f9abb 100644 --- a/src/test/ui/parser/issue-45296.rs +++ b/src/test/ui/parser/issue-45296.rs @@ -2,4 +2,5 @@ fn main() { let unused = (); #![allow(unused_variables)] //~ ERROR not permitted in this context + fn foo() {} } diff --git a/src/test/ui/parser/issue-45296.stderr b/src/test/ui/parser/issue-45296.stderr index c0d4ce1243e01..6abe266d4e90e 100644 --- a/src/test/ui/parser/issue-45296.stderr +++ b/src/test/ui/parser/issue-45296.stderr @@ -3,8 +3,15 @@ error: an inner attribute is not permitted in this context | LL | #![allow(unused_variables)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo() {} + | ----------- the inner attribute doesn't annotate this function | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +help: to annotate the function, change the attribute from inner to outer style + | +LL - #![allow(unused_variables)] +LL + #[allow(unused_variables)] + | error: aborting due to previous error diff --git a/src/test/ui/parser/stmt_expr_attrs_placement.stderr b/src/test/ui/parser/stmt_expr_attrs_placement.stderr index 808903d9c62f3..bf4005698a3d6 100644 --- a/src/test/ui/parser/stmt_expr_attrs_placement.stderr +++ b/src/test/ui/parser/stmt_expr_attrs_placement.stderr @@ -4,7 +4,8 @@ error: an inner attribute is not permitted in this context LL | let a = #![allow(warnings)] (1, 2); | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/stmt_expr_attrs_placement.rs:10:14 @@ -12,7 +13,8 @@ error: an inner attribute is not permitted in this context LL | let b = (#![allow(warnings)] 1, 2); | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/stmt_expr_attrs_placement.rs:15:10 @@ -20,7 +22,8 @@ error: an inner attribute is not permitted in this context LL | (#![allow(warnings)] 1, 2) | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/stmt_expr_attrs_placement.rs:21:18 @@ -28,7 +31,8 @@ error: an inner attribute is not permitted in this context LL | let e = (#![allow(warnings)] 1, 2); | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/stmt_expr_attrs_placement.rs:26:14 @@ -36,7 +40,8 @@ error: an inner attribute is not permitted in this context LL | let e = [#![allow(warnings)] 1, 2]; | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/stmt_expr_attrs_placement.rs:29:14 @@ -44,7 +49,8 @@ error: an inner attribute is not permitted in this context LL | let f = [#![allow(warnings)] 1; 0]; | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: an inner attribute is not permitted in this context --> $DIR/stmt_expr_attrs_placement.rs:36:24 @@ -52,7 +58,8 @@ error: an inner attribute is not permitted in this context LL | let h = MyStruct { #![allow(warnings)] field: 0 }; | ^^^^^^^^^^^^^^^^^^^ | - = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + = note: outer attributes, like `#[test]`, annotate the item following them error: aborting due to 7 previous errors diff --git a/src/test/ui/proc-macro/issue-86781-bad-inner-doc.fixed b/src/test/ui/proc-macro/issue-86781-bad-inner-doc.fixed new file mode 100644 index 0000000000000..426a5fa723fcf --- /dev/null +++ b/src/test/ui/proc-macro/issue-86781-bad-inner-doc.fixed @@ -0,0 +1,12 @@ +// aux-build:test-macros.rs +// run-rustfix + +#[macro_use] +extern crate test_macros; + +/// Inner doc comment +//~^ ERROR expected outer doc comment +#[derive(Empty)] +pub struct Foo; //~ NOTE the inner doc comment doesn't annotate this struct + +fn main() {} diff --git a/src/test/ui/proc-macro/issue-86781-bad-inner-doc.rs b/src/test/ui/proc-macro/issue-86781-bad-inner-doc.rs index 8be1ae77738e9..31e3f3c859236 100644 --- a/src/test/ui/proc-macro/issue-86781-bad-inner-doc.rs +++ b/src/test/ui/proc-macro/issue-86781-bad-inner-doc.rs @@ -1,4 +1,5 @@ // aux-build:test-macros.rs +// run-rustfix #[macro_use] extern crate test_macros; @@ -6,6 +7,6 @@ extern crate test_macros; //! Inner doc comment //~^ ERROR expected outer doc comment #[derive(Empty)] -pub struct Foo; +pub struct Foo; //~ NOTE the inner doc comment doesn't annotate this struct fn main() {} diff --git a/src/test/ui/proc-macro/issue-86781-bad-inner-doc.stderr b/src/test/ui/proc-macro/issue-86781-bad-inner-doc.stderr index 0b2e612ee5bb9..a92f07522e5f2 100644 --- a/src/test/ui/proc-macro/issue-86781-bad-inner-doc.stderr +++ b/src/test/ui/proc-macro/issue-86781-bad-inner-doc.stderr @@ -1,10 +1,16 @@ error[E0753]: expected outer doc comment - --> $DIR/issue-86781-bad-inner-doc.rs:6:1 + --> $DIR/issue-86781-bad-inner-doc.rs:7:1 | LL | //! Inner doc comment | ^^^^^^^^^^^^^^^^^^^^^ +... +LL | pub struct Foo; + | --------------- the inner doc comment doesn't annotate this struct | - = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items +help: to annotate the struct, change the doc comment from inner to outer style + | +LL | /// Inner doc comment + | ~ error: aborting due to previous error From 486d79f1243135564931c574ce5cfff946ee3867 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 4 Sep 2021 18:29:03 -0700 Subject: [PATCH 4/4] Fix 2021 `dyn` suggestion that used code as label The arguments to `span_suggestion` were in the wrong order, so the error looked like this: error[E0783]: trait objects without an explicit `dyn` are deprecated --> src/test/ui/editions/dyn-trait-sugg-2021.rs:10:5 | 10 | Foo::hi(123); | ^^^ help: : `use `dyn`` Now the error looks like this, as expected: error[E0783]: trait objects without an explicit `dyn` are deprecated --> src/test/ui/editions/dyn-trait-sugg-2021.rs:10:5 | 10 | Foo::hi(123); | ^^^ help: use `dyn`: `` This issue was only present in the 2021 error; the 2018 lint was correct. --- compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs | 8 ++++---- src/test/ui/editions/dyn-trait-sugg-2021.rs | 12 ++++++++++++ src/test/ui/editions/dyn-trait-sugg-2021.stderr | 9 +++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/editions/dyn-trait-sugg-2021.rs create mode 100644 src/test/ui/editions/dyn-trait-sugg-2021.stderr diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 17e0c42440c21..9748c0835bf12 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -945,7 +945,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(s) if s.starts_with('<') => sugg, _ => format!("<{}>", sugg), }; - let replace = String::from("use `dyn`"); + let sugg_label = "use `dyn`"; if self.sess().edition() >= Edition::Edition2021 { let mut err = rustc_errors::struct_span_err!( self.sess(), @@ -956,8 +956,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); err.span_suggestion( self_ty.span, - &sugg, - replace, + sugg_label, + sugg, Applicability::MachineApplicable, ) .emit(); @@ -968,7 +968,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty.span, |lint| { let mut db = lint.build(msg); - db.span_suggestion(self_ty.span, &replace, sugg, app); + db.span_suggestion(self_ty.span, sugg_label, sugg, app); db.emit() }, ); diff --git a/src/test/ui/editions/dyn-trait-sugg-2021.rs b/src/test/ui/editions/dyn-trait-sugg-2021.rs new file mode 100644 index 0000000000000..47c48e7ec9e8b --- /dev/null +++ b/src/test/ui/editions/dyn-trait-sugg-2021.rs @@ -0,0 +1,12 @@ +// edition:2021 + +trait Foo {} + +impl dyn Foo { + fn hi(_x: T) {} +} + +fn main() { + Foo::hi(123); + //~^ ERROR trait objects without an explicit `dyn` are deprecated +} diff --git a/src/test/ui/editions/dyn-trait-sugg-2021.stderr b/src/test/ui/editions/dyn-trait-sugg-2021.stderr new file mode 100644 index 0000000000000..f6e9fa96a15b5 --- /dev/null +++ b/src/test/ui/editions/dyn-trait-sugg-2021.stderr @@ -0,0 +1,9 @@ +error[E0783]: trait objects without an explicit `dyn` are deprecated + --> $DIR/dyn-trait-sugg-2021.rs:10:5 + | +LL | Foo::hi(123); + | ^^^ help: use `dyn`: `` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0783`.