From 07e8b2866d31fcc9c603146bfd98f6a0d0137a97 Mon Sep 17 00:00:00 2001 From: Shun Sakai Date: Mon, 10 Feb 2025 12:39:28 +0900 Subject: [PATCH 01/20] Implement `Random` for tuple Implement `Random` for tuples of arity 12 or less. Each element is expected to implement `Random`. --- library/core/src/primitive_docs.rs | 2 ++ library/core/src/tuple.rs | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 369bf18c2b9f7..d834a23b35b6c 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1078,11 +1078,13 @@ mod prim_str {} /// * [`Debug`] /// * [`Default`] /// * [`Hash`] +/// * [`Random`] /// * [`From<[T; N]>`][from] /// /// [from]: convert::From /// [`Debug`]: fmt::Debug /// [`Hash`]: hash::Hash +/// [`Random`]: random::Random /// /// The following traits are implemented for tuples of any length. These traits have /// implementations that are automatically generated by the compiler, so are not limited by diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 02eb805ece121..42d9cc49ff61a 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -3,6 +3,7 @@ use crate::cmp::Ordering::{self, *}; use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy}; use crate::ops::ControlFlow::{self, Break, Continue}; +use crate::random::{Random, RandomSource}; // Recursive macro for implementing n-ary tuple functions and operations // @@ -139,6 +140,16 @@ macro_rules! tuple_impls { } } + maybe_tuple_doc! { + $($T)+ @ + #[unstable(feature = "random", issue = "130703")] + impl<$($T: Random),+> Random for ($($T,)+) { + fn random(source: &mut (impl RandomSource + ?Sized)) -> Self { + ($({ let x: $T = Random::random(source); x},)+) + } + } + } + maybe_tuple_doc! { $($T)+ @ #[stable(feature = "array_tuple_conv", since = "1.71.0")] From 3a56a03f05da6725e4e851c3a18fb5493ab5cd87 Mon Sep 17 00:00:00 2001 From: Diggory Blake Date: Sun, 1 Jun 2025 17:26:27 +0100 Subject: [PATCH 02/20] Address documentation issues identified with Future --- library/core/src/future/future.rs | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs index cfbd88bbe7998..fab13bb7c8535 100644 --- a/library/core/src/future/future.rs +++ b/library/core/src/future/future.rs @@ -4,7 +4,8 @@ use crate::ops; use crate::pin::Pin; use crate::task::{Context, Poll}; -/// A future represents an asynchronous computation obtained by use of [`async`]. +/// A future represents an asynchronous computation, commonly obtained by use of +/// [`async`]. /// /// A future is a value that might not have finished computing yet. This kind of /// "asynchronous value" makes it possible for a thread to continue doing useful @@ -68,13 +69,21 @@ pub trait Future { /// /// # Runtime characteristics /// - /// Futures alone are *inert*; they must be *actively* `poll`ed to make - /// progress, meaning that each time the current task is woken up, it should - /// actively re-`poll` pending futures that it still has an interest in. + /// Futures alone are *inert*; they must be *actively* `poll`ed for the + /// underlying computation to make progress, meaning that each time the + /// current task is woken up, it should actively re-`poll` pending futures + /// that it still has an interest in. /// - /// The `poll` function is not called repeatedly in a tight loop -- instead, - /// it should only be called when the future indicates that it is ready to - /// make progress (by calling `wake()`). If you're familiar with the + /// Having said that, some Futures may represent a value that is being + /// computed in a different task. In this case, the future's underlying + /// computation is simply acting as a conduit for a value being computed + /// by that other task, which will proceed independently of the Future. + /// Futures of this kind are typically obtained when spawning a new task into an + /// async runtime. + /// + /// The `poll` function should not be called repeatedly in a tight loop -- + /// instead, it should only be called when the future indicates that it is + /// ready to make progress (by calling `wake()`). If you're familiar with the /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures /// typically do *not* suffer the same problems of "all wakeups must poll /// all events"; they are more like `epoll(4)`. From 977752fb01e868642bdac004113f2620950c6304 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 19 Jun 2025 20:39:54 -0500 Subject: [PATCH 03/20] docs(fs): Touch up grammar on lock api --- library/std/src/fs.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 865ea620a283f..ea342ec9c128d 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -682,11 +682,11 @@ impl File { /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not /// cause non-lockholders to block. /// - /// If this file handle/descriptor, or a clone of it, already holds an lock the exact behavior + /// If this file handle/descriptor, or a clone of it, already holds a lock the exact behavior /// is unspecified and platform dependent, including the possibility that it will deadlock. /// However, if this method returns, then an exclusive lock is held. /// - /// If the file not open for writing, it is unspecified whether this function returns an error. + /// If the file is not open for writing, it is unspecified whether this function returns an error. /// /// The lock will be released when this file (along with any other file descriptors/handles /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called. @@ -736,7 +736,7 @@ impl File { /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not /// cause non-lockholders to block. /// - /// If this file handle/descriptor, or a clone of it, already holds an lock, the exact behavior + /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact behavior /// is unspecified and platform dependent, including the possibility that it will deadlock. /// However, if this method returns, then a shared lock is held. /// @@ -790,11 +790,11 @@ impl File { /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not /// cause non-lockholders to block. /// - /// If this file handle/descriptor, or a clone of it, already holds an lock, the exact behavior + /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact behavior /// is unspecified and platform dependent, including the possibility that it will deadlock. /// However, if this method returns `Ok(true)`, then it has acquired an exclusive lock. /// - /// If the file not open for writing, it is unspecified whether this function returns an error. + /// If the file is not open for writing, it is unspecified whether this function returns an error. /// /// The lock will be released when this file (along with any other file descriptors/handles /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called. @@ -855,7 +855,7 @@ impl File { /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not /// cause non-lockholders to block. /// - /// If this file handle, or a clone of it, already holds an lock, the exact behavior is + /// If this file handle, or a clone of it, already holds a lock, the exact behavior is /// unspecified and platform dependent, including the possibility that it will deadlock. /// However, if this method returns `Ok(true)`, then it has acquired a shared lock. /// From 4b6c3d923f9c9ec869bfc77e6c08e98f9de87ac8 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Sun, 29 Jun 2025 22:47:01 +0500 Subject: [PATCH 04/20] moved & deleted some tests --- .../ui/{newlambdas.rs => closures/basic-closure-syntax.rs} | 0 .../newtype-with-generics.rs} | 0 .../{new-impl-syntax.rs => impl-trait/basic-trait-impl.rs} | 0 tests/ui/new-import-syntax.rs | 5 ----- tests/ui/new-style-constants.rs | 7 ------- .../unicode-escape-sequences.rs} | 0 tests/ui/{newtype.rs => structs/basic-newtype-pattern.rs} | 0 .../{no_send-enum.rs => traits/enum-negative-send-impl.rs} | 0 .../enum-negative-send-impl.stderr} | 0 .../enum-negative-sync-impl.rs} | 0 .../enum-negative-sync-impl.stderr} | 0 tests/ui/{no_send-rc.rs => traits/rc-not-send.rs} | 0 tests/ui/{no_send-rc.stderr => traits/rc-not-send.stderr} | 0 .../struct-negative-sync-impl.rs} | 0 .../struct-negative-sync-impl.stderr} | 0 15 files changed, 12 deletions(-) rename tests/ui/{newlambdas.rs => closures/basic-closure-syntax.rs} (100%) rename tests/ui/{newtype-polymorphic.rs => generics/newtype-with-generics.rs} (100%) rename tests/ui/{new-impl-syntax.rs => impl-trait/basic-trait-impl.rs} (100%) delete mode 100644 tests/ui/new-import-syntax.rs delete mode 100644 tests/ui/new-style-constants.rs rename tests/ui/{new-unicode-escapes.rs => parser/unicode-escape-sequences.rs} (100%) rename tests/ui/{newtype.rs => structs/basic-newtype-pattern.rs} (100%) rename tests/ui/{no_send-enum.rs => traits/enum-negative-send-impl.rs} (100%) rename tests/ui/{no_send-enum.stderr => traits/enum-negative-send-impl.stderr} (100%) rename tests/ui/{no_share-enum.rs => traits/enum-negative-sync-impl.rs} (100%) rename tests/ui/{no_share-enum.stderr => traits/enum-negative-sync-impl.stderr} (100%) rename tests/ui/{no_send-rc.rs => traits/rc-not-send.rs} (100%) rename tests/ui/{no_send-rc.stderr => traits/rc-not-send.stderr} (100%) rename tests/ui/{no_share-struct.rs => traits/struct-negative-sync-impl.rs} (100%) rename tests/ui/{no_share-struct.stderr => traits/struct-negative-sync-impl.stderr} (100%) diff --git a/tests/ui/newlambdas.rs b/tests/ui/closures/basic-closure-syntax.rs similarity index 100% rename from tests/ui/newlambdas.rs rename to tests/ui/closures/basic-closure-syntax.rs diff --git a/tests/ui/newtype-polymorphic.rs b/tests/ui/generics/newtype-with-generics.rs similarity index 100% rename from tests/ui/newtype-polymorphic.rs rename to tests/ui/generics/newtype-with-generics.rs diff --git a/tests/ui/new-impl-syntax.rs b/tests/ui/impl-trait/basic-trait-impl.rs similarity index 100% rename from tests/ui/new-impl-syntax.rs rename to tests/ui/impl-trait/basic-trait-impl.rs diff --git a/tests/ui/new-import-syntax.rs b/tests/ui/new-import-syntax.rs deleted file mode 100644 index 547900fab6128..0000000000000 --- a/tests/ui/new-import-syntax.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ run-pass - -pub fn main() { - println!("Hello world!"); -} diff --git a/tests/ui/new-style-constants.rs b/tests/ui/new-style-constants.rs deleted file mode 100644 index e33a2da38785e..0000000000000 --- a/tests/ui/new-style-constants.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass - -static FOO: isize = 3; - -pub fn main() { - println!("{}", FOO); -} diff --git a/tests/ui/new-unicode-escapes.rs b/tests/ui/parser/unicode-escape-sequences.rs similarity index 100% rename from tests/ui/new-unicode-escapes.rs rename to tests/ui/parser/unicode-escape-sequences.rs diff --git a/tests/ui/newtype.rs b/tests/ui/structs/basic-newtype-pattern.rs similarity index 100% rename from tests/ui/newtype.rs rename to tests/ui/structs/basic-newtype-pattern.rs diff --git a/tests/ui/no_send-enum.rs b/tests/ui/traits/enum-negative-send-impl.rs similarity index 100% rename from tests/ui/no_send-enum.rs rename to tests/ui/traits/enum-negative-send-impl.rs diff --git a/tests/ui/no_send-enum.stderr b/tests/ui/traits/enum-negative-send-impl.stderr similarity index 100% rename from tests/ui/no_send-enum.stderr rename to tests/ui/traits/enum-negative-send-impl.stderr diff --git a/tests/ui/no_share-enum.rs b/tests/ui/traits/enum-negative-sync-impl.rs similarity index 100% rename from tests/ui/no_share-enum.rs rename to tests/ui/traits/enum-negative-sync-impl.rs diff --git a/tests/ui/no_share-enum.stderr b/tests/ui/traits/enum-negative-sync-impl.stderr similarity index 100% rename from tests/ui/no_share-enum.stderr rename to tests/ui/traits/enum-negative-sync-impl.stderr diff --git a/tests/ui/no_send-rc.rs b/tests/ui/traits/rc-not-send.rs similarity index 100% rename from tests/ui/no_send-rc.rs rename to tests/ui/traits/rc-not-send.rs diff --git a/tests/ui/no_send-rc.stderr b/tests/ui/traits/rc-not-send.stderr similarity index 100% rename from tests/ui/no_send-rc.stderr rename to tests/ui/traits/rc-not-send.stderr diff --git a/tests/ui/no_share-struct.rs b/tests/ui/traits/struct-negative-sync-impl.rs similarity index 100% rename from tests/ui/no_share-struct.rs rename to tests/ui/traits/struct-negative-sync-impl.rs diff --git a/tests/ui/no_share-struct.stderr b/tests/ui/traits/struct-negative-sync-impl.stderr similarity index 100% rename from tests/ui/no_share-struct.stderr rename to tests/ui/traits/struct-negative-sync-impl.stderr From 4feb5de34c1e41da0c10e149e243a25a6eafcd17 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Mon, 30 Jun 2025 00:03:28 +0500 Subject: [PATCH 05/20] moved tests --- .../non-primitive-cast-suggestion.fixed} | 0 .../{nonscalar-cast.rs => cast/non-primitive-cast-suggestion.rs} | 0 .../non-primitive-cast-suggestion.stderr} | 0 .../closure-clone-requires-captured-clone.rs} | 0 .../closure-clone-requires-captured-clone.stderr} | 0 .../array-repeat-expr-not-const.rs} | 0 .../array-repeat-expr-not-const.stderr} | 0 tests/ui/{ => cross-crate}/auxiliary/noexporttypelib.rs | 0 .../unexported-type-error-message.rs} | 0 .../unexported-type-error-message.stderr} | 0 .../field-replace-in-struct-with-drop.rs} | 0 tests/ui/{no-core-2.rs => no_std/no-core-edition2018-syntax.rs} | 0 .../ui/{no-core-1.rs => no_std/no-core-with-explicit-std-core.rs} | 0 .../{no-send-res-ports.rs => threads-sendsync/rc-is-not-send.rs} | 0 .../rc-is-not-send.stderr} | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{nonscalar-cast.fixed => cast/non-primitive-cast-suggestion.fixed} (100%) rename tests/ui/{nonscalar-cast.rs => cast/non-primitive-cast-suggestion.rs} (100%) rename tests/ui/{nonscalar-cast.stderr => cast/non-primitive-cast-suggestion.stderr} (100%) rename tests/ui/{not-clone-closure.rs => closures/closure-clone-requires-captured-clone.rs} (100%) rename tests/ui/{not-clone-closure.stderr => closures/closure-clone-requires-captured-clone.stderr} (100%) rename tests/ui/{non-constant-expr-for-arr-len.rs => consts/array-repeat-expr-not-const.rs} (100%) rename tests/ui/{non-constant-expr-for-arr-len.stderr => consts/array-repeat-expr-not-const.stderr} (100%) rename tests/ui/{ => cross-crate}/auxiliary/noexporttypelib.rs (100%) rename tests/ui/{noexporttypeexe.rs => cross-crate/unexported-type-error-message.rs} (100%) rename tests/ui/{noexporttypeexe.stderr => cross-crate/unexported-type-error-message.stderr} (100%) rename tests/ui/{no-warn-on-field-replace-issue-34101.rs => drop/field-replace-in-struct-with-drop.rs} (100%) rename tests/ui/{no-core-2.rs => no_std/no-core-edition2018-syntax.rs} (100%) rename tests/ui/{no-core-1.rs => no_std/no-core-with-explicit-std-core.rs} (100%) rename tests/ui/{no-send-res-ports.rs => threads-sendsync/rc-is-not-send.rs} (100%) rename tests/ui/{no-send-res-ports.stderr => threads-sendsync/rc-is-not-send.stderr} (100%) diff --git a/tests/ui/nonscalar-cast.fixed b/tests/ui/cast/non-primitive-cast-suggestion.fixed similarity index 100% rename from tests/ui/nonscalar-cast.fixed rename to tests/ui/cast/non-primitive-cast-suggestion.fixed diff --git a/tests/ui/nonscalar-cast.rs b/tests/ui/cast/non-primitive-cast-suggestion.rs similarity index 100% rename from tests/ui/nonscalar-cast.rs rename to tests/ui/cast/non-primitive-cast-suggestion.rs diff --git a/tests/ui/nonscalar-cast.stderr b/tests/ui/cast/non-primitive-cast-suggestion.stderr similarity index 100% rename from tests/ui/nonscalar-cast.stderr rename to tests/ui/cast/non-primitive-cast-suggestion.stderr diff --git a/tests/ui/not-clone-closure.rs b/tests/ui/closures/closure-clone-requires-captured-clone.rs similarity index 100% rename from tests/ui/not-clone-closure.rs rename to tests/ui/closures/closure-clone-requires-captured-clone.rs diff --git a/tests/ui/not-clone-closure.stderr b/tests/ui/closures/closure-clone-requires-captured-clone.stderr similarity index 100% rename from tests/ui/not-clone-closure.stderr rename to tests/ui/closures/closure-clone-requires-captured-clone.stderr diff --git a/tests/ui/non-constant-expr-for-arr-len.rs b/tests/ui/consts/array-repeat-expr-not-const.rs similarity index 100% rename from tests/ui/non-constant-expr-for-arr-len.rs rename to tests/ui/consts/array-repeat-expr-not-const.rs diff --git a/tests/ui/non-constant-expr-for-arr-len.stderr b/tests/ui/consts/array-repeat-expr-not-const.stderr similarity index 100% rename from tests/ui/non-constant-expr-for-arr-len.stderr rename to tests/ui/consts/array-repeat-expr-not-const.stderr diff --git a/tests/ui/auxiliary/noexporttypelib.rs b/tests/ui/cross-crate/auxiliary/noexporttypelib.rs similarity index 100% rename from tests/ui/auxiliary/noexporttypelib.rs rename to tests/ui/cross-crate/auxiliary/noexporttypelib.rs diff --git a/tests/ui/noexporttypeexe.rs b/tests/ui/cross-crate/unexported-type-error-message.rs similarity index 100% rename from tests/ui/noexporttypeexe.rs rename to tests/ui/cross-crate/unexported-type-error-message.rs diff --git a/tests/ui/noexporttypeexe.stderr b/tests/ui/cross-crate/unexported-type-error-message.stderr similarity index 100% rename from tests/ui/noexporttypeexe.stderr rename to tests/ui/cross-crate/unexported-type-error-message.stderr diff --git a/tests/ui/no-warn-on-field-replace-issue-34101.rs b/tests/ui/drop/field-replace-in-struct-with-drop.rs similarity index 100% rename from tests/ui/no-warn-on-field-replace-issue-34101.rs rename to tests/ui/drop/field-replace-in-struct-with-drop.rs diff --git a/tests/ui/no-core-2.rs b/tests/ui/no_std/no-core-edition2018-syntax.rs similarity index 100% rename from tests/ui/no-core-2.rs rename to tests/ui/no_std/no-core-edition2018-syntax.rs diff --git a/tests/ui/no-core-1.rs b/tests/ui/no_std/no-core-with-explicit-std-core.rs similarity index 100% rename from tests/ui/no-core-1.rs rename to tests/ui/no_std/no-core-with-explicit-std-core.rs diff --git a/tests/ui/no-send-res-ports.rs b/tests/ui/threads-sendsync/rc-is-not-send.rs similarity index 100% rename from tests/ui/no-send-res-ports.rs rename to tests/ui/threads-sendsync/rc-is-not-send.rs diff --git a/tests/ui/no-send-res-ports.stderr b/tests/ui/threads-sendsync/rc-is-not-send.stderr similarity index 100% rename from tests/ui/no-send-res-ports.stderr rename to tests/ui/threads-sendsync/rc-is-not-send.stderr From bf5910d9bb0c5cc3e4fb1a1a9ed3d73e26793c71 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Sun, 29 Jun 2025 23:13:37 +0500 Subject: [PATCH 06/20] cleaned up some tests --- tests/ui/closures/basic-closure-syntax.rs | 33 +++++++++++++--- tests/ui/generics/newtype-with-generics.rs | 39 +++++++++++-------- tests/ui/impl-trait/basic-trait-impl.rs | 8 ++-- tests/ui/parser/unicode-escape-sequences.rs | 6 +++ tests/ui/structs/basic-newtype-pattern.rs | 24 ++++++------ tests/ui/traits/enum-negative-send-impl.rs | 14 ++++--- .../ui/traits/enum-negative-send-impl.stderr | 24 ++++++------ tests/ui/traits/enum-negative-sync-impl.rs | 14 +++++-- .../ui/traits/enum-negative-sync-impl.stderr | 24 ++++++------ tests/ui/traits/rc-not-send.rs | 8 ++-- tests/ui/traits/rc-not-send.stderr | 18 ++++----- tests/ui/traits/struct-negative-sync-impl.rs | 19 ++++++--- .../traits/struct-negative-sync-impl.stderr | 18 ++++----- 13 files changed, 152 insertions(+), 97 deletions(-) diff --git a/tests/ui/closures/basic-closure-syntax.rs b/tests/ui/closures/basic-closure-syntax.rs index 75e851fb73a28..1d968f8cf4af7 100644 --- a/tests/ui/closures/basic-closure-syntax.rs +++ b/tests/ui/closures/basic-closure-syntax.rs @@ -1,14 +1,35 @@ -//@ run-pass -// Tests for the new |args| expr lambda syntax +//! Test basic closure syntax and usage with generic functions. +//! +//! This test checks that closure syntax works correctly for: +//! - Closures with parameters and return values +//! - Closures without parameters (both expression and block forms) +//! - Integration with generic functions and FnOnce trait bounds +//@ run-pass -fn f(i: isize, f: F) -> isize where F: FnOnce(isize) -> isize { f(i) } +fn f(i: isize, f: F) -> isize +where + F: FnOnce(isize) -> isize, +{ + f(i) +} -fn g(_g: G) where G: FnOnce() { } +fn g(_g: G) +where + G: FnOnce(), +{ +} pub fn main() { + // Closure with parameter that returns the same value assert_eq!(f(10, |a| a), 10); - g(||()); + + // Closure without parameters - expression form + g(|| ()); + + // Test closure reuse in generic context assert_eq!(f(10, |a| a), 10); - g(||{}); + + // Closure without parameters - block form + g(|| {}); } diff --git a/tests/ui/generics/newtype-with-generics.rs b/tests/ui/generics/newtype-with-generics.rs index 146d49fdf6819..c5e200e4bc4c4 100644 --- a/tests/ui/generics/newtype-with-generics.rs +++ b/tests/ui/generics/newtype-with-generics.rs @@ -1,27 +1,32 @@ -//@ run-pass - -#![allow(non_camel_case_types)] +//! Test newtype pattern with generic parameters. +//@ run-pass #[derive(Clone)] -struct myvec(Vec ); +struct MyVec(Vec); -fn myvec_deref(mv: myvec) -> Vec { - let myvec(v) = mv; - return v.clone(); +fn extract_inner_vec(wrapper: MyVec) -> Vec { + let MyVec(inner_vec) = wrapper; + inner_vec.clone() } -fn myvec_elt(mv: myvec) -> X { - let myvec(v) = mv; - return v.into_iter().next().unwrap(); +fn get_first_element(wrapper: MyVec) -> T { + let MyVec(inner_vec) = wrapper; + inner_vec.into_iter().next().unwrap() } pub fn main() { - let mv = myvec(vec![1, 2, 3]); - let mv_clone = mv.clone(); - let mv_clone = myvec_deref(mv_clone); - assert_eq!(mv_clone[1], 2); - assert_eq!(myvec_elt(mv.clone()), 1); - let myvec(v) = mv; - assert_eq!(v[2], 3); + let my_vec = MyVec(vec![1, 2, 3]); + let cloned_vec = my_vec.clone(); + + // Test extracting inner vector + let extracted = extract_inner_vec(cloned_vec); + assert_eq!(extracted[1], 2); + + // Test getting first element + assert_eq!(get_first_element(my_vec.clone()), 1); + + // Test direct destructuring + let MyVec(inner) = my_vec; + assert_eq!(inner[2], 3); } diff --git a/tests/ui/impl-trait/basic-trait-impl.rs b/tests/ui/impl-trait/basic-trait-impl.rs index 124d604e6a87a..2706c9c179879 100644 --- a/tests/ui/impl-trait/basic-trait-impl.rs +++ b/tests/ui/impl-trait/basic-trait-impl.rs @@ -1,10 +1,12 @@ +//! Test basic trait implementation syntax for both simple and generic types. + //@ run-pass use std::fmt; struct Thingy { x: isize, - y: isize + y: isize, } impl fmt::Debug for Thingy { @@ -14,10 +16,10 @@ impl fmt::Debug for Thingy { } struct PolymorphicThingy { - x: T + x: T, } -impl fmt::Debug for PolymorphicThingy { +impl fmt::Debug for PolymorphicThingy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.x) } diff --git a/tests/ui/parser/unicode-escape-sequences.rs b/tests/ui/parser/unicode-escape-sequences.rs index 867a50da081c7..8b084866f196e 100644 --- a/tests/ui/parser/unicode-escape-sequences.rs +++ b/tests/ui/parser/unicode-escape-sequences.rs @@ -1,6 +1,12 @@ +//! Test ES6-style Unicode escape sequences in string literals. +//! +//! Regression test for RFC 446 implementation. +//! See . + //@ run-pass pub fn main() { + // Basic Unicode escape - snowman character let s = "\u{2603}"; assert_eq!(s, "☃"); diff --git a/tests/ui/structs/basic-newtype-pattern.rs b/tests/ui/structs/basic-newtype-pattern.rs index 8a07c67eb4f9c..38ccd0ea8e0c2 100644 --- a/tests/ui/structs/basic-newtype-pattern.rs +++ b/tests/ui/structs/basic-newtype-pattern.rs @@ -1,23 +1,25 @@ +//! Test basic newtype pattern functionality. + //@ run-pass -#![allow(non_camel_case_types)] #[derive(Copy, Clone)] -struct mytype(Mytype); +struct Counter(CounterData); #[derive(Copy, Clone)] -struct Mytype { - compute: fn(mytype) -> isize, +struct CounterData { + compute: fn(Counter) -> isize, val: isize, } -fn compute(i: mytype) -> isize { - let mytype(m) = i; - return m.val + 20; +fn compute_value(counter: Counter) -> isize { + let Counter(data) = counter; + data.val + 20 } pub fn main() { - let myval = mytype(Mytype{compute: compute, val: 30}); - println!("{}", compute(myval)); - let mytype(m) = myval; - assert_eq!((m.compute)(myval), 50); + let my_counter = Counter(CounterData { compute: compute_value, val: 30 }); + + // Test destructuring and function pointer call + let Counter(data) = my_counter; + assert_eq!((data.compute)(my_counter), 50); } diff --git a/tests/ui/traits/enum-negative-send-impl.rs b/tests/ui/traits/enum-negative-send-impl.rs index bd560649b990e..6bff42e999919 100644 --- a/tests/ui/traits/enum-negative-send-impl.rs +++ b/tests/ui/traits/enum-negative-send-impl.rs @@ -1,3 +1,7 @@ +//! Test that enums inherit Send/!Send properties from their variants. +//! +//! Uses the unstable `negative_impls` feature to explicitly opt-out of Send. + #![feature(negative_impls)] use std::marker::Send; @@ -5,14 +9,14 @@ use std::marker::Send; struct NoSend; impl !Send for NoSend {} -enum Foo { - A(NoSend) +enum Container { + WithNoSend(NoSend), } -fn bar(_: T) {} +fn requires_send(_: T) {} fn main() { - let x = Foo::A(NoSend); - bar(x); + let container = Container::WithNoSend(NoSend); + requires_send(container); //~^ ERROR `NoSend` cannot be sent between threads safely } diff --git a/tests/ui/traits/enum-negative-send-impl.stderr b/tests/ui/traits/enum-negative-send-impl.stderr index 3b66c7db545e1..1992becccf40e 100644 --- a/tests/ui/traits/enum-negative-send-impl.stderr +++ b/tests/ui/traits/enum-negative-send-impl.stderr @@ -1,22 +1,22 @@ error[E0277]: `NoSend` cannot be sent between threads safely - --> $DIR/no_send-enum.rs:16:9 + --> $DIR/enum-negative-send-impl.rs:20:19 | -LL | bar(x); - | --- ^ `NoSend` cannot be sent between threads safely +LL | requires_send(container); + | ------------- ^^^^^^^^^ `NoSend` cannot be sent between threads safely | | | required by a bound introduced by this call | - = help: within `Foo`, the trait `Send` is not implemented for `NoSend` -note: required because it appears within the type `Foo` - --> $DIR/no_send-enum.rs:8:6 + = help: within `Container`, the trait `Send` is not implemented for `NoSend` +note: required because it appears within the type `Container` + --> $DIR/enum-negative-send-impl.rs:12:6 | -LL | enum Foo { - | ^^^ -note: required by a bound in `bar` - --> $DIR/no_send-enum.rs:12:11 +LL | enum Container { + | ^^^^^^^^^ +note: required by a bound in `requires_send` + --> $DIR/enum-negative-send-impl.rs:16:21 | -LL | fn bar(_: T) {} - | ^^^^ required by this bound in `bar` +LL | fn requires_send(_: T) {} + | ^^^^ required by this bound in `requires_send` error: aborting due to 1 previous error diff --git a/tests/ui/traits/enum-negative-sync-impl.rs b/tests/ui/traits/enum-negative-sync-impl.rs index 44bf1913e7aac..aa81a9fbbf9a9 100644 --- a/tests/ui/traits/enum-negative-sync-impl.rs +++ b/tests/ui/traits/enum-negative-sync-impl.rs @@ -1,3 +1,7 @@ +//! Test that enums inherit Sync/!Sync properties from their variants. +//! +//! Uses the unstable `negative_impls` feature to explicitly opt-out of Sync. + #![feature(negative_impls)] use std::marker::Sync; @@ -5,12 +9,14 @@ use std::marker::Sync; struct NoSync; impl !Sync for NoSync {} -enum Foo { A(NoSync) } +enum Container { + WithNoSync(NoSync), +} -fn bar(_: T) {} +fn requires_sync(_: T) {} fn main() { - let x = Foo::A(NoSync); - bar(x); + let container = Container::WithNoSync(NoSync); + requires_sync(container); //~^ ERROR `NoSync` cannot be shared between threads safely [E0277] } diff --git a/tests/ui/traits/enum-negative-sync-impl.stderr b/tests/ui/traits/enum-negative-sync-impl.stderr index 89939216d5b16..a97b7a36a7bec 100644 --- a/tests/ui/traits/enum-negative-sync-impl.stderr +++ b/tests/ui/traits/enum-negative-sync-impl.stderr @@ -1,22 +1,22 @@ error[E0277]: `NoSync` cannot be shared between threads safely - --> $DIR/no_share-enum.rs:14:9 + --> $DIR/enum-negative-sync-impl.rs:20:19 | -LL | bar(x); - | --- ^ `NoSync` cannot be shared between threads safely +LL | requires_sync(container); + | ------------- ^^^^^^^^^ `NoSync` cannot be shared between threads safely | | | required by a bound introduced by this call | - = help: within `Foo`, the trait `Sync` is not implemented for `NoSync` -note: required because it appears within the type `Foo` - --> $DIR/no_share-enum.rs:8:6 + = help: within `Container`, the trait `Sync` is not implemented for `NoSync` +note: required because it appears within the type `Container` + --> $DIR/enum-negative-sync-impl.rs:12:6 | -LL | enum Foo { A(NoSync) } - | ^^^ -note: required by a bound in `bar` - --> $DIR/no_share-enum.rs:10:11 +LL | enum Container { + | ^^^^^^^^^ +note: required by a bound in `requires_sync` + --> $DIR/enum-negative-sync-impl.rs:16:21 | -LL | fn bar(_: T) {} - | ^^^^ required by this bound in `bar` +LL | fn requires_sync(_: T) {} + | ^^^^ required by this bound in `requires_sync` error: aborting due to 1 previous error diff --git a/tests/ui/traits/rc-not-send.rs b/tests/ui/traits/rc-not-send.rs index f31db15ef2eb6..83084c6173a00 100644 --- a/tests/ui/traits/rc-not-send.rs +++ b/tests/ui/traits/rc-not-send.rs @@ -1,9 +1,11 @@ +//! Test that `Rc` does not implement `Send`. + use std::rc::Rc; -fn bar(_: T) {} +fn requires_send(_: T) {} fn main() { - let x = Rc::new(5); - bar(x); + let rc_value = Rc::new(5); + requires_send(rc_value); //~^ ERROR `Rc<{integer}>` cannot be sent between threads safely } diff --git a/tests/ui/traits/rc-not-send.stderr b/tests/ui/traits/rc-not-send.stderr index 1430a7a29ea26..d6171a39ad047 100644 --- a/tests/ui/traits/rc-not-send.stderr +++ b/tests/ui/traits/rc-not-send.stderr @@ -1,21 +1,21 @@ error[E0277]: `Rc<{integer}>` cannot be sent between threads safely - --> $DIR/no_send-rc.rs:7:9 + --> $DIR/rc-not-send.rs:9:19 | -LL | bar(x); - | --- ^ `Rc<{integer}>` cannot be sent between threads safely +LL | requires_send(rc_value); + | ------------- ^^^^^^^^ `Rc<{integer}>` cannot be sent between threads safely | | | required by a bound introduced by this call | = help: the trait `Send` is not implemented for `Rc<{integer}>` -note: required by a bound in `bar` - --> $DIR/no_send-rc.rs:3:11 +note: required by a bound in `requires_send` + --> $DIR/rc-not-send.rs:5:21 | -LL | fn bar(_: T) {} - | ^^^^ required by this bound in `bar` +LL | fn requires_send(_: T) {} + | ^^^^ required by this bound in `requires_send` help: consider dereferencing here | -LL | bar(*x); - | + +LL | requires_send(*rc_value); + | + error: aborting due to 1 previous error diff --git a/tests/ui/traits/struct-negative-sync-impl.rs b/tests/ui/traits/struct-negative-sync-impl.rs index 7d8a36a76f274..d32846276f626 100644 --- a/tests/ui/traits/struct-negative-sync-impl.rs +++ b/tests/ui/traits/struct-negative-sync-impl.rs @@ -1,14 +1,21 @@ +//! Test negative Sync implementation on structs. +//! +//! Uses the unstable `negative_impls` feature to explicitly opt-out of Sync. + #![feature(negative_impls)] use std::marker::Sync; -struct Foo { a: isize } -impl !Sync for Foo {} +struct NotSync { + value: isize, +} + +impl !Sync for NotSync {} -fn bar(_: T) {} +fn requires_sync(_: T) {} fn main() { - let x = Foo { a: 5 }; - bar(x); - //~^ ERROR `Foo` cannot be shared between threads safely [E0277] + let not_sync = NotSync { value: 5 }; + requires_sync(not_sync); + //~^ ERROR `NotSync` cannot be shared between threads safely [E0277] } diff --git a/tests/ui/traits/struct-negative-sync-impl.stderr b/tests/ui/traits/struct-negative-sync-impl.stderr index 9c7a921b8d8ba..c5fd13f42e50e 100644 --- a/tests/ui/traits/struct-negative-sync-impl.stderr +++ b/tests/ui/traits/struct-negative-sync-impl.stderr @@ -1,17 +1,17 @@ -error[E0277]: `Foo` cannot be shared between threads safely - --> $DIR/no_share-struct.rs:12:9 +error[E0277]: `NotSync` cannot be shared between threads safely + --> $DIR/struct-negative-sync-impl.rs:19:19 | -LL | bar(x); - | --- ^ `Foo` cannot be shared between threads safely +LL | requires_sync(not_sync); + | ------------- ^^^^^^^^ `NotSync` cannot be shared between threads safely | | | required by a bound introduced by this call | - = help: the trait `Sync` is not implemented for `Foo` -note: required by a bound in `bar` - --> $DIR/no_share-struct.rs:8:11 + = help: the trait `Sync` is not implemented for `NotSync` +note: required by a bound in `requires_sync` + --> $DIR/struct-negative-sync-impl.rs:15:21 | -LL | fn bar(_: T) {} - | ^^^^ required by this bound in `bar` +LL | fn requires_sync(_: T) {} + | ^^^^ required by this bound in `requires_sync` error: aborting due to 1 previous error From 90e0835004b2ec6dc596bbecf65eb49f49c01e7f Mon Sep 17 00:00:00 2001 From: dianqk Date: Tue, 1 Jul 2025 07:02:14 +0800 Subject: [PATCH 07/20] mir: Mark `Statement` and `BasicBlockData` as `#[non_exhaustive]` Ensure they are always created using constructors. --- .../src/diagnostics/mutability_errors.rs | 1 + compiler/rustc_middle/src/mir/mod.rs | 1 + compiler/rustc_middle/src/mir/statement.rs | 1 + .../rustc_mir_transform/src/check_enums.rs | 49 +++++++++---------- 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index fd8a2a6bc3544..7c69baba62e8b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1168,6 +1168,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { _, mir::Rvalue::Use(mir::Operand::Copy(place)), )), + .. }) = self.body[location.block].statements.get(location.statement_index) { self.body.local_decls[place.local].source_info.span diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 9f39908c3b2f8..33e97766a027b 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1336,6 +1336,7 @@ impl BasicBlock { /// /// See [`BasicBlock`] for documentation on what basic blocks are at a high level. #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +#[non_exhaustive] pub struct BasicBlockData<'tcx> { /// List of statements in this block. pub statements: Vec>, diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index d16477adb7767..683d7b486171f 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -11,6 +11,7 @@ use crate::ty::CoroutineArgsExt; /// A statement in a basic block, including information about its source code. #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +#[non_exhaustive] pub struct Statement<'tcx> { pub source_info: SourceInfo, pub kind: StatementKind<'tcx>, diff --git a/compiler/rustc_mir_transform/src/check_enums.rs b/compiler/rustc_mir_transform/src/check_enums.rs index e06e0c6122e8d..240da87ab278b 100644 --- a/compiler/rustc_mir_transform/src/check_enums.rs +++ b/compiler/rustc_mir_transform/src/check_enums.rs @@ -230,11 +230,11 @@ fn split_block( let block_data = &mut basic_blocks[location.block]; // Drain every statement after this one and move the current terminator to a new basic block. - let new_block = BasicBlockData { - statements: block_data.statements.split_off(location.statement_index), - terminator: block_data.terminator.take(), - is_cleanup: block_data.is_cleanup, - }; + let new_block = BasicBlockData::new_stmts( + block_data.statements.split_off(location.statement_index), + block_data.terminator.take(), + block_data.is_cleanup, + ); basic_blocks.push(new_block) } @@ -270,10 +270,9 @@ fn insert_discr_cast_to_u128<'tcx>( let mu_array = local_decls.push(LocalDecl::with_source_info(mu_array_ty, source_info)).into(); let rvalue = Rvalue::Cast(CastKind::Transmute, source_op, mu_array_ty); - block_data.statements.push(Statement { - source_info, - kind: StatementKind::Assign(Box::new((mu_array, rvalue))), - }); + block_data + .statements + .push(Statement::new(source_info, StatementKind::Assign(Box::new((mu_array, rvalue))))); // Index into the array of MaybeUninit to get something that is actually // as wide as the discriminant. @@ -294,10 +293,10 @@ fn insert_discr_cast_to_u128<'tcx>( let op_as_int = local_decls.push(LocalDecl::with_source_info(operand_int_ty, source_info)).into(); let rvalue = Rvalue::Cast(CastKind::Transmute, source_op, operand_int_ty); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new((op_as_int, rvalue))), - }); + StatementKind::Assign(Box::new((op_as_int, rvalue))), + )); (CastKind::IntToInt, Operand::Copy(op_as_int)) }; @@ -306,10 +305,10 @@ fn insert_discr_cast_to_u128<'tcx>( let rvalue = Rvalue::Cast(cast_kind, discr_ty_bits, discr.ty); let discr_in_discr_ty = local_decls.push(LocalDecl::with_source_info(discr.ty, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new((discr_in_discr_ty, rvalue))), - }); + StatementKind::Assign(Box::new((discr_in_discr_ty, rvalue))), + )); // Cast the discriminant to a u128 (base for comparisions of enum discriminants). let const_u128 = Ty::new_uint(tcx, ty::UintTy::U128); @@ -317,7 +316,7 @@ fn insert_discr_cast_to_u128<'tcx>( let discr = local_decls.push(LocalDecl::with_source_info(const_u128, source_info)).into(); block_data .statements - .push(Statement { source_info, kind: StatementKind::Assign(Box::new((discr, rvalue))) }); + .push(Statement::new(source_info, StatementKind::Assign(Box::new((discr, rvalue))))); discr } @@ -390,9 +389,9 @@ fn insert_uninhabited_enum_check<'tcx>( ) { let is_ok: Place<'_> = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new(( + StatementKind::Assign(Box::new(( is_ok, Rvalue::Use(Operand::Constant(Box::new(ConstOperand { span: source_info.span, @@ -400,7 +399,7 @@ fn insert_uninhabited_enum_check<'tcx>( const_: Const::Val(ConstValue::from_bool(false), tcx.types.bool), }))), ))), - }); + )); block_data.terminator = Some(Terminator { source_info, @@ -463,19 +462,19 @@ fn insert_niche_check<'tcx>( let discr_diff: Place<'_> = local_decls.push(LocalDecl::with_source_info(tcx.types.u128, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new(( + StatementKind::Assign(Box::new(( discr_diff, Rvalue::BinaryOp(BinOp::Sub, Box::new((Operand::Copy(discr), start_const))), ))), - }); + )); let is_ok: Place<'_> = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new(( + StatementKind::Assign(Box::new(( is_ok, Rvalue::BinaryOp( // This is a `WrappingRange`, so make sure to get the wrapping right. @@ -483,7 +482,7 @@ fn insert_niche_check<'tcx>( Box::new((Operand::Copy(discr_diff), end_start_diff_const)), ), ))), - }); + )); block_data.terminator = Some(Terminator { source_info, From c3fb7d1d1c3d05be8ed3abdfd01196782f6c7821 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Mon, 30 Jun 2025 16:59:28 +0800 Subject: [PATCH 08/20] Make some compiletest errors/warnings/help more visually obvious --- src/tools/compiletest/src/common.rs | 9 ++-- src/tools/compiletest/src/diagnostics.rs | 46 +++++++++++++++++++ src/tools/compiletest/src/header.rs | 24 +++++----- src/tools/compiletest/src/lib.rs | 21 +++------ src/tools/compiletest/src/runtest.rs | 18 +++++--- .../compiletest/src/runtest/codegen_units.rs | 4 +- 6 files changed, 84 insertions(+), 38 deletions(-) create mode 100644 src/tools/compiletest/src/diagnostics.rs diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 9b9d94bbead09..cdce5d941d015 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -11,6 +11,7 @@ use serde::de::{Deserialize, Deserializer, Error as _}; pub use self::Mode::*; use crate::executor::{ColorConfig, OutputFormat}; +use crate::fatal; use crate::util::{Utf8PathBufExt, add_dylib_path}; macro_rules! string_enum { @@ -783,11 +784,13 @@ fn rustc_output(config: &Config, args: &[&str], envs: HashMap) - let output = match command.output() { Ok(output) => output, - Err(e) => panic!("error: failed to run {command:?}: {e}"), + Err(e) => { + fatal!("failed to run {command:?}: {e}"); + } }; if !output.status.success() { - panic!( - "error: failed to run {command:?}\n--- stdout\n{}\n--- stderr\n{}", + fatal!( + "failed to run {command:?}\n--- stdout\n{}\n--- stderr\n{}", String::from_utf8(output.stdout).unwrap(), String::from_utf8(output.stderr).unwrap(), ); diff --git a/src/tools/compiletest/src/diagnostics.rs b/src/tools/compiletest/src/diagnostics.rs new file mode 100644 index 0000000000000..207a6cb91d7ca --- /dev/null +++ b/src/tools/compiletest/src/diagnostics.rs @@ -0,0 +1,46 @@ +//! Collection of diagnostics helpers for `compiletest` *itself*. + +#[macro_export] +macro_rules! fatal { + ($($arg:tt)*) => { + let status = ::colored::Colorize::bright_red("FATAL: "); + let status = ::colored::Colorize::bold(status); + eprint!("{status}"); + eprintln!($($arg)*); + // This intentionally uses a seemingly-redundant panic to include backtrace location. + // + // FIXME: in the long term, we should handle "logic bug in compiletest itself" vs "fatal + // user error" separately. + panic!("fatal error"); + }; +} + +#[macro_export] +macro_rules! error { + ($($arg:tt)*) => { + let status = ::colored::Colorize::red("ERROR: "); + let status = ::colored::Colorize::bold(status); + eprint!("{status}"); + eprintln!($($arg)*); + }; +} + +#[macro_export] +macro_rules! warning { + ($($arg:tt)*) => { + let status = ::colored::Colorize::yellow("WARNING: "); + let status = ::colored::Colorize::bold(status); + eprint!("{status}"); + eprintln!($($arg)*); + }; +} + +#[macro_export] +macro_rules! help { + ($($arg:tt)*) => { + let status = ::colored::Colorize::cyan("HELP: "); + let status = ::colored::Colorize::bold(status); + eprint!("{status}"); + eprintln!($($arg)*); + }; +} diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 2b203bb309c63..5636a146b0f4d 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -15,6 +15,7 @@ use crate::errors::ErrorKind; use crate::executor::{CollectedTestDesc, ShouldPanic}; use crate::header::auxiliary::{AuxProps, parse_and_update_aux}; use crate::header::needs::CachedNeedsConditions; +use crate::help; use crate::util::static_regex; pub(crate) mod auxiliary; @@ -920,9 +921,9 @@ fn iter_header( if !is_known_directive { *poisoned = true; - eprintln!( - "error: detected unknown compiletest test directive `{}` in {}:{}", - directive_line.raw_directive, testfile, line_number, + error!( + "{testfile}:{line_number}: detected unknown compiletest test directive `{}`", + directive_line.raw_directive, ); return; @@ -931,11 +932,11 @@ fn iter_header( if let Some(trailing_directive) = &trailing_directive { *poisoned = true; - eprintln!( - "error: detected trailing compiletest test directive `{}` in {}:{}\n \ - help: put the trailing directive in it's own line: `//@ {}`", - trailing_directive, testfile, line_number, trailing_directive, + error!( + "{testfile}:{line_number}: detected trailing compiletest test directive `{}`", + trailing_directive, ); + help!("put the trailing directive in it's own line: `//@ {}`", trailing_directive); return; } @@ -1031,10 +1032,9 @@ impl Config { }; let Some((regex, replacement)) = parse_normalize_rule(raw_value) else { - panic!( - "couldn't parse custom normalization rule: `{raw_directive}`\n\ - help: expected syntax is: `{directive_name}: \"REGEX\" -> \"REPLACEMENT\"`" - ); + error!("couldn't parse custom normalization rule: `{raw_directive}`"); + help!("expected syntax is: `{directive_name}: \"REGEX\" -> \"REPLACEMENT\"`"); + panic!("invalid normalization rule detected"); }; Some(NormalizeRule { kind, regex, replacement }) } @@ -1406,7 +1406,7 @@ pub(crate) fn make_test_description( ignore_message = Some(reason.into()); } IgnoreDecision::Error { message } => { - eprintln!("error: {}:{line_number}: {message}", path); + error!("{path}:{line_number}: {message}"); *poisoned = true; return; } diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 23a4dd73796e2..09de3eb4c7025 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -11,6 +11,7 @@ mod tests; pub mod common; pub mod compute_diff; mod debuggers; +pub mod diagnostics; pub mod errors; mod executor; pub mod header; @@ -33,7 +34,7 @@ use build_helper::git::{get_git_modified_files, get_git_untracked_files}; use camino::{Utf8Path, Utf8PathBuf}; use getopts::Options; use rayon::iter::{ParallelBridge, ParallelIterator}; -use tracing::*; +use tracing::debug; use walkdir::WalkDir; use self::header::{EarlyProps, make_test_description}; @@ -651,10 +652,7 @@ pub(crate) fn collect_and_make_tests(config: Arc) -> Vec let common_inputs_stamp = common_inputs_stamp(&config); let modified_tests = modified_tests(&config, &config.src_test_suite_root).unwrap_or_else(|err| { - panic!( - "modified_tests got error from dir: {}, error: {}", - config.src_test_suite_root, err - ) + fatal!("modified_tests: {}: {err}", config.src_test_suite_root); }); let cache = HeadersCache::load(&config); @@ -1108,22 +1106,17 @@ fn check_for_overlapping_test_paths(found_path_stems: &HashSet) { pub fn early_config_check(config: &Config) { if !config.has_html_tidy && config.mode == Mode::Rustdoc { - eprintln!("warning: `tidy` (html-tidy.org) is not installed; diffs will not be generated"); + warning!("`tidy` (html-tidy.org) is not installed; diffs will not be generated"); } if !config.profiler_runtime && config.mode == Mode::CoverageRun { let actioned = if config.bless { "blessed" } else { "checked" }; - eprintln!( - r#" -WARNING: profiler runtime is not available, so `.coverage` files won't be {actioned} -help: try setting `profiler = true` in the `[build]` section of `bootstrap.toml`"# - ); + warning!("profiler runtime is not available, so `.coverage` files won't be {actioned}"); + help!("try setting `profiler = true` in the `[build]` section of `bootstrap.toml`"); } // `RUST_TEST_NOCAPTURE` is a libtest env var, but we don't callout to libtest. if env::var("RUST_TEST_NOCAPTURE").is_ok() { - eprintln!( - "WARNING: RUST_TEST_NOCAPTURE is not supported. Use the `--no-capture` flag instead." - ); + warning!("`RUST_TEST_NOCAPTURE` is not supported; use the `--no-capture` flag instead"); } } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 980e89889abba..53b5990d3cde1 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -27,7 +27,7 @@ use crate::errors::{Error, ErrorKind, load_errors}; use crate::header::TestProps; use crate::read2::{Truncated, read2_abbreviated}; use crate::util::{Utf8PathBufExt, add_dylib_path, logv, static_regex}; -use crate::{ColorConfig, json, stamp_file_path}; +use crate::{ColorConfig, help, json, stamp_file_path, warning}; mod debugger; @@ -485,12 +485,15 @@ impl<'test> TestCx<'test> { .windows(2) .any(|args| args == cfg_arg || args[0] == arg || args[1] == arg) { - panic!( - "error: redundant cfg argument `{normalized_revision}` is already created by the revision" + error!( + "redundant cfg argument `{normalized_revision}` is already created by the \ + revision" ); + panic!("redundant cfg argument"); } if self.config.builtin_cfg_names().contains(&normalized_revision) { - panic!("error: revision `{normalized_revision}` collides with a builtin cfg"); + error!("revision `{normalized_revision}` collides with a built-in cfg"); + panic!("revision collides with built-in cfg"); } cmd.args(cfg_arg); } @@ -2167,9 +2170,10 @@ impl<'test> TestCx<'test> { println!("{}", String::from_utf8_lossy(&output.stdout)); eprintln!("{}", String::from_utf8_lossy(&output.stderr)); } else { - eprintln!("warning: no pager configured, falling back to unified diff"); - eprintln!( - "help: try configuring a git pager (e.g. `delta`) with `git config --global core.pager delta`" + warning!("no pager configured, falling back to unified diff"); + help!( + "try configuring a git pager (e.g. `delta`) with \ + `git config --global core.pager delta`" ); let mut out = io::stdout(); let mut diff = BufReader::new(File::open(&diff_filename).unwrap()); diff --git a/src/tools/compiletest/src/runtest/codegen_units.rs b/src/tools/compiletest/src/runtest/codegen_units.rs index 8dfa8d18d1a0b..44ddcb1d28882 100644 --- a/src/tools/compiletest/src/runtest/codegen_units.rs +++ b/src/tools/compiletest/src/runtest/codegen_units.rs @@ -1,8 +1,8 @@ use std::collections::HashSet; use super::{Emit, TestCx, WillExecute}; -use crate::errors; use crate::util::static_regex; +use crate::{errors, fatal}; impl TestCx<'_> { pub(super) fn run_codegen_units_test(&self) { @@ -100,7 +100,7 @@ impl TestCx<'_> { } if !(missing.is_empty() && unexpected.is_empty() && wrong_cgus.is_empty()) { - panic!(); + fatal!("!(missing.is_empty() && unexpected.is_empty() && wrong_cgus.is_empty())"); } #[derive(Clone, Eq, PartialEq)] From c2daa280209b5a72a4393cee9214fc773f13c6c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 30 Jun 2025 22:04:15 +0200 Subject: [PATCH 09/20] Do not enable LLD by default in the dist profile --- src/bootstrap/defaults/bootstrap.dist.toml | 1 - src/bootstrap/src/utils/change_tracker.rs | 5 +++++ src/ci/run.sh | 7 +++---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/defaults/bootstrap.dist.toml b/src/bootstrap/defaults/bootstrap.dist.toml index f0cb34eb45856..9daf9faac14a2 100644 --- a/src/bootstrap/defaults/bootstrap.dist.toml +++ b/src/bootstrap/defaults/bootstrap.dist.toml @@ -20,7 +20,6 @@ download-ci-llvm = false channel = "auto-detect" # Never download a rustc, distributions must build a fresh compiler. download-rustc = false -lld = true # Build the llvm-bitcode-linker llvm-bitcode-linker = true diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 006c294d4458f..f873c62588bdd 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -436,4 +436,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "It is no longer possible to combine `rust.lld = true` with configuring external LLVM using `llvm.llvm-config`.", }, + ChangeInfo { + change_id: 143255, + severity: ChangeSeverity::Warning, + summary: "`llvm.lld` is no longer enabled by default for the dist profile.", + }, ]; diff --git a/src/ci/run.sh b/src/ci/run.sh index a6721a818b303..f58a067041dd8 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -86,13 +86,12 @@ fi # space required for CI artifacts. RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --dist-compression-formats=xz" -if [ "$EXTERNAL_LLVM" = "1" ]; then - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.lld=false" -fi - # Enable the `c` feature for compiler_builtins, but only when the `compiler-rt` source is available # (to avoid spending a lot of time cloning llvm) if [ "$EXTERNAL_LLVM" = "" ]; then + # Enable building & shipping lld + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.lld=true" + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.optimized-compiler-builtins" # Likewise, only demand we test all LLVM components if we know we built LLVM with them export COMPILETEST_REQUIRE_ALL_LLVM_COMPONENTS=1 From 09e0dcae1d224c0c207dfa79e06ac76b0cd1179e Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 1 Jul 2025 08:56:53 +0200 Subject: [PATCH 10/20] bootstrap: make comment more clear Reading that at first made me think the code block ensures that the said artefacts are created --- src/bootstrap/src/core/build_steps/tool.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 83c0525d7c421..a7220515ca09d 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -120,14 +120,14 @@ impl Step for ToolBuild { match self.mode { Mode::ToolRustc => { - // If compiler was forced, its artifacts should be prepared earlier. + // If compiler was forced, its artifacts should have been prepared earlier. if !self.compiler.is_forced_compiler() { builder.std(self.compiler, self.compiler.host); builder.ensure(compile::Rustc::new(self.compiler, target)); } } Mode::ToolStd => { - // If compiler was forced, its artifacts should be prepared earlier. + // If compiler was forced, its artifacts should have been prepared earlier. if !self.compiler.is_forced_compiler() { builder.std(self.compiler, target) } From da5c6395dad7c5be33f842c3660ae2f6af287f3a Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Mon, 30 Jun 2025 00:05:58 +0500 Subject: [PATCH 11/20] cleaned up some tests --- .../cast/non-primitive-cast-suggestion.fixed | 11 ++++- .../ui/cast/non-primitive-cast-suggestion.rs | 11 ++++- .../cast/non-primitive-cast-suggestion.stderr | 10 ++-- .../closure-clone-requires-captured-clone.rs | 20 +++++--- ...osure-clone-requires-captured-clone.stderr | 22 ++++----- .../ui/consts/array-repeat-expr-not-const.rs | 6 ++- .../consts/array-repeat-expr-not-const.stderr | 6 +-- ...ib.rs => unexported-type-error-message.rs} | 0 .../unexported-type-error-message.rs | 6 +-- .../unexported-type-error-message.stderr | 14 +++--- .../drop/field-replace-in-struct-with-drop.rs | 48 ++++++++----------- tests/ui/no_std/no-core-edition2018-syntax.rs | 18 +++++-- .../no_std/no-core-with-explicit-std-core.rs | 8 +++- tests/ui/threads-sendsync/rc-is-not-send.rs | 30 ++++++------ .../ui/threads-sendsync/rc-is-not-send.stderr | 24 +++++----- 15 files changed, 132 insertions(+), 102 deletions(-) rename tests/ui/cross-crate/auxiliary/{noexporttypelib.rs => unexported-type-error-message.rs} (100%) diff --git a/tests/ui/cast/non-primitive-cast-suggestion.fixed b/tests/ui/cast/non-primitive-cast-suggestion.fixed index cb5591dbb9de4..9a1a3c022c791 100644 --- a/tests/ui/cast/non-primitive-cast-suggestion.fixed +++ b/tests/ui/cast/non-primitive-cast-suggestion.fixed @@ -1,8 +1,14 @@ +//! Test that casting non-primitive types with `as` is rejected with a helpful suggestion. +//! +//! You can't use `as` to cast between non-primitive types, even if they have +//! `From`/`Into` implementations. The compiler should suggest using `From::from()` +//! or `.into()` instead, and rustfix should be able to apply the suggestion. + //@ run-rustfix #[derive(Debug)] struct Foo { - x: isize + x: isize, } impl From for isize { @@ -12,5 +18,6 @@ impl From for isize { } fn main() { - println!("{}", isize::from(Foo { x: 1 })); //~ ERROR non-primitive cast: `Foo` as `isize` [E0605] + let _ = isize::from(Foo { x: 1 }); + //~^ ERROR non-primitive cast: `Foo` as `isize` [E0605] } diff --git a/tests/ui/cast/non-primitive-cast-suggestion.rs b/tests/ui/cast/non-primitive-cast-suggestion.rs index 27429b44cd086..79006f4ba26d3 100644 --- a/tests/ui/cast/non-primitive-cast-suggestion.rs +++ b/tests/ui/cast/non-primitive-cast-suggestion.rs @@ -1,8 +1,14 @@ +//! Test that casting non-primitive types with `as` is rejected with a helpful suggestion. +//! +//! You can't use `as` to cast between non-primitive types, even if they have +//! `From`/`Into` implementations. The compiler should suggest using `From::from()` +//! or `.into()` instead, and rustfix should be able to apply the suggestion. + //@ run-rustfix #[derive(Debug)] struct Foo { - x: isize + x: isize, } impl From for isize { @@ -12,5 +18,6 @@ impl From for isize { } fn main() { - println!("{}", Foo { x: 1 } as isize); //~ ERROR non-primitive cast: `Foo` as `isize` [E0605] + let _ = Foo { x: 1 } as isize; + //~^ ERROR non-primitive cast: `Foo` as `isize` [E0605] } diff --git a/tests/ui/cast/non-primitive-cast-suggestion.stderr b/tests/ui/cast/non-primitive-cast-suggestion.stderr index 834d4ea241c12..bd35ded15a46c 100644 --- a/tests/ui/cast/non-primitive-cast-suggestion.stderr +++ b/tests/ui/cast/non-primitive-cast-suggestion.stderr @@ -1,13 +1,13 @@ error[E0605]: non-primitive cast: `Foo` as `isize` - --> $DIR/nonscalar-cast.rs:15:20 + --> $DIR/non-primitive-cast-suggestion.rs:21:13 | -LL | println!("{}", Foo { x: 1 } as isize); - | ^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object +LL | let _ = Foo { x: 1 } as isize; + | ^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object | help: consider using the `From` trait instead | -LL - println!("{}", Foo { x: 1 } as isize); -LL + println!("{}", isize::from(Foo { x: 1 })); +LL - let _ = Foo { x: 1 } as isize; +LL + let _ = isize::from(Foo { x: 1 }); | error: aborting due to 1 previous error diff --git a/tests/ui/closures/closure-clone-requires-captured-clone.rs b/tests/ui/closures/closure-clone-requires-captured-clone.rs index 976e3b9e81c2e..80938e50b67a7 100644 --- a/tests/ui/closures/closure-clone-requires-captured-clone.rs +++ b/tests/ui/closures/closure-clone-requires-captured-clone.rs @@ -1,13 +1,19 @@ -//@compile-flags: --diagnostic-width=300 -// Check that closures do not implement `Clone` if their environment is not `Clone`. +//! Test that closures only implement `Clone` if all captured values implement `Clone`. +//! +//! When a closure captures variables from its environment, it can only be cloned +//! if all those captured variables are cloneable. This test makes sure the compiler +//! properly rejects attempts to clone closures that capture non-Clone types. -struct S(i32); +//@ compile-flags: --diagnostic-width=300 + +struct NonClone(i32); fn main() { - let a = S(5); - let hello = move || { - println!("Hello {}", a.0); + let captured_value = NonClone(5); + let closure = move || { + let _ = captured_value.0; }; - let hello = hello.clone(); //~ ERROR the trait bound `S: Clone` is not satisfied + closure.clone(); + //~^ ERROR the trait bound `NonClone: Clone` is not satisfied } diff --git a/tests/ui/closures/closure-clone-requires-captured-clone.stderr b/tests/ui/closures/closure-clone-requires-captured-clone.stderr index 0c95a99d0c095..785cc8a3032e2 100644 --- a/tests/ui/closures/closure-clone-requires-captured-clone.stderr +++ b/tests/ui/closures/closure-clone-requires-captured-clone.stderr @@ -1,21 +1,21 @@ -error[E0277]: the trait bound `S: Clone` is not satisfied in `{closure@$DIR/not-clone-closure.rs:8:17: 8:24}` - --> $DIR/not-clone-closure.rs:12:23 +error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{closure@$DIR/closure-clone-requires-captured-clone.rs:13:19: 13:26}` + --> $DIR/closure-clone-requires-captured-clone.rs:17:13 | -LL | let hello = move || { - | ------- within this `{closure@$DIR/not-clone-closure.rs:8:17: 8:24}` +LL | let closure = move || { + | ------- within this `{closure@$DIR/closure-clone-requires-captured-clone.rs:13:19: 13:26}` ... -LL | let hello = hello.clone(); - | ^^^^^ within `{closure@$DIR/not-clone-closure.rs:8:17: 8:24}`, the trait `Clone` is not implemented for `S` +LL | closure.clone(); + | ^^^^^ within `{closure@$DIR/closure-clone-requires-captured-clone.rs:13:19: 13:26}`, the trait `Clone` is not implemented for `NonClone` | note: required because it's used within this closure - --> $DIR/not-clone-closure.rs:8:17 + --> $DIR/closure-clone-requires-captured-clone.rs:13:19 | -LL | let hello = move || { - | ^^^^^^^ -help: consider annotating `S` with `#[derive(Clone)]` +LL | let closure = move || { + | ^^^^^^^ +help: consider annotating `NonClone` with `#[derive(Clone)]` | LL + #[derive(Clone)] -LL | struct S(i32); +LL | struct NonClone(i32); | error: aborting due to 1 previous error diff --git a/tests/ui/consts/array-repeat-expr-not-const.rs b/tests/ui/consts/array-repeat-expr-not-const.rs index 1b101d3233f14..55aee7336da32 100644 --- a/tests/ui/consts/array-repeat-expr-not-const.rs +++ b/tests/ui/consts/array-repeat-expr-not-const.rs @@ -1,7 +1,9 @@ -// Check that non constant exprs fail for array repeat syntax +//! Arrays created with `[value; length]` syntax need the length to be known at +//! compile time. This test makes sure the compiler rejects runtime values like +//! function parameters in the length position. fn main() { - fn bar(n: usize) { + fn create_array(n: usize) { let _x = [0; n]; //~^ ERROR attempt to use a non-constant value in a constant [E0435] } diff --git a/tests/ui/consts/array-repeat-expr-not-const.stderr b/tests/ui/consts/array-repeat-expr-not-const.stderr index c9f977fbaa409..f576154525964 100644 --- a/tests/ui/consts/array-repeat-expr-not-const.stderr +++ b/tests/ui/consts/array-repeat-expr-not-const.stderr @@ -1,8 +1,8 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/non-constant-expr-for-arr-len.rs:5:22 + --> $DIR/array-repeat-expr-not-const.rs:7:22 | -LL | fn bar(n: usize) { - | - this would need to be a `const` +LL | fn create_array(n: usize) { + | - this would need to be a `const` LL | let _x = [0; n]; | ^ diff --git a/tests/ui/cross-crate/auxiliary/noexporttypelib.rs b/tests/ui/cross-crate/auxiliary/unexported-type-error-message.rs similarity index 100% rename from tests/ui/cross-crate/auxiliary/noexporttypelib.rs rename to tests/ui/cross-crate/auxiliary/unexported-type-error-message.rs diff --git a/tests/ui/cross-crate/unexported-type-error-message.rs b/tests/ui/cross-crate/unexported-type-error-message.rs index 35257b20ccdf8..5998f0dc6e233 100644 --- a/tests/ui/cross-crate/unexported-type-error-message.rs +++ b/tests/ui/cross-crate/unexported-type-error-message.rs @@ -1,13 +1,13 @@ -//@ aux-build:noexporttypelib.rs +//@ aux-build:unexported-type-error-message.rs -extern crate noexporttypelib; +extern crate unexported_type_error_message; fn main() { // Here, the type returned by foo() is not exported. // This used to cause internal errors when serializing // because the def_id associated with the type was // not convertible to a path. - let x: isize = noexporttypelib::foo(); + let x: isize = unexported_type_error_message::foo(); //~^ ERROR mismatched types //~| NOTE expected type `isize` //~| NOTE found enum `Option` diff --git a/tests/ui/cross-crate/unexported-type-error-message.stderr b/tests/ui/cross-crate/unexported-type-error-message.stderr index 59759b696c7a2..b468d9839e10e 100644 --- a/tests/ui/cross-crate/unexported-type-error-message.stderr +++ b/tests/ui/cross-crate/unexported-type-error-message.stderr @@ -1,17 +1,17 @@ error[E0308]: mismatched types - --> $DIR/noexporttypeexe.rs:10:18 + --> $DIR/unexported-type-error-message.rs:10:20 | -LL | let x: isize = noexporttypelib::foo(); - | ----- ^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `Option` - | | - | expected due to this +LL | let x: isize = unexported_type_error_message::foo(); + | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `Option` + | | + | expected due to this | = note: expected type `isize` found enum `Option` help: consider using `Option::expect` to unwrap the `Option` value, panicking if the value is an `Option::None` | -LL | let x: isize = noexporttypelib::foo().expect("REASON"); - | +++++++++++++++++ +LL | let x: isize = unexported_type_error_message::foo().expect("REASON"); + | +++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/drop/field-replace-in-struct-with-drop.rs b/tests/ui/drop/field-replace-in-struct-with-drop.rs index e1d5e9c5268b8..8c65a4b3ad1e0 100644 --- a/tests/ui/drop/field-replace-in-struct-with-drop.rs +++ b/tests/ui/drop/field-replace-in-struct-with-drop.rs @@ -1,22 +1,17 @@ -// Issue 34101: Circa 2016-06-05, `fn inline` below issued an -// erroneous warning from the elaborate_drops pass about moving out of -// a field in `Foo`, which has a destructor (and thus cannot have -// content moved out of it). The reason that the warning is erroneous -// in this case is that we are doing a *replace*, not a move, of the -// content in question, and it is okay to replace fields within `Foo`. -// -// Another more subtle problem was that the elaborate_drops was -// creating a separate drop flag for that internally replaced content, -// even though the compiler should enforce an invariant that any drop -// flag for such subcontent of `Foo` will always have the same value -// as the drop flag for `Foo` itself. - - - - - - - +//! Circa 2016-06-05, `fn inline` below issued an +//! erroneous warning from the elaborate_drops pass about moving out of +//! a field in `Foo`, which has a destructor (and thus cannot have +//! content moved out of it). The reason that the warning is erroneous +//! in this case is that we are doing a *replace*, not a move, of the +//! content in question, and it is okay to replace fields within `Foo`. +//! +//! Another more subtle problem was that the elaborate_drops was +//! creating a separate drop flag for that internally replaced content, +//! even though the compiler should enforce an invariant that any drop +//! flag for such subcontent of `Foo` will always have the same value +//! as the drop flag for `Foo` itself. +//! +//! Regression test for . //@ check-pass @@ -26,21 +21,20 @@ impl Drop for Foo { fn drop(&mut self) {} } -fn inline() { - // (dummy variable so `f` gets assigned `var1` in MIR for both fn's) +fn test_inline_replacement() { + // dummy variable so `f` gets assigned `var1` in MIR for both functions let _s = (); let mut f = Foo(String::from("foo")); - f.0 = String::from("bar"); + f.0 = String::from("bar"); // This should not warn } -fn outline() { +fn test_outline_replacement() { let _s = String::from("foo"); let mut f = Foo(_s); - f.0 = String::from("bar"); + f.0 = String::from("bar"); // This should not warn either } - fn main() { - inline(); - outline(); + test_inline_replacement(); + test_outline_replacement(); } diff --git a/tests/ui/no_std/no-core-edition2018-syntax.rs b/tests/ui/no_std/no-core-edition2018-syntax.rs index 2f55365bdd0f3..9a327e4c8e316 100644 --- a/tests/ui/no_std/no-core-edition2018-syntax.rs +++ b/tests/ui/no_std/no-core-edition2018-syntax.rs @@ -1,19 +1,27 @@ +//! Test that `#![no_core]` doesn't break modern Rust syntax in edition 2018. +//! +//! When you use `#![no_core]`, you lose the automatic prelude, but you can still +//! get everything back by manually importing `use core::{prelude::v1::*, *}`. +//! This test makes sure that after doing that, things like `for` loops and the +//! `?` operator still work as expected. + //@ run-pass +//@ edition:2018 #![allow(dead_code, unused_imports)] #![feature(no_core)] #![no_core] -//@ edition:2018 -extern crate std; extern crate core; -use core::{prelude::v1::*, *}; +extern crate std; +use core::prelude::v1::*; +use core::*; -fn foo() { +fn test_for_loop() { for _ in &[()] {} } -fn bar() -> Option<()> { +fn test_question_mark_operator() -> Option<()> { None? } diff --git a/tests/ui/no_std/no-core-with-explicit-std-core.rs b/tests/ui/no_std/no-core-with-explicit-std-core.rs index d6d2ba6044585..3940bcb3aa4fb 100644 --- a/tests/ui/no_std/no-core-with-explicit-std-core.rs +++ b/tests/ui/no_std/no-core-with-explicit-std-core.rs @@ -1,11 +1,17 @@ +//! Test that you can use `#![no_core]` and still import std and core manually. +//! +//! The `#![no_core]` attribute disables the automatic core prelude, but you should +//! still be able to explicitly import both `std` and `core` crates and use types +//! like `Option` normally. + //@ run-pass #![allow(stable_features)] #![feature(no_core, core)] #![no_core] -extern crate std; extern crate core; +extern crate std; use std::option::Option::Some; diff --git a/tests/ui/threads-sendsync/rc-is-not-send.rs b/tests/ui/threads-sendsync/rc-is-not-send.rs index 1bac5868e73fe..dd562e9e8f34f 100644 --- a/tests/ui/threads-sendsync/rc-is-not-send.rs +++ b/tests/ui/threads-sendsync/rc-is-not-send.rs @@ -1,28 +1,28 @@ -use std::thread; +//! Test that `Rc` cannot be sent between threads. + use std::rc::Rc; +use std::thread; #[derive(Debug)] struct Port(Rc); -fn main() { - #[derive(Debug)] - struct Foo { - _x: Port<()>, - } +#[derive(Debug)] +struct Foo { + _x: Port<()>, +} - impl Drop for Foo { - fn drop(&mut self) {} - } +impl Drop for Foo { + fn drop(&mut self) {} +} - fn foo(x: Port<()>) -> Foo { - Foo { - _x: x - } - } +fn foo(x: Port<()>) -> Foo { + Foo { _x: x } +} +fn main() { let x = foo(Port(Rc::new(()))); - thread::spawn(move|| { + thread::spawn(move || { //~^ ERROR `Rc<()>` cannot be sent between threads safely let y = x; println!("{:?}", y); diff --git a/tests/ui/threads-sendsync/rc-is-not-send.stderr b/tests/ui/threads-sendsync/rc-is-not-send.stderr index 9c30261e5cb73..a06b683f729e0 100644 --- a/tests/ui/threads-sendsync/rc-is-not-send.stderr +++ b/tests/ui/threads-sendsync/rc-is-not-send.stderr @@ -1,10 +1,10 @@ error[E0277]: `Rc<()>` cannot be sent between threads safely - --> $DIR/no-send-res-ports.rs:25:19 + --> $DIR/rc-is-not-send.rs:25:19 | -LL | thread::spawn(move|| { - | ------------- ^----- +LL | thread::spawn(move || { + | ------------- ^------ | | | - | _____|_____________within this `{closure@$DIR/no-send-res-ports.rs:25:19: 25:25}` + | _____|_____________within this `{closure@$DIR/rc-is-not-send.rs:25:19: 25:26}` | | | | | required by a bound introduced by this call LL | | @@ -13,22 +13,22 @@ LL | | println!("{:?}", y); LL | | }); | |_____^ `Rc<()>` cannot be sent between threads safely | - = help: within `{closure@$DIR/no-send-res-ports.rs:25:19: 25:25}`, the trait `Send` is not implemented for `Rc<()>` + = help: within `{closure@$DIR/rc-is-not-send.rs:25:19: 25:26}`, the trait `Send` is not implemented for `Rc<()>` note: required because it appears within the type `Port<()>` - --> $DIR/no-send-res-ports.rs:5:8 + --> $DIR/rc-is-not-send.rs:7:8 | LL | struct Port(Rc); | ^^^^ note: required because it appears within the type `Foo` - --> $DIR/no-send-res-ports.rs:9:12 + --> $DIR/rc-is-not-send.rs:10:8 | -LL | struct Foo { - | ^^^ +LL | struct Foo { + | ^^^ note: required because it's used within this closure - --> $DIR/no-send-res-ports.rs:25:19 + --> $DIR/rc-is-not-send.rs:25:19 | -LL | thread::spawn(move|| { - | ^^^^^^ +LL | thread::spawn(move || { + | ^^^^^^^ note: required by a bound in `spawn` --> $SRC_DIR/std/src/thread/mod.rs:LL:COL From 022c91465aad3688f38e75bdaba93aa2caf577c9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 1 Jul 2025 14:36:28 +0200 Subject: [PATCH 12/20] Remove `ItemKind::descr` method --- compiler/rustc_hir/src/hir.rs | 21 --------------------- compiler/rustc_passes/src/check_attr.rs | 2 +- tests/ui/lowering/issue-121108.stderr | 2 +- 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4bb6a796be444..f8506d8b29b49 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -4400,27 +4400,6 @@ impl ItemKind<'_> { _ => return None, }) } - - pub fn descr(&self) -> &'static str { - match self { - ItemKind::ExternCrate(..) => "extern crate", - ItemKind::Use(..) => "`use` import", - ItemKind::Static(..) => "static item", - ItemKind::Const(..) => "constant item", - ItemKind::Fn { .. } => "function", - ItemKind::Macro(..) => "macro", - ItemKind::Mod(..) => "module", - ItemKind::ForeignMod { .. } => "extern block", - ItemKind::GlobalAsm { .. } => "global asm item", - ItemKind::TyAlias(..) => "type alias", - ItemKind::Enum(..) => "enum", - ItemKind::Struct(..) => "struct", - ItemKind::Union(..) => "union", - ItemKind::Trait(..) => "trait", - ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl(..) => "implementation", - } - } } /// A reference from an trait to one of its associated items. This diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 34c76bd3f27f3..19729cbc726a4 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2844,7 +2844,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { .find(|item| !item.span.is_dummy()) // Skip prelude `use`s .map(|item| errors::ItemFollowingInnerAttr { span: if let Some(ident) = item.kind.ident() { ident.span } else { item.span }, - kind: item.kind.descr(), + kind: tcx.def_descr(item.owner_id.to_def_id()), }); let err = tcx.dcx().create_err(errors::InvalidAttrAtCrateLevel { span, diff --git a/tests/ui/lowering/issue-121108.stderr b/tests/ui/lowering/issue-121108.stderr index e4942e8cb0796..f68655a70021f 100644 --- a/tests/ui/lowering/issue-121108.stderr +++ b/tests/ui/lowering/issue-121108.stderr @@ -5,7 +5,7 @@ LL | #![derive(Clone, Copy)] | ^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | use std::ptr::addr_of; - | ------- the inner attribute doesn't annotate this `use` import + | ------- the inner attribute doesn't annotate this import | help: perhaps you meant to use an outer attribute | From 0fcf295b64693e39e53507e8385ae61f790a45fd Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 28 Jun 2025 16:11:01 +0200 Subject: [PATCH 13/20] New test for malformed attributes Signed-off-by: Jonathan Brouwer --- tests/ui/attributes/malformed-attrs.rs | 222 ++++++++ tests/ui/attributes/malformed-attrs.stderr | 603 +++++++++++++++++++++ 2 files changed, 825 insertions(+) create mode 100644 tests/ui/attributes/malformed-attrs.rs create mode 100644 tests/ui/attributes/malformed-attrs.stderr diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs new file mode 100644 index 0000000000000..3ab68ee63f848 --- /dev/null +++ b/tests/ui/attributes/malformed-attrs.rs @@ -0,0 +1,222 @@ +// This file contains a bunch of malformed attributes. +// We enable a bunch of features to not get feature-gate errs in this test. +#![feature(rustc_attrs)] +#![feature(rustc_allow_const_fn_unstable)] +#![feature(allow_internal_unstable)] +#![feature(fn_align)] +#![feature(optimize_attribute)] +#![feature(dropck_eyepatch)] +#![feature(export_stable)] +#![allow(incomplete_features)] +#![feature(min_generic_const_args)] +#![feature(ffi_const, ffi_pure)] +#![feature(coverage_attribute)] +#![feature(no_sanitize)] +#![feature(marker_trait_attr)] +#![feature(thread_local)] +#![feature(must_not_suspend)] +#![feature(coroutines)] +#![feature(linkage)] +#![feature(cfi_encoding, extern_types)] +#![feature(patchable_function_entry)] +#![feature(omit_gdb_pretty_printer_section)] +#![feature(fundamental)] + + +#![omit_gdb_pretty_printer_section = 1] +//~^ ERROR malformed `omit_gdb_pretty_printer_section` attribute input + +#![windows_subsystem] +//~^ ERROR malformed + +#[unsafe(export_name)] +//~^ ERROR malformed +//~| ERROR malformed +#[rustc_allow_const_fn_unstable] +//~^ ERROR `rustc_allow_const_fn_unstable` expects a list of feature names +#[allow_internal_unstable] +//~^ ERROR `allow_internal_unstable` expects a list of feature names +#[rustc_confusables] +//~^ ERROR malformed +#[deprecated = 5] +//~^ ERROR malformed +#[doc] +//~^ ERROR valid forms for the attribute are +//~| WARN this was previously accepted by the compiler +#[rustc_macro_transparency] +//~^ ERROR malformed +//~| ERROR malformed +#[repr] +//~^ ERROR malformed +#[rustc_as_ptr = 5] +//~^ ERROR malformed +#[inline = 5] +//~^ ERROR valid forms for the attribute are +//~| WARN this was previously accepted by the compiler +#[align] +//~^ ERROR malformed +#[optimize] +//~^ ERROR malformed +#[cold = 1] +//~^ ERROR malformed +#[must_use()] +//~^ ERROR valid forms for the attribute are +#[no_mangle = 1] +//~^ ERROR malformed +#[unsafe(naked())] +//~^ ERROR malformed +#[track_caller()] +//~^ ERROR malformed +#[export_name()] +//~^ ERROR malformed +//~| ERROR malformed +#[used()] +//~^ ERROR malformed +#[crate_name] +//~^ ERROR malformed +#[doc] +//~^ ERROR valid forms for the attribute are +//~| WARN this was previously accepted by the compiler +#[target_feature] +//~^ ERROR malformed +#[export_stable = 1] +//~^ ERROR malformed +#[link] +//~^ ERROR attribute must be of the form +//~| WARN this was previously accepted by the compiler +#[link_name] +//~^ ERROR malformed +#[link_section] +//~^ ERROR malformed +#[coverage] +//~^ ERROR malformed `coverage` attribute input +#[no_sanitize] +//~^ ERROR malformed +#[ignore()] +//~^ ERROR valid forms for the attribute are +//~| WARN this was previously accepted by the compiler +#[no_implicit_prelude = 23] +//~^ ERROR malformed +#[proc_macro = 18] +//~^ ERROR malformed +//~| ERROR the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type +#[cfg] +//~^ ERROR is not followed by parentheses +#[cfg_attr] +//~^ ERROR malformed +#[instruction_set] +//~^ ERROR malformed +#[patchable_function_entry] +//~^ ERROR malformed +fn test() { + #[coroutine = 63] || {} + //~^ ERROR malformed `coroutine` attribute input + //~| ERROR mismatched types [E0308] +} + +#[proc_macro_attribute = 19] +//~^ ERROR malformed +//~| ERROR the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type +fn test2() { } + +#[proc_macro_derive] +//~^ ERROR malformed `proc_macro_derive` attribute +//~| ERROR the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type +pub fn test3() {} + +#[rustc_layout_scalar_valid_range_start] +//~^ ERROR malformed +#[rustc_layout_scalar_valid_range_end] +//~^ ERROR malformed +#[must_not_suspend()] +//~^ ERROR malformed +#[cfi_encoding] +//~^ ERROR malformed +struct Test; + +#[diagnostic::on_unimplemented] +//~^ WARN missing options for `on_unimplemented` attribute +#[diagnostic::on_unimplemented = 1] +//~^ WARN malformed +trait Hey { + #[type_const = 1] + //~^ ERROR malformed + const HEY: usize = 5; +} + +struct Empty; +#[diagnostic::do_not_recommend()] +//~^ WARN does not expect any arguments +impl Hey for Empty { + +} + +#[marker = 3] +//~^ ERROR malformed +#[fundamental()] +//~^ ERROR malformed +trait EmptyTrait { + +} + + +extern "C" { + #[unsafe(ffi_pure = 1)] + //~^ ERROR malformed + #[link_ordinal] + //~^ ERROR malformed + pub fn baz(); + + #[unsafe(ffi_const = 1)] + //~^ ERROR malformed + #[linkage] + //~^ ERROR malformed + pub fn bar(); +} + +#[allow] +//~^ ERROR malformed +#[expect] +//~^ ERROR malformed +#[warn] +//~^ ERROR malformed +#[deny] +//~^ ERROR malformed +#[forbid] +//~^ ERROR malformed +#[debugger_visualizer] +//~^ ERROR invalid argument +//~| ERROR malformed `debugger_visualizer` attribute input +#[automatically_derived = 18] +//~^ ERROR malformed +mod yooo { + +} + +#[non_exhaustive = 1] +//~^ ERROR malformed +enum Slenum { + +} + +#[thread_local()] +//~^ ERROR malformed +static mut TLS: u8 = 42; + +#[no_link()] +//~^ ERROR malformed +#[macro_use = 1] +//~^ ERROR malformed +extern crate wloop; +//~^ ERROR can't find crate for `wloop` [E0463] + +#[macro_export = 18] +//~^ ERROR malformed `macro_export` attribute input +#[allow_internal_unsafe = 1] +//~^ ERROR malformed +//~| ERROR allow_internal_unsafe side-steps the unsafe_code lint +macro_rules! slump { + () => {} +} + +fn main() {} diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr new file mode 100644 index 0000000000000..5e731f16a8a26 --- /dev/null +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -0,0 +1,603 @@ +error: `cfg` is not followed by parentheses + --> $DIR/malformed-attrs.rs:103:1 + | +LL | #[cfg] + | ^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + +error: malformed `cfg_attr` attribute input + --> $DIR/malformed-attrs.rs:105:1 + | +LL | #[cfg_attr] + | ^^^^^^^^^^^ + | + = note: for more information, visit +help: missing condition and attribute + | +LL | #[cfg_attr(condition, attribute, other_attribute, ...)] + | ++++++++++++++++++++++++++++++++++++++++++++ + +error[E0463]: can't find crate for `wloop` + --> $DIR/malformed-attrs.rs:210:1 + | +LL | extern crate wloop; + | ^^^^^^^^^^^^^^^^^^^ can't find crate + +error: malformed `omit_gdb_pretty_printer_section` attribute input + --> $DIR/malformed-attrs.rs:26:1 + | +LL | #![omit_gdb_pretty_printer_section = 1] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![omit_gdb_pretty_printer_section]` + +error: malformed `windows_subsystem` attribute input + --> $DIR/malformed-attrs.rs:29:1 + | +LL | #![windows_subsystem] + | ^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![windows_subsystem = "windows|console"]` + +error: malformed `export_name` attribute input + --> $DIR/malformed-attrs.rs:32:1 + | +LL | #[unsafe(export_name)] + | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]` + +error: malformed `rustc_macro_transparency` attribute input + --> $DIR/malformed-attrs.rs:46:1 + | +LL | #[rustc_macro_transparency] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_macro_transparency = "transparent|semiopaque|opaque"]` + +error: malformed `export_name` attribute input + --> $DIR/malformed-attrs.rs:70:1 + | +LL | #[export_name()] + | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]` + +error: malformed `crate_name` attribute input + --> $DIR/malformed-attrs.rs:75:1 + | +LL | #[crate_name] + | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]` + +error: malformed `target_feature` attribute input + --> $DIR/malformed-attrs.rs:80:1 + | +LL | #[target_feature] + | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]` + +error: malformed `export_stable` attribute input + --> $DIR/malformed-attrs.rs:82:1 + | +LL | #[export_stable = 1] + | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_stable]` + +error: malformed `link_section` attribute input + --> $DIR/malformed-attrs.rs:89:1 + | +LL | #[link_section] + | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` + +error: malformed `coverage` attribute input + --> $DIR/malformed-attrs.rs:91:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ + +error: malformed `no_sanitize` attribute input + --> $DIR/malformed-attrs.rs:93:1 + | +LL | #[no_sanitize] + | ^^^^^^^^^^^^^^ help: must be of the form: `#[no_sanitize(address, kcfi, memory, thread)]` + +error: malformed `no_implicit_prelude` attribute input + --> $DIR/malformed-attrs.rs:98:1 + | +LL | #[no_implicit_prelude = 23] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[no_implicit_prelude]` + +error: malformed `proc_macro` attribute input + --> $DIR/malformed-attrs.rs:100:1 + | +LL | #[proc_macro = 18] + | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]` + +error: malformed `instruction_set` attribute input + --> $DIR/malformed-attrs.rs:107:1 + | +LL | #[instruction_set] + | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]` + +error: malformed `patchable_function_entry` attribute input + --> $DIR/malformed-attrs.rs:109:1 + | +LL | #[patchable_function_entry] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` + +error: malformed `coroutine` attribute input + --> $DIR/malformed-attrs.rs:112:5 + | +LL | #[coroutine = 63] || {} + | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[coroutine]` + +error: malformed `proc_macro_attribute` attribute input + --> $DIR/malformed-attrs.rs:117:1 + | +LL | #[proc_macro_attribute = 19] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]` + +error: malformed `proc_macro_derive` attribute input + --> $DIR/malformed-attrs.rs:122:1 + | +LL | #[proc_macro_derive] + | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` + +error: malformed `rustc_layout_scalar_valid_range_start` attribute input + --> $DIR/malformed-attrs.rs:127:1 + | +LL | #[rustc_layout_scalar_valid_range_start] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_layout_scalar_valid_range_start(value)]` + +error: malformed `rustc_layout_scalar_valid_range_end` attribute input + --> $DIR/malformed-attrs.rs:129:1 + | +LL | #[rustc_layout_scalar_valid_range_end] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_layout_scalar_valid_range_end(value)]` + +error: malformed `must_not_suspend` attribute input + --> $DIR/malformed-attrs.rs:131:1 + | +LL | #[must_not_suspend()] + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL - #[must_not_suspend()] +LL + #[must_not_suspend = "reason"] + | +LL - #[must_not_suspend()] +LL + #[must_not_suspend] + | + +error: malformed `cfi_encoding` attribute input + --> $DIR/malformed-attrs.rs:133:1 + | +LL | #[cfi_encoding] + | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` + +error: malformed `type_const` attribute input + --> $DIR/malformed-attrs.rs:142:5 + | +LL | #[type_const = 1] + | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]` + +error: malformed `marker` attribute input + --> $DIR/malformed-attrs.rs:154:1 + | +LL | #[marker = 3] + | ^^^^^^^^^^^^^ help: must be of the form: `#[marker]` + +error: malformed `fundamental` attribute input + --> $DIR/malformed-attrs.rs:156:1 + | +LL | #[fundamental()] + | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[fundamental]` + +error: malformed `ffi_pure` attribute input + --> $DIR/malformed-attrs.rs:164:5 + | +LL | #[unsafe(ffi_pure = 1)] + | ^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_pure]` + +error: malformed `link_ordinal` attribute input + --> $DIR/malformed-attrs.rs:166:5 + | +LL | #[link_ordinal] + | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_ordinal(ordinal)]` + +error: malformed `ffi_const` attribute input + --> $DIR/malformed-attrs.rs:170:5 + | +LL | #[unsafe(ffi_const = 1)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_const]` + +error: malformed `linkage` attribute input + --> $DIR/malformed-attrs.rs:172:5 + | +LL | #[linkage] + | ^^^^^^^^^^ help: must be of the form: `#[linkage = "external|internal|..."]` + +error: malformed `allow` attribute input + --> $DIR/malformed-attrs.rs:177:1 + | +LL | #[allow] + | ^^^^^^^^ help: must be of the form: `#[allow(lint1, lint2, ..., /*opt*/ reason = "...")]` + +error: malformed `expect` attribute input + --> $DIR/malformed-attrs.rs:179:1 + | +LL | #[expect] + | ^^^^^^^^^ help: must be of the form: `#[expect(lint1, lint2, ..., /*opt*/ reason = "...")]` + +error: malformed `warn` attribute input + --> $DIR/malformed-attrs.rs:181:1 + | +LL | #[warn] + | ^^^^^^^ help: must be of the form: `#[warn(lint1, lint2, ..., /*opt*/ reason = "...")]` + +error: malformed `deny` attribute input + --> $DIR/malformed-attrs.rs:183:1 + | +LL | #[deny] + | ^^^^^^^ help: must be of the form: `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]` + +error: malformed `forbid` attribute input + --> $DIR/malformed-attrs.rs:185:1 + | +LL | #[forbid] + | ^^^^^^^^^ help: must be of the form: `#[forbid(lint1, lint2, ..., /*opt*/ reason = "...")]` + +error: malformed `debugger_visualizer` attribute input + --> $DIR/malformed-attrs.rs:187:1 + | +LL | #[debugger_visualizer] + | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[debugger_visualizer(natvis_file = "...", gdb_script_file = "...")]` + +error: malformed `automatically_derived` attribute input + --> $DIR/malformed-attrs.rs:190:1 + | +LL | #[automatically_derived = 18] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[automatically_derived]` + +error: malformed `non_exhaustive` attribute input + --> $DIR/malformed-attrs.rs:196:1 + | +LL | #[non_exhaustive = 1] + | ^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[non_exhaustive]` + +error: malformed `thread_local` attribute input + --> $DIR/malformed-attrs.rs:202:1 + | +LL | #[thread_local()] + | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]` + +error: malformed `no_link` attribute input + --> $DIR/malformed-attrs.rs:206:1 + | +LL | #[no_link()] + | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]` + +error: malformed `macro_use` attribute input + --> $DIR/malformed-attrs.rs:208:1 + | +LL | #[macro_use = 1] + | ^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL - #[macro_use = 1] +LL + #[macro_use(name1, name2, ...)] + | +LL - #[macro_use = 1] +LL + #[macro_use] + | + +error: malformed `macro_export` attribute input + --> $DIR/malformed-attrs.rs:213:1 + | +LL | #[macro_export = 18] + | ^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL - #[macro_export = 18] +LL + #[macro_export(local_inner_macros)] + | +LL - #[macro_export = 18] +LL + #[macro_export] + | + +error: malformed `allow_internal_unsafe` attribute input + --> $DIR/malformed-attrs.rs:215:1 + | +LL | #[allow_internal_unsafe = 1] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[allow_internal_unsafe]` + +error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type + --> $DIR/malformed-attrs.rs:100:1 + | +LL | #[proc_macro = 18] + | ^^^^^^^^^^^^^^^^^^ + +error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type + --> $DIR/malformed-attrs.rs:117:1 + | +LL | #[proc_macro_attribute = 19] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type + --> $DIR/malformed-attrs.rs:122:1 + | +LL | #[proc_macro_derive] + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint + --> $DIR/malformed-attrs.rs:215:1 + | +LL | #[allow_internal_unsafe = 1] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(allow_internal_unsafe)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]` + --> $DIR/malformed-attrs.rs:43:1 + | +LL | #[doc] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + = note: `#[deny(ill_formed_attribute_input)]` on by default + +error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]` + --> $DIR/malformed-attrs.rs:77:1 + | +LL | #[doc] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` + --> $DIR/malformed-attrs.rs:84:1 + | +LL | #[link] + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +error: valid forms for the attribute are `#[ignore]` and `#[ignore = "reason"]` + --> $DIR/malformed-attrs.rs:95:1 + | +LL | #[ignore()] + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +error: invalid argument + --> $DIR/malformed-attrs.rs:187:1 + | +LL | #[debugger_visualizer] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: expected: `natvis_file = "..."` + = note: OR + = note: expected: `gdb_script_file = "..."` + +error[E0539]: malformed `export_name` attribute input + --> $DIR/malformed-attrs.rs:32:1 + | +LL | #[unsafe(export_name)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be of the form `export_name = "..."` + | help: must be of the form: `#[export_name = "name"]` + +error: `rustc_allow_const_fn_unstable` expects a list of feature names + --> $DIR/malformed-attrs.rs:35:1 + | +LL | #[rustc_allow_const_fn_unstable] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `allow_internal_unstable` expects a list of feature names + --> $DIR/malformed-attrs.rs:37:1 + | +LL | #[allow_internal_unstable] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0539]: malformed `rustc_confusables` attribute input + --> $DIR/malformed-attrs.rs:39:1 + | +LL | #[rustc_confusables] + | ^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[rustc_confusables("name1", "name2", ...)]` + +error[E0539]: malformed `deprecated` attribute input + --> $DIR/malformed-attrs.rs:41:1 + | +LL | #[deprecated = 5] + | ^^^^^^^^^^^^^^^-^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[deprecated = 5] +LL + #[deprecated = "reason"] + | +LL - #[deprecated = 5] +LL + #[deprecated(/*opt*/ since = "version", /*opt*/ note = "reason")] + | +LL - #[deprecated = 5] +LL + #[deprecated] + | + +error[E0539]: malformed `rustc_macro_transparency` attribute input + --> $DIR/malformed-attrs.rs:46:1 + | +LL | #[rustc_macro_transparency] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be of the form `rustc_macro_transparency = "..."` + | help: must be of the form: `#[rustc_macro_transparency = "transparent|semitransparent|opaque"]` + +error[E0539]: malformed `repr` attribute input + --> $DIR/malformed-attrs.rs:49:1 + | +LL | #[repr] + | ^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[repr(C | Rust | align(...) | packed(...) | | transparent)]` + +error[E0565]: malformed `rustc_as_ptr` attribute input + --> $DIR/malformed-attrs.rs:51:1 + | +LL | #[rustc_as_ptr = 5] + | ^^^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[rustc_as_ptr]` + +error[E0539]: malformed `align` attribute input + --> $DIR/malformed-attrs.rs:56:1 + | +LL | #[align] + | ^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[align()]` + +error[E0539]: malformed `optimize` attribute input + --> $DIR/malformed-attrs.rs:58:1 + | +LL | #[optimize] + | ^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[optimize(size|speed|none)]` + +error[E0565]: malformed `cold` attribute input + --> $DIR/malformed-attrs.rs:60:1 + | +LL | #[cold = 1] + | ^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[cold]` + +error: valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]` + --> $DIR/malformed-attrs.rs:62:1 + | +LL | #[must_use()] + | ^^^^^^^^^^^^^ + +error[E0565]: malformed `no_mangle` attribute input + --> $DIR/malformed-attrs.rs:64:1 + | +LL | #[no_mangle = 1] + | ^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[no_mangle]` + +error[E0565]: malformed `naked` attribute input + --> $DIR/malformed-attrs.rs:66:1 + | +LL | #[unsafe(naked())] + | ^^^^^^^^^^^^^^--^^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[naked]` + +error[E0565]: malformed `track_caller` attribute input + --> $DIR/malformed-attrs.rs:68:1 + | +LL | #[track_caller()] + | ^^^^^^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[track_caller]` + +error[E0539]: malformed `export_name` attribute input + --> $DIR/malformed-attrs.rs:70:1 + | +LL | #[export_name()] + | ^^^^^^^^^^^^^^^^ + | | + | expected this to be of the form `export_name = "..."` + | help: must be of the form: `#[export_name = "name"]` + +error[E0805]: malformed `used` attribute input + --> $DIR/malformed-attrs.rs:73:1 + | +LL | #[used()] + | ^^^^^^--^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL | #[used(compiler|linker)] + | +++++++++++++++ +LL - #[used()] +LL + #[used] + | + +error[E0539]: malformed `link_name` attribute input + --> $DIR/malformed-attrs.rs:87:1 + | +LL | #[link_name] + | ^^^^^^^^^^^^ + | | + | expected this to be of the form `link_name = "..."` + | help: must be of the form: `#[link_name = "name"]` + +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/malformed-attrs.rs:148:1 + | +LL | #[diagnostic::do_not_recommend()] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + +warning: missing options for `on_unimplemented` attribute + --> $DIR/malformed-attrs.rs:137:1 + | +LL | #[diagnostic::on_unimplemented] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: at least one of the `message`, `note` and `label` options are expected + +warning: malformed `on_unimplemented` attribute + --> $DIR/malformed-attrs.rs:139:1 + | +LL | #[diagnostic::on_unimplemented = 1] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here + | + = help: only `message`, `note` and `label` are allowed as options + +error: valid forms for the attribute are `#[inline(always|never)]` and `#[inline]` + --> $DIR/malformed-attrs.rs:53:1 + | +LL | #[inline = 5] + | ^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +error[E0308]: mismatched types + --> $DIR/malformed-attrs.rs:112:23 + | +LL | fn test() { + | - help: a return type might be missing here: `-> _` +LL | #[coroutine = 63] || {} + | ^^^^^ expected `()`, found coroutine + | + = note: expected unit type `()` + found coroutine `{coroutine@$DIR/malformed-attrs.rs:112:23: 112:25}` + +error: aborting due to 74 previous errors; 3 warnings emitted + +Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805. +For more information about an error, try `rustc --explain E0308`. From 86b54d5729f019d5e2c5acff4ddfddbd7af2fde3 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 29 Jun 2025 11:30:47 +0200 Subject: [PATCH 14/20] Fix double error for `export_name` Signed-off-by: Jonathan Brouwer --- compiler/rustc_parse/src/validate_attr.rs | 1 + tests/ui/attributes/malformed-attrs.rs | 2 - tests/ui/attributes/malformed-attrs.stderr | 160 ++++++++++----------- 3 files changed, 75 insertions(+), 88 deletions(-) diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 8b1d864c9957d..11cff88ba4fbf 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -303,6 +303,7 @@ fn emit_malformed_attribute( | sym::must_use | sym::track_caller | sym::link_name + | sym::export_name ) { return; } diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index 3ab68ee63f848..8096e99db301d 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -31,7 +31,6 @@ #[unsafe(export_name)] //~^ ERROR malformed -//~| ERROR malformed #[rustc_allow_const_fn_unstable] //~^ ERROR `rustc_allow_const_fn_unstable` expects a list of feature names #[allow_internal_unstable] @@ -69,7 +68,6 @@ //~^ ERROR malformed #[export_name()] //~^ ERROR malformed -//~| ERROR malformed #[used()] //~^ ERROR malformed #[crate_name] diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 5e731f16a8a26..67fe9b621f2ef 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -1,11 +1,11 @@ error: `cfg` is not followed by parentheses - --> $DIR/malformed-attrs.rs:103:1 + --> $DIR/malformed-attrs.rs:101:1 | LL | #[cfg] | ^^^^^^ help: expected syntax is: `cfg(/* predicate */)` error: malformed `cfg_attr` attribute input - --> $DIR/malformed-attrs.rs:105:1 + --> $DIR/malformed-attrs.rs:103:1 | LL | #[cfg_attr] | ^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | #[cfg_attr(condition, attribute, other_attribute, ...)] | ++++++++++++++++++++++++++++++++++++++++++++ error[E0463]: can't find crate for `wloop` - --> $DIR/malformed-attrs.rs:210:1 + --> $DIR/malformed-attrs.rs:208:1 | LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate @@ -34,50 +34,38 @@ error: malformed `windows_subsystem` attribute input LL | #![windows_subsystem] | ^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![windows_subsystem = "windows|console"]` -error: malformed `export_name` attribute input - --> $DIR/malformed-attrs.rs:32:1 - | -LL | #[unsafe(export_name)] - | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]` - error: malformed `rustc_macro_transparency` attribute input - --> $DIR/malformed-attrs.rs:46:1 + --> $DIR/malformed-attrs.rs:45:1 | LL | #[rustc_macro_transparency] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_macro_transparency = "transparent|semiopaque|opaque"]` -error: malformed `export_name` attribute input - --> $DIR/malformed-attrs.rs:70:1 - | -LL | #[export_name()] - | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]` - error: malformed `crate_name` attribute input - --> $DIR/malformed-attrs.rs:75:1 + --> $DIR/malformed-attrs.rs:73:1 | LL | #[crate_name] | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]` error: malformed `target_feature` attribute input - --> $DIR/malformed-attrs.rs:80:1 + --> $DIR/malformed-attrs.rs:78:1 | LL | #[target_feature] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]` error: malformed `export_stable` attribute input - --> $DIR/malformed-attrs.rs:82:1 + --> $DIR/malformed-attrs.rs:80:1 | LL | #[export_stable = 1] | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_stable]` error: malformed `link_section` attribute input - --> $DIR/malformed-attrs.rs:89:1 + --> $DIR/malformed-attrs.rs:87:1 | LL | #[link_section] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` error: malformed `coverage` attribute input - --> $DIR/malformed-attrs.rs:91:1 + --> $DIR/malformed-attrs.rs:89:1 | LL | #[coverage] | ^^^^^^^^^^^ @@ -90,67 +78,67 @@ LL | #[coverage(on)] | ++++ error: malformed `no_sanitize` attribute input - --> $DIR/malformed-attrs.rs:93:1 + --> $DIR/malformed-attrs.rs:91:1 | LL | #[no_sanitize] | ^^^^^^^^^^^^^^ help: must be of the form: `#[no_sanitize(address, kcfi, memory, thread)]` error: malformed `no_implicit_prelude` attribute input - --> $DIR/malformed-attrs.rs:98:1 + --> $DIR/malformed-attrs.rs:96:1 | LL | #[no_implicit_prelude = 23] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[no_implicit_prelude]` error: malformed `proc_macro` attribute input - --> $DIR/malformed-attrs.rs:100:1 + --> $DIR/malformed-attrs.rs:98:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]` error: malformed `instruction_set` attribute input - --> $DIR/malformed-attrs.rs:107:1 + --> $DIR/malformed-attrs.rs:105:1 | LL | #[instruction_set] | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]` error: malformed `patchable_function_entry` attribute input - --> $DIR/malformed-attrs.rs:109:1 + --> $DIR/malformed-attrs.rs:107:1 | LL | #[patchable_function_entry] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` error: malformed `coroutine` attribute input - --> $DIR/malformed-attrs.rs:112:5 + --> $DIR/malformed-attrs.rs:110:5 | LL | #[coroutine = 63] || {} | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[coroutine]` error: malformed `proc_macro_attribute` attribute input - --> $DIR/malformed-attrs.rs:117:1 + --> $DIR/malformed-attrs.rs:115:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]` error: malformed `proc_macro_derive` attribute input - --> $DIR/malformed-attrs.rs:122:1 + --> $DIR/malformed-attrs.rs:120:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` error: malformed `rustc_layout_scalar_valid_range_start` attribute input - --> $DIR/malformed-attrs.rs:127:1 + --> $DIR/malformed-attrs.rs:125:1 | LL | #[rustc_layout_scalar_valid_range_start] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_layout_scalar_valid_range_start(value)]` error: malformed `rustc_layout_scalar_valid_range_end` attribute input - --> $DIR/malformed-attrs.rs:129:1 + --> $DIR/malformed-attrs.rs:127:1 | LL | #[rustc_layout_scalar_valid_range_end] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_layout_scalar_valid_range_end(value)]` error: malformed `must_not_suspend` attribute input - --> $DIR/malformed-attrs.rs:131:1 + --> $DIR/malformed-attrs.rs:129:1 | LL | #[must_not_suspend()] | ^^^^^^^^^^^^^^^^^^^^^ @@ -165,115 +153,115 @@ LL + #[must_not_suspend] | error: malformed `cfi_encoding` attribute input - --> $DIR/malformed-attrs.rs:133:1 + --> $DIR/malformed-attrs.rs:131:1 | LL | #[cfi_encoding] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` error: malformed `type_const` attribute input - --> $DIR/malformed-attrs.rs:142:5 + --> $DIR/malformed-attrs.rs:140:5 | LL | #[type_const = 1] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]` error: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:154:1 + --> $DIR/malformed-attrs.rs:152:1 | LL | #[marker = 3] | ^^^^^^^^^^^^^ help: must be of the form: `#[marker]` error: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:156:1 + --> $DIR/malformed-attrs.rs:154:1 | LL | #[fundamental()] | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[fundamental]` error: malformed `ffi_pure` attribute input - --> $DIR/malformed-attrs.rs:164:5 + --> $DIR/malformed-attrs.rs:162:5 | LL | #[unsafe(ffi_pure = 1)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_pure]` error: malformed `link_ordinal` attribute input - --> $DIR/malformed-attrs.rs:166:5 + --> $DIR/malformed-attrs.rs:164:5 | LL | #[link_ordinal] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_ordinal(ordinal)]` error: malformed `ffi_const` attribute input - --> $DIR/malformed-attrs.rs:170:5 + --> $DIR/malformed-attrs.rs:168:5 | LL | #[unsafe(ffi_const = 1)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_const]` error: malformed `linkage` attribute input - --> $DIR/malformed-attrs.rs:172:5 + --> $DIR/malformed-attrs.rs:170:5 | LL | #[linkage] | ^^^^^^^^^^ help: must be of the form: `#[linkage = "external|internal|..."]` error: malformed `allow` attribute input - --> $DIR/malformed-attrs.rs:177:1 + --> $DIR/malformed-attrs.rs:175:1 | LL | #[allow] | ^^^^^^^^ help: must be of the form: `#[allow(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `expect` attribute input - --> $DIR/malformed-attrs.rs:179:1 + --> $DIR/malformed-attrs.rs:177:1 | LL | #[expect] | ^^^^^^^^^ help: must be of the form: `#[expect(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `warn` attribute input - --> $DIR/malformed-attrs.rs:181:1 + --> $DIR/malformed-attrs.rs:179:1 | LL | #[warn] | ^^^^^^^ help: must be of the form: `#[warn(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `deny` attribute input - --> $DIR/malformed-attrs.rs:183:1 + --> $DIR/malformed-attrs.rs:181:1 | LL | #[deny] | ^^^^^^^ help: must be of the form: `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `forbid` attribute input - --> $DIR/malformed-attrs.rs:185:1 + --> $DIR/malformed-attrs.rs:183:1 | LL | #[forbid] | ^^^^^^^^^ help: must be of the form: `#[forbid(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `debugger_visualizer` attribute input - --> $DIR/malformed-attrs.rs:187:1 + --> $DIR/malformed-attrs.rs:185:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[debugger_visualizer(natvis_file = "...", gdb_script_file = "...")]` error: malformed `automatically_derived` attribute input - --> $DIR/malformed-attrs.rs:190:1 + --> $DIR/malformed-attrs.rs:188:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[automatically_derived]` error: malformed `non_exhaustive` attribute input - --> $DIR/malformed-attrs.rs:196:1 + --> $DIR/malformed-attrs.rs:194:1 | LL | #[non_exhaustive = 1] | ^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[non_exhaustive]` error: malformed `thread_local` attribute input - --> $DIR/malformed-attrs.rs:202:1 + --> $DIR/malformed-attrs.rs:200:1 | LL | #[thread_local()] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]` error: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:206:1 + --> $DIR/malformed-attrs.rs:204:1 | LL | #[no_link()] | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]` error: malformed `macro_use` attribute input - --> $DIR/malformed-attrs.rs:208:1 + --> $DIR/malformed-attrs.rs:206:1 | LL | #[macro_use = 1] | ^^^^^^^^^^^^^^^^ @@ -288,7 +276,7 @@ LL + #[macro_use] | error: malformed `macro_export` attribute input - --> $DIR/malformed-attrs.rs:213:1 + --> $DIR/malformed-attrs.rs:211:1 | LL | #[macro_export = 18] | ^^^^^^^^^^^^^^^^^^^^ @@ -303,31 +291,31 @@ LL + #[macro_export] | error: malformed `allow_internal_unsafe` attribute input - --> $DIR/malformed-attrs.rs:215:1 + --> $DIR/malformed-attrs.rs:213:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[allow_internal_unsafe]` error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:100:1 + --> $DIR/malformed-attrs.rs:98:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:117:1 + --> $DIR/malformed-attrs.rs:115:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:122:1 + --> $DIR/malformed-attrs.rs:120:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint - --> $DIR/malformed-attrs.rs:215:1 + --> $DIR/malformed-attrs.rs:213:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -336,7 +324,7 @@ LL | #[allow_internal_unsafe = 1] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]` - --> $DIR/malformed-attrs.rs:43:1 + --> $DIR/malformed-attrs.rs:42:1 | LL | #[doc] | ^^^^^^ @@ -346,7 +334,7 @@ LL | #[doc] = note: `#[deny(ill_formed_attribute_input)]` on by default error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]` - --> $DIR/malformed-attrs.rs:77:1 + --> $DIR/malformed-attrs.rs:75:1 | LL | #[doc] | ^^^^^^ @@ -355,7 +343,7 @@ LL | #[doc] = note: for more information, see issue #57571 error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` - --> $DIR/malformed-attrs.rs:84:1 + --> $DIR/malformed-attrs.rs:82:1 | LL | #[link] | ^^^^^^^ @@ -364,7 +352,7 @@ LL | #[link] = note: for more information, see issue #57571 error: valid forms for the attribute are `#[ignore]` and `#[ignore = "reason"]` - --> $DIR/malformed-attrs.rs:95:1 + --> $DIR/malformed-attrs.rs:93:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -373,7 +361,7 @@ LL | #[ignore()] = note: for more information, see issue #57571 error: invalid argument - --> $DIR/malformed-attrs.rs:187:1 + --> $DIR/malformed-attrs.rs:185:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -392,19 +380,19 @@ LL | #[unsafe(export_name)] | help: must be of the form: `#[export_name = "name"]` error: `rustc_allow_const_fn_unstable` expects a list of feature names - --> $DIR/malformed-attrs.rs:35:1 + --> $DIR/malformed-attrs.rs:34:1 | LL | #[rustc_allow_const_fn_unstable] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `allow_internal_unstable` expects a list of feature names - --> $DIR/malformed-attrs.rs:37:1 + --> $DIR/malformed-attrs.rs:36:1 | LL | #[allow_internal_unstable] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0539]: malformed `rustc_confusables` attribute input - --> $DIR/malformed-attrs.rs:39:1 + --> $DIR/malformed-attrs.rs:38:1 | LL | #[rustc_confusables] | ^^^^^^^^^^^^^^^^^^^^ @@ -413,7 +401,7 @@ LL | #[rustc_confusables] | help: must be of the form: `#[rustc_confusables("name1", "name2", ...)]` error[E0539]: malformed `deprecated` attribute input - --> $DIR/malformed-attrs.rs:41:1 + --> $DIR/malformed-attrs.rs:40:1 | LL | #[deprecated = 5] | ^^^^^^^^^^^^^^^-^ @@ -433,7 +421,7 @@ LL + #[deprecated] | error[E0539]: malformed `rustc_macro_transparency` attribute input - --> $DIR/malformed-attrs.rs:46:1 + --> $DIR/malformed-attrs.rs:45:1 | LL | #[rustc_macro_transparency] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -442,7 +430,7 @@ LL | #[rustc_macro_transparency] | help: must be of the form: `#[rustc_macro_transparency = "transparent|semitransparent|opaque"]` error[E0539]: malformed `repr` attribute input - --> $DIR/malformed-attrs.rs:49:1 + --> $DIR/malformed-attrs.rs:48:1 | LL | #[repr] | ^^^^^^^ @@ -451,7 +439,7 @@ LL | #[repr] | help: must be of the form: `#[repr(C | Rust | align(...) | packed(...) | | transparent)]` error[E0565]: malformed `rustc_as_ptr` attribute input - --> $DIR/malformed-attrs.rs:51:1 + --> $DIR/malformed-attrs.rs:50:1 | LL | #[rustc_as_ptr = 5] | ^^^^^^^^^^^^^^^---^ @@ -460,7 +448,7 @@ LL | #[rustc_as_ptr = 5] | help: must be of the form: `#[rustc_as_ptr]` error[E0539]: malformed `align` attribute input - --> $DIR/malformed-attrs.rs:56:1 + --> $DIR/malformed-attrs.rs:55:1 | LL | #[align] | ^^^^^^^^ @@ -469,7 +457,7 @@ LL | #[align] | help: must be of the form: `#[align()]` error[E0539]: malformed `optimize` attribute input - --> $DIR/malformed-attrs.rs:58:1 + --> $DIR/malformed-attrs.rs:57:1 | LL | #[optimize] | ^^^^^^^^^^^ @@ -478,7 +466,7 @@ LL | #[optimize] | help: must be of the form: `#[optimize(size|speed|none)]` error[E0565]: malformed `cold` attribute input - --> $DIR/malformed-attrs.rs:60:1 + --> $DIR/malformed-attrs.rs:59:1 | LL | #[cold = 1] | ^^^^^^^---^ @@ -487,13 +475,13 @@ LL | #[cold = 1] | help: must be of the form: `#[cold]` error: valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]` - --> $DIR/malformed-attrs.rs:62:1 + --> $DIR/malformed-attrs.rs:61:1 | LL | #[must_use()] | ^^^^^^^^^^^^^ error[E0565]: malformed `no_mangle` attribute input - --> $DIR/malformed-attrs.rs:64:1 + --> $DIR/malformed-attrs.rs:63:1 | LL | #[no_mangle = 1] | ^^^^^^^^^^^^---^ @@ -502,7 +490,7 @@ LL | #[no_mangle = 1] | help: must be of the form: `#[no_mangle]` error[E0565]: malformed `naked` attribute input - --> $DIR/malformed-attrs.rs:66:1 + --> $DIR/malformed-attrs.rs:65:1 | LL | #[unsafe(naked())] | ^^^^^^^^^^^^^^--^^ @@ -511,7 +499,7 @@ LL | #[unsafe(naked())] | help: must be of the form: `#[naked]` error[E0565]: malformed `track_caller` attribute input - --> $DIR/malformed-attrs.rs:68:1 + --> $DIR/malformed-attrs.rs:67:1 | LL | #[track_caller()] | ^^^^^^^^^^^^^^--^ @@ -520,7 +508,7 @@ LL | #[track_caller()] | help: must be of the form: `#[track_caller]` error[E0539]: malformed `export_name` attribute input - --> $DIR/malformed-attrs.rs:70:1 + --> $DIR/malformed-attrs.rs:69:1 | LL | #[export_name()] | ^^^^^^^^^^^^^^^^ @@ -529,7 +517,7 @@ LL | #[export_name()] | help: must be of the form: `#[export_name = "name"]` error[E0805]: malformed `used` attribute input - --> $DIR/malformed-attrs.rs:73:1 + --> $DIR/malformed-attrs.rs:71:1 | LL | #[used()] | ^^^^^^--^ @@ -545,7 +533,7 @@ LL + #[used] | error[E0539]: malformed `link_name` attribute input - --> $DIR/malformed-attrs.rs:87:1 + --> $DIR/malformed-attrs.rs:85:1 | LL | #[link_name] | ^^^^^^^^^^^^ @@ -554,7 +542,7 @@ LL | #[link_name] | help: must be of the form: `#[link_name = "name"]` warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/malformed-attrs.rs:148:1 + --> $DIR/malformed-attrs.rs:146:1 | LL | #[diagnostic::do_not_recommend()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -562,7 +550,7 @@ LL | #[diagnostic::do_not_recommend()] = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: missing options for `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:137:1 + --> $DIR/malformed-attrs.rs:135:1 | LL | #[diagnostic::on_unimplemented] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -570,7 +558,7 @@ LL | #[diagnostic::on_unimplemented] = help: at least one of the `message`, `note` and `label` options are expected warning: malformed `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:139:1 + --> $DIR/malformed-attrs.rs:137:1 | LL | #[diagnostic::on_unimplemented = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here @@ -578,7 +566,7 @@ LL | #[diagnostic::on_unimplemented = 1] = help: only `message`, `note` and `label` are allowed as options error: valid forms for the attribute are `#[inline(always|never)]` and `#[inline]` - --> $DIR/malformed-attrs.rs:53:1 + --> $DIR/malformed-attrs.rs:52:1 | LL | #[inline = 5] | ^^^^^^^^^^^^^ @@ -587,7 +575,7 @@ LL | #[inline = 5] = note: for more information, see issue #57571 error[E0308]: mismatched types - --> $DIR/malformed-attrs.rs:112:23 + --> $DIR/malformed-attrs.rs:110:23 | LL | fn test() { | - help: a return type might be missing here: `-> _` @@ -595,9 +583,9 @@ LL | #[coroutine = 63] || {} | ^^^^^ expected `()`, found coroutine | = note: expected unit type `()` - found coroutine `{coroutine@$DIR/malformed-attrs.rs:112:23: 112:25}` + found coroutine `{coroutine@$DIR/malformed-attrs.rs:110:23: 110:25}` -error: aborting due to 74 previous errors; 3 warnings emitted +error: aborting due to 72 previous errors; 3 warnings emitted Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805. For more information about an error, try `rustc --explain E0308`. From 149bdde97e65779b126ec1ae6bcbe152fd90f856 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 29 Jun 2025 11:34:29 +0200 Subject: [PATCH 15/20] Fix `#[must_use = 1]` not giving an error Signed-off-by: Jonathan Brouwer --- .../src/attributes/must_use.rs | 11 ++- tests/ui/attributes/malformed-attrs.rs | 2 + tests/ui/attributes/malformed-attrs.stderr | 83 +++++++++++-------- tests/ui/parser/bad-lit-suffixes.rs | 1 + tests/ui/parser/bad-lit-suffixes.stderr | 28 ++++--- 5 files changed, 81 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/must_use.rs b/compiler/rustc_attr_parsing/src/attributes/must_use.rs index a672d95612746..b5eb85f68b4f8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/must_use.rs +++ b/compiler/rustc_attr_parsing/src/attributes/must_use.rs @@ -21,7 +21,16 @@ impl SingleAttributeParser for MustUseParser { span: cx.attr_span, reason: match args { ArgParser::NoArgs => None, - ArgParser::NameValue(name_value) => name_value.value_as_str(), + ArgParser::NameValue(name_value) => { + let Some(value_str) = name_value.value_as_str() else { + cx.expected_string_literal( + name_value.value_span, + Some(&name_value.value_as_lit()), + ); + return None; + }; + Some(value_str) + } ArgParser::List(_) => { let suggestions = >::TEMPLATE.suggestions(false, "must_use"); diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index 8096e99db301d..4a368ea4e96da 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -115,6 +115,8 @@ fn test() { #[proc_macro_attribute = 19] //~^ ERROR malformed //~| ERROR the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type +#[must_use = 1] +//~^ ERROR malformed fn test2() { } #[proc_macro_derive] diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 67fe9b621f2ef..50c75d65f6db5 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -17,7 +17,7 @@ LL | #[cfg_attr(condition, attribute, other_attribute, ...)] | ++++++++++++++++++++++++++++++++++++++++++++ error[E0463]: can't find crate for `wloop` - --> $DIR/malformed-attrs.rs:208:1 + --> $DIR/malformed-attrs.rs:210:1 | LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate @@ -120,25 +120,25 @@ LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]` error: malformed `proc_macro_derive` attribute input - --> $DIR/malformed-attrs.rs:120:1 + --> $DIR/malformed-attrs.rs:122:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` error: malformed `rustc_layout_scalar_valid_range_start` attribute input - --> $DIR/malformed-attrs.rs:125:1 + --> $DIR/malformed-attrs.rs:127:1 | LL | #[rustc_layout_scalar_valid_range_start] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_layout_scalar_valid_range_start(value)]` error: malformed `rustc_layout_scalar_valid_range_end` attribute input - --> $DIR/malformed-attrs.rs:127:1 + --> $DIR/malformed-attrs.rs:129:1 | LL | #[rustc_layout_scalar_valid_range_end] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_layout_scalar_valid_range_end(value)]` error: malformed `must_not_suspend` attribute input - --> $DIR/malformed-attrs.rs:129:1 + --> $DIR/malformed-attrs.rs:131:1 | LL | #[must_not_suspend()] | ^^^^^^^^^^^^^^^^^^^^^ @@ -153,115 +153,115 @@ LL + #[must_not_suspend] | error: malformed `cfi_encoding` attribute input - --> $DIR/malformed-attrs.rs:131:1 + --> $DIR/malformed-attrs.rs:133:1 | LL | #[cfi_encoding] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` error: malformed `type_const` attribute input - --> $DIR/malformed-attrs.rs:140:5 + --> $DIR/malformed-attrs.rs:142:5 | LL | #[type_const = 1] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]` error: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:152:1 + --> $DIR/malformed-attrs.rs:154:1 | LL | #[marker = 3] | ^^^^^^^^^^^^^ help: must be of the form: `#[marker]` error: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:154:1 + --> $DIR/malformed-attrs.rs:156:1 | LL | #[fundamental()] | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[fundamental]` error: malformed `ffi_pure` attribute input - --> $DIR/malformed-attrs.rs:162:5 + --> $DIR/malformed-attrs.rs:164:5 | LL | #[unsafe(ffi_pure = 1)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_pure]` error: malformed `link_ordinal` attribute input - --> $DIR/malformed-attrs.rs:164:5 + --> $DIR/malformed-attrs.rs:166:5 | LL | #[link_ordinal] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_ordinal(ordinal)]` error: malformed `ffi_const` attribute input - --> $DIR/malformed-attrs.rs:168:5 + --> $DIR/malformed-attrs.rs:170:5 | LL | #[unsafe(ffi_const = 1)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_const]` error: malformed `linkage` attribute input - --> $DIR/malformed-attrs.rs:170:5 + --> $DIR/malformed-attrs.rs:172:5 | LL | #[linkage] | ^^^^^^^^^^ help: must be of the form: `#[linkage = "external|internal|..."]` error: malformed `allow` attribute input - --> $DIR/malformed-attrs.rs:175:1 + --> $DIR/malformed-attrs.rs:177:1 | LL | #[allow] | ^^^^^^^^ help: must be of the form: `#[allow(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `expect` attribute input - --> $DIR/malformed-attrs.rs:177:1 + --> $DIR/malformed-attrs.rs:179:1 | LL | #[expect] | ^^^^^^^^^ help: must be of the form: `#[expect(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `warn` attribute input - --> $DIR/malformed-attrs.rs:179:1 + --> $DIR/malformed-attrs.rs:181:1 | LL | #[warn] | ^^^^^^^ help: must be of the form: `#[warn(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `deny` attribute input - --> $DIR/malformed-attrs.rs:181:1 + --> $DIR/malformed-attrs.rs:183:1 | LL | #[deny] | ^^^^^^^ help: must be of the form: `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `forbid` attribute input - --> $DIR/malformed-attrs.rs:183:1 + --> $DIR/malformed-attrs.rs:185:1 | LL | #[forbid] | ^^^^^^^^^ help: must be of the form: `#[forbid(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `debugger_visualizer` attribute input - --> $DIR/malformed-attrs.rs:185:1 + --> $DIR/malformed-attrs.rs:187:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[debugger_visualizer(natvis_file = "...", gdb_script_file = "...")]` error: malformed `automatically_derived` attribute input - --> $DIR/malformed-attrs.rs:188:1 + --> $DIR/malformed-attrs.rs:190:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[automatically_derived]` error: malformed `non_exhaustive` attribute input - --> $DIR/malformed-attrs.rs:194:1 + --> $DIR/malformed-attrs.rs:196:1 | LL | #[non_exhaustive = 1] | ^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[non_exhaustive]` error: malformed `thread_local` attribute input - --> $DIR/malformed-attrs.rs:200:1 + --> $DIR/malformed-attrs.rs:202:1 | LL | #[thread_local()] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]` error: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:204:1 + --> $DIR/malformed-attrs.rs:206:1 | LL | #[no_link()] | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]` error: malformed `macro_use` attribute input - --> $DIR/malformed-attrs.rs:206:1 + --> $DIR/malformed-attrs.rs:208:1 | LL | #[macro_use = 1] | ^^^^^^^^^^^^^^^^ @@ -276,7 +276,7 @@ LL + #[macro_use] | error: malformed `macro_export` attribute input - --> $DIR/malformed-attrs.rs:211:1 + --> $DIR/malformed-attrs.rs:213:1 | LL | #[macro_export = 18] | ^^^^^^^^^^^^^^^^^^^^ @@ -291,7 +291,7 @@ LL + #[macro_export] | error: malformed `allow_internal_unsafe` attribute input - --> $DIR/malformed-attrs.rs:213:1 + --> $DIR/malformed-attrs.rs:215:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[allow_internal_unsafe]` @@ -309,13 +309,13 @@ LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:120:1 + --> $DIR/malformed-attrs.rs:122:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint - --> $DIR/malformed-attrs.rs:213:1 + --> $DIR/malformed-attrs.rs:215:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -361,7 +361,7 @@ LL | #[ignore()] = note: for more information, see issue #57571 error: invalid argument - --> $DIR/malformed-attrs.rs:185:1 + --> $DIR/malformed-attrs.rs:187:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -541,8 +541,25 @@ LL | #[link_name] | expected this to be of the form `link_name = "..."` | help: must be of the form: `#[link_name = "name"]` +error[E0539]: malformed `must_use` attribute input + --> $DIR/malformed-attrs.rs:118:1 + | +LL | #[must_use = 1] + | ^^^^^^^^^^^^^-^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[must_use = 1] +LL + #[must_use = "reason"] + | +LL - #[must_use = 1] +LL + #[must_use] + | + warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/malformed-attrs.rs:146:1 + --> $DIR/malformed-attrs.rs:148:1 | LL | #[diagnostic::do_not_recommend()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -550,7 +567,7 @@ LL | #[diagnostic::do_not_recommend()] = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: missing options for `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:135:1 + --> $DIR/malformed-attrs.rs:137:1 | LL | #[diagnostic::on_unimplemented] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -558,7 +575,7 @@ LL | #[diagnostic::on_unimplemented] = help: at least one of the `message`, `note` and `label` options are expected warning: malformed `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:137:1 + --> $DIR/malformed-attrs.rs:139:1 | LL | #[diagnostic::on_unimplemented = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here @@ -585,7 +602,7 @@ LL | #[coroutine = 63] || {} = note: expected unit type `()` found coroutine `{coroutine@$DIR/malformed-attrs.rs:110:23: 110:25}` -error: aborting due to 72 previous errors; 3 warnings emitted +error: aborting due to 73 previous errors; 3 warnings emitted Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/parser/bad-lit-suffixes.rs b/tests/ui/parser/bad-lit-suffixes.rs index 13287aabb1d96..0a01bb84f01a3 100644 --- a/tests/ui/parser/bad-lit-suffixes.rs +++ b/tests/ui/parser/bad-lit-suffixes.rs @@ -33,6 +33,7 @@ fn f() {} #[must_use = "string"suffix] //~^ ERROR suffixes on string literals are invalid +//~| ERROR malformed `must_use` attribute input fn g() {} #[link(name = "string"suffix)] diff --git a/tests/ui/parser/bad-lit-suffixes.stderr b/tests/ui/parser/bad-lit-suffixes.stderr index 295e3112ec0a8..e68893535eb6a 100644 --- a/tests/ui/parser/bad-lit-suffixes.stderr +++ b/tests/ui/parser/bad-lit-suffixes.stderr @@ -23,13 +23,13 @@ LL | #[must_use = "string"suffix] | ^^^^^^^^^^^^^^ invalid suffix `suffix` error: suffixes on string literals are invalid - --> $DIR/bad-lit-suffixes.rs:38:15 + --> $DIR/bad-lit-suffixes.rs:39:15 | LL | #[link(name = "string"suffix)] | ^^^^^^^^^^^^^^ invalid suffix `suffix` error: invalid suffix `suffix` for number literal - --> $DIR/bad-lit-suffixes.rs:42:41 + --> $DIR/bad-lit-suffixes.rs:43:41 | LL | #[rustc_layout_scalar_valid_range_start(0suffix)] | ^^^^^^^ invalid suffix `suffix` @@ -150,15 +150,23 @@ LL | 1.0e10suffix; | = help: valid suffixes are `f32` and `f64` -error[E0805]: malformed `rustc_layout_scalar_valid_range_start` attribute input - --> $DIR/bad-lit-suffixes.rs:42:1 +error[E0539]: malformed `must_use` attribute input + --> $DIR/bad-lit-suffixes.rs:34:1 + | +LL | #[must_use = "string"suffix] + | ^^^^^^^^^^^^^--------------^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[must_use = "string"suffix] +LL + #[must_use = "reason"] + | +LL - #[must_use = "string"suffix] +LL + #[must_use] | -LL | #[rustc_layout_scalar_valid_range_start(0suffix)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------^ - | | | - | | expected a single argument here - | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]` error: aborting due to 21 previous errors; 2 warnings emitted -For more information about this error, try `rustc --explain E0805`. +For more information about this error, try `rustc --explain E0539`. From 0b67d14b31aefa8a2bf8e336ee4f029e046dd545 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 29 Jun 2025 11:35:31 +0200 Subject: [PATCH 16/20] Fix `#[rustc_macro_transparency]` giving two errors Signed-off-by: Jonathan Brouwer --- compiler/rustc_parse/src/validate_attr.rs | 1 + tests/ui/attributes/malformed-attrs.rs | 1 - tests/ui/attributes/malformed-attrs.stderr | 142 ++++++++++----------- 3 files changed, 69 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 11cff88ba4fbf..cc95e3d6567bb 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -304,6 +304,7 @@ fn emit_malformed_attribute( | sym::track_caller | sym::link_name | sym::export_name + | sym::rustc_macro_transparency ) { return; } diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index 4a368ea4e96da..64c0d223f835c 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -44,7 +44,6 @@ //~| WARN this was previously accepted by the compiler #[rustc_macro_transparency] //~^ ERROR malformed -//~| ERROR malformed #[repr] //~^ ERROR malformed #[rustc_as_ptr = 5] diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 50c75d65f6db5..de639aa958c3f 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -1,11 +1,11 @@ error: `cfg` is not followed by parentheses - --> $DIR/malformed-attrs.rs:101:1 + --> $DIR/malformed-attrs.rs:100:1 | LL | #[cfg] | ^^^^^^ help: expected syntax is: `cfg(/* predicate */)` error: malformed `cfg_attr` attribute input - --> $DIR/malformed-attrs.rs:103:1 + --> $DIR/malformed-attrs.rs:102:1 | LL | #[cfg_attr] | ^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | #[cfg_attr(condition, attribute, other_attribute, ...)] | ++++++++++++++++++++++++++++++++++++++++++++ error[E0463]: can't find crate for `wloop` - --> $DIR/malformed-attrs.rs:210:1 + --> $DIR/malformed-attrs.rs:209:1 | LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate @@ -34,38 +34,32 @@ error: malformed `windows_subsystem` attribute input LL | #![windows_subsystem] | ^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![windows_subsystem = "windows|console"]` -error: malformed `rustc_macro_transparency` attribute input - --> $DIR/malformed-attrs.rs:45:1 - | -LL | #[rustc_macro_transparency] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_macro_transparency = "transparent|semiopaque|opaque"]` - error: malformed `crate_name` attribute input - --> $DIR/malformed-attrs.rs:73:1 + --> $DIR/malformed-attrs.rs:72:1 | LL | #[crate_name] | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]` error: malformed `target_feature` attribute input - --> $DIR/malformed-attrs.rs:78:1 + --> $DIR/malformed-attrs.rs:77:1 | LL | #[target_feature] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]` error: malformed `export_stable` attribute input - --> $DIR/malformed-attrs.rs:80:1 + --> $DIR/malformed-attrs.rs:79:1 | LL | #[export_stable = 1] | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_stable]` error: malformed `link_section` attribute input - --> $DIR/malformed-attrs.rs:87:1 + --> $DIR/malformed-attrs.rs:86:1 | LL | #[link_section] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` error: malformed `coverage` attribute input - --> $DIR/malformed-attrs.rs:89:1 + --> $DIR/malformed-attrs.rs:88:1 | LL | #[coverage] | ^^^^^^^^^^^ @@ -78,67 +72,67 @@ LL | #[coverage(on)] | ++++ error: malformed `no_sanitize` attribute input - --> $DIR/malformed-attrs.rs:91:1 + --> $DIR/malformed-attrs.rs:90:1 | LL | #[no_sanitize] | ^^^^^^^^^^^^^^ help: must be of the form: `#[no_sanitize(address, kcfi, memory, thread)]` error: malformed `no_implicit_prelude` attribute input - --> $DIR/malformed-attrs.rs:96:1 + --> $DIR/malformed-attrs.rs:95:1 | LL | #[no_implicit_prelude = 23] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[no_implicit_prelude]` error: malformed `proc_macro` attribute input - --> $DIR/malformed-attrs.rs:98:1 + --> $DIR/malformed-attrs.rs:97:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]` error: malformed `instruction_set` attribute input - --> $DIR/malformed-attrs.rs:105:1 + --> $DIR/malformed-attrs.rs:104:1 | LL | #[instruction_set] | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]` error: malformed `patchable_function_entry` attribute input - --> $DIR/malformed-attrs.rs:107:1 + --> $DIR/malformed-attrs.rs:106:1 | LL | #[patchable_function_entry] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` error: malformed `coroutine` attribute input - --> $DIR/malformed-attrs.rs:110:5 + --> $DIR/malformed-attrs.rs:109:5 | LL | #[coroutine = 63] || {} | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[coroutine]` error: malformed `proc_macro_attribute` attribute input - --> $DIR/malformed-attrs.rs:115:1 + --> $DIR/malformed-attrs.rs:114:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]` error: malformed `proc_macro_derive` attribute input - --> $DIR/malformed-attrs.rs:122:1 + --> $DIR/malformed-attrs.rs:121:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` error: malformed `rustc_layout_scalar_valid_range_start` attribute input - --> $DIR/malformed-attrs.rs:127:1 + --> $DIR/malformed-attrs.rs:126:1 | LL | #[rustc_layout_scalar_valid_range_start] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_layout_scalar_valid_range_start(value)]` error: malformed `rustc_layout_scalar_valid_range_end` attribute input - --> $DIR/malformed-attrs.rs:129:1 + --> $DIR/malformed-attrs.rs:128:1 | LL | #[rustc_layout_scalar_valid_range_end] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_layout_scalar_valid_range_end(value)]` error: malformed `must_not_suspend` attribute input - --> $DIR/malformed-attrs.rs:131:1 + --> $DIR/malformed-attrs.rs:130:1 | LL | #[must_not_suspend()] | ^^^^^^^^^^^^^^^^^^^^^ @@ -153,115 +147,115 @@ LL + #[must_not_suspend] | error: malformed `cfi_encoding` attribute input - --> $DIR/malformed-attrs.rs:133:1 + --> $DIR/malformed-attrs.rs:132:1 | LL | #[cfi_encoding] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` error: malformed `type_const` attribute input - --> $DIR/malformed-attrs.rs:142:5 + --> $DIR/malformed-attrs.rs:141:5 | LL | #[type_const = 1] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]` error: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:154:1 + --> $DIR/malformed-attrs.rs:153:1 | LL | #[marker = 3] | ^^^^^^^^^^^^^ help: must be of the form: `#[marker]` error: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:156:1 + --> $DIR/malformed-attrs.rs:155:1 | LL | #[fundamental()] | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[fundamental]` error: malformed `ffi_pure` attribute input - --> $DIR/malformed-attrs.rs:164:5 + --> $DIR/malformed-attrs.rs:163:5 | LL | #[unsafe(ffi_pure = 1)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_pure]` error: malformed `link_ordinal` attribute input - --> $DIR/malformed-attrs.rs:166:5 + --> $DIR/malformed-attrs.rs:165:5 | LL | #[link_ordinal] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_ordinal(ordinal)]` error: malformed `ffi_const` attribute input - --> $DIR/malformed-attrs.rs:170:5 + --> $DIR/malformed-attrs.rs:169:5 | LL | #[unsafe(ffi_const = 1)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_const]` error: malformed `linkage` attribute input - --> $DIR/malformed-attrs.rs:172:5 + --> $DIR/malformed-attrs.rs:171:5 | LL | #[linkage] | ^^^^^^^^^^ help: must be of the form: `#[linkage = "external|internal|..."]` error: malformed `allow` attribute input - --> $DIR/malformed-attrs.rs:177:1 + --> $DIR/malformed-attrs.rs:176:1 | LL | #[allow] | ^^^^^^^^ help: must be of the form: `#[allow(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `expect` attribute input - --> $DIR/malformed-attrs.rs:179:1 + --> $DIR/malformed-attrs.rs:178:1 | LL | #[expect] | ^^^^^^^^^ help: must be of the form: `#[expect(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `warn` attribute input - --> $DIR/malformed-attrs.rs:181:1 + --> $DIR/malformed-attrs.rs:180:1 | LL | #[warn] | ^^^^^^^ help: must be of the form: `#[warn(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `deny` attribute input - --> $DIR/malformed-attrs.rs:183:1 + --> $DIR/malformed-attrs.rs:182:1 | LL | #[deny] | ^^^^^^^ help: must be of the form: `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `forbid` attribute input - --> $DIR/malformed-attrs.rs:185:1 + --> $DIR/malformed-attrs.rs:184:1 | LL | #[forbid] | ^^^^^^^^^ help: must be of the form: `#[forbid(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `debugger_visualizer` attribute input - --> $DIR/malformed-attrs.rs:187:1 + --> $DIR/malformed-attrs.rs:186:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[debugger_visualizer(natvis_file = "...", gdb_script_file = "...")]` error: malformed `automatically_derived` attribute input - --> $DIR/malformed-attrs.rs:190:1 + --> $DIR/malformed-attrs.rs:189:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[automatically_derived]` error: malformed `non_exhaustive` attribute input - --> $DIR/malformed-attrs.rs:196:1 + --> $DIR/malformed-attrs.rs:195:1 | LL | #[non_exhaustive = 1] | ^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[non_exhaustive]` error: malformed `thread_local` attribute input - --> $DIR/malformed-attrs.rs:202:1 + --> $DIR/malformed-attrs.rs:201:1 | LL | #[thread_local()] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]` error: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:206:1 + --> $DIR/malformed-attrs.rs:205:1 | LL | #[no_link()] | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]` error: malformed `macro_use` attribute input - --> $DIR/malformed-attrs.rs:208:1 + --> $DIR/malformed-attrs.rs:207:1 | LL | #[macro_use = 1] | ^^^^^^^^^^^^^^^^ @@ -276,7 +270,7 @@ LL + #[macro_use] | error: malformed `macro_export` attribute input - --> $DIR/malformed-attrs.rs:213:1 + --> $DIR/malformed-attrs.rs:212:1 | LL | #[macro_export = 18] | ^^^^^^^^^^^^^^^^^^^^ @@ -291,31 +285,31 @@ LL + #[macro_export] | error: malformed `allow_internal_unsafe` attribute input - --> $DIR/malformed-attrs.rs:215:1 + --> $DIR/malformed-attrs.rs:214:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[allow_internal_unsafe]` error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:98:1 + --> $DIR/malformed-attrs.rs:97:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:115:1 + --> $DIR/malformed-attrs.rs:114:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:122:1 + --> $DIR/malformed-attrs.rs:121:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint - --> $DIR/malformed-attrs.rs:215:1 + --> $DIR/malformed-attrs.rs:214:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -334,7 +328,7 @@ LL | #[doc] = note: `#[deny(ill_formed_attribute_input)]` on by default error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]` - --> $DIR/malformed-attrs.rs:75:1 + --> $DIR/malformed-attrs.rs:74:1 | LL | #[doc] | ^^^^^^ @@ -343,7 +337,7 @@ LL | #[doc] = note: for more information, see issue #57571 error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` - --> $DIR/malformed-attrs.rs:82:1 + --> $DIR/malformed-attrs.rs:81:1 | LL | #[link] | ^^^^^^^ @@ -352,7 +346,7 @@ LL | #[link] = note: for more information, see issue #57571 error: valid forms for the attribute are `#[ignore]` and `#[ignore = "reason"]` - --> $DIR/malformed-attrs.rs:93:1 + --> $DIR/malformed-attrs.rs:92:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -361,7 +355,7 @@ LL | #[ignore()] = note: for more information, see issue #57571 error: invalid argument - --> $DIR/malformed-attrs.rs:187:1 + --> $DIR/malformed-attrs.rs:186:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -430,7 +424,7 @@ LL | #[rustc_macro_transparency] | help: must be of the form: `#[rustc_macro_transparency = "transparent|semitransparent|opaque"]` error[E0539]: malformed `repr` attribute input - --> $DIR/malformed-attrs.rs:48:1 + --> $DIR/malformed-attrs.rs:47:1 | LL | #[repr] | ^^^^^^^ @@ -439,7 +433,7 @@ LL | #[repr] | help: must be of the form: `#[repr(C | Rust | align(...) | packed(...) | | transparent)]` error[E0565]: malformed `rustc_as_ptr` attribute input - --> $DIR/malformed-attrs.rs:50:1 + --> $DIR/malformed-attrs.rs:49:1 | LL | #[rustc_as_ptr = 5] | ^^^^^^^^^^^^^^^---^ @@ -448,7 +442,7 @@ LL | #[rustc_as_ptr = 5] | help: must be of the form: `#[rustc_as_ptr]` error[E0539]: malformed `align` attribute input - --> $DIR/malformed-attrs.rs:55:1 + --> $DIR/malformed-attrs.rs:54:1 | LL | #[align] | ^^^^^^^^ @@ -457,7 +451,7 @@ LL | #[align] | help: must be of the form: `#[align()]` error[E0539]: malformed `optimize` attribute input - --> $DIR/malformed-attrs.rs:57:1 + --> $DIR/malformed-attrs.rs:56:1 | LL | #[optimize] | ^^^^^^^^^^^ @@ -466,7 +460,7 @@ LL | #[optimize] | help: must be of the form: `#[optimize(size|speed|none)]` error[E0565]: malformed `cold` attribute input - --> $DIR/malformed-attrs.rs:59:1 + --> $DIR/malformed-attrs.rs:58:1 | LL | #[cold = 1] | ^^^^^^^---^ @@ -475,13 +469,13 @@ LL | #[cold = 1] | help: must be of the form: `#[cold]` error: valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]` - --> $DIR/malformed-attrs.rs:61:1 + --> $DIR/malformed-attrs.rs:60:1 | LL | #[must_use()] | ^^^^^^^^^^^^^ error[E0565]: malformed `no_mangle` attribute input - --> $DIR/malformed-attrs.rs:63:1 + --> $DIR/malformed-attrs.rs:62:1 | LL | #[no_mangle = 1] | ^^^^^^^^^^^^---^ @@ -490,7 +484,7 @@ LL | #[no_mangle = 1] | help: must be of the form: `#[no_mangle]` error[E0565]: malformed `naked` attribute input - --> $DIR/malformed-attrs.rs:65:1 + --> $DIR/malformed-attrs.rs:64:1 | LL | #[unsafe(naked())] | ^^^^^^^^^^^^^^--^^ @@ -499,7 +493,7 @@ LL | #[unsafe(naked())] | help: must be of the form: `#[naked]` error[E0565]: malformed `track_caller` attribute input - --> $DIR/malformed-attrs.rs:67:1 + --> $DIR/malformed-attrs.rs:66:1 | LL | #[track_caller()] | ^^^^^^^^^^^^^^--^ @@ -508,7 +502,7 @@ LL | #[track_caller()] | help: must be of the form: `#[track_caller]` error[E0539]: malformed `export_name` attribute input - --> $DIR/malformed-attrs.rs:69:1 + --> $DIR/malformed-attrs.rs:68:1 | LL | #[export_name()] | ^^^^^^^^^^^^^^^^ @@ -517,7 +511,7 @@ LL | #[export_name()] | help: must be of the form: `#[export_name = "name"]` error[E0805]: malformed `used` attribute input - --> $DIR/malformed-attrs.rs:71:1 + --> $DIR/malformed-attrs.rs:70:1 | LL | #[used()] | ^^^^^^--^ @@ -533,7 +527,7 @@ LL + #[used] | error[E0539]: malformed `link_name` attribute input - --> $DIR/malformed-attrs.rs:85:1 + --> $DIR/malformed-attrs.rs:84:1 | LL | #[link_name] | ^^^^^^^^^^^^ @@ -542,7 +536,7 @@ LL | #[link_name] | help: must be of the form: `#[link_name = "name"]` error[E0539]: malformed `must_use` attribute input - --> $DIR/malformed-attrs.rs:118:1 + --> $DIR/malformed-attrs.rs:117:1 | LL | #[must_use = 1] | ^^^^^^^^^^^^^-^ @@ -559,7 +553,7 @@ LL + #[must_use] | warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/malformed-attrs.rs:148:1 + --> $DIR/malformed-attrs.rs:147:1 | LL | #[diagnostic::do_not_recommend()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -567,7 +561,7 @@ LL | #[diagnostic::do_not_recommend()] = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: missing options for `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:137:1 + --> $DIR/malformed-attrs.rs:136:1 | LL | #[diagnostic::on_unimplemented] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -575,7 +569,7 @@ LL | #[diagnostic::on_unimplemented] = help: at least one of the `message`, `note` and `label` options are expected warning: malformed `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:139:1 + --> $DIR/malformed-attrs.rs:138:1 | LL | #[diagnostic::on_unimplemented = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here @@ -583,7 +577,7 @@ LL | #[diagnostic::on_unimplemented = 1] = help: only `message`, `note` and `label` are allowed as options error: valid forms for the attribute are `#[inline(always|never)]` and `#[inline]` - --> $DIR/malformed-attrs.rs:52:1 + --> $DIR/malformed-attrs.rs:51:1 | LL | #[inline = 5] | ^^^^^^^^^^^^^ @@ -592,7 +586,7 @@ LL | #[inline = 5] = note: for more information, see issue #57571 error[E0308]: mismatched types - --> $DIR/malformed-attrs.rs:110:23 + --> $DIR/malformed-attrs.rs:109:23 | LL | fn test() { | - help: a return type might be missing here: `-> _` @@ -600,9 +594,9 @@ LL | #[coroutine = 63] || {} | ^^^^^ expected `()`, found coroutine | = note: expected unit type `()` - found coroutine `{coroutine@$DIR/malformed-attrs.rs:110:23: 110:25}` + found coroutine `{coroutine@$DIR/malformed-attrs.rs:109:23: 109:25}` -error: aborting due to 73 previous errors; 3 warnings emitted +error: aborting due to 72 previous errors; 3 warnings emitted Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805. For more information about an error, try `rustc --explain E0308`. From d22ce4c5eb40d718a1465967acfb8cee38e3aec8 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 29 Jun 2025 12:40:30 +0200 Subject: [PATCH 17/20] Fix duplicate help on export_name and others Signed-off-by: Jonathan Brouwer --- .../src/session_diagnostics.rs | 5 +---- tests/ui/attributes/malformed-attrs.stderr | 20 ++++--------------- tests/ui/extern/issue-47725.rs | 1 - tests/ui/extern/issue-47725.stderr | 5 +---- 4 files changed, 6 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index a815aa8c7a8ae..6145f1e1d3e30 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -577,10 +577,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError { diag.code(E0565); } AttributeParseErrorReason::ExpectedNameValue(None) => { - diag.span_label( - self.span, - format!("expected this to be of the form `{name} = \"...\"`"), - ); + // The suggestion we add below this match already contains enough information } AttributeParseErrorReason::ExpectedNameValue(Some(name)) => { diag.span_label( diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index de639aa958c3f..a6baf2e02d65f 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -368,10 +368,7 @@ error[E0539]: malformed `export_name` attribute input --> $DIR/malformed-attrs.rs:32:1 | LL | #[unsafe(export_name)] - | ^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected this to be of the form `export_name = "..."` - | help: must be of the form: `#[export_name = "name"]` + | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]` error: `rustc_allow_const_fn_unstable` expects a list of feature names --> $DIR/malformed-attrs.rs:34:1 @@ -418,10 +415,7 @@ error[E0539]: malformed `rustc_macro_transparency` attribute input --> $DIR/malformed-attrs.rs:45:1 | LL | #[rustc_macro_transparency] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected this to be of the form `rustc_macro_transparency = "..."` - | help: must be of the form: `#[rustc_macro_transparency = "transparent|semitransparent|opaque"]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_macro_transparency = "transparent|semitransparent|opaque"]` error[E0539]: malformed `repr` attribute input --> $DIR/malformed-attrs.rs:47:1 @@ -505,10 +499,7 @@ error[E0539]: malformed `export_name` attribute input --> $DIR/malformed-attrs.rs:68:1 | LL | #[export_name()] - | ^^^^^^^^^^^^^^^^ - | | - | expected this to be of the form `export_name = "..."` - | help: must be of the form: `#[export_name = "name"]` + | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]` error[E0805]: malformed `used` attribute input --> $DIR/malformed-attrs.rs:70:1 @@ -530,10 +521,7 @@ error[E0539]: malformed `link_name` attribute input --> $DIR/malformed-attrs.rs:84:1 | LL | #[link_name] - | ^^^^^^^^^^^^ - | | - | expected this to be of the form `link_name = "..."` - | help: must be of the form: `#[link_name = "name"]` + | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]` error[E0539]: malformed `must_use` attribute input --> $DIR/malformed-attrs.rs:117:1 diff --git a/tests/ui/extern/issue-47725.rs b/tests/ui/extern/issue-47725.rs index 012673b9159f1..60d0cd6234745 100644 --- a/tests/ui/extern/issue-47725.rs +++ b/tests/ui/extern/issue-47725.rs @@ -17,7 +17,6 @@ extern "C" { #[link_name] //~^ ERROR malformed `link_name` attribute input //~| HELP must be of the form -//~| NOTE expected this to be of the form `link_name = "..." extern "C" { fn bar() -> u32; } diff --git a/tests/ui/extern/issue-47725.stderr b/tests/ui/extern/issue-47725.stderr index 53d6b4927f89f..4fd02a1778be6 100644 --- a/tests/ui/extern/issue-47725.stderr +++ b/tests/ui/extern/issue-47725.stderr @@ -2,10 +2,7 @@ error[E0539]: malformed `link_name` attribute input --> $DIR/issue-47725.rs:17:1 | LL | #[link_name] - | ^^^^^^^^^^^^ - | | - | expected this to be of the form `link_name = "..."` - | help: must be of the form: `#[link_name = "name"]` + | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]` warning: attribute should be applied to a foreign function or static --> $DIR/issue-47725.rs:3:1 From 1e474c2c6cea4b4ce36e3f00a8bc6a60b9c2cbf5 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 1 Jul 2025 16:31:23 +0200 Subject: [PATCH 18/20] Port `#[rustc_object_lifetime_default]` to the new attribute parsing infrastructure --- .../src/attributes.rs | 3 +++ .../src/encode_cross_crate.rs | 1 + .../src/attributes/rustc_internal.rs | 18 ++++++++++++++++++ compiler/rustc_attr_parsing/src/context.rs | 2 ++ compiler/rustc_passes/src/check_attr.rs | 5 +++-- 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 4651cf504fa5a..6f4cc83fd1050 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -296,6 +296,9 @@ pub enum AttributeKind { /// Represents `#[rustc_layout_scalar_valid_range_start]`. RustcLayoutScalarValidRangeStart(Box, Span), + /// Represents `#[rustc_object_lifetime_default]`. + RustcObjectLifetimeDefault, + /// Represents `#[rustc_skip_during_method_dispatch]`. SkipDuringMethodDispatch { array: bool, boxed_slice: bool, span: Span }, diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 17f7a7a2e6dd7..58ced8e328173 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -40,6 +40,7 @@ impl AttributeKind { PubTransparent(..) => Yes, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, + RustcObjectLifetimeDefault => No, SkipDuringMethodDispatch { .. } => No, TrackCaller(..) => Yes, Used { .. } => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 7364a3f20e27f..e6b6a6fe3c9e5 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -57,3 +57,21 @@ fn parse_rustc_layout_scalar_valid_range( }; Some(Box::new(num.0)) } + +pub(crate) struct RustcObjectLifetimeDefaultParser; + +impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { + const PATH: &[rustc_span::Symbol] = &[sym::rustc_object_lifetime_default]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const TEMPLATE: AttributeTemplate = template!(Word); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + if let Err(span) = args.no_args() { + cx.expected_no_args(span); + return None; + } + + Some(AttributeKind::RustcObjectLifetimeDefault) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 6a03cde3a53a8..cfba06509325b 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -29,6 +29,7 @@ use crate::attributes::must_use::MustUseParser; use crate::attributes::repr::{AlignParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart, + RustcObjectLifetimeDefaultParser, }; use crate::attributes::semantics::MayDangleParser; use crate::attributes::stability::{ @@ -136,6 +137,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4bc48cb6aca6f..49b23ce50b8b8 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -164,7 +164,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */ } - + Attribute::Parsed(AttributeKind::RustcObjectLifetimeDefault) => { + self.check_object_lifetime_default(hir_id); + } &Attribute::Parsed(AttributeKind::PubTransparent(attr_span)) => { self.check_rustc_pub_transparent(attr_span, span, attrs) } @@ -303,7 +305,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::no_implicit_prelude, ..] => { self.check_generic_attr(hir_id, attr, target, Target::Mod) } - [sym::rustc_object_lifetime_default, ..] => self.check_object_lifetime_default(hir_id), [sym::proc_macro, ..] => { self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike) } From 57a5e3b6d29b31f9af7afbeacde90cf131a23d43 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 1 Jul 2025 16:12:17 +0200 Subject: [PATCH 19/20] Fix duplicate errors for `link_section`, `rustc_layout_scalar_valid_range_start` and `rustc_layout_scalar_valid_range_end` --- compiler/rustc_parse/src/validate_attr.rs | 3 ++ tests/ui/attributes/malformed-attrs.stderr | 42 ++++++++++++---------- tests/ui/parser/bad-lit-suffixes.stderr | 14 ++++++-- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index cc95e3d6567bb..6c2c571d240c9 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -305,6 +305,9 @@ fn emit_malformed_attribute( | sym::link_name | sym::export_name | sym::rustc_macro_transparency + | sym::link_section + | sym::rustc_layout_scalar_valid_range_start + | sym::rustc_layout_scalar_valid_range_end ) { return; } diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index a6baf2e02d65f..bf063e8f6e54b 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -52,12 +52,6 @@ error: malformed `export_stable` attribute input LL | #[export_stable = 1] | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_stable]` -error: malformed `link_section` attribute input - --> $DIR/malformed-attrs.rs:86:1 - | -LL | #[link_section] - | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` - error: malformed `coverage` attribute input --> $DIR/malformed-attrs.rs:88:1 | @@ -119,18 +113,6 @@ error: malformed `proc_macro_derive` attribute input LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: malformed `rustc_layout_scalar_valid_range_start` attribute input - --> $DIR/malformed-attrs.rs:126:1 - | -LL | #[rustc_layout_scalar_valid_range_start] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_layout_scalar_valid_range_start(value)]` - -error: malformed `rustc_layout_scalar_valid_range_end` attribute input - --> $DIR/malformed-attrs.rs:128:1 - | -LL | #[rustc_layout_scalar_valid_range_end] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_layout_scalar_valid_range_end(value)]` - error: malformed `must_not_suspend` attribute input --> $DIR/malformed-attrs.rs:130:1 | @@ -523,6 +505,12 @@ error[E0539]: malformed `link_name` attribute input LL | #[link_name] | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]` +error[E0539]: malformed `link_section` attribute input + --> $DIR/malformed-attrs.rs:86:1 + | +LL | #[link_section] + | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` + error[E0539]: malformed `must_use` attribute input --> $DIR/malformed-attrs.rs:117:1 | @@ -540,6 +528,24 @@ LL - #[must_use = 1] LL + #[must_use] | +error[E0539]: malformed `rustc_layout_scalar_valid_range_start` attribute input + --> $DIR/malformed-attrs.rs:126:1 + | +LL | #[rustc_layout_scalar_valid_range_start] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]` + +error[E0539]: malformed `rustc_layout_scalar_valid_range_end` attribute input + --> $DIR/malformed-attrs.rs:128:1 + | +LL | #[rustc_layout_scalar_valid_range_end] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` + warning: `#[diagnostic::do_not_recommend]` does not expect any arguments --> $DIR/malformed-attrs.rs:147:1 | diff --git a/tests/ui/parser/bad-lit-suffixes.stderr b/tests/ui/parser/bad-lit-suffixes.stderr index e68893535eb6a..7876d75c5a427 100644 --- a/tests/ui/parser/bad-lit-suffixes.stderr +++ b/tests/ui/parser/bad-lit-suffixes.stderr @@ -167,6 +167,16 @@ LL - #[must_use = "string"suffix] LL + #[must_use] | -error: aborting due to 21 previous errors; 2 warnings emitted +error[E0805]: malformed `rustc_layout_scalar_valid_range_start` attribute input + --> $DIR/bad-lit-suffixes.rs:43:1 + | +LL | #[rustc_layout_scalar_valid_range_start(0suffix)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------^ + | | | + | | expected a single argument here + | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]` + +error: aborting due to 22 previous errors; 2 warnings emitted -For more information about this error, try `rustc --explain E0539`. +Some errors have detailed explanations: E0539, E0805. +For more information about an error, try `rustc --explain E0539`. From 711c6166bc2ed7d3afb769ab24cee7a1ad436a32 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 1 Jul 2025 15:15:44 +0200 Subject: [PATCH 20/20] Update clippy source code to make use of `TyCtxt::def_descr` instead of `ItemKind::descr` --- .../clippy_lints/src/undocumented_unsafe_blocks.rs | 10 ++++++++-- .../undocumented_unsafe_blocks.default.stderr | 2 +- .../undocumented_unsafe_blocks.disabled.stderr | 2 +- .../clippy/tests/ui/unnecessary_safety_comment.stderr | 4 ++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index 92427473a8ee9..6cc4b589a7207 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -256,7 +256,10 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { cx, UNNECESSARY_SAFETY_COMMENT, span, - format!("{} has unnecessary safety comment", item.kind.descr()), + format!( + "{} has unnecessary safety comment", + cx.tcx.def_descr(item.owner_id.to_def_id()), + ), |diag| { diag.span_help(help_span, "consider removing the safety comment"); }, @@ -274,7 +277,10 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { cx, UNNECESSARY_SAFETY_COMMENT, span, - format!("{} has unnecessary safety comment", item.kind.descr()), + format!( + "{} has unnecessary safety comment", + cx.tcx.def_descr(item.owner_id.to_def_id()), + ), |diag| { diag.span_help(help_span, "consider removing the safety comment"); }, diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr index 8a2f201009a92..bfc14be5421fc 100644 --- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr +++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr @@ -240,7 +240,7 @@ LL | unsafe impl TrailingComment for () {} // SAFETY: | = help: consider adding a safety comment on the preceding line -error: constant item has unnecessary safety comment +error: constant has unnecessary safety comment --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:508:5 | LL | const BIG_NUMBER: i32 = 1000000; diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr index e9c5e5f9f1146..20cdff5fcd12b 100644 --- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr +++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr @@ -240,7 +240,7 @@ LL | unsafe impl TrailingComment for () {} // SAFETY: | = help: consider adding a safety comment on the preceding line -error: constant item has unnecessary safety comment +error: constant has unnecessary safety comment --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:508:5 | LL | const BIG_NUMBER: i32 = 1000000; diff --git a/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr b/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr index b56e8b354931c..732e6767c1780 100644 --- a/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr @@ -1,4 +1,4 @@ -error: constant item has unnecessary safety comment +error: constant has unnecessary safety comment --> tests/ui/unnecessary_safety_comment.rs:6:5 | LL | const CONST: u32 = 0; @@ -12,7 +12,7 @@ LL | // SAFETY: = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]` -error: static item has unnecessary safety comment +error: static has unnecessary safety comment --> tests/ui/unnecessary_safety_comment.rs:10:5 | LL | static STATIC: u32 = 0;