From 98642da6a9dda39e711b7f3520b0b6d40c1cd043 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 29 Mar 2024 12:31:34 -0700 Subject: [PATCH 01/10] rustdoc: point at span in `include_str!`-ed md file --- .../rustc_builtin_macros/src/source_util.rs | 10 +++-- compiler/rustc_resolve/src/rustdoc.rs | 45 ++++++++++++++++--- compiler/rustc_span/src/source_map.rs | 14 ++++-- .../auxiliary/include-str-bare-urls.md | 10 +++++ tests/rustdoc-ui/include-str-bare-urls.rs | 15 +++++++ tests/rustdoc-ui/include-str-bare-urls.stderr | 15 +++++++ tests/rustdoc-ui/intra-doc/warning.rs | 4 +- tests/rustdoc-ui/intra-doc/warning.stderr | 19 ++++---- tests/rustdoc-ui/invalid-syntax.stderr | 7 +-- tests/rustdoc-ui/unescaped_backticks.stderr | 24 +++++----- 10 files changed, 121 insertions(+), 42 deletions(-) create mode 100644 tests/rustdoc-ui/auxiliary/include-str-bare-urls.md create mode 100644 tests/rustdoc-ui/include-str-bare-urls.rs create mode 100644 tests/rustdoc-ui/include-str-bare-urls.stderr diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index abcdfabcaedae..5197556898125 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -196,10 +196,10 @@ pub fn expand_include_str( Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)), }; ExpandResult::Ready(match load_binary_file(cx, path.as_str().as_ref(), sp, path_span) { - Ok(bytes) => match std::str::from_utf8(&bytes) { + Ok((bytes, bsp)) => match std::str::from_utf8(&bytes) { Ok(src) => { let interned_src = Symbol::intern(src); - MacEager::expr(cx.expr_str(sp, interned_src)) + MacEager::expr(cx.expr_str(cx.with_def_site_ctxt(bsp), interned_src)) } Err(_) => { let guar = cx.dcx().span_err(sp, format!("`{path}` wasn't a utf-8 file")); @@ -225,7 +225,9 @@ pub fn expand_include_bytes( Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)), }; ExpandResult::Ready(match load_binary_file(cx, path.as_str().as_ref(), sp, path_span) { - Ok(bytes) => { + Ok((bytes, _bsp)) => { + // Don't care about getting the span for the raw bytes, + // because the console can't really show them anyway. let expr = cx.expr(sp, ast::ExprKind::IncludedBytes(bytes)); MacEager::expr(expr) } @@ -238,7 +240,7 @@ fn load_binary_file( original_path: &Path, macro_span: Span, path_span: Span, -) -> Result, Box> { +) -> Result<(Lrc<[u8]>, Span), Box> { let resolved_path = match resolve_path(&cx.sess, original_path, macro_span) { Ok(path) => path, Err(err) => { diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 0ebcad3cdb809..0bc7579918ccf 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -194,12 +194,12 @@ pub fn attrs_to_doc_fragments<'a>( for (attr, item_id) in attrs { if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() { let doc = beautify_doc_string(doc_str, comment_kind); - let kind = if attr.is_doc_comment() { - DocFragmentKind::SugaredDoc + let (span, kind) = if attr.is_doc_comment() { + (attr.span, DocFragmentKind::SugaredDoc) } else { - DocFragmentKind::RawDoc + (span_for_value(attr), DocFragmentKind::RawDoc) }; - let fragment = DocFragment { span: attr.span, doc, kind, item_id, indent: 0 }; + let fragment = DocFragment { span, doc, kind, item_id, indent: 0 }; doc_fragments.push(fragment); } else if !doc_only { other_attrs.push(attr.clone()); @@ -211,6 +211,16 @@ pub fn attrs_to_doc_fragments<'a>( (doc_fragments, other_attrs) } +fn span_for_value(attr: &ast::Attribute) -> Span { + if let ast::AttrKind::Normal(normal) = &attr.kind + && let ast::AttrArgs::Eq(_, ast::AttrArgsEq::Hir(meta)) = &normal.item.args + { + meta.span.with_ctxt(attr.span.ctxt()) + } else { + attr.span + } +} + /// Return the doc-comments on this item, grouped by the module they came from. /// The module can be different if this is a re-export with added documentation. /// @@ -482,15 +492,36 @@ pub fn span_of_fragments(fragments: &[DocFragment]) -> Option { /// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code. /// -/// This method will return `None` if we cannot construct a span from the source map or if the -/// fragments are not all sugared doc comments. It's difficult to calculate the correct span in -/// that case due to escaping and other source features. +/// This method does not always work, because markdown bytes don't necessarily match source bytes, +/// like if escapes are used in the string. In this case, it returns `None`. +/// +/// This method will return `Some` only if: +/// +/// - The doc is made entirely from sugared doc comments, which cannot contain escapes +/// - The doc is entirely from a single doc fragment, with a string literal, exactly equal +/// - The doc comes from `include_str!` pub fn source_span_for_markdown_range( tcx: TyCtxt<'_>, markdown: &str, md_range: &Range, fragments: &[DocFragment], ) -> Option { + if let &[fragment] = &fragments + && fragment.kind == DocFragmentKind::RawDoc + && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(fragment.span) + && snippet.trim_end() == markdown.trim_end() + && let Ok(md_range_lo) = u32::try_from(md_range.start) + && let Ok(md_range_hi) = u32::try_from(md_range.end) + { + // Single fragment with string that contains same bytes as doc. + return Some(Span::new( + fragment.span.lo() + rustc_span::BytePos(md_range_lo), + fragment.span.lo() + rustc_span::BytePos(md_range_hi), + fragment.span.ctxt(), + fragment.span.parent(), + )); + } + let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc); if !is_all_sugared_doc { diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index df7635e447da8..cac4d6064e55c 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -218,7 +218,7 @@ impl SourceMap { /// /// Unlike `load_file`, guarantees that no normalization like BOM-removal /// takes place. - pub fn load_binary_file(&self, path: &Path) -> io::Result> { + pub fn load_binary_file(&self, path: &Path) -> io::Result<(Lrc<[u8]>, Span)> { let bytes = self.file_loader.read_binary_file(path)?; // We need to add file to the `SourceMap`, so that it is present @@ -227,8 +227,16 @@ impl SourceMap { // via `mod`, so we try to use real file contents and not just an // empty string. let text = std::str::from_utf8(&bytes).unwrap_or("").to_string(); - self.new_source_file(path.to_owned().into(), text); - Ok(bytes) + let file = self.new_source_file(path.to_owned().into(), text); + Ok(( + bytes, + Span::new( + file.start_pos, + BytePos(file.start_pos.0 + file.source_len.0), + SyntaxContext::root(), + None, + ), + )) } // By returning a `MonotonicVec`, we ensure that consumers cannot invalidate diff --git a/tests/rustdoc-ui/auxiliary/include-str-bare-urls.md b/tests/rustdoc-ui/auxiliary/include-str-bare-urls.md new file mode 100644 index 0000000000000..b07717d8f020f --- /dev/null +++ b/tests/rustdoc-ui/auxiliary/include-str-bare-urls.md @@ -0,0 +1,10 @@ +HEADS UP! https://example.com MUST SHOW UP IN THE STDERR FILE! + +Normally, a line with errors on it will also have a comment +marking it up as something that needs to generate an error. + +The test harness doesn't gather hot comments from this file. +Rustdoc will generate an error for the line, and the `.stderr` +snapshot includes this error, but Compiletest doesn't see it. + +If the stderr file changes, make sure the warning points at the URL! diff --git a/tests/rustdoc-ui/include-str-bare-urls.rs b/tests/rustdoc-ui/include-str-bare-urls.rs new file mode 100644 index 0000000000000..c452c88cdd3db --- /dev/null +++ b/tests/rustdoc-ui/include-str-bare-urls.rs @@ -0,0 +1,15 @@ +// https://github.com/rust-lang/rust/issues/118549 +// +// HEADS UP! +// +// Normally, a line with errors on it will also have a comment +// marking it up as something that needs to generate an error. +// +// The test harness doesn't gather hot comments from the `.md` file. +// Rustdoc will generate an error for the line, and the `.stderr` +// snapshot includes this error, but Compiletest doesn't see it. +// +// If the stderr file changes, make sure the warning points at the URL! + +#![deny(rustdoc::bare_urls)] +#![doc=include_str!("auxiliary/include-str-bare-urls.md")] diff --git a/tests/rustdoc-ui/include-str-bare-urls.stderr b/tests/rustdoc-ui/include-str-bare-urls.stderr new file mode 100644 index 0000000000000..a4234196b2310 --- /dev/null +++ b/tests/rustdoc-ui/include-str-bare-urls.stderr @@ -0,0 +1,15 @@ +error: this URL is not a hyperlink + --> $DIR/auxiliary/include-str-bare-urls.md:1:11 + | +LL | HEADS UP! https://example.com MUST SHOW UP IN THE STDERR FILE! + | ^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | + = note: bare URLs are not automatically turned into clickable links +note: the lint level is defined here + --> $DIR/include-str-bare-urls.rs:14:9 + | +LL | #![deny(rustdoc::bare_urls)] + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/warning.rs b/tests/rustdoc-ui/intra-doc/warning.rs index 96b5c2b36a181..ed51b2fa41b03 100644 --- a/tests/rustdoc-ui/intra-doc/warning.rs +++ b/tests/rustdoc-ui/intra-doc/warning.rs @@ -47,11 +47,11 @@ pub fn d() {} macro_rules! f { ($f:expr) => { - #[doc = $f] //~ WARNING `BarF` + #[doc = $f] pub fn f() {} } } -f!("Foo\nbar [BarF] bar\nbaz"); +f!("Foo\nbar [BarF] bar\nbaz"); //~ WARNING `BarF` /** # for example, * diff --git a/tests/rustdoc-ui/intra-doc/warning.stderr b/tests/rustdoc-ui/intra-doc/warning.stderr index 19399a0df5bf9..3a06f1787e093 100644 --- a/tests/rustdoc-ui/intra-doc/warning.stderr +++ b/tests/rustdoc-ui/intra-doc/warning.stderr @@ -69,10 +69,10 @@ LL | bar [BarC] bar = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarD` - --> $DIR/warning.rs:45:1 + --> $DIR/warning.rs:45:9 | LL | #[doc = "Foo\nbar [BarD] bar\nbaz"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the link appears in this line: @@ -82,13 +82,10 @@ LL | #[doc = "Foo\nbar [BarD] bar\nbaz"] = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarF` - --> $DIR/warning.rs:50:9 + --> $DIR/warning.rs:54:4 | -LL | #[doc = $f] - | ^^^^^^^^^^^ -... LL | f!("Foo\nbar [BarF] bar\nbaz"); - | ------------------------------ in this macro invocation + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the link appears in this line: @@ -115,10 +112,10 @@ LL | * time to introduce a link [error] = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` - --> $DIR/warning.rs:68:1 + --> $DIR/warning.rs:68:9 | LL | #[doc = "single line [error]"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ | = note: the link appears in this line: @@ -128,10 +125,10 @@ LL | #[doc = "single line [error]"] = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` - --> $DIR/warning.rs:71:1 + --> $DIR/warning.rs:71:9 | LL | #[doc = "single line with \"escaping\" [error]"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the link appears in this line: diff --git a/tests/rustdoc-ui/invalid-syntax.stderr b/tests/rustdoc-ui/invalid-syntax.stderr index 6140a06c555f2..46d7cdb4f7e64 100644 --- a/tests/rustdoc-ui/invalid-syntax.stderr +++ b/tests/rustdoc-ui/invalid-syntax.stderr @@ -90,12 +90,13 @@ LL | | /// ``` = note: error from rustc: unknown start of token: \ warning: could not parse code block as Rust code - --> $DIR/invalid-syntax.rs:70:1 + --> $DIR/invalid-syntax.rs:70:9 | -LL | / #[doc = "```"] +LL | #[doc = "```"] + | _________^ LL | | /// \_ LL | | #[doc = "```"] - | |______________^ + | |_____________^ | = help: mark blocks that do not contain Rust code as text: ```text = note: error from rustc: unknown start of token: \ diff --git a/tests/rustdoc-ui/unescaped_backticks.stderr b/tests/rustdoc-ui/unescaped_backticks.stderr index 000a5b597d299..67b87f353a153 100644 --- a/tests/rustdoc-ui/unescaped_backticks.stderr +++ b/tests/rustdoc-ui/unescaped_backticks.stderr @@ -640,10 +640,10 @@ LL | /// or even to add a number `n` to 42 (`add(42, n)\`)! | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:108:1 + --> $DIR/unescaped_backticks.rs:108:9 | LL | #[doc = "`"] - | ^^^^^^^^^^^^ + | ^^^ | = help: the opening or closing backtick of an inline code may be missing = help: if you meant to use a literal backtick, escape it @@ -651,10 +651,10 @@ LL | #[doc = "`"] to this: \` error: unescaped backtick - --> $DIR/unescaped_backticks.rs:115:1 + --> $DIR/unescaped_backticks.rs:115:9 | LL | #[doc = concat!("\\", "`")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ | = help: the opening backtick of an inline code may be missing change: \` @@ -664,10 +664,10 @@ LL | #[doc = concat!("\\", "`")] to this: \\` error: unescaped backtick - --> $DIR/unescaped_backticks.rs:119:1 + --> $DIR/unescaped_backticks.rs:119:9 | LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: the opening backtick of a previous inline code may be missing change: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. @@ -677,10 +677,10 @@ LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same a to this: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:123:1 + --> $DIR/unescaped_backticks.rs:123:9 | LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: a previous inline code might be longer than expected change: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. @@ -690,10 +690,10 @@ LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same a to this: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:127:1 + --> $DIR/unescaped_backticks.rs:127:9 | LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: the opening backtick of an inline code may be missing change: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. @@ -703,10 +703,10 @@ LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same to this: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:131:1 + --> $DIR/unescaped_backticks.rs:131:9 | LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: the closing backtick of an inline code may be missing change: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). From 1b73c7d1e505152e96454364f1eb9d1c25b84772 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 29 Mar 2024 13:34:01 -0700 Subject: [PATCH 02/10] clippy: fix up `include_str!` spans in diagnostics --- .../clippy/clippy_lints/src/large_include_file.rs | 2 +- src/tools/clippy/clippy_lints/src/strings.rs | 2 +- .../large_include_file/large_include_file.stderr | 2 -- src/tools/clippy/tests/ui/empty_docs.stderr | 11 ++++++----- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/large_include_file.rs b/src/tools/clippy/clippy_lints/src/large_include_file.rs index 1b5981ecc281a..553d447d440a3 100644 --- a/src/tools/clippy/clippy_lints/src/large_include_file.rs +++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs @@ -71,7 +71,7 @@ impl LateLintPass<'_> for LargeIncludeFile { span_lint_and_note( cx, LARGE_INCLUDE_FILE, - expr.span, + expr.span.source_callsite(), "attempted to include a large file", None, &format!( diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs index 13ae1ff52ddfe..2179013485452 100644 --- a/src/tools/clippy/clippy_lints/src/strings.rs +++ b/src/tools/clippy/clippy_lints/src/strings.rs @@ -300,7 +300,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes { e.span, "calling `as_bytes()` on `include_str!(..)`", "consider using `include_bytes!(..)` instead", - snippet_with_applicability(cx, receiver.span, r#""foo""#, &mut applicability).replacen( + snippet_with_applicability(cx, receiver.span.source_callsite(), r#""foo""#, &mut applicability).replacen( "include_str", "include_bytes", 1, diff --git a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr index b45cb11939f0f..34224065f0789 100644 --- a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr +++ b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr @@ -7,7 +7,6 @@ LL | const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt"); = note: the configuration allows a maximum size of 600 bytes = note: `-D clippy::large-include-file` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::large_include_file)]` - = note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info) error: attempted to include a large file --> tests/ui-toml/large_include_file/large_include_file.rs:14:35 @@ -16,7 +15,6 @@ LL | const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the configuration allows a maximum size of 600 bytes - = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/empty_docs.stderr b/src/tools/clippy/tests/ui/empty_docs.stderr index 28ebea22c5db8..5fd7272d7c168 100644 --- a/src/tools/clippy/tests/ui/empty_docs.stderr +++ b/src/tools/clippy/tests/ui/empty_docs.stderr @@ -25,19 +25,20 @@ LL | /// = help: consider removing or filling it error: empty doc comment - --> tests/ui/empty_docs.rs:30:5 + --> tests/ui/empty_docs.rs:30:13 | LL | #[doc = ""] - | ^^^^^^^^^^^ + | ^^ | = help: consider removing or filling it error: empty doc comment - --> tests/ui/empty_docs.rs:33:5 + --> tests/ui/empty_docs.rs:33:13 | -LL | / #[doc = ""] +LL | #[doc = ""] + | _____________^ LL | | #[doc = ""] - | |_______________^ + | |______________^ | = help: consider removing or filling it From 1c41dd6320f1729e799171d98f5ff384246ddcd5 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 29 Mar 2024 17:13:46 -0700 Subject: [PATCH 03/10] diagnostics: fix crash on completely empty included file --- compiler/rustc_errors/src/emitter.rs | 9 +++++++-- tests/ui/include-macros/mismatched-types.stderr | 7 +++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index bd8e78bda2639..6ce3fa3535dc9 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1513,7 +1513,9 @@ impl HumanEmitter { for line_idx in 0..annotated_file.lines.len() { let file = annotated_file.file.clone(); let line = &annotated_file.lines[line_idx]; - if let Some(source_string) = file.get_line(line.line_index - 1) { + if let Some(source_string) = + line.line_index.checked_sub(1).and_then(|l| file.get_line(l)) + { let leading_whitespace = source_string .chars() .take_while(|c| c.is_whitespace()) @@ -1553,7 +1555,10 @@ impl HumanEmitter { for line in &annotated_file.lines { max_line_len = max( max_line_len, - annotated_file.file.get_line(line.line_index - 1).map_or(0, |s| s.len()), + line.line_index + .checked_sub(1) + .and_then(|l| annotated_file.file.get_line(l)) + .map_or(0, |s| s.len()), ); for ann in &line.annotations { span_right_margin = max(span_right_margin, ann.start_col.display); diff --git a/tests/ui/include-macros/mismatched-types.stderr b/tests/ui/include-macros/mismatched-types.stderr index 4f2880e2f5d49..9bc0e64464e23 100644 --- a/tests/ui/include-macros/mismatched-types.stderr +++ b/tests/ui/include-macros/mismatched-types.stderr @@ -1,8 +1,11 @@ error[E0308]: mismatched types - --> $DIR/mismatched-types.rs:2:20 + --> $DIR/file.txt:0:1 + | + | + ::: $DIR/mismatched-types.rs:2:12 | LL | let b: &[u8] = include_str!("file.txt"); - | ----- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `&[u8]`, found `&str` + | ----- ------------------------ in this macro invocation | | | expected due to this | From e572a194bf76957fa41495aa13f9925df6e632b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 30 Mar 2024 02:50:17 +0000 Subject: [PATCH 04/10] Fix invalid silencing of parsing error Given ```rust macro_rules! a { ( ) => { impl<'b> c for d { e:: } }; } ``` ensure an error is emitted. Fix #123079. --- compiler/rustc_parse/src/lexer/mod.rs | 20 +++++--------- ...on-invalid-lifetime-in-macro-definition.rs | 9 +++++++ ...nvalid-lifetime-in-macro-definition.stderr | 14 ++++++++++ .../ui/lexer/lex-bad-str-literal-as-char-3.rs | 3 ++- ...-bad-str-literal-as-char-3.rust2021.stderr | 14 +++++++++- .../ui/lexer/lex-bad-str-literal-as-char-4.rs | 9 +++++++ .../lex-bad-str-literal-as-char-4.stderr | 26 +++++++++++++++++++ 7 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.rs create mode 100644 tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.stderr create mode 100644 tests/ui/lexer/lex-bad-str-literal-as-char-4.rs create mode 100644 tests/ui/lexer/lex-bad-str-literal-as-char-4.stderr diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 69b48bf0aff71..f381995d346bd 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -698,7 +698,6 @@ impl<'psess, 'src> StringReader<'psess, 'src> { let expn_data = prefix_span.ctxt().outer_expn_data(); if expn_data.edition >= Edition::Edition2021 { - let mut silence = false; // In Rust 2021, this is a hard error. let sugg = if prefix == "rb" { Some(errors::UnknownPrefixSugg::UseBr(prefix_span)) @@ -706,25 +705,20 @@ impl<'psess, 'src> StringReader<'psess, 'src> { if self.cursor.first() == '\'' && let Some(start) = self.last_lifetime && self.cursor.third() != '\'' + && let end = self.mk_sp(self.pos, self.pos + BytePos(1)) + && !self.psess.source_map().is_multiline(start.until(end)) { - // An "unclosed `char`" error will be emitted already, silence redundant error. - silence = true; - Some(errors::UnknownPrefixSugg::MeantStr { - start, - end: self.mk_sp(self.pos, self.pos + BytePos(1)), - }) + // FIXME: An "unclosed `char`" error will be emitted already in some cases, + // but it's hard to silence this error while not also silencing important cases + // too. We should use the error stashing machinery instead. + Some(errors::UnknownPrefixSugg::MeantStr { start, end }) } else { Some(errors::UnknownPrefixSugg::Whitespace(prefix_span.shrink_to_hi())) } } else { None }; - let err = errors::UnknownPrefix { span: prefix_span, prefix, sugg }; - if silence { - self.dcx().create_err(err).delay_as_bug(); - } else { - self.dcx().emit_err(err); - } + self.dcx().emit_err(errors::UnknownPrefix { span: prefix_span, prefix, sugg }); } else { // Before Rust 2021, only emit a lint for migration. self.psess.buffer_lint_with_diagnostic( diff --git a/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.rs b/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.rs new file mode 100644 index 0000000000000..caae48dfd3bdf --- /dev/null +++ b/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.rs @@ -0,0 +1,9 @@ +//@ edition:2021 +macro_rules! a { + ( ) => { + impl<'b> c for d { + e:: //~ ERROR prefix `f` is unknown + } + }; +} +fn main() {} diff --git a/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.stderr b/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.stderr new file mode 100644 index 0000000000000..ecce2c6650459 --- /dev/null +++ b/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.stderr @@ -0,0 +1,14 @@ +error: prefix `f` is unknown + --> $DIR/dont-ice-on-invalid-lifetime-in-macro-definition.rs:5:17 + | +LL | e:: + | ^ unknown prefix + | + = note: prefixed identifiers and literals are reserved since Rust 2021 +help: consider inserting whitespace here + | +LL | e:: + | + + +error: aborting due to 1 previous error + diff --git a/tests/ui/lexer/lex-bad-str-literal-as-char-3.rs b/tests/ui/lexer/lex-bad-str-literal-as-char-3.rs index 0ae227da5f1e6..52781d9c6d858 100644 --- a/tests/ui/lexer/lex-bad-str-literal-as-char-3.rs +++ b/tests/ui/lexer/lex-bad-str-literal-as-char-3.rs @@ -3,5 +3,6 @@ //@[rust2021] edition:2021 fn main() { println!('hello world'); - //[rust2015,rust2018,rust2021]~^ ERROR unterminated character literal + //~^ ERROR unterminated character literal + //[rust2021]~| ERROR prefix `world` is unknown } diff --git a/tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr b/tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr index 06f127426679f..4170560cfcb04 100644 --- a/tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr +++ b/tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr @@ -1,3 +1,15 @@ +error: prefix `world` is unknown + --> $DIR/lex-bad-str-literal-as-char-3.rs:5:21 + | +LL | println!('hello world'); + | ^^^^^ unknown prefix + | + = note: prefixed identifiers and literals are reserved since Rust 2021 +help: if you meant to write a string literal, use double quotes + | +LL | println!("hello world"); + | ~ ~ + error[E0762]: unterminated character literal --> $DIR/lex-bad-str-literal-as-char-3.rs:5:26 | @@ -9,6 +21,6 @@ help: if you meant to write a string literal, use double quotes LL | println!("hello world"); | ~ ~ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0762`. diff --git a/tests/ui/lexer/lex-bad-str-literal-as-char-4.rs b/tests/ui/lexer/lex-bad-str-literal-as-char-4.rs new file mode 100644 index 0000000000000..f0c7ad8f82b7e --- /dev/null +++ b/tests/ui/lexer/lex-bad-str-literal-as-char-4.rs @@ -0,0 +1,9 @@ +//@edition:2021 +macro_rules! foo { + () => { + println!('hello world'); + //~^ ERROR unterminated character literal + //~| ERROR prefix `world` is unknown + } +} +fn main() {} diff --git a/tests/ui/lexer/lex-bad-str-literal-as-char-4.stderr b/tests/ui/lexer/lex-bad-str-literal-as-char-4.stderr new file mode 100644 index 0000000000000..af42b5b7f7b78 --- /dev/null +++ b/tests/ui/lexer/lex-bad-str-literal-as-char-4.stderr @@ -0,0 +1,26 @@ +error: prefix `world` is unknown + --> $DIR/lex-bad-str-literal-as-char-4.rs:4:25 + | +LL | println!('hello world'); + | ^^^^^ unknown prefix + | + = note: prefixed identifiers and literals are reserved since Rust 2021 +help: if you meant to write a string literal, use double quotes + | +LL | println!("hello world"); + | ~ ~ + +error[E0762]: unterminated character literal + --> $DIR/lex-bad-str-literal-as-char-4.rs:4:30 + | +LL | println!('hello world'); + | ^^^ + | +help: if you meant to write a string literal, use double quotes + | +LL | println!("hello world"); + | ~ ~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0762`. From d8dc28b93e4cbfe2a3c26af06c73b0ea46f67a1e Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Thu, 11 Apr 2024 17:27:49 -0400 Subject: [PATCH 05/10] Call the panic hook for non-unwind panics in proc-macros --- library/proc_macro/src/bridge/client.rs | 6 +++++- library/proc_macro/src/lib.rs | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index f3cfc41bac7c6..faca745e56f74 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -283,7 +283,11 @@ fn maybe_install_panic_hook(force_show_panics: bool) { HIDE_PANICS_DURING_EXPANSION.call_once(|| { let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { - if force_show_panics || !is_available() { + // We normally report panics by catching unwinds and passing the payload from the + // unwind back to the compiler, but if the panic doesn't unwind we'll abort before + // the compiler has a chance to print an error. So we special-case PanicInfo where + // can_unwind is false. + if force_show_panics || !is_available() || !info.can_unwind() { prev(info) } })); diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 01c449563ee92..a3ebef45c8849 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -30,6 +30,7 @@ #![feature(maybe_uninit_write_slice)] #![feature(negative_impls)] #![feature(new_uninit)] +#![feature(panic_can_unwind)] #![feature(restricted_std)] #![feature(rustc_attrs)] #![feature(min_specialization)] From 8a6ec2eadd6b4b3dd5561eea5e57aa70ecda3ca8 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Thu, 11 Apr 2024 16:26:02 -0700 Subject: [PATCH 06/10] Update stdarch submodule --- library/core/src/lib.rs | 1 + library/stdarch | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 10d2698c5dd1b..981dde4dfc2e2 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -111,6 +111,7 @@ // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(associated_type_bounds))] #![feature(array_ptr_get)] +#![feature(asm_experimental_arch)] #![feature(char_indices_offset)] #![feature(const_align_of_val)] #![feature(const_align_of_val_raw)] diff --git a/library/stdarch b/library/stdarch index 967e7afd87cbe..7df81ba8c3e2d 160000 --- a/library/stdarch +++ b/library/stdarch @@ -1 +1 @@ -Subproject commit 967e7afd87cbea3232581a4a55031134ab88f595 +Subproject commit 7df81ba8c3e2d02c2ace0c5a6f4f32d800c09e56 From ac1bee64938b5eb8244702400f700df88f2589ff Mon Sep 17 00:00:00 2001 From: morine0122 Date: Fri, 12 Apr 2024 12:40:11 +0900 Subject: [PATCH 07/10] Improve diagnostic by suggesting to remove visibility qualifier --- compiler/rustc_ast_passes/messages.ftl | 1 + .../rustc_ast_passes/src/ast_validation.rs | 6 +++- compiler/rustc_ast_passes/src/errors.rs | 6 ++++ tests/ui/error-codes/E0449.fixed | 18 ++++++++++ tests/ui/error-codes/E0449.rs | 4 +++ tests/ui/error-codes/E0449.stderr | 12 +++---- tests/ui/issues/issue-28433.stderr | 4 +-- .../assoc/assoc-static-semantic-fail.stderr | 4 +-- tests/ui/parser/default.stderr | 2 +- tests/ui/parser/trait-pub-assoc-const.stderr | 2 +- tests/ui/parser/trait-pub-assoc-ty.stderr | 2 +- tests/ui/parser/trait-pub-method.stderr | 2 +- tests/ui/privacy/issue-113860-1.stderr | 2 +- tests/ui/privacy/issue-113860-2.stderr | 2 +- tests/ui/privacy/issue-113860.stderr | 2 +- tests/ui/privacy/issue-29161.stderr | 2 +- tests/ui/privacy/priv-in-bad-locations.stderr | 8 ++--- tests/ui/privacy/privacy-sanity.stderr | 36 +++++++++---------- tests/ui/privacy/useless-pub.stderr | 6 ++-- 19 files changed, 77 insertions(+), 44 deletions(-) create mode 100644 tests/ui/error-codes/E0449.fixed diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index ac3799e7a0565..a3731e94276b5 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -273,6 +273,7 @@ ast_passes_visibility_not_permitted = .trait_impl = trait items always share the visibility of their trait .individual_impl_items = place qualifiers on individual impl items instead .individual_foreign_items = place qualifiers on individual foreign items instead + .remove_qualifier_sugg = remove the qualifier ast_passes_where_clause_after_type_alias = where clauses are not allowed after the type for type aliases .note = see issue #112792 for more information diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 093a985495c9f..a386bc70ad439 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -266,7 +266,11 @@ impl<'a> AstValidator<'a> { return; } - self.dcx().emit_err(errors::VisibilityNotPermitted { span: vis.span, note }); + self.dcx().emit_err(errors::VisibilityNotPermitted { + span: vis.span, + note, + remove_qualifier_sugg: vis.span, + }); } fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option, bool)) { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 8ae9f7d3966f8..f397c949e0486 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -31,6 +31,12 @@ pub struct VisibilityNotPermitted { pub span: Span, #[subdiagnostic] pub note: VisibilityNotPermittedNote, + #[suggestion( + ast_passes_remove_qualifier_sugg, + code = "", + applicability = "machine-applicable" + )] + pub remove_qualifier_sugg: Span, } #[derive(Subdiagnostic)] diff --git a/tests/ui/error-codes/E0449.fixed b/tests/ui/error-codes/E0449.fixed new file mode 100644 index 0000000000000..c7b4566303dc0 --- /dev/null +++ b/tests/ui/error-codes/E0449.fixed @@ -0,0 +1,18 @@ +//@ run-rustfix + +#![allow(warnings)] + +struct Bar; + +trait Foo { + fn foo(); +} + + impl Bar {} //~ ERROR E0449 + + impl Foo for Bar { //~ ERROR E0449 + fn foo() {} //~ ERROR E0449 +} + +fn main() { +} diff --git a/tests/ui/error-codes/E0449.rs b/tests/ui/error-codes/E0449.rs index eba0d479e9712..32d9b35169cea 100644 --- a/tests/ui/error-codes/E0449.rs +++ b/tests/ui/error-codes/E0449.rs @@ -1,3 +1,7 @@ +//@ run-rustfix + +#![allow(warnings)] + struct Bar; trait Foo { diff --git a/tests/ui/error-codes/E0449.stderr b/tests/ui/error-codes/E0449.stderr index cf41bcce8c202..c6a98269a19ce 100644 --- a/tests/ui/error-codes/E0449.stderr +++ b/tests/ui/error-codes/E0449.stderr @@ -1,24 +1,24 @@ error[E0449]: visibility qualifiers are not permitted here - --> $DIR/E0449.rs:7:1 + --> $DIR/E0449.rs:11:1 | LL | pub impl Bar {} - | ^^^ + | ^^^ help: remove the qualifier | = note: place qualifiers on individual impl items instead error[E0449]: visibility qualifiers are not permitted here - --> $DIR/E0449.rs:9:1 + --> $DIR/E0449.rs:13:1 | LL | pub impl Foo for Bar { - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/E0449.rs:10:5 + --> $DIR/E0449.rs:14:5 | LL | pub fn foo() {} - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait diff --git a/tests/ui/issues/issue-28433.stderr b/tests/ui/issues/issue-28433.stderr index 5fb8a89621c2d..0fa67e35f1d4b 100644 --- a/tests/ui/issues/issue-28433.stderr +++ b/tests/ui/issues/issue-28433.stderr @@ -2,7 +2,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/issue-28433.rs:2:5 | LL | pub Duck, - | ^^^ + | ^^^ help: remove the qualifier | = note: enum variants and their fields always share the visibility of the enum they are in @@ -10,7 +10,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/issue-28433.rs:5:5 | LL | pub(crate) Dove - | ^^^^^^^^^^ + | ^^^^^^^^^^ help: remove the qualifier | = note: enum variants and their fields always share the visibility of the enum they are in diff --git a/tests/ui/parser/assoc/assoc-static-semantic-fail.stderr b/tests/ui/parser/assoc/assoc-static-semantic-fail.stderr index 8178bd2237326..cc21df77353f5 100644 --- a/tests/ui/parser/assoc/assoc-static-semantic-fail.stderr +++ b/tests/ui/parser/assoc/assoc-static-semantic-fail.stderr @@ -138,7 +138,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/assoc-static-semantic-fail.rs:32:5 | LL | pub(crate) default static TD: u8; - | ^^^^^^^^^^ + | ^^^^^^^^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -162,7 +162,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/assoc-static-semantic-fail.rs:47:5 | LL | pub default static TD: u8; - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait diff --git a/tests/ui/parser/default.stderr b/tests/ui/parser/default.stderr index e6330f368d917..c420e5a774d20 100644 --- a/tests/ui/parser/default.stderr +++ b/tests/ui/parser/default.stderr @@ -21,7 +21,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/default.rs:17:5 | LL | pub default fn foo() -> T { - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait diff --git a/tests/ui/parser/trait-pub-assoc-const.stderr b/tests/ui/parser/trait-pub-assoc-const.stderr index 436f6a3909c32..1bace786b2181 100644 --- a/tests/ui/parser/trait-pub-assoc-const.stderr +++ b/tests/ui/parser/trait-pub-assoc-const.stderr @@ -2,7 +2,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/trait-pub-assoc-const.rs:2:5 | LL | pub const Foo: u32; - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait diff --git a/tests/ui/parser/trait-pub-assoc-ty.stderr b/tests/ui/parser/trait-pub-assoc-ty.stderr index 279e3a95354b5..28e05bdc63045 100644 --- a/tests/ui/parser/trait-pub-assoc-ty.stderr +++ b/tests/ui/parser/trait-pub-assoc-ty.stderr @@ -2,7 +2,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/trait-pub-assoc-ty.rs:2:5 | LL | pub type Foo; - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait diff --git a/tests/ui/parser/trait-pub-method.stderr b/tests/ui/parser/trait-pub-method.stderr index ee8b6f7cb62eb..cc1ba0eaaeaea 100644 --- a/tests/ui/parser/trait-pub-method.stderr +++ b/tests/ui/parser/trait-pub-method.stderr @@ -2,7 +2,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/trait-pub-method.rs:2:5 | LL | pub fn foo(); - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait diff --git a/tests/ui/privacy/issue-113860-1.stderr b/tests/ui/privacy/issue-113860-1.stderr index c33ce26f0f6e8..c05452fb51c79 100644 --- a/tests/ui/privacy/issue-113860-1.stderr +++ b/tests/ui/privacy/issue-113860-1.stderr @@ -2,7 +2,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/issue-113860-1.rs:12:5 | LL | pub(self) fn fun() {} - | ^^^^^^^^^ + | ^^^^^^^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait diff --git a/tests/ui/privacy/issue-113860-2.stderr b/tests/ui/privacy/issue-113860-2.stderr index 6748bc276684a..c53c490ca1ecb 100644 --- a/tests/ui/privacy/issue-113860-2.stderr +++ b/tests/ui/privacy/issue-113860-2.stderr @@ -2,7 +2,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/issue-113860-2.rs:12:5 | LL | pub(self) type X = Self; - | ^^^^^^^^^ + | ^^^^^^^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait diff --git a/tests/ui/privacy/issue-113860.stderr b/tests/ui/privacy/issue-113860.stderr index 3204f4ff9162f..d813b740ac5bd 100644 --- a/tests/ui/privacy/issue-113860.stderr +++ b/tests/ui/privacy/issue-113860.stderr @@ -2,7 +2,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/issue-113860.rs:12:5 | LL | pub(self) const X: u32 = 3; - | ^^^^^^^^^ + | ^^^^^^^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait diff --git a/tests/ui/privacy/issue-29161.stderr b/tests/ui/privacy/issue-29161.stderr index 1a6c80499a1bf..f8911cb09c1bc 100644 --- a/tests/ui/privacy/issue-29161.stderr +++ b/tests/ui/privacy/issue-29161.stderr @@ -2,7 +2,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/issue-29161.rs:5:9 | LL | pub fn default() -> A { - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait diff --git a/tests/ui/privacy/priv-in-bad-locations.stderr b/tests/ui/privacy/priv-in-bad-locations.stderr index 70dab5bfe13df..93a0eabb91456 100644 --- a/tests/ui/privacy/priv-in-bad-locations.stderr +++ b/tests/ui/privacy/priv-in-bad-locations.stderr @@ -2,7 +2,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/priv-in-bad-locations.rs:1:1 | LL | pub extern "C" { - | ^^^ + | ^^^ help: remove the qualifier | = note: place qualifiers on individual foreign items instead @@ -10,7 +10,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/priv-in-bad-locations.rs:11:1 | LL | pub impl B {} - | ^^^ + | ^^^ help: remove the qualifier | = note: place qualifiers on individual impl items instead @@ -18,7 +18,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/priv-in-bad-locations.rs:13:1 | LL | pub impl A for B { - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -26,7 +26,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/priv-in-bad-locations.rs:14:5 | LL | pub fn foo(&self) {} - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait diff --git a/tests/ui/privacy/privacy-sanity.stderr b/tests/ui/privacy/privacy-sanity.stderr index a537f8c190103..0acb05cbabaa7 100644 --- a/tests/ui/privacy/privacy-sanity.stderr +++ b/tests/ui/privacy/privacy-sanity.stderr @@ -2,7 +2,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:13:1 | LL | pub impl Tr for S { - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -10,7 +10,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:14:5 | LL | pub fn f() {} - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -18,7 +18,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:15:5 | LL | pub const C: u8 = 0; - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -26,7 +26,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:16:5 | LL | pub type T = u8; - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -34,7 +34,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:18:1 | LL | pub impl S { - | ^^^ + | ^^^ help: remove the qualifier | = note: place qualifiers on individual impl items instead @@ -42,7 +42,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:23:1 | LL | pub extern "C" { - | ^^^ + | ^^^ help: remove the qualifier | = note: place qualifiers on individual foreign items instead @@ -50,7 +50,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:39:5 | LL | pub impl Tr for S { - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -58,7 +58,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:40:9 | LL | pub fn f() {} - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -66,7 +66,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:41:9 | LL | pub const C: u8 = 0; - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -74,7 +74,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:42:9 | LL | pub type T = u8; - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -82,7 +82,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:44:5 | LL | pub impl S { - | ^^^ + | ^^^ help: remove the qualifier | = note: place qualifiers on individual impl items instead @@ -90,7 +90,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:49:5 | LL | pub extern "C" { - | ^^^ + | ^^^ help: remove the qualifier | = note: place qualifiers on individual foreign items instead @@ -98,7 +98,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:68:5 | LL | pub impl Tr for S { - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -106,7 +106,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:69:9 | LL | pub fn f() {} - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -114,7 +114,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:70:9 | LL | pub const C: u8 = 0; - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -122,7 +122,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:71:9 | LL | pub type T = u8; - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -130,7 +130,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:73:5 | LL | pub impl S { - | ^^^ + | ^^^ help: remove the qualifier | = note: place qualifiers on individual impl items instead @@ -138,7 +138,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/privacy-sanity.rs:78:5 | LL | pub extern "C" { - | ^^^ + | ^^^ help: remove the qualifier | = note: place qualifiers on individual foreign items instead diff --git a/tests/ui/privacy/useless-pub.stderr b/tests/ui/privacy/useless-pub.stderr index 73497e3fed5bf..7d064c12a09d6 100644 --- a/tests/ui/privacy/useless-pub.stderr +++ b/tests/ui/privacy/useless-pub.stderr @@ -2,7 +2,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/useless-pub.rs:8:5 | LL | pub fn foo(&self) {} - | ^^^ + | ^^^ help: remove the qualifier | = note: trait items always share the visibility of their trait @@ -10,7 +10,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/useless-pub.rs:12:10 | LL | V1 { pub f: i32 }, - | ^^^ + | ^^^ help: remove the qualifier | = note: enum variants and their fields always share the visibility of the enum they are in @@ -18,7 +18,7 @@ error[E0449]: visibility qualifiers are not permitted here --> $DIR/useless-pub.rs:13:8 | LL | V2(pub i32), - | ^^^ + | ^^^ help: remove the qualifier | = note: enum variants and their fields always share the visibility of the enum they are in From 9139d7252de74c30539afb35dc05e3536456971b Mon Sep 17 00:00:00 2001 From: Guy Shefy Date: Sat, 30 Mar 2024 16:33:18 +0300 Subject: [PATCH 08/10] do not add prolog for variadic naked functions fixes #99858 --- compiler/rustc_codegen_ssa/src/mir/mod.rs | 7 +++++++ tests/codegen/cffi/c-variadic-naked.rs | 19 +++++++++++++++++++ tests/codegen/naked-fn/naked-functions.rs | 2 +- 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 tests/codegen/cffi/c-variadic-naked.rs diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 387a5366b209b..dc589a5fd306e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -2,6 +2,7 @@ use crate::base; use crate::traits::*; use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir; use rustc_middle::mir::traversal; use rustc_middle::mir::UnwindTerminateReason; @@ -290,6 +291,12 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let mut num_untupled = None; + let codegen_fn_attrs = bx.tcx().codegen_fn_attrs(fx.instance.def_id()); + let naked = codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED); + if naked { + return vec![]; + } + let args = mir .args_iter() .enumerate() diff --git a/tests/codegen/cffi/c-variadic-naked.rs b/tests/codegen/cffi/c-variadic-naked.rs new file mode 100644 index 0000000000000..807873ea3689f --- /dev/null +++ b/tests/codegen/cffi/c-variadic-naked.rs @@ -0,0 +1,19 @@ +//@ needs-asm-support +//@ only-x86_64 + +// tests that `va_start` is not injected into naked functions + +#![crate_type = "lib"] +#![feature(c_variadic)] +#![feature(naked_functions)] +#![no_std] + +#[naked] +pub unsafe extern "C" fn c_variadic(_: usize, _: ...) { + // CHECK-NOT: va_start + // CHECK-NOT: alloca + core::arch::asm! { + "ret", + options(noreturn), + } +} diff --git a/tests/codegen/naked-fn/naked-functions.rs b/tests/codegen/naked-fn/naked-functions.rs index 755dd15511269..3c426825537b6 100644 --- a/tests/codegen/naked-fn/naked-functions.rs +++ b/tests/codegen/naked-fn/naked-functions.rs @@ -19,7 +19,7 @@ pub unsafe extern "C" fn naked_empty() { } // CHECK: Function Attrs: naked -// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i64 %a, i64 %b) +// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i64 %0, i64 %1) #[no_mangle] #[naked] pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize { From 47c3ffa5d41b22a40b90902b22d022ef9fc6d080 Mon Sep 17 00:00:00 2001 From: kamaboko123 <6112062+kamaboko123@users.noreply.github.com> Date: Fri, 12 Apr 2024 22:02:08 +0900 Subject: [PATCH 09/10] fix typo in library/std/src/lib.rs --- library/std/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index ac475b5530a78..f5a89a67417b9 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -221,7 +221,7 @@ issue = "none", reason = "You have attempted to use a standard library built for a platform that it doesn't \ know how to support. Consider building it for a known environment, disabling it with \ - `#![no_std]` or overriding this warning by enabling this feature". + `#![no_std]` or overriding this warning by enabling this feature." ) )] #![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)] From 0b5653f0986a005a558bc552091f1b3f030f00f5 Mon Sep 17 00:00:00 2001 From: Jimmy Ohn Date: Fri, 12 Apr 2024 20:58:10 +0900 Subject: [PATCH 10/10] Update compiler/rustc_error_codes/src/error_codes/E0384.md Add an example for the shadowing usage. --- compiler/rustc_error_codes/src/error_codes/E0384.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/compiler/rustc_error_codes/src/error_codes/E0384.md b/compiler/rustc_error_codes/src/error_codes/E0384.md index e21fac0797cb9..6680dbed3dd63 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0384.md +++ b/compiler/rustc_error_codes/src/error_codes/E0384.md @@ -18,3 +18,16 @@ fn main() { x = 5; } ``` + +Alternatively, you might consider initializing a new variable: either with a new +bound name or (by [shadowing]) with the bound name of your existing variable. +For example: + +[shadowing]: https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing + +``` +fn main() { + let x = 3; + let x = 5; +} +```