From eb8da2f3bab8ca472b180ee060e9787da3fb1ec3 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Sat, 13 Dec 2025 00:32:10 +0900 Subject: [PATCH 1/9] move tests --- .../anon-params-trait-method-multiple.rs} | 0 .../autoderef-arc-boxed-closure-call.rs} | 0 .../issue-27268.rs => consts/const-closure-fn-trait-object.rs} | 0 .../issue-24161.rs => extern/extern-fn-pointer-clone-copy.rs} | 0 tests/ui/{issues/issue-23036.rs => hashmap/hashmap-path-key.rs} | 0 .../issue-20454.rs => inference/inference-thread-loop-closure.rs} | 0 .../disjoint-ref-mut-method.rs} | 0 .../issue-29540.rs => limits/limit-huge-struct-derive-debug.rs} | 0 .../unused/unused-attr-repr-packed-c-order.rs} | 0 .../issue-37686.rs => match/match-usize-min-max-pattern.rs} | 0 .../i128-min-literal-parses.rs} | 0 .../const-pattern-str-match-lifetime.rs} | 0 .../static-array-shared-slice-references.rs} | 0 .../raw-string-literal-unescaped-unicode.rs} | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-34074.rs => anon-params/anon-params-trait-method-multiple.rs} (100%) rename tests/ui/{issues/issue-21306.rs => autoref-autoderef/autoderef-arc-boxed-closure-call.rs} (100%) rename tests/ui/{issues/issue-27268.rs => consts/const-closure-fn-trait-object.rs} (100%) rename tests/ui/{issues/issue-24161.rs => extern/extern-fn-pointer-clone-copy.rs} (100%) rename tests/ui/{issues/issue-23036.rs => hashmap/hashmap-path-key.rs} (100%) rename tests/ui/{issues/issue-20454.rs => inference/inference-thread-loop-closure.rs} (100%) rename tests/ui/{issues/issue-19097.rs => inherent-impls-overlap-check/disjoint-ref-mut-method.rs} (100%) rename tests/ui/{issues/issue-29540.rs => limits/limit-huge-struct-derive-debug.rs} (100%) rename tests/ui/{issues/issue-26646.rs => lint/unused/unused-attr-repr-packed-c-order.rs} (100%) rename tests/ui/{issues/issue-37686.rs => match/match-usize-min-max-pattern.rs} (100%) rename tests/ui/{issues/issue-38987.rs => numbers-arithmetic/i128-min-literal-parses.rs} (100%) rename tests/ui/{issues/issue-18352.rs => pattern/const-pattern-str-match-lifetime.rs} (100%) rename tests/ui/{issues/issue-21891.rs => static/static-array-shared-slice-references.rs} (100%) rename tests/ui/{issues/issue-50471.rs => str/raw-string-literal-unescaped-unicode.rs} (100%) diff --git a/tests/ui/issues/issue-34074.rs b/tests/ui/anon-params/anon-params-trait-method-multiple.rs similarity index 100% rename from tests/ui/issues/issue-34074.rs rename to tests/ui/anon-params/anon-params-trait-method-multiple.rs diff --git a/tests/ui/issues/issue-21306.rs b/tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs similarity index 100% rename from tests/ui/issues/issue-21306.rs rename to tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs diff --git a/tests/ui/issues/issue-27268.rs b/tests/ui/consts/const-closure-fn-trait-object.rs similarity index 100% rename from tests/ui/issues/issue-27268.rs rename to tests/ui/consts/const-closure-fn-trait-object.rs diff --git a/tests/ui/issues/issue-24161.rs b/tests/ui/extern/extern-fn-pointer-clone-copy.rs similarity index 100% rename from tests/ui/issues/issue-24161.rs rename to tests/ui/extern/extern-fn-pointer-clone-copy.rs diff --git a/tests/ui/issues/issue-23036.rs b/tests/ui/hashmap/hashmap-path-key.rs similarity index 100% rename from tests/ui/issues/issue-23036.rs rename to tests/ui/hashmap/hashmap-path-key.rs diff --git a/tests/ui/issues/issue-20454.rs b/tests/ui/inference/inference-thread-loop-closure.rs similarity index 100% rename from tests/ui/issues/issue-20454.rs rename to tests/ui/inference/inference-thread-loop-closure.rs diff --git a/tests/ui/issues/issue-19097.rs b/tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs similarity index 100% rename from tests/ui/issues/issue-19097.rs rename to tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs diff --git a/tests/ui/issues/issue-29540.rs b/tests/ui/limits/limit-huge-struct-derive-debug.rs similarity index 100% rename from tests/ui/issues/issue-29540.rs rename to tests/ui/limits/limit-huge-struct-derive-debug.rs diff --git a/tests/ui/issues/issue-26646.rs b/tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs similarity index 100% rename from tests/ui/issues/issue-26646.rs rename to tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs diff --git a/tests/ui/issues/issue-37686.rs b/tests/ui/match/match-usize-min-max-pattern.rs similarity index 100% rename from tests/ui/issues/issue-37686.rs rename to tests/ui/match/match-usize-min-max-pattern.rs diff --git a/tests/ui/issues/issue-38987.rs b/tests/ui/numbers-arithmetic/i128-min-literal-parses.rs similarity index 100% rename from tests/ui/issues/issue-38987.rs rename to tests/ui/numbers-arithmetic/i128-min-literal-parses.rs diff --git a/tests/ui/issues/issue-18352.rs b/tests/ui/pattern/const-pattern-str-match-lifetime.rs similarity index 100% rename from tests/ui/issues/issue-18352.rs rename to tests/ui/pattern/const-pattern-str-match-lifetime.rs diff --git a/tests/ui/issues/issue-21891.rs b/tests/ui/static/static-array-shared-slice-references.rs similarity index 100% rename from tests/ui/issues/issue-21891.rs rename to tests/ui/static/static-array-shared-slice-references.rs diff --git a/tests/ui/issues/issue-50471.rs b/tests/ui/str/raw-string-literal-unescaped-unicode.rs similarity index 100% rename from tests/ui/issues/issue-50471.rs rename to tests/ui/str/raw-string-literal-unescaped-unicode.rs From 1f406db0767bffaad1def6ec5fdfb2f4ab874103 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Sat, 13 Dec 2025 00:45:22 +0900 Subject: [PATCH 2/9] cleaned up some tests --- .../ui/anon-params/anon-params-trait-method-multiple.rs | 4 ++-- .../autoderef-arc-boxed-closure-call.rs | 3 ++- tests/ui/consts/const-closure-fn-trait-object.rs | 3 ++- tests/ui/extern/extern-fn-pointer-clone-copy.rs | 5 +++-- tests/ui/hashmap/hashmap-path-key.rs | 1 + tests/ui/inference/inference-thread-loop-closure.rs | 7 +++++-- .../disjoint-ref-mut-method.rs | 2 +- tests/ui/limits/limit-huge-struct-derive-debug.rs | 1 + tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs | 3 ++- tests/ui/match/match-usize-min-max-pattern.rs | 1 + tests/ui/numbers-arithmetic/i128-min-literal-parses.rs | 1 + tests/ui/pattern/const-pattern-str-match-lifetime.rs | 3 ++- tests/ui/static/static-array-shared-slice-references.rs | 9 ++++----- tests/ui/str/raw-string-literal-unescaped-unicode.rs | 3 ++- 14 files changed, 29 insertions(+), 17 deletions(-) diff --git a/tests/ui/anon-params/anon-params-trait-method-multiple.rs b/tests/ui/anon-params/anon-params-trait-method-multiple.rs index d642c74d412a4..ba06aa5115ba0 100644 --- a/tests/ui/anon-params/anon-params-trait-method-multiple.rs +++ b/tests/ui/anon-params/anon-params-trait-method-multiple.rs @@ -1,3 +1,4 @@ +//! regression test for //@ edition: 2015 //@ check-pass // Make sure several unnamed function parameters don't conflict with each other @@ -7,5 +8,4 @@ trait Tr { fn f(u8, u8) {} } -fn main() { -} +fn main() {} diff --git a/tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs b/tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs index bf42e70a5bc04..fb7a8ee103e13 100644 --- a/tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs +++ b/tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs @@ -1,9 +1,10 @@ +//! regression test for //@ run-pass use std::sync::Arc; fn main() { let x = 5; - let command = Arc::new(Box::new(|| { x*2 })); + let command = Arc::new(Box::new(|| x * 2)); assert_eq!(command(), 10); } diff --git a/tests/ui/consts/const-closure-fn-trait-object.rs b/tests/ui/consts/const-closure-fn-trait-object.rs index e8704d215e888..e47a118dd3f45 100644 --- a/tests/ui/consts/const-closure-fn-trait-object.rs +++ b/tests/ui/consts/const-closure-fn-trait-object.rs @@ -1,4 +1,5 @@ +//! regression test for //@ run-pass fn main() { - const _C: &'static dyn Fn() = &||{}; + const _C: &'static dyn Fn() = &|| {}; } diff --git a/tests/ui/extern/extern-fn-pointer-clone-copy.rs b/tests/ui/extern/extern-fn-pointer-clone-copy.rs index 974add4386165..a67e0d1d703ac 100644 --- a/tests/ui/extern/extern-fn-pointer-clone-copy.rs +++ b/tests/ui/extern/extern-fn-pointer-clone-copy.rs @@ -1,11 +1,12 @@ +//! regression test for //@ check-pass #![allow(dead_code)] -#[derive(Copy,Clone)] +#[derive(Copy, Clone)] struct Functions { a: fn(u32) -> u32, b: extern "C" fn(u32) -> u32, c: unsafe fn(u32) -> u32, - d: unsafe extern "C" fn(u32) -> u32 + d: unsafe extern "C" fn(u32) -> u32, } pub fn main() {} diff --git a/tests/ui/hashmap/hashmap-path-key.rs b/tests/ui/hashmap/hashmap-path-key.rs index 5186fccd042b2..0551ba7ea8ee9 100644 --- a/tests/ui/hashmap/hashmap-path-key.rs +++ b/tests/ui/hashmap/hashmap-path-key.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass use std::collections::HashMap; diff --git a/tests/ui/inference/inference-thread-loop-closure.rs b/tests/ui/inference/inference-thread-loop-closure.rs index e56f2ffa371a3..78b1b145367e8 100644 --- a/tests/ui/inference/inference-thread-loop-closure.rs +++ b/tests/ui/inference/inference-thread-loop-closure.rs @@ -1,13 +1,16 @@ +//! regression test for //@ check-pass #![allow(unused_must_use)] use std::thread; fn _foo() { - thread::spawn(move || { // no need for -> () + thread::spawn(move || { + // no need for -> () loop { println!("hello"); } - }).join(); + }) + .join(); } fn main() {} diff --git a/tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs b/tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs index a329ba6f073e2..d4594b2e2c951 100644 --- a/tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs +++ b/tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs @@ -1,6 +1,6 @@ +//! regression test for //@ check-pass #![allow(dead_code)] -// regression test for #19097 struct Foo(T); diff --git a/tests/ui/limits/limit-huge-struct-derive-debug.rs b/tests/ui/limits/limit-huge-struct-derive-debug.rs index 6bfeae8559dc9..eb793aadd8c65 100644 --- a/tests/ui/limits/limit-huge-struct-derive-debug.rs +++ b/tests/ui/limits/limit-huge-struct-derive-debug.rs @@ -1,3 +1,4 @@ +//! regression test for //@ build-pass #[derive(Debug)] pub struct Config { diff --git a/tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs b/tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs index b1789b1a91fc2..a9da3e4175bdf 100644 --- a/tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs +++ b/tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs @@ -1,3 +1,4 @@ +//! regression test for //@ check-pass #![deny(unused_attributes)] @@ -9,4 +10,4 @@ pub struct Foo; #[repr(C)] pub struct Bar; -fn main() { } +fn main() {} diff --git a/tests/ui/match/match-usize-min-max-pattern.rs b/tests/ui/match/match-usize-min-max-pattern.rs index 5a72f2fc74c2d..6a801406895d3 100644 --- a/tests/ui/match/match-usize-min-max-pattern.rs +++ b/tests/ui/match/match-usize-min-max-pattern.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass fn main() { match (0, 0) { diff --git a/tests/ui/numbers-arithmetic/i128-min-literal-parses.rs b/tests/ui/numbers-arithmetic/i128-min-literal-parses.rs index 713fd5027918f..623a8a92ae62b 100644 --- a/tests/ui/numbers-arithmetic/i128-min-literal-parses.rs +++ b/tests/ui/numbers-arithmetic/i128-min-literal-parses.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass fn main() { let _ = -0x8000_0000_0000_0000_0000_0000_0000_0000i128; diff --git a/tests/ui/pattern/const-pattern-str-match-lifetime.rs b/tests/ui/pattern/const-pattern-str-match-lifetime.rs index 8b6aa82ea8c0c..8814d55c63b6f 100644 --- a/tests/ui/pattern/const-pattern-str-match-lifetime.rs +++ b/tests/ui/pattern/const-pattern-str-match-lifetime.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass const X: &'static str = "12345"; @@ -5,7 +6,7 @@ const X: &'static str = "12345"; fn test(s: String) -> bool { match &*s { X => true, - _ => false + _ => false, } } diff --git a/tests/ui/static/static-array-shared-slice-references.rs b/tests/ui/static/static-array-shared-slice-references.rs index 0da6071cdac4b..a2ef169e2a290 100644 --- a/tests/ui/static/static-array-shared-slice-references.rs +++ b/tests/ui/static/static-array-shared-slice-references.rs @@ -1,11 +1,10 @@ +//! regression test for //@ build-pass #![allow(dead_code)] -#![allow(non_upper_case_globals)] +static FOO: [usize; 3] = [1, 2, 3]; -static foo: [usize; 3] = [1, 2, 3]; - -static slice_1: &'static [usize] = &foo; -static slice_2: &'static [usize] = &foo; +static SLICE_1: &'static [usize] = &FOO; +static SLICE_2: &'static [usize] = &FOO; fn main() {} diff --git a/tests/ui/str/raw-string-literal-unescaped-unicode.rs b/tests/ui/str/raw-string-literal-unescaped-unicode.rs index 1d8bad20377c7..c0dc0743a28f7 100644 --- a/tests/ui/str/raw-string-literal-unescaped-unicode.rs +++ b/tests/ui/str/raw-string-literal-unescaped-unicode.rs @@ -1,7 +1,8 @@ +//! regression test for //@ check-pass fn main() { - assert!({false}); + assert!({ false }); assert!(r"\u{41}" == "A"); From bf9221458acbc9358c5043208838f18d5f094d92 Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Sat, 13 Dec 2025 01:04:59 +0900 Subject: [PATCH 3/9] Move inherent-impls-overlap-check to duplicate's subdirectory --- tests/ui/README.md | 6 ------ .../inherent-impls-overlap-check/auxiliary/repeat.rs | 0 .../inherent-impls-overlap-check/disjoint-ref-mut-method.rs | 0 .../inherent-impls-overlap-check/no-overlap.rs | 0 .../{ => duplicate}/inherent-impls-overlap-check/overlap.rs | 0 .../inherent-impls-overlap-check/overlap.stderr | 0 6 files changed, 6 deletions(-) rename tests/ui/{ => duplicate}/inherent-impls-overlap-check/auxiliary/repeat.rs (100%) rename tests/ui/{ => duplicate}/inherent-impls-overlap-check/disjoint-ref-mut-method.rs (100%) rename tests/ui/{ => duplicate}/inherent-impls-overlap-check/no-overlap.rs (100%) rename tests/ui/{ => duplicate}/inherent-impls-overlap-check/overlap.rs (100%) rename tests/ui/{ => duplicate}/inherent-impls-overlap-check/overlap.stderr (100%) diff --git a/tests/ui/README.md b/tests/ui/README.md index 25e870fd8f188..fd77c340b6a98 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -697,12 +697,6 @@ Tests on type inference. Tests for diagnostics on infinitely recursive types without indirection. -## `tests/ui/inherent-impls-overlap-check/` - -Checks that repeating the same function names across separate `impl` blocks triggers an informative error, but not if the `impl` are for different types, such as `Bar` and `Bar`. - -NOTE: This should maybe be a subdirectory within another related to duplicate definitions, such as `tests/ui/duplicate/`. - ## `tests/ui/inline-const/` These tests revolve around the inline `const` block that forces the compiler to const-eval its content. diff --git a/tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs b/tests/ui/duplicate/inherent-impls-overlap-check/auxiliary/repeat.rs similarity index 100% rename from tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs rename to tests/ui/duplicate/inherent-impls-overlap-check/auxiliary/repeat.rs diff --git a/tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs b/tests/ui/duplicate/inherent-impls-overlap-check/disjoint-ref-mut-method.rs similarity index 100% rename from tests/ui/inherent-impls-overlap-check/disjoint-ref-mut-method.rs rename to tests/ui/duplicate/inherent-impls-overlap-check/disjoint-ref-mut-method.rs diff --git a/tests/ui/inherent-impls-overlap-check/no-overlap.rs b/tests/ui/duplicate/inherent-impls-overlap-check/no-overlap.rs similarity index 100% rename from tests/ui/inherent-impls-overlap-check/no-overlap.rs rename to tests/ui/duplicate/inherent-impls-overlap-check/no-overlap.rs diff --git a/tests/ui/inherent-impls-overlap-check/overlap.rs b/tests/ui/duplicate/inherent-impls-overlap-check/overlap.rs similarity index 100% rename from tests/ui/inherent-impls-overlap-check/overlap.rs rename to tests/ui/duplicate/inherent-impls-overlap-check/overlap.rs diff --git a/tests/ui/inherent-impls-overlap-check/overlap.stderr b/tests/ui/duplicate/inherent-impls-overlap-check/overlap.stderr similarity index 100% rename from tests/ui/inherent-impls-overlap-check/overlap.stderr rename to tests/ui/duplicate/inherent-impls-overlap-check/overlap.stderr From 851f1698ab9defd3728137f1e04a60dc10070f22 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 17 Dec 2025 16:57:22 +0100 Subject: [PATCH 4/9] Fix invalid handling of field followed by negated macro call --- src/librustdoc/html/highlight.rs | 76 +++++++++++-------- .../field-followed-by-exclamation.rs | 26 +++++++ 2 files changed, 71 insertions(+), 31 deletions(-) create mode 100644 tests/rustdoc/macro-expansion/field-followed-by-exclamation.rs diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 6f6345cd86664..bc268d9495f85 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -832,6 +832,20 @@ impl<'a> PeekIter<'a> { .copied() } + fn peek_next_if bool>( + &mut self, + f: F, + ) -> Option<(TokenKind, &'a str)> { + let next = self.peek_next()?; + if f(next) { + Some(next) + } else { + // We go one step back. + self.peek_pos -= 1; + None + } + } + fn stop_peeking(&mut self) { self.peek_pos = 0; } @@ -903,18 +917,19 @@ fn classify<'src>( } } - if let Some((TokenKind::Colon | TokenKind::Ident, _)) = classifier.tokens.peek() { - let tokens = classifier.get_full_ident_path(); - for &(token, start, end) in &tokens { - let text = &classifier.src[start..end]; - classifier.advance(token, text, sink, start as u32); - classifier.byte_pos += text.len() as u32; - } - if !tokens.is_empty() { - continue; + if let Some((TokenKind::Colon | TokenKind::Ident, _)) = classifier.tokens.peek() + && let Some(nb_items) = classifier.get_full_ident_path() + { + let start = classifier.byte_pos as usize; + let mut len = 0; + for _ in 0..nb_items { + if let Some((_, text, _)) = classifier.next() { + len += text.len(); + } } - } - if let Some((token, text, before)) = classifier.next() { + let text = &classifier.src[start..start + len]; + classifier.advance(TokenKind::Ident, text, sink, start as u32); + } else if let Some((token, text, before)) = classifier.next() { classifier.advance(token, text, sink, before); } else { break; @@ -957,47 +972,47 @@ impl<'src> Classifier<'src> { } /// Concatenate colons and idents as one when possible. - fn get_full_ident_path(&mut self) -> Vec<(TokenKind, usize, usize)> { - let start = self.byte_pos as usize; - let mut pos = start; + fn get_full_ident_path(&mut self) -> Option { let mut has_ident = false; + let mut nb_items = 0; - loop { + let ret = loop { let mut nb = 0; - while let Some((TokenKind::Colon, _)) = self.tokens.peek() { - self.tokens.next(); + while self.tokens.peek_next_if(|(token, _)| token == TokenKind::Colon).is_some() { nb += 1; + nb_items += 1; } // Ident path can start with "::" but if we already have content in the ident path, // the "::" is mandatory. if has_ident && nb == 0 { - return vec![(TokenKind::Ident, start, pos)]; + break Some(nb_items); } else if nb != 0 && nb != 2 { if has_ident { - return vec![(TokenKind::Ident, start, pos), (TokenKind::Colon, pos, pos + nb)]; + // Following `;` will be handled on its own. + break Some(nb_items - 1); } else { - return vec![(TokenKind::Colon, start, pos + nb)]; + break None; } } - if let Some((TokenKind::Ident, text)) = self.tokens.peek() + if let Some((TokenKind::Ident, text)) = + self.tokens.peek_next_if(|(token, _)| token == TokenKind::Ident) && let symbol = Symbol::intern(text) && (symbol.is_path_segment_keyword() || !is_keyword(symbol)) { - // We only "add" the colon if there is an ident behind. - pos += text.len() + nb; has_ident = true; - self.tokens.next(); + nb_items += 1; } else if nb > 0 && has_ident { - return vec![(TokenKind::Ident, start, pos), (TokenKind::Colon, pos, pos + nb)]; - } else if nb > 0 { - return vec![(TokenKind::Colon, start, start + nb)]; + // Following `;` will be handled on its own. + break Some(nb_items - 1); } else if has_ident { - return vec![(TokenKind::Ident, start, pos)]; + break Some(nb_items); } else { - return Vec::new(); + break None; } - } + }; + self.tokens.stop_peeking(); + ret } /// Wraps the tokens iteration to ensure that the `byte_pos` is always correct. @@ -1243,7 +1258,6 @@ impl<'src> Classifier<'src> { Class::MacroNonTerminal } TokenKind::Ident => { - let file_span = self.file_span; let span = || new_span(before, text, file_span); match text { diff --git a/tests/rustdoc/macro-expansion/field-followed-by-exclamation.rs b/tests/rustdoc/macro-expansion/field-followed-by-exclamation.rs new file mode 100644 index 0000000000000..e80b4c4ec8731 --- /dev/null +++ b/tests/rustdoc/macro-expansion/field-followed-by-exclamation.rs @@ -0,0 +1,26 @@ +// This test ensures that the macro expansion is correctly handled in cases like: +// `field: !f!`, because the `:` was simply not considered because of how paths +// are handled. + +//@ compile-flags: -Zunstable-options --generate-macro-expansion + +#![crate_name = "foo"] + +//@ has 'src/foo/field-followed-by-exclamation.rs.html' + +struct Bar { + bla: bool, +} + +macro_rules! f { + () => {{ false }} +} + +const X: Bar = Bar { + //@ has - '//*[@class="expansion"]/*[@class="original"]/*[@class="macro"]' 'f!' + //@ has - '//*[@class="expansion"]/*[@class="original"]' 'f!()' + //@ has - '//*[@class="expansion"]/*[@class="expanded"]' '{ false }' + // It includes both original and expanded code. + //@ has - '//*[@class="expansion"]' ' bla: !{ false }f!()' + bla: !f!(), +}; From bbda675aacff15a8bf93c9b98a66d2faeb0c0d1b Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 17 Dec 2025 12:31:58 +0100 Subject: [PATCH 5/9] Port `#[rustc_no_implicit_autorefs]` to attribute parser --- .../src/attributes/rustc_internal.rs | 15 +++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 3 ++- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_lint/src/autorefs.rs | 6 +++--- compiler/rustc_passes/src/check_attr.rs | 4 +--- 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 620878fb87a7e..dc743117d69ce 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -27,6 +27,21 @@ impl NoArgsAttributeParser for RustcNeverReturnsNullPointerParser { ]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNeverReturnsNullPointer; } +pub(crate) struct RustcNoImplicitAutorefsParser; + +impl NoArgsAttributeParser for RustcNoImplicitAutorefsParser { + const PATH: &[Symbol] = &[sym::rustc_no_implicit_autorefs]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoImplicitAutorefs; +} pub(crate) struct RustcLayoutScalarValidRangeStartParser; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 54c9785a42f6c..8f286d4a08828 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -61,7 +61,7 @@ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, - RustcLegacyConstGenericsParser, RustcMainParser, RustcNeverReturnsNullPointerParser, + RustcLegacyConstGenericsParser, RustcMainParser, RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; @@ -257,6 +257,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 4a81c4ebe1e7f..bc5473f91cf73 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -881,6 +881,9 @@ pub enum AttributeKind { /// Represents `#[rustc_never_returns_null_ptr]` RustcNeverReturnsNullPointer, + /// Represents `#[rustc_no_implicit_autorefs]` + RustcNoImplicitAutorefs, + /// Represents `#[rustc_object_lifetime_default]`. RustcObjectLifetimeDefault, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index e631d6a2ab872..7b930ca22b1f3 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -96,6 +96,7 @@ impl AttributeKind { RustcLegacyConstGenerics { .. } => Yes, RustcMain => No, RustcNeverReturnsNullPointer => Yes, + RustcNoImplicitAutorefs => Yes, RustcObjectLifetimeDefault => No, RustcPassIndirectlyInNonRusticAbis(..) => No, RustcScalableVector { .. } => Yes, diff --git a/compiler/rustc_lint/src/autorefs.rs b/compiler/rustc_lint/src/autorefs.rs index 5490a3aac9b7a..ed7ac0e33244b 100644 --- a/compiler/rustc_lint/src/autorefs.rs +++ b/compiler/rustc_lint/src/autorefs.rs @@ -1,8 +1,8 @@ use rustc_ast::{BorrowKind, UnOp}; -use rustc_hir::{Expr, ExprKind, Mutability}; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::{Expr, ExprKind, Mutability, find_attr}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, OverloadedDeref}; use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::sym; use crate::lints::{ ImplicitUnsafeAutorefsDiag, ImplicitUnsafeAutorefsMethodNote, ImplicitUnsafeAutorefsOrigin, @@ -106,7 +106,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitAutorefs { ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(expr.hir_id), _ => None, } - && method_did.map(|did| cx.tcx.has_attr(did, sym::rustc_no_implicit_autorefs)).unwrap_or(true) + && method_did.map(|did| find_attr!(cx.tcx.get_all_attrs(did), AttributeKind::RustcNoImplicitAutorefs)).unwrap_or(true) { cx.emit_span_lint( DANGEROUS_IMPLICIT_AUTOREFS, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d1f96721fc65d..25628605a03cb 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -255,6 +255,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::MacroUse { .. } | AttributeKind::MacroEscape( .. ) | AttributeKind::NoLink + | AttributeKind::RustcNoImplicitAutorefs | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) | AttributeKind::RustcNeverReturnsNullPointer @@ -305,9 +306,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_const(attr.span(), hir_id, target, item) } [sym::thread_local, ..] => self.check_thread_local(attr, span, target), - [sym::rustc_no_implicit_autorefs, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) - } [sym::rustc_lint_query_instability, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } From 81d20363b3f7e1c5d56b35c0de516061b04709a8 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 17 Dec 2025 13:38:19 +0100 Subject: [PATCH 6/9] Port `#[rustc_lint_opt_ty]` to parsed attribute --- .../src/attributes/rustc_internal.rs | 9 +++++++++ compiler/rustc_attr_parsing/src/context.rs | 4 +++- compiler/rustc_hir/src/attrs/data_structures.rs | 3 +++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_lint/src/internal.rs | 5 +++-- compiler/rustc_passes/messages.ftl | 4 ---- compiler/rustc_passes/src/check_attr.rs | 12 +----------- compiler/rustc_passes/src/errors.rs | 9 --------- 8 files changed, 20 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index dc743117d69ce..dc03e1c9312a1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -117,6 +117,15 @@ impl SingleAttributeParser for RustcLegacyConstGenericsParser { } } +pub(crate) struct RustcLintOptTyParser; + +impl NoArgsAttributeParser for RustcLintOptTyParser { + const PATH: &[Symbol] = &[sym::rustc_lint_opt_ty]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy; +} + pub(crate) struct RustcObjectLifetimeDefaultParser; impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 8f286d4a08828..8cd30ac9ca463 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -61,7 +61,8 @@ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, - RustcLegacyConstGenericsParser, RustcMainParser, RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, + RustcLegacyConstGenericsParser, RustcLintOptTyParser, RustcMainParser, + RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; @@ -255,6 +256,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index bc5473f91cf73..761078bf79faf 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -875,6 +875,9 @@ pub enum AttributeKind { /// Represents `#[rustc_legacy_const_generics]` RustcLegacyConstGenerics { fn_indexes: ThinVec<(usize, Span)>, attr_span: Span }, + /// Represents `#[rustc_lint_opt_ty]` + RustcLintOptTy, + /// Represents `#[rustc_main]`. RustcMain, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 7b930ca22b1f3..e84fca61ac489 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -94,6 +94,7 @@ impl AttributeKind { RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, RustcLegacyConstGenerics { .. } => Yes, + RustcLintOptTy => Yes, RustcMain => No, RustcNeverReturnsNullPointer => Yes, RustcNoImplicitAutorefs => Yes, diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index c00ba4959c940..25f5710cca3a3 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -1,9 +1,10 @@ //! Some lints that are only useful in the compiler or crates that use compiler internals, such as //! Clippy. +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; -use rustc_hir::{Expr, ExprKind, HirId}; +use rustc_hir::{Expr, ExprKind, HirId, find_attr}; use rustc_middle::ty::{self, GenericArgsRef, PredicatePolarity, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::hygiene::{ExpnKind, MacroKind}; @@ -658,7 +659,7 @@ impl LateLintPass<'_> for BadOptAccess { let Some(adt_def) = cx.typeck_results().expr_ty(base).ty_adt_def() else { return }; // Skip types without `#[rustc_lint_opt_ty]` - only so that the rest of the lint can be // avoided. - if !cx.tcx.has_attr(adt_def.did(), sym::rustc_lint_opt_ty) { + if !find_attr!(cx.tcx.get_all_attrs(adt_def.did()), AttributeKind::RustcLintOptTy) { return; } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index dfa7826ece7d3..5a9b759575172 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -477,10 +477,6 @@ passes_rustc_lint_opt_deny_field_access = `#[rustc_lint_opt_deny_field_access]` should be applied to a field .label = not a field -passes_rustc_lint_opt_ty = - `#[rustc_lint_opt_ty]` should be applied to a struct - .label = not a struct - passes_rustc_pub_transparent = attribute should be applied to `#[repr(transparent)]` types .label = not a `#[repr(transparent)]` type diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 25628605a03cb..00169cf6ae0cd 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -258,6 +258,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcNoImplicitAutorefs | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) + | AttributeKind::RustcLintOptTy | AttributeKind::RustcNeverReturnsNullPointer | AttributeKind::RustcScalableVector { .. } | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) @@ -315,7 +316,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_lint_diagnostics, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } - [sym::rustc_lint_opt_ty, ..] => self.check_rustc_lint_opt_ty(attr, span, target), [sym::rustc_lint_opt_deny_field_access, ..] => { self.check_rustc_lint_opt_deny_field_access(attr, span, target) } @@ -1253,16 +1253,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks that the `#[rustc_lint_opt_ty]` attribute is only applied to a struct. - fn check_rustc_lint_opt_ty(&self, attr: &Attribute, span: Span, target: Target) { - match target { - Target::Struct => {} - _ => { - self.dcx().emit_err(errors::RustcLintOptTy { attr_span: attr.span(), span }); - } - } - } - /// Checks that the `#[rustc_lint_opt_deny_field_access]` attribute is only applied to a field. fn check_rustc_lint_opt_deny_field_access(&self, attr: &Attribute, span: Span, target: Target) { match target { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 6b3c2bd1a7b29..f2b7d3740cb64 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -412,15 +412,6 @@ pub(crate) struct UnusedMultiple { pub name: Symbol, } -#[derive(Diagnostic)] -#[diag(passes_rustc_lint_opt_ty)] -pub(crate) struct RustcLintOptTy { - #[primary_span] - pub attr_span: Span, - #[label] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(passes_rustc_lint_opt_deny_field_access)] pub(crate) struct RustcLintOptDenyFieldAccess { From 96e453d713738204f68f75558d13f923097e33ae Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Wed, 17 Dec 2025 14:38:56 +0100 Subject: [PATCH 7/9] Port `#[rustc_lint_query_instability]` to parsed attribute --- .../src/attributes/rustc_internal.rs | 15 ++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 5 ++-- .../rustc_hir/src/attrs/data_structures.rs | 3 +++ .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_lint/src/internal.rs | 7 ++++-- compiler/rustc_passes/src/check_attr.rs | 4 +--- .../query_stability_incorrect.rs | 2 +- .../query_stability_incorrect.stderr | 23 +++++++++++-------- 8 files changed, 42 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index dc03e1c9312a1..7910443787b4f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -126,6 +126,21 @@ impl NoArgsAttributeParser for RustcLintOptTyParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy; } +pub(crate) struct RustcLintQueryInstabilityParser; + +impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { + const PATH: &[Symbol] = &[sym::rustc_lint_query_instability]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintQueryInstability; +} + pub(crate) struct RustcObjectLifetimeDefaultParser; impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 8cd30ac9ca463..b4854c430cae0 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -61,8 +61,8 @@ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, - RustcLegacyConstGenericsParser, RustcLintOptTyParser, RustcMainParser, - RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, + RustcLegacyConstGenericsParser, RustcLintOptTyParser, RustcLintQueryInstabilityParser, + RustcMainParser, RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; @@ -257,6 +257,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 761078bf79faf..3c7edb3201b7f 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -878,6 +878,9 @@ pub enum AttributeKind { /// Represents `#[rustc_lint_opt_ty]` RustcLintOptTy, + /// Represents `#[rustc_lint_query_instability]` + RustcLintQueryInstability, + /// Represents `#[rustc_main]`. RustcMain, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index e84fca61ac489..f99069e416bd2 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -95,6 +95,7 @@ impl AttributeKind { RustcLayoutScalarValidRangeStart(..) => Yes, RustcLegacyConstGenerics { .. } => Yes, RustcLintOptTy => Yes, + RustcLintQueryInstability => Yes, RustcMain => No, RustcNeverReturnsNullPointer => Yes, RustcNoImplicitAutorefs => Yes, diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 25f5710cca3a3..c32fed3674fcc 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -91,7 +91,7 @@ impl<'tcx> LateLintPass<'tcx> for QueryStability { ty::Instance::try_resolve(cx.tcx, cx.typing_env(), callee_def_id, generic_args) { let def_id = instance.def_id(); - if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) { + if find_attr!(cx.tcx.get_all_attrs(def_id), AttributeKind::RustcLintQueryInstability) { cx.emit_span_lint( POTENTIAL_QUERY_INSTABILITY, span, @@ -151,7 +151,10 @@ fn has_unstable_into_iter_predicate<'tcx>( }; // Does the input type's `IntoIterator` implementation have the // `rustc_lint_query_instability` attribute on its `into_iter` method? - if cx.tcx.has_attr(instance.def_id(), sym::rustc_lint_query_instability) { + if find_attr!( + cx.tcx.get_all_attrs(instance.def_id()), + AttributeKind::RustcLintQueryInstability + ) { return true; } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 00169cf6ae0cd..d03da2e06cf13 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -259,6 +259,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) | AttributeKind::RustcLintOptTy + | AttributeKind::RustcLintQueryInstability | AttributeKind::RustcNeverReturnsNullPointer | AttributeKind::RustcScalableVector { .. } | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) @@ -307,9 +308,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_const(attr.span(), hir_id, target, item) } [sym::thread_local, ..] => self.check_thread_local(attr, span, target), - [sym::rustc_lint_query_instability, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) - } [sym::rustc_lint_untracked_query_information, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } diff --git a/tests/ui/internal-lints/query_stability_incorrect.rs b/tests/ui/internal-lints/query_stability_incorrect.rs index a428611caaa47..cefd898677113 100644 --- a/tests/ui/internal-lints/query_stability_incorrect.rs +++ b/tests/ui/internal-lints/query_stability_incorrect.rs @@ -3,7 +3,7 @@ #![feature(rustc_attrs)] #[rustc_lint_query_instability] -//~^ ERROR attribute should be applied to a function +//~^ ERROR `#[rustc_lint_query_instability]` attribute cannot be used on structs struct Foo; impl Foo { diff --git a/tests/ui/internal-lints/query_stability_incorrect.stderr b/tests/ui/internal-lints/query_stability_incorrect.stderr index 3f78b39edd96a..8149ac3b95184 100644 --- a/tests/ui/internal-lints/query_stability_incorrect.stderr +++ b/tests/ui/internal-lints/query_stability_incorrect.stderr @@ -1,17 +1,20 @@ -error: malformed `rustc_lint_query_instability` attribute input - --> $DIR/query_stability_incorrect.rs:10:5 - | -LL | #[rustc_lint_query_instability(a)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_lint_query_instability]` - -error: attribute should be applied to a function definition +error: `#[rustc_lint_query_instability]` attribute cannot be used on structs --> $DIR/query_stability_incorrect.rs:5:1 | LL | #[rustc_lint_query_instability] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | struct Foo; - | ----------- not a function definition + | + = help: `#[rustc_lint_query_instability]` can only be applied to functions + +error[E0565]: malformed `rustc_lint_query_instability` attribute input + --> $DIR/query_stability_incorrect.rs:10:5 + | +LL | #[rustc_lint_query_instability(a)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[rustc_lint_query_instability]` error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0565`. From 78f52c1d127858c6d50751cd62876982b6708945 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Wed, 17 Dec 2025 20:16:02 +0000 Subject: [PATCH 8/9] Update tracking issue for PinCoerceUnsized --- library/alloc/src/boxed.rs | 2 +- library/alloc/src/rc.rs | 6 +++--- library/alloc/src/sync.rs | 6 +++--- library/core/src/cell.rs | 12 ++++++------ library/core/src/pin.rs | 2 +- library/core/src/ptr/unique.rs | 2 +- library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index f714a87c18687..60758551cc048 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -2253,7 +2253,7 @@ impl + ?Sized, A: Allocator> AsyncFn for Box #[unstable(feature = "coerce_unsized", issue = "18598")] impl, U: ?Sized, A: Allocator> CoerceUnsized> for Box {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Box {} // It is quite crucial that we only allow the `Global` allocator here. diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index a3ebbbbaae05f..8a72748668ccb 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2417,14 +2417,14 @@ impl Deref for Rc { } } -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Rc {} //#[unstable(feature = "unique_rc_arc", issue = "112566")] -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for UniqueRc {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Weak {} #[unstable(feature = "deref_pure_trait", issue = "87121")] diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 6a49017a82767..4180fe91cb558 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2423,10 +2423,10 @@ impl Deref for Arc { } } -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Arc {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Weak {} #[unstable(feature = "deref_pure_trait", issue = "87121")] @@ -4852,7 +4852,7 @@ impl Deref for UniqueArc { } // #[unstable(feature = "unique_rc_arc", issue = "112566")] -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for UniqueArc {} #[unstable(feature = "unique_rc_arc", issue = "112566")] diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index c8340c328be12..9a3f7166f1fcb 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2696,20 +2696,20 @@ fn assert_coerce_unsized( let _: RefCell<&dyn Send> = d; } -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for UnsafeCell {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for SyncUnsafeCell {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Cell {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for RefCell {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl<'b, T: ?Sized> PinCoerceUnsized for Ref<'b, T> {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl<'b, T: ?Sized> PinCoerceUnsized for RefMut<'b, T> {} diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 81c2dabf0d1d8..74ecb5ee4946f 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1825,7 +1825,7 @@ where { } -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] /// Trait that indicates that this is a pointer or a wrapper for one, where /// unsizing can be performed on the pointee when it is pinned. /// diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index 1bbe3ea242f6c..3160c9de4b7e9 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -176,7 +176,7 @@ impl CoerceUnsized> for Unique wh #[unstable(feature = "ptr_internals", issue = "none")] impl DispatchFromDyn> for Unique where T: Unsize {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for Unique {} #[unstable(feature = "ptr_internals", issue = "none")] diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs index fb410c2851604..aaf380d1bef47 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs @@ -773,7 +773,7 @@ where #[unstable(feature = "sgx_platform", issue = "56975")] impl, U> CoerceUnsized> for UserRef {} -#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] +#[unstable(feature = "pin_coerce_unsized_trait", issue = "150112")] unsafe impl PinCoerceUnsized for UserRef {} #[unstable(feature = "sgx_platform", issue = "56975")] From 2114b2107068617b0303f9d0e91ad12ad00a296c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 17 Dec 2025 23:27:38 +0100 Subject: [PATCH 9/9] Improve code by using `iterator::sum` instead of looping --- src/librustdoc/html/highlight.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index bc268d9495f85..f70b350de283b 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -921,12 +921,10 @@ fn classify<'src>( && let Some(nb_items) = classifier.get_full_ident_path() { let start = classifier.byte_pos as usize; - let mut len = 0; - for _ in 0..nb_items { - if let Some((_, text, _)) = classifier.next() { - len += text.len(); - } - } + let len: usize = iter::from_fn(|| classifier.next()) + .take(nb_items) + .map(|(_, text, _)| text.len()) + .sum(); let text = &classifier.src[start..start + len]; classifier.advance(TokenKind::Ident, text, sink, start as u32); } else if let Some((token, text, before)) = classifier.next() {