From 93b960ee72d1fc0f019d00001f54963fd075558a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 20 Mar 2026 16:25:00 +0100 Subject: [PATCH 01/37] Do not attempt generating imports for extern types --- compiler/rustc_metadata/src/native_libs.rs | 8 ++++--- .../raw-dylib-elf-extern-types/bin.rs | 21 +++++++++++++++++++ .../raw-dylib-elf-extern-types/extern.c | 16 ++++++++++++++ .../raw-dylib-elf-extern-types/output.txt | 1 + .../raw-dylib-elf-extern-types/rmake.rs | 18 ++++++++++++++++ 5 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 tests/run-make/raw-dylib-elf-extern-types/bin.rs create mode 100644 tests/run-make/raw-dylib-elf-extern-types/extern.c create mode 100644 tests/run-make/raw-dylib-elf-extern-types/output.txt create mode 100644 tests/run-make/raw-dylib-elf-extern-types/rmake.rs diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 17b16b3cfe2d..d1c4b51eee4a 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -224,7 +224,7 @@ fn process_module(&mut self, module: &ForeignModule) { let dll_imports = match attr.kind { NativeLibKind::RawDylib { .. } => foreign_items .iter() - .map(|&child_item| { + .filter_map(|&child_item| { self.build_dll_import( abi, attr.import_name_type.map(|(import_name_type, _)| import_name_type), @@ -388,7 +388,7 @@ fn build_dll_import( abi: ExternAbi, import_name_type: Option, item: DefId, - ) -> DllImport { + ) -> Option { let span = self.tcx.def_span(item); // This `extern` block should have been checked for general ABI support before, but let's @@ -465,6 +465,8 @@ fn build_dll_import( } else { DllImportSymbolType::Static } + } else if def_kind == DefKind::ForeignTy { + return None; } else { bug!("Unexpected type for raw-dylib: {}", def_kind.descr(item)); }; @@ -482,6 +484,6 @@ fn build_dll_import( } }; - DllImport { name, import_name_type, calling_convention, span, symbol_type, size } + Some(DllImport { name, import_name_type, calling_convention, span, symbol_type, size }) } } diff --git a/tests/run-make/raw-dylib-elf-extern-types/bin.rs b/tests/run-make/raw-dylib-elf-extern-types/bin.rs new file mode 100644 index 000000000000..a62445af4f9c --- /dev/null +++ b/tests/run-make/raw-dylib-elf-extern-types/bin.rs @@ -0,0 +1,21 @@ +#![feature(extern_types)] +#![feature(raw_dylib_elf)] + +use std::ffi::c_char; + +#[link(name = "extern", kind = "raw-dylib")] +unsafe extern "C" { + type FOO; + fn create_foo() -> *const FOO; + fn get_foo(foo: *const FOO) -> c_char; + fn set_foo(foo: *const FOO, value: c_char); +} + +pub fn main() { + let value = unsafe { + let foo = create_foo(); + set_foo(foo, 42); + get_foo(foo) + }; + println!("{}", value); +} diff --git a/tests/run-make/raw-dylib-elf-extern-types/extern.c b/tests/run-make/raw-dylib-elf-extern-types/extern.c new file mode 100644 index 000000000000..0201cd3348ff --- /dev/null +++ b/tests/run-make/raw-dylib-elf-extern-types/extern.c @@ -0,0 +1,16 @@ +typedef struct FOO { + char val; +} FOO; + +FOO* create_foo() { + static FOO foo; + return &foo; +} + +void set_foo(FOO* foo, char val) { + foo->val = val; +} + +char get_foo(FOO* foo) { + return foo->val; +} diff --git a/tests/run-make/raw-dylib-elf-extern-types/output.txt b/tests/run-make/raw-dylib-elf-extern-types/output.txt new file mode 100644 index 000000000000..d81cc0710eb6 --- /dev/null +++ b/tests/run-make/raw-dylib-elf-extern-types/output.txt @@ -0,0 +1 @@ +42 diff --git a/tests/run-make/raw-dylib-elf-extern-types/rmake.rs b/tests/run-make/raw-dylib-elf-extern-types/rmake.rs new file mode 100644 index 000000000000..410982548ca1 --- /dev/null +++ b/tests/run-make/raw-dylib-elf-extern-types/rmake.rs @@ -0,0 +1,18 @@ +//@ only-elf +//@ ignore-cross-compile: Runs a binary. +//@ needs-dynamic-linking +// FIXME(raw_dylib_elf): Debug the failures on other targets. +//@ only-gnu +//@ only-x86_64 + +//@ ignore-rustc-debug-assertions + +use run_make_support::{build_native_dynamic_lib, diff, run, rustc}; + +fn main() { + rustc().crate_type("bin").crate_name("raw_dylib_test").input("bin.rs").run(); + build_native_dynamic_lib("extern"); + + let out_raw = run("raw_dylib_test").stdout_utf8(); + diff().expected_file("output.txt").actual_text("actual", out_raw).normalize(r#"\r"#, "").run(); +} From e6098df4d0480d0c69bdffba82082df0f220b1a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 14 Mar 2026 15:21:13 +0100 Subject: [PATCH 02/37] Remove `TaggedQueryKey::def_kind` --- compiler/rustc_middle/src/query/plumbing.rs | 24 --------------------- compiler/rustc_query_impl/src/job.rs | 22 +++++++++++++------ 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index ef6259b1a0c1..9f9373ba36dc 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -448,30 +448,6 @@ pub fn default_span(&self, tcx: TyCtxt<'tcx>, span: Span) -> Span { )* } } - - pub fn def_kind(&self, tcx: TyCtxt<'tcx>) -> Option { - // This is used to reduce code generation as it - // can be reused for queries with the same key type. - fn inner<'tcx>(key: &impl $crate::query::QueryKey, tcx: TyCtxt<'tcx>) - -> Option - { - key - .key_as_def_id() - .and_then(|def_id| def_id.as_local()) - .map(|def_id| tcx.def_kind(def_id)) - } - - if let TaggedQueryKey::def_kind(..) = self { - // Try to avoid infinite recursion. - return None - } - - match self { - $( - TaggedQueryKey::$name(key) => inner(key, tcx), - )* - } - } } /// Holds a `QueryVTable` for each query. diff --git a/compiler/rustc_query_impl/src/job.rs b/compiler/rustc_query_impl/src/job.rs index a27a6f4ea322..ef3122bac5b2 100644 --- a/compiler/rustc_query_impl/src/job.rs +++ b/compiler/rustc_query_impl/src/job.rs @@ -481,13 +481,23 @@ pub(crate) fn create_cycle_error<'tcx>( usage: usage.tagged_key.description(tcx), }); - let alias = if frames - .iter() - .all(|frame| frame.tagged_key.def_kind(tcx) == Some(DefKind::TyAlias)) - { + let is_all_def_kind = |def_kind| { + // Trivial type alias and trait alias cycles consists of `type_of` and + // `explicit_implied_predicates_of` queries, so we just check just these here. + frames.iter().all(|frame| match frame.tagged_key { + TaggedQueryKey::type_of(def_id) + | TaggedQueryKey::explicit_implied_predicates_of(def_id) + if tcx.def_kind(def_id) == def_kind => + { + true + } + _ => false, + }) + }; + + let alias = if is_all_def_kind(DefKind::TyAlias) { Some(crate::error::Alias::Ty) - } else if frames.iter().all(|frame| frame.tagged_key.def_kind(tcx) == Some(DefKind::TraitAlias)) - { + } else if is_all_def_kind(DefKind::TraitAlias) { Some(crate::error::Alias::Trait) } else { None From 3d9452681c3cce0299ba9c801517a156ceb5397f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 13 Mar 2026 09:46:20 +0100 Subject: [PATCH 03/37] Split out the creation of `Cycle` to a new `process_cycle` function --- compiler/rustc_query_impl/src/job.rs | 148 ++++++++++++++------------- 1 file changed, 75 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_query_impl/src/job.rs b/compiler/rustc_query_impl/src/job.rs index a27a6f4ea322..e8199e73cdd6 100644 --- a/compiler/rustc_query_impl/src/job.rs +++ b/compiler/rustc_query_impl/src/job.rs @@ -229,6 +229,80 @@ fn connected_to_root<'tcx>( false } +/// Processes a found query cycle into a `Cycle` +fn process_cycle<'tcx>(job_map: &QueryJobMap<'tcx>, stack: Vec<(Span, QueryJobId)>) -> Cycle<'tcx> { + // The stack is a vector of pairs of spans and queries; reverse it so that + // the earlier entries require later entries + let (mut spans, queries): (Vec<_>, Vec<_>) = stack.into_iter().rev().unzip(); + + // Shift the spans so that queries are matched with the span for their waitee + spans.rotate_right(1); + + // Zip them back together + let mut stack: Vec<_> = iter::zip(spans, queries).collect(); + + struct EntryPoint { + query_in_cycle: QueryJobId, + query_waiting_on_cycle: Option<(Span, QueryJobId)>, + } + + // Find the queries in the cycle which are + // connected to queries outside the cycle + let entry_points = stack + .iter() + .filter_map(|&(_, query_in_cycle)| { + let mut entrypoint = false; + let mut query_waiting_on_cycle = None; + + // Find a direct waiter who leads to the root + for abstracted_waiter in abstracted_waiters_of(job_map, query_in_cycle) { + let Some(parent) = abstracted_waiter.parent else { + // The query in the cycle is directly connected to root. + entrypoint = true; + continue; + }; + + // Mark all the other queries in the cycle as already visited, + // so paths to the root through the cycle itself won't count. + let mut visited = FxHashSet::from_iter(stack.iter().map(|q| q.1)); + + if connected_to_root(job_map, parent, &mut visited) { + query_waiting_on_cycle = Some((abstracted_waiter.span, parent)); + entrypoint = true; + break; + } + } + + entrypoint.then_some(EntryPoint { query_in_cycle, query_waiting_on_cycle }) + }) + .collect::>(); + + // Pick an entry point, preferring ones with waiters + let entry_point = entry_points + .iter() + .find(|entry_point| entry_point.query_waiting_on_cycle.is_some()) + .unwrap_or(&entry_points[0]); + + // Shift the stack so that our entry point is first + let entry_point_pos = stack.iter().position(|(_, query)| *query == entry_point.query_in_cycle); + if let Some(pos) = entry_point_pos { + stack.rotate_left(pos); + } + + let usage = entry_point + .query_waiting_on_cycle + .map(|(span, job)| QueryStackFrame { span, tagged_key: job_map.tagged_key_of(job) }); + + // Create the cycle error + Cycle { + usage, + frames: stack + .iter() + .map(|&(span, job)| QueryStackFrame { span, tagged_key: job_map.tagged_key_of(job) }) + .collect(), + } +} + /// Looks for a query cycle using the last query in `jobs`. /// If a cycle is found, all queries in the cycle is removed from `jobs` and /// the function return true. @@ -245,16 +319,6 @@ fn remove_cycle<'tcx>( if let ControlFlow::Break(resumable) = find_cycle(job_map, jobs.pop().unwrap(), DUMMY_SP, &mut stack, &mut visited) { - // The stack is a vector of pairs of spans and queries; reverse it so that - // the earlier entries require later entries - let (mut spans, queries): (Vec<_>, Vec<_>) = stack.into_iter().rev().unzip(); - - // Shift the spans so that queries are matched with the span for their waitee - spans.rotate_right(1); - - // Zip them back together - let mut stack: Vec<_> = iter::zip(spans, queries).collect(); - // Remove the queries in our cycle from the list of jobs to look at for r in &stack { if let Some(pos) = jobs.iter().position(|j| j == &r.1) { @@ -262,70 +326,8 @@ fn remove_cycle<'tcx>( } } - struct EntryPoint { - query_in_cycle: QueryJobId, - query_waiting_on_cycle: Option<(Span, QueryJobId)>, - } - - // Find the queries in the cycle which are - // connected to queries outside the cycle - let entry_points = stack - .iter() - .filter_map(|&(_, query_in_cycle)| { - let mut entrypoint = false; - let mut query_waiting_on_cycle = None; - - // Find a direct waiter who leads to the root - for abstracted_waiter in abstracted_waiters_of(job_map, query_in_cycle) { - let Some(parent) = abstracted_waiter.parent else { - // The query in the cycle is directly connected to root. - entrypoint = true; - continue; - }; - - // Mark all the other queries in the cycle as already visited, - // so paths to the root through the cycle itself won't count. - let mut visited = FxHashSet::from_iter(stack.iter().map(|q| q.1)); - - if connected_to_root(job_map, parent, &mut visited) { - query_waiting_on_cycle = Some((abstracted_waiter.span, parent)); - entrypoint = true; - break; - } - } - - entrypoint.then_some(EntryPoint { query_in_cycle, query_waiting_on_cycle }) - }) - .collect::>(); - - // Pick an entry point, preferring ones with waiters - let entry_point = entry_points - .iter() - .find(|entry_point| entry_point.query_waiting_on_cycle.is_some()) - .unwrap_or(&entry_points[0]); - - // Shift the stack so that our entry point is first - let entry_point_pos = - stack.iter().position(|(_, query)| *query == entry_point.query_in_cycle); - if let Some(pos) = entry_point_pos { - stack.rotate_left(pos); - } - - let usage = entry_point - .query_waiting_on_cycle - .map(|(span, job)| QueryStackFrame { span, tagged_key: job_map.tagged_key_of(job) }); - // Create the cycle error - let error = Cycle { - usage, - frames: stack - .iter() - .map(|&(span, job)| QueryStackFrame { - span, - tagged_key: job_map.tagged_key_of(job), - }) - .collect(), - }; + let error = process_cycle(job_map, stack); // We unwrap `resumable` here since there must always be one // edge which is resumable / waited using a query latch From 8717b4b9c85cc2e66273fe623bebdbcba03fe938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 1 Apr 2026 11:56:45 +0200 Subject: [PATCH 04/37] Use a different name for fast try builds --- src/ci/github-actions/jobs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 7c0f1d3f2930..97ddde799a75 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -94,6 +94,7 @@ jobs: dist-x86_64-linux: &job-dist-x86_64-linux name: dist-x86_64-linux env: + IMAGE: dist-x86_64-linux CODEGEN_BACKENDS: llvm,cranelift DOCKER_SCRIPT: dist.sh <<: *job-linux-36c-codebuild @@ -150,6 +151,7 @@ pr: # it in each job definition. try: - <<: *job-dist-x86_64-linux + name: dist-x86_64-linux-quick # Jobs that only run when explicitly invoked in one of the following ways: # - comment `@bors try jobs=` From cf4e8c6752694f953e50c8df89a211c012d9fe43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Mon, 2 Mar 2026 04:28:37 +0100 Subject: [PATCH 05/37] GCI: During reachability analysis don't try to evaluate the initializer of overly generic free const items --- compiler/rustc_passes/src/reachable.rs | 22 +++++++---- ...rivate_const_fn_only_used_in_const_eval.rs | 27 ------------- ...rivate-const-fn-only-used-in-const-eval.rs | 38 +++++++++++++++++++ .../def-site-eval.fail.stderr | 2 +- tests/ui/generic-const-items/def-site-eval.rs | 31 +++++++++++---- .../trivially-unsatisfied-bounds-0.rs | 12 ------ .../trivially-unsatisfied-bounds-1.rs | 12 ------ .../trivially-unsatisfied-bounds-1.stderr | 11 ------ ...ially-unsatisfied-bounds.mentioned.stderr} | 14 +++---- .../trivially-unsatisfied-bounds.rs | 33 ++++++++++++++++ ...ally-unsatisfied-bounds.unmentioned.stderr | 11 ++++++ 11 files changed, 129 insertions(+), 84 deletions(-) delete mode 100644 tests/codegen-llvm/dont_codegen_private_const_fn_only_used_in_const_eval.rs create mode 100644 tests/codegen-llvm/private-const-fn-only-used-in-const-eval.rs delete mode 100644 tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.rs delete mode 100644 tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.rs delete mode 100644 tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.stderr rename tests/ui/generic-const-items/{trivially-unsatisfied-bounds-0.stderr => trivially-unsatisfied-bounds.mentioned.stderr} (60%) create mode 100644 tests/ui/generic-const-items/trivially-unsatisfied-bounds.rs create mode 100644 tests/ui/generic-const-items/trivially-unsatisfied-bounds.unmentioned.stderr diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index f72899a66cae..41ec05621721 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -214,18 +214,26 @@ fn propagate_node(&mut self, node: &Node<'tcx>, search_item: LocalDefId) { self.visit_const_item_rhs(init); } hir::ItemKind::Const(_, _, _, init) => { - // Only things actually ending up in the final constant value are reachable - // for codegen. Everything else is only needed during const-eval, so even if - // const-eval happens in a downstream crate, all they need is - // `mir_for_ctfe`. + if self.tcx.generics_of(item.owner_id).own_requires_monomorphization() { + // In this case, we don't want to evaluate the const initializer. + // In lieu of that, we have to consider everything mentioned in it + // as reachable, since it *may* end up in the final value. + self.visit_const_item_rhs(init); + return; + } + match self.tcx.const_eval_poly_to_alloc(item.owner_id.def_id.into()) { Ok(alloc) => { + // Only things actually ending up in the final constant value are + // reachable for codegen. Everything else is only needed during + // const-eval, so even if const-eval happens in a downstream crate, + // all they need is `mir_for_ctfe`. let alloc = self.tcx.global_alloc(alloc.alloc_id).unwrap_memory(); self.propagate_from_alloc(alloc); } - // We can't figure out which value the constant will evaluate to. In - // lieu of that, we have to consider everything mentioned in the const - // initializer reachable, since it *may* end up in the final value. + // Trivially unsatisfiable bounds on the item prevented us from + // normalizing the initializer. Similar to the other case, we have to + // everything mentioned in it as reachable. Err(ErrorHandled::TooGeneric(_)) => self.visit_const_item_rhs(init), // If there was an error evaluating the const, nothing can be reachable // via it, and anyway compilation will fail. diff --git a/tests/codegen-llvm/dont_codegen_private_const_fn_only_used_in_const_eval.rs b/tests/codegen-llvm/dont_codegen_private_const_fn_only_used_in_const_eval.rs deleted file mode 100644 index df50b4af8098..000000000000 --- a/tests/codegen-llvm/dont_codegen_private_const_fn_only_used_in_const_eval.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! This test checks that we do not monomorphize functions that are only -//! used to evaluate static items, but never used in runtime code. - -//@compile-flags: --crate-type=lib -Copt-level=0 - -#![feature(generic_const_items)] - -const fn foo() {} - -pub static FOO: () = foo(); - -// CHECK-NOT: define{{.*}}foo{{.*}} - -const fn bar() {} - -pub const BAR: () = bar(); - -// CHECK-NOT: define{{.*}}bar{{.*}} - -const fn baz() {} - -#[rustfmt::skip] -pub const BAZ: () = if C { - baz() -}; - -// CHECK: define{{.*}}baz{{.*}} diff --git a/tests/codegen-llvm/private-const-fn-only-used-in-const-eval.rs b/tests/codegen-llvm/private-const-fn-only-used-in-const-eval.rs new file mode 100644 index 000000000000..6dd20cb17c43 --- /dev/null +++ b/tests/codegen-llvm/private-const-fn-only-used-in-const-eval.rs @@ -0,0 +1,38 @@ +// Check that we — where possible — don't codegen functions that are only used to evaluate +// static / const items, but never used in runtime code. + +//@ compile-flags: --crate-type=lib -Copt-level=0 + +#![feature(generic_const_items)] // only used in the last few test cases + +pub static STATIC: () = func0(); +const fn func0() {} +// CHECK-NOT: define{{.*}}func0{{.*}} + +pub const CONSTANT: () = func1(); +const fn func1() {} +// CHECK-NOT: define{{.*}}func1{{.*}} + +// We generally don't want to evaluate the initializer of free const items if they have +// non-region params (and even if we did, const eval would fail anyway with "too polymorphic" +// if the initializer actually referenced such a param). +// +// As a result of not being able to look at the final value, during reachability analysis we +// can't tell for sure if for example certain functions end up in the final value or if they're +// only used during const eval. We fall back to a conservative HIR-based approach. + +// `func2` isn't needed at runtime but the compiler can't tell for the reason mentioned above. +pub const POLY_CONST_0: () = func2(); +const fn func2() {} +// CHECK: define{{.*}}func2{{.*}} + +// `func3` isn't needed at runtime but the compiler can't tell for the reason mentioned above. +pub const POLY_CONST_1: () = if C { func3() }; +const fn func3() {} +// CHECK: define{{.*}}func3{{.*}} + +// `func4` *is* needed at runtime (here, the HIR-based approach gets it right). +pub const POLY_CONST_2: Option = + if C { Some(func4) } else { None }; +const fn func4() {} +// CHECK: define{{.*}}func4{{.*}} diff --git a/tests/ui/generic-const-items/def-site-eval.fail.stderr b/tests/ui/generic-const-items/def-site-eval.fail.stderr index e39fbdf7802d..1fae0790c9fd 100644 --- a/tests/ui/generic-const-items/def-site-eval.fail.stderr +++ b/tests/ui/generic-const-items/def-site-eval.fail.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation panicked: explicit panic - --> $DIR/def-site-eval.rs:13:20 + --> $DIR/def-site-eval.rs:32:20 | LL | const _<'_a>: () = panic!(); | ^^^^^^^^ evaluation of `_` failed here diff --git a/tests/ui/generic-const-items/def-site-eval.rs b/tests/ui/generic-const-items/def-site-eval.rs index fa3ef5907b26..44440450b600 100644 --- a/tests/ui/generic-const-items/def-site-eval.rs +++ b/tests/ui/generic-const-items/def-site-eval.rs @@ -1,15 +1,32 @@ -//! Test that we only evaluate free const items (their def site to be clear) -//! whose generics don't require monomorphization. -#![feature(generic_const_items)] -#![expect(incomplete_features)] - +// Test that we don't evaluate the initializer of free const items if they have +// non-region generic parameters (i.e., ones that "require monomorphization"). +// +// To peek behind the curtains for a bit, at the time of writing there are three places where we +// usually evaluate the initializer: "analysis", mono item collection & reachability analysis. +// We must ensure that all of them take the generics into account. +// //@ revisions: fail pass //@[pass] check-pass +#![feature(generic_const_items)] +#![expect(incomplete_features)] +#![crate_type = "lib"] // (*) + +// All of these constants are intentionally unused since we want to test the +// behavior at the def site, not at use sites. + const _<_T>: () = panic!(); const _: () = panic!(); +// Check *public* const items specifically to exercise reachability analysis which normally +// evaluates const initializers to look for function pointers in the final const value. +// +// (*): While reachability analysis also runs for purely binary crates (to find e.g., extern items) +// setting the crate type to library (1) makes the case below 'more realistic' since +// hypothetical downstream crates that require runtime MIR could actually exist. +// (2) It ensures that we exercise the relevant part of the compiler under test. +pub const K<_T>: () = panic!(); +pub const Q: () = loop {}; + #[cfg(fail)] const _<'_a>: () = panic!(); //[fail]~ ERROR evaluation panicked: explicit panic - -fn main() {} diff --git a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.rs b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.rs deleted file mode 100644 index 102c7b1e5f93..000000000000 --- a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![feature(generic_const_items, trivial_bounds)] -#![allow(incomplete_features)] - -// Ensure that we check if trivial bounds on const items hold or not. - -const UNUSABLE: () = () //~ ERROR entering unreachable code -where - String: Copy; - -fn main() { - let _ = UNUSABLE; //~ ERROR the trait bound `String: Copy` is not satisfied -} diff --git a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.rs b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.rs deleted file mode 100644 index ebe97a65bbf3..000000000000 --- a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![feature(generic_const_items, trivial_bounds)] -#![allow(incomplete_features, dead_code, trivial_bounds)] - -// FIXME(generic_const_items): This looks like a bug to me. I expected that we wouldn't emit any -// errors. I thought we'd skip the evaluation of consts whose bounds don't hold. - -const UNUSED: () = () -where - String: Copy; -//~^^^ ERROR unreachable code - -fn main() {} diff --git a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.stderr b/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.stderr deleted file mode 100644 index a5f6dd980bdc..000000000000 --- a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-1.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0080]: entering unreachable code - --> $DIR/trivially-unsatisfied-bounds-1.rs:7:1 - | -LL | / const UNUSED: () = () -LL | | where -LL | | String: Copy; - | |_________________^ evaluation of `UNUSED` failed here - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.stderr b/tests/ui/generic-const-items/trivially-unsatisfied-bounds.mentioned.stderr similarity index 60% rename from tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.stderr rename to tests/ui/generic-const-items/trivially-unsatisfied-bounds.mentioned.stderr index e5c3bbb0c7db..d0d65a030841 100644 --- a/tests/ui/generic-const-items/trivially-unsatisfied-bounds-0.stderr +++ b/tests/ui/generic-const-items/trivially-unsatisfied-bounds.mentioned.stderr @@ -1,25 +1,25 @@ error[E0080]: entering unreachable code - --> $DIR/trivially-unsatisfied-bounds-0.rs:6:1 + --> $DIR/trivially-unsatisfied-bounds.rs:17:1 | LL | / const UNUSABLE: () = () LL | | where -LL | | String: Copy; - | |_________________^ evaluation of `UNUSABLE` failed here +LL | | for<'_delay> String: Copy; + | |______________________________^ evaluation of `UNUSABLE` failed here error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/trivially-unsatisfied-bounds-0.rs:11:13 + --> $DIR/trivially-unsatisfied-bounds.rs:24:13 | LL | let _ = UNUSABLE; | ^^^^^^^^ the trait `Copy` is not implemented for `String` | note: required by a bound in `UNUSABLE` - --> $DIR/trivially-unsatisfied-bounds-0.rs:8:13 + --> $DIR/trivially-unsatisfied-bounds.rs:19:26 | LL | const UNUSABLE: () = () | -------- required by a bound in this constant LL | where -LL | String: Copy; - | ^^^^ required by this bound in `UNUSABLE` +LL | for<'_delay> String: Copy; + | ^^^^ required by this bound in `UNUSABLE` error: aborting due to 2 previous errors diff --git a/tests/ui/generic-const-items/trivially-unsatisfied-bounds.rs b/tests/ui/generic-const-items/trivially-unsatisfied-bounds.rs new file mode 100644 index 000000000000..9a0c6d0feeca --- /dev/null +++ b/tests/ui/generic-const-items/trivially-unsatisfied-bounds.rs @@ -0,0 +1,33 @@ +// Exercise trivially unsatisfied bounds on free const items. +// Their interaction with the evaluation of the initializer is interesting. +// +//@ revisions: mentioned unmentioned + +#![feature(generic_const_items)] + +// FIXME(generic_const_items): Try to get rid of error "entering unreachable error", it's +// unnecessary and actually caused by MIR pass `ImpossiblePredicates` replacing the body with the +// terminator `Unreachable` due to the unsatisfied bound which is subsequently reached. +// +// NOTE(#142293): However, don't think about suppressing the evaluation of the initializer if the +// bounds are "impossible". That'd be a SemVer hazard since it could cause downstream to fail to +// compile if upstream added a new trait impl which is undesirable[^1]. +// [^1]: Strictly speaking that's already possible due to the one-impl rule. + +const UNUSABLE: () = () //~ ERROR entering unreachable code +where + for<'_delay> String: Copy; + +fn scope() { + // Ensure that we successfully reject references of consts with trivially unsatisfied bounds. + #[cfg(mentioned)] + let _ = UNUSABLE; //[mentioned]~ ERROR the trait bound `String: Copy` is not satisfied +} + +const _BAD: () = <() as Unimplemented>::CT +where + for<'_delay> (): Unimplemented; + +trait Unimplemented { const CT: (); } + +fn main() {} diff --git a/tests/ui/generic-const-items/trivially-unsatisfied-bounds.unmentioned.stderr b/tests/ui/generic-const-items/trivially-unsatisfied-bounds.unmentioned.stderr new file mode 100644 index 000000000000..14bf489b15fb --- /dev/null +++ b/tests/ui/generic-const-items/trivially-unsatisfied-bounds.unmentioned.stderr @@ -0,0 +1,11 @@ +error[E0080]: entering unreachable code + --> $DIR/trivially-unsatisfied-bounds.rs:17:1 + | +LL | / const UNUSABLE: () = () +LL | | where +LL | | for<'_delay> String: Copy; + | |______________________________^ evaluation of `UNUSABLE` failed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. From 51c4299433f4ca3e018edcf4665282cfc5537c60 Mon Sep 17 00:00:00 2001 From: Vastargazing Date: Fri, 3 Apr 2026 18:37:13 +0300 Subject: [PATCH 06/37] coretests: add argument order regression tests for min_by/max_by/minmax_by MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A recent regression swapped the argument order passed to the compare closure in min_by, max_by and minmax_by (compare(&v2, &v1) instead of compare(&v1, &v2)). This was fixed, but no regression test was added. Add tests that record the arguments the compare closure receives and assert they match (v1, v2) — the documented contract. --- library/coretests/tests/cmp.rs | 31 +++++++++++++++++++++++++++++++ library/coretests/tests/lib.rs | 1 + 2 files changed, 32 insertions(+) diff --git a/library/coretests/tests/cmp.rs b/library/coretests/tests/cmp.rs index 0a14470060c3..888a3cfd57a8 100644 --- a/library/coretests/tests/cmp.rs +++ b/library/coretests/tests/cmp.rs @@ -48,6 +48,37 @@ fn test_ord_min_max_by() { assert_eq!(cmp::max_by(2, -1, f), 2); } +// Regression test for #136307 / #139357: ensure compare() receives (v1, v2), not (v2, v1). +#[test] +fn min_by_compare_argument_order() { + let mut order = vec![]; + let _ = cmp::min_by(1i32, 2, |a, b| { + order.push((*a, *b)); + a.cmp(b) + }); + assert_eq!(order, [(1, 2)]); +} + +#[test] +fn max_by_compare_argument_order() { + let mut order = vec![]; + let _ = cmp::max_by(1i32, 2, |a, b| { + order.push((*a, *b)); + a.cmp(b) + }); + assert_eq!(order, [(1, 2)]); +} + +#[test] +fn minmax_by_compare_argument_order() { + let mut order = vec![]; + let _ = cmp::minmax_by(1i32, 2, |a, b| { + order.push((*a, *b)); + a.cmp(b) + }); + assert_eq!(order, [(1, 2)]); +} + #[test] fn test_ord_min_max_by_key() { let f = |x: &i32| x.abs(); diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 90a33aeead15..851eb12eb65c 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -13,6 +13,7 @@ #![feature(char_internals)] #![feature(char_max_len)] #![feature(clone_to_uninit)] +#![feature(cmp_minmax)] #![feature(const_array)] #![feature(const_bool)] #![feature(const_cell_traits)] From e7a00dfa6700e6565de7be68120ed72f120b8eed Mon Sep 17 00:00:00 2001 From: Shagun Agrawal Date: Sat, 4 Apr 2026 19:40:57 +0530 Subject: [PATCH 07/37] Update Fira Mono License Information --- src/librustdoc/build.rs | 1 + src/librustdoc/html/static/COPYRIGHT.txt | 10 ++ .../html/static/fonts/FiraMono-LICENSE.txt | 97 +++++++++++++++++++ src/librustdoc/html/static_files.rs | 1 + 4 files changed, 109 insertions(+) create mode 100644 src/librustdoc/html/static/fonts/FiraMono-LICENSE.txt diff --git a/src/librustdoc/build.rs b/src/librustdoc/build.rs index 5b497183ae60..d1217f712689 100644 --- a/src/librustdoc/build.rs +++ b/src/librustdoc/build.rs @@ -28,6 +28,7 @@ fn main() { "static/fonts/FiraMono-Regular.woff2", "static/fonts/FiraMono-Medium.woff2", "static/fonts/FiraSans-LICENSE.txt", + "static/fonts/FiraMono-LICENSE.txt", "static/fonts/SourceSerif4-Regular.ttf.woff2", "static/fonts/SourceSerif4-Semibold.ttf.woff2", "static/fonts/SourceSerif4-Bold.ttf.woff2", diff --git a/src/librustdoc/html/static/COPYRIGHT.txt b/src/librustdoc/html/static/COPYRIGHT.txt index 752dab0a3478..e20c9cff0acc 100644 --- a/src/librustdoc/html/static/COPYRIGHT.txt +++ b/src/librustdoc/html/static/COPYRIGHT.txt @@ -14,6 +14,16 @@ included, and carry their own copyright notices and license terms: Licensed under the SIL Open Font License, Version 1.1. See FiraSans-LICENSE.txt. +* Fira Mono (FiraMono-Regular.woff2, FiraMono-Medium.woff2): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Mono. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraMono-LICENSE.txt. + * rustdoc.css, main.js, and playpen.js: Copyright 2015 The Rust Developers. diff --git a/src/librustdoc/html/static/fonts/FiraMono-LICENSE.txt b/src/librustdoc/html/static/fonts/FiraMono-LICENSE.txt new file mode 100644 index 000000000000..4737fa435f8f --- /dev/null +++ b/src/librustdoc/html/static/fonts/FiraMono-LICENSE.txt @@ -0,0 +1,97 @@ +// REUSE-IgnoreStart + +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index e670c2f39e72..33969597bd29 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -98,6 +98,7 @@ pub(crate) fn for_each(f: impl Fn(&StaticFile) -> Result<(), E>) -> Result<() fira_mono_regular => "static/fonts/FiraMono-Regular.woff2", fira_mono_medium => "static/fonts/FiraMono-Medium.woff2", fira_sans_license => "static/fonts/FiraSans-LICENSE.txt", + fira_mono_license => "static/fonts/FiraMono-LICENSE.txt", source_serif_4_regular => "static/fonts/SourceSerif4-Regular.ttf.woff2", source_serif_4_semibold => "static/fonts/SourceSerif4-Semibold.ttf.woff2", source_serif_4_bold => "static/fonts/SourceSerif4-Bold.ttf.woff2", From 29d70d4dc25904fd45883646be83573b2693302d Mon Sep 17 00:00:00 2001 From: Shagun Agrawal Date: Sat, 4 Apr 2026 20:42:45 +0530 Subject: [PATCH 08/37] Update license-metadata with FiraMono license --- license-metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/license-metadata.json b/license-metadata.json index 4fb59210854e..298b453b24ae 100644 --- a/license-metadata.json +++ b/license-metadata.json @@ -114,6 +114,7 @@ { "directories": [], "files": [ + "FiraMono-LICENSE.txt", "FiraMono-Medium.woff2", "FiraMono-Regular.woff2", "FiraSans-Italic.woff2", From c0b383cf0455da2d6bbc47d8c607d768b517df0c Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Sat, 4 Apr 2026 05:36:49 +0200 Subject: [PATCH 09/37] Add more info about where autodiff can be applied --- library/core/src/autodiff.md | 153 +++++++++++++++++++++++++++++++++++ library/core/src/lib.rs | 2 +- library/std/src/lib.rs | 2 +- 3 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 library/core/src/autodiff.md diff --git a/library/core/src/autodiff.md b/library/core/src/autodiff.md new file mode 100644 index 000000000000..f15d4d348c17 --- /dev/null +++ b/library/core/src/autodiff.md @@ -0,0 +1,153 @@ +This module provides support for automatic differentiation. For precise information on +differences between the `autodiff_forward` and `autodiff_reverse` macros and how to +use them, see their respective documentation. + +## General usage + +Autodiff macros can be applied to almost all function definitions, see below for examples. +They can be applied to functions accepting structs, arrays, slices, vectors, tuples, and more. + +It is possible to apply multiple autodiff macros to the same function. As an example, this can +be helpful to compute the partial derivatives with respect to `x` and `y` independently: +```rust,ignore (optional component) +#[autodiff_forward(dsquare1, Dual, Const, Dual)] +#[autodiff_forward(dsquare2, Const, Dual, Dual)] +#[autodiff_forward(dsquare3, Active, Active, Active)] +fn square(x: f64, y: f64) -> f64 { + x * x + 2.0 * y +} +``` + +We also support autodiff on functions with generic parameters: +```rust,ignore (optional component) +#[autodiff_forward(generic_derivative, Duplicated, Active)] +fn generic_f + Copy>(x: &T) -> T { + x * x +} +``` + +or applying autodiff to nested functions: +```rust,ignore (optional component) +fn outer(x: f64) -> f64 { + #[autodiff_forward(inner_derivative, Dual, Const)] + fn inner(y: f64) -> f64 { + y * y + } + inner_derivative(x, 1.0) +} + +fn main() { + assert_eq!(outer(3.14), 6.28); +} +``` +The generated function will be available in the same scope as the function differentiated, and +have the same private/pub usability. + +## Traits and impls +Autodiff macros can be used in multiple ways in combination with traits: +```rust,ignore (optional component) +struct Foo { + a: f64, +} + +trait MyTrait { + #[autodiff_reverse(df, Const, Active, Active)] + fn f(&self, x: f64) -> f64; +} + +impl MyTrait for Foo { + fn f(&self, x: f64) -> f64 { + x.sin() + } +} + +fn main() { + let foo = Foo { a: 3.0f64 }; + assert_eq!(foo.f(2.0), 2.0_f64.sin()); + assert_eq!(foo.df(2.0, 1.0).1, 2.0_f64.cos()); +} +``` +In this case `df` will be the default implementation provided by the library who provided the +trait. A user implementing `MyTrait` could then decide to use the default implementation of +`df`, or overwrite it with a custom implementation as a form of "custom derivatives". + +On the other hand, a function generated by either autodiff macro can also be used to implement a +trait: +```rust,ignore (optional component) +struct Foo { + a: f64, +} + +trait MyTrait { + fn f(&self, x: f64) -> f64; + fn df(&self, x: f64, seed: f64) -> (f64, f64); +} + +impl MyTrait for Foo { + #[autodiff_reverse(df, Const, Active, Active)] + fn f(&self, x: f64) -> f64 { + self.a * 0.25 * (x * x - 1.0 - 2.0 * x.ln()) + } +} +``` + +Simple `impl` blocks without traits are also supported. Differentiating with respect to the +implemented struct will then require the use of a "shadow struct" to hold the derivatives of the +struct fields: + +```rust,ignore (optional component) +struct OptProblem { + a: f64, + b: f64, +} + +impl OptProblem { + #[autodiff_reverse(d_objective, Duplicated, Duplicated, Duplicated)] + fn objective(&self, x: &[f64], out: &mut f64) { + *out = self.a + x[0].sqrt() * self.b + } +} +fn main() { + let p = OptProblem { a: 1., b: 2. }; + let mut p_shadow = OptProblem { a: 0., b: 0. }; + let mut dx = [0.0]; + let mut out = 0.0; + let mut dout = 1.0; + + p.d_objective(&mut p_shadow, &x, &mut dx, &mut out, &mut dout); +} +``` + +## Higher-order derivatives +Finally, it is possible to generate higher-order derivatives (e.g. Hessian) by applying an +autodiff macro to a function that is already generated by an autodiff macro, via a thin wrapper. +The following example uses Forward mode over Reverse mode + +```rust,ignore (optional component) +#[autodiff_reverse(df, Duplicated, Duplicated)] +fn f(x: &[f64;2], y: &mut f64) { + *y = x[0] * x[0] + x[1] * x[0] +} + +#[autodiff_forward(h, Dual, Dual, Dual, Dual)] +fn wrapper(x: &[f64;2], dx: &mut [f64;2], y: &mut f64, dy: &mut f64) { + df(x, dx, y, dy); +} + +fn main() { + let mut y = 0.0; + let x = [2.0, 2.0]; + + let mut dy = 0.0; + let mut dx = [1.0, 0.0]; + + let mut bx = [0.0, 0.0]; + let mut by = 1.0; + let mut dbx = [0.0, 0.0]; + let mut dby = 0.0; + h(&x, &mut dx, &mut bx, &mut dbx, &mut y, &mut dy, &mut by, &mut dby); + assert_eq!(&dbx, [2.0, 1.0]); +} +``` + + diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 35f93d8fb33b..45fde363be63 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -218,7 +218,7 @@ pub mod from { // We don't export this through #[macro_export] for now, to avoid breakage. #[unstable(feature = "autodiff", issue = "124509")] -/// Unstable module containing the unstable `autodiff` macro. +#[doc = include_str!("../../core/src/autodiff.md")] pub mod autodiff { #[unstable(feature = "autodiff", issue = "124509")] pub use crate::macros::builtin::{autodiff_forward, autodiff_reverse}; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index c8c8a6c89714..c1daaf8263a3 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -634,7 +634,7 @@ pub mod simd { } #[unstable(feature = "autodiff", issue = "124509")] -/// This module provides support for automatic differentiation. +#[doc = include_str!("../../core/src/autodiff.md")] pub mod autodiff { /// This macro handles automatic differentiation. pub use core::autodiff::{autodiff_forward, autodiff_reverse}; From 3a7ffdc12df5cc02647188b283cfcbadb1af92e3 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Sat, 4 Apr 2026 18:46:53 +0200 Subject: [PATCH 10/37] add current autodiff limitations --- library/core/src/autodiff.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/core/src/autodiff.md b/library/core/src/autodiff.md index f15d4d348c17..847ed8b3ef32 100644 --- a/library/core/src/autodiff.md +++ b/library/core/src/autodiff.md @@ -150,4 +150,8 @@ fn main() { } ``` +## Current limitations: +- Differentiating a function which accepts a `dyn Trait` is currently not supported. +- Builds without `lto="fat"` are not yet supported. +- Builds in debug mode are currently more likely to fail compilation. From 256f0365580df52c9e7b88c61802688898c864d6 Mon Sep 17 00:00:00 2001 From: Lars Schumann Date: Sat, 4 Apr 2026 18:27:08 +0000 Subject: [PATCH 11/37] constify Step for NonZero ints --- library/core/src/iter/range.rs | 6 ++++-- library/core/src/num/nonzero.rs | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index c57f41ffbf06..3b025fdcda90 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -513,7 +513,8 @@ macro_rules! step_nonzero_impls { $( #[allow(unreachable_patterns)] #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] - impl Step for NonZero<$narrower> { + #[rustc_const_unstable(feature = "step_trait", issue = "42168")] + impl const Step for NonZero<$narrower> { step_nonzero_identical_methods!($narrower); #[inline] @@ -538,7 +539,8 @@ fn backward_checked(start: Self, n: usize) -> Option { $( #[allow(unreachable_patterns)] #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] - impl Step for NonZero<$wider> { + #[rustc_const_unstable(feature = "step_trait", issue = "42168")] + impl const Step for NonZero<$wider> { step_nonzero_identical_methods!($wider); #[inline] diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 3415e1d435ce..c270b947d4fd 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -184,7 +184,8 @@ impl $Trait for NonZero where T: ZeroablePrimitive + $Trait {} impl_nonzero_auto_trait!(UnwindSafe); #[stable(feature = "nonzero", since = "1.28.0")] -impl Clone for NonZero +#[rustc_const_unstable(feature = "const_clone", issue = "142757")] +impl const Clone for NonZero where T: ZeroablePrimitive, { @@ -202,7 +203,8 @@ impl Copy for NonZero where T: ZeroablePrimitive {} #[doc(hidden)] #[unstable(feature = "trivial_clone", issue = "none")] -unsafe impl TrivialClone for NonZero where T: ZeroablePrimitive {} +#[rustc_const_unstable(feature = "const_clone", issue = "142757")] +unsafe impl const TrivialClone for NonZero where T: ZeroablePrimitive {} #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] From 92426ef48211cd757fff5e6912532a80de14b985 Mon Sep 17 00:00:00 2001 From: "U. Lasiotus" Date: Sat, 4 Apr 2026 18:53:09 -0700 Subject: [PATCH 12/37] library: std: motor: use OS' process::exit in abort_internal abort_internal() is used in panics; if it calls core::intrinsics::abort(), the process triggers an invalid op code (on x86_64), which is a much harder "abort" than a user-controlled exit via a panic. Most other OSes don't use core::intrinsics::abort() here, but either libc::abort(), or a native OS abort/exit API. --- library/std/src/sys/pal/motor/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/motor/mod.rs b/library/std/src/sys/pal/motor/mod.rs index 705413cbe0a7..ac10d81ecfb8 100644 --- a/library/std/src/sys/pal/motor/mod.rs +++ b/library/std/src/sys/pal/motor/mod.rs @@ -42,5 +42,5 @@ pub fn unsupported_err() -> io::Error { } pub fn abort_internal() -> ! { - core::intrinsics::abort(); + moto_rt::process::exit(-1) } From c324d6e1414f7f08b37a3377524b74cc8d56fa2c Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 3 Apr 2026 22:57:29 +0200 Subject: [PATCH 13/37] Simplify attribute validation --- .../rustc_attr_parsing/src/validate_attr.rs | 45 +++++-------------- 1 file changed, 12 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index f56e85b11061..ed1d1a81f7a5 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -1,7 +1,6 @@ //! Meta-syntax validation logic of attributes for post-expansion. use std::convert::identity; -use std::slice; use rustc_ast::token::Delimiter; use rustc_ast::tokenstream::DelimSpan; @@ -9,7 +8,7 @@ self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, Safety, }; use rustc_errors::{Applicability, FatalError, PResult}; -use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute}; +use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir::AttrPath; use rustc_hir::lints::AttributeLintKind; use rustc_parse::parse_in; @@ -19,43 +18,23 @@ use rustc_session::parse::ParseSess; use rustc_span::{Span, Symbol, sym}; -use crate::{AttributeParser, Late, session_diagnostics as errors}; +use crate::session_diagnostics as errors; pub fn check_attr(psess: &ParseSess, attr: &Attribute) { - if attr.is_doc_comment() || attr.has_name(sym::cfg_trace) || attr.has_name(sym::cfg_attr_trace) + // Built-in attributes are parsed in their respective attribute parsers, so can be ignored here + if attr.is_doc_comment() + || attr.name().is_some_and(|name| BUILTIN_ATTRIBUTE_MAP.contains_key(&name)) { return; } - let builtin_attr_info = attr.name().and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name)); - - // Check input tokens for built-in and key-value attributes. - match builtin_attr_info { - // `rustc_dummy` doesn't have any restrictions specific to built-in attributes. - Some(BuiltinAttribute { name, template, .. }) => { - if AttributeParser::::is_parsed_attribute(slice::from_ref(&name)) { - return; - } - match parse_meta(psess, attr) { - // Don't check safety again, we just did that - Ok(meta) => { - check_builtin_meta_item(psess, &meta, attr.style, *name, *template, false) - } - Err(err) => { - err.emit(); - } - } - } - _ => { - let attr_item = attr.get_normal_item(); - if let AttrArgs::Eq { .. } = attr_item.args.unparsed_ref().unwrap() { - // All key-value attributes are restricted to meta-item syntax. - match parse_meta(psess, attr) { - Ok(_) => {} - Err(err) => { - err.emit(); - } - } + let attr_item = attr.get_normal_item(); + if let AttrArgs::Eq { .. } = attr_item.args.unparsed_ref().unwrap() { + // All key-value attributes are restricted to meta-item syntax. + match parse_meta(psess, attr) { + Ok(_) => {} + Err(err) => { + err.emit(); } } } From abb15f5a636496a0f74be42ef1990ddaebc960a7 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 4 Apr 2026 13:15:57 +0200 Subject: [PATCH 14/37] Remove `emit_fatal_malformed_builtin_attribute` --- compiler/rustc_attr_parsing/src/validate_attr.rs | 16 ++-------------- compiler/rustc_expand/src/module.rs | 11 ++++++++--- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index ed1d1a81f7a5..f5c241a1f0e9 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -7,7 +7,7 @@ use rustc_ast::{ self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, Safety, }; -use rustc_errors::{Applicability, FatalError, PResult}; +use rustc_errors::{Applicability, PResult}; use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir::AttrPath; use rustc_hir::lints::AttributeLintKind; @@ -149,7 +149,7 @@ pub fn check_builtin_meta_item( } } -fn emit_malformed_attribute( +pub fn emit_malformed_attribute( psess: &ParseSess, style: ast::AttrStyle, span: Span, @@ -210,15 +210,3 @@ fn emit_malformed_attribute( err.emit(); } } - -pub fn emit_fatal_malformed_builtin_attribute( - psess: &ParseSess, - attr: &Attribute, - name: Symbol, -) -> ! { - let template = BUILTIN_ATTRIBUTE_MAP.get(&name).expect("builtin attr defined").template; - emit_malformed_attribute(psess, attr.style, attr.span, name, template); - // This is fatal, otherwise it will likely cause a cascade of other errors - // (and an error here is expected to be very rare). - FatalError.raise() -} diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index 79ab3cab22ce..0c2595a6de5f 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -2,7 +2,6 @@ use std::path::{self, Path, PathBuf}; use rustc_ast::{AttrVec, Attribute, Inline, Item, ModSpans}; -use rustc_attr_parsing::validate_attr; use rustc_errors::{Diag, ErrorGuaranteed}; use rustc_parse::lexer::StripTokens; use rustc_parse::{exp, new_parser_from_file, unwrap_or_emit_fatal}; @@ -10,7 +9,9 @@ use rustc_session::parse::ParseSess; use rustc_span::{Ident, Span, sym}; use thin_vec::ThinVec; - +use rustc_attr_parsing::validate_attr::emit_malformed_attribute; +use rustc_feature::template; +use rustc_span::fatal_error::FatalError; use crate::base::ModuleData; use crate::errors::{ ModuleCircular, ModuleFileNotFound, ModuleInBlock, ModuleInBlockName, ModuleMultipleCandidates, @@ -195,7 +196,11 @@ pub(crate) fn mod_file_path_from_attr( // Usually bad forms are checked during semantic analysis via // `TyCtxt::check_mod_attrs`), but by the time that runs the macro // is expanded, and it doesn't give an error. - validate_attr::emit_fatal_malformed_builtin_attribute(&sess.psess, first_path, sym::path); + emit_malformed_attribute(&sess.psess, first_path.style, first_path.span, sym::path, template!( + NameValueStr: "file", + "https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute" + )); + FatalError.raise() }; let path_str = path_sym.as_str(); From cb87c36bd97f1cc8ba9c90e84746ea912eab6ace Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 4 Apr 2026 13:24:24 +0200 Subject: [PATCH 15/37] Remove template from BUILTIN_ATTRIBUTES --- compiler/rustc_expand/src/module.rs | 21 +- compiler/rustc_feature/src/builtin_attrs.rs | 470 +++++++------------- 2 files changed, 163 insertions(+), 328 deletions(-) diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index 0c2595a6de5f..6f0ecfb1cf1c 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -2,16 +2,17 @@ use std::path::{self, Path, PathBuf}; use rustc_ast::{AttrVec, Attribute, Inline, Item, ModSpans}; +use rustc_attr_parsing::validate_attr::emit_malformed_attribute; use rustc_errors::{Diag, ErrorGuaranteed}; +use rustc_feature::template; use rustc_parse::lexer::StripTokens; use rustc_parse::{exp, new_parser_from_file, unwrap_or_emit_fatal}; use rustc_session::Session; use rustc_session::parse::ParseSess; +use rustc_span::fatal_error::FatalError; use rustc_span::{Ident, Span, sym}; use thin_vec::ThinVec; -use rustc_attr_parsing::validate_attr::emit_malformed_attribute; -use rustc_feature::template; -use rustc_span::fatal_error::FatalError; + use crate::base::ModuleData; use crate::errors::{ ModuleCircular, ModuleFileNotFound, ModuleInBlock, ModuleInBlockName, ModuleMultipleCandidates, @@ -196,10 +197,16 @@ pub(crate) fn mod_file_path_from_attr( // Usually bad forms are checked during semantic analysis via // `TyCtxt::check_mod_attrs`), but by the time that runs the macro // is expanded, and it doesn't give an error. - emit_malformed_attribute(&sess.psess, first_path.style, first_path.span, sym::path, template!( - NameValueStr: "file", - "https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute" - )); + emit_malformed_attribute( + &sess.psess, + first_path.style, + first_path.span, + sym::path, + template!( + NameValueStr: "file", + "https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute" + ), + ); FatalError.raise() }; diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index acbcba90fbcc..675a817890cb 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -78,7 +78,6 @@ pub enum AttributeType { /// Normal, builtin attribute that is consumed /// by the compiler before the unused_attribute check Normal, - /// Builtin attribute that is only allowed at the crate level CrateLevel, } @@ -87,7 +86,6 @@ pub enum AttributeType { pub enum AttributeSafety { /// Normal attribute that does not need `#[unsafe(...)]` Normal, - /// Unsafe attribute that requires safety obligations to be discharged. /// /// An error is emitted when `#[unsafe(...)]` is omitted, except when the attribute's edition @@ -268,35 +266,32 @@ macro_rules! template { } macro_rules! ungated { - (unsafe($edition:ident) $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { + (unsafe($edition:ident) $attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: Some(Edition::$edition) }, - template: $tpl, gate: Ungated, duplicates: $duplicates, } }; - (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { + (unsafe $attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: None }, - template: $tpl, gate: Ungated, duplicates: $duplicates, } }; - ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { + ($attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Normal, - template: $tpl, gate: Ungated, duplicates: $duplicates, } @@ -304,13 +299,12 @@ macro_rules! ungated { } macro_rules! gated { - (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $message:expr $(,)?) => { + (unsafe $attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: None }, - template: $tpl, duplicates: $duplicates, gate: Gated { feature: sym::$gate, @@ -320,13 +314,12 @@ macro_rules! gated { }, } }; - (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $message:expr $(,)?) => { + (unsafe $attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: None }, - template: $tpl, duplicates: $duplicates, gate: Gated { feature: sym::$attr, @@ -336,13 +329,12 @@ macro_rules! gated { }, } }; - ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $message:expr $(,)?) => { + ($attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Normal, - template: $tpl, duplicates: $duplicates, gate: Gated { feature: sym::$gate, @@ -352,13 +344,12 @@ macro_rules! gated { }, } }; - ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $message:expr $(,)?) => { + ($attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Normal, - template: $tpl, duplicates: $duplicates, gate: Gated { feature: sym::$attr, @@ -371,11 +362,10 @@ macro_rules! gated { } macro_rules! rustc_attr { - (TEST, $attr:ident, $typ:expr, $tpl:expr, $duplicate:expr, $encode_cross_crate:expr $(,)?) => { + (TEST, $attr:ident, $typ:expr, $duplicate:expr, $encode_cross_crate:expr $(,)?) => { rustc_attr!( $attr, $typ, - $tpl, $duplicate, $encode_cross_crate, concat!( @@ -385,13 +375,12 @@ macro_rules! rustc_attr { ), ) }; - ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $($notes:expr),* $(,)?) => { + ($attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr, $($notes:expr),* $(,)?) => { BuiltinAttribute { name: sym::$attr, encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Normal, - template: $tpl, duplicates: $duplicates, gate: Gated { feature: sym::rustc_attrs, @@ -423,7 +412,6 @@ pub struct BuiltinAttribute { pub encode_cross_crate: EncodeCrossCrate, pub type_: AttributeType, pub safety: AttributeSafety, - pub template: AttributeTemplate, pub duplicates: AttributeDuplicates, pub gate: AttributeGate, } @@ -438,240 +426,141 @@ pub struct BuiltinAttribute { // Conditional compilation: ungated!( cfg, Normal, - template!( - List: &["predicate"], - "https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute" - ), DuplicatesOk, EncodeCrossCrate::No ), ungated!( cfg_attr, Normal, - template!( - List: &["predicate, attr1, attr2, ..."], - "https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute" - ), DuplicatesOk, EncodeCrossCrate::No ), // Testing: ungated!( ignore, Normal, - template!( - Word, - NameValueStr: "reason", - "https://doc.rust-lang.org/reference/attributes/testing.html#the-ignore-attribute" - ), WarnFollowing, EncodeCrossCrate::No, ), ungated!( should_panic, Normal, - template!( - Word, - List: &[r#"expected = "reason""#], - NameValueStr: "reason", - "https://doc.rust-lang.org/reference/attributes/testing.html#the-should_panic-attribute" - ), FutureWarnFollowing, EncodeCrossCrate::No, ), // Macros: ungated!( automatically_derived, Normal, - template!( - Word, - "https://doc.rust-lang.org/reference/attributes/derive.html#the-automatically_derived-attribute" - ), WarnFollowing, EncodeCrossCrate::Yes ), ungated!( macro_use, Normal, - template!( - Word, - List: &["name1, name2, ..."], - "https://doc.rust-lang.org/reference/macros-by-example.html#the-macro_use-attribute" - ), WarnFollowingWordOnly, EncodeCrossCrate::No, ), - ungated!(macro_escape, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), // Deprecated synonym for `macro_use`. + ungated!(macro_escape, Normal, WarnFollowing, EncodeCrossCrate::No), // Deprecated synonym for `macro_use`. ungated!( macro_export, Normal, - template!( - Word, - List: &["local_inner_macros"], - "https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope" - ), WarnFollowing, EncodeCrossCrate::Yes ), ungated!( proc_macro, Normal, - template!( - Word, - "https://doc.rust-lang.org/reference/procedural-macros.html#function-like-procedural-macros"), ErrorFollowing, EncodeCrossCrate::No ), ungated!( proc_macro_derive, Normal, - template!( - List: &["TraitName", "TraitName, attributes(name1, name2, ...)"], - "https://doc.rust-lang.org/reference/procedural-macros.html#derive-macros" - ), ErrorFollowing, EncodeCrossCrate::No, ), ungated!( proc_macro_attribute, Normal, - template!(Word, "https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros"), ErrorFollowing, EncodeCrossCrate::No ), // Lints: ungated!( warn, Normal, - template!( - List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#], - "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes" - ), DuplicatesOk, EncodeCrossCrate::No, ), ungated!( allow, Normal, - template!( - List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#], - "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes" - ), DuplicatesOk, EncodeCrossCrate::No, ), ungated!( expect, Normal, - template!( - List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#], - "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes" - ), DuplicatesOk, EncodeCrossCrate::No, ), ungated!( forbid, Normal, - template!( - List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#], - "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes" - ), DuplicatesOk, EncodeCrossCrate::No ), ungated!( deny, Normal, - template!( - List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#], - "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes" - ), DuplicatesOk, EncodeCrossCrate::No ), ungated!( must_use, Normal, - template!( - Word, - NameValueStr: "reason", - "https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute" - ), FutureWarnFollowing, EncodeCrossCrate::Yes ), gated!( - must_not_suspend, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, + must_not_suspend, Normal, WarnFollowing, EncodeCrossCrate::Yes, experimental!(must_not_suspend) ), ungated!( deprecated, Normal, - template!( - Word, - List: &[r#"/*opt*/ since = "version", /*opt*/ note = "reason""#], - NameValueStr: "reason", - "https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute" - ), ErrorFollowing, EncodeCrossCrate::Yes ), // Crate properties: ungated!( crate_name, CrateLevel, - template!( - NameValueStr: "name", - "https://doc.rust-lang.org/reference/crates-and-source-files.html#the-crate_name-attribute" - ), FutureWarnFollowing, EncodeCrossCrate::No, ), ungated!( crate_type, CrateLevel, - template!( - NameValueStr: ["bin", "lib", "dylib", "cdylib", "rlib", "staticlib", "sdylib", "proc-macro"], - "https://doc.rust-lang.org/reference/linkage.html" - ), DuplicatesOk, EncodeCrossCrate::No, ), // ABI, linking, symbols, and FFI ungated!( link, Normal, - template!(List: &[ - r#"name = "...""#, - r#"name = "...", kind = "dylib|static|...""#, - r#"name = "...", wasm_import_module = "...""#, - r#"name = "...", import_name_type = "decorated|noprefix|undecorated""#, - r#"name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated""#, - ], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute"), DuplicatesOk, EncodeCrossCrate::No, ), ungated!( link_name, Normal, - template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_name-attribute"), FutureWarnPreceding, EncodeCrossCrate::Yes ), ungated!( no_link, Normal, - template!(Word, "https://doc.rust-lang.org/reference/items/extern-crates.html#the-no_link-attribute"), WarnFollowing, EncodeCrossCrate::No ), ungated!( repr, Normal, - template!( - List: &["C", "Rust", "transparent", "align(...)", "packed(...)", ""], - "https://doc.rust-lang.org/reference/type-layout.html#representations" - ), DuplicatesOk, EncodeCrossCrate::No ), // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity - gated!(rustc_align, Normal, template!(List: &["alignment"]), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(rustc_align)), - gated!(rustc_align_static, Normal, template!(List: &["alignment"]), DuplicatesOk, EncodeCrossCrate::No, static_align, experimental!(rustc_align_static)), + gated!(rustc_align, Normal, DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(rustc_align)), + gated!(rustc_align_static, Normal, DuplicatesOk, EncodeCrossCrate::No, static_align, experimental!(rustc_align_static)), ungated!( unsafe(Edition2024) export_name, Normal, - template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute"), FutureWarnPreceding, EncodeCrossCrate::No ), ungated!( unsafe(Edition2024) link_section, Normal, - template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute"), FutureWarnPreceding, EncodeCrossCrate::No ), ungated!( unsafe(Edition2024) no_mangle, Normal, - template!(Word, "https://doc.rust-lang.org/reference/abi.html#the-no_mangle-attribute"), WarnFollowing, EncodeCrossCrate::No ), ungated!( used, Normal, - template!(Word, List: &["compiler", "linker"], "https://doc.rust-lang.org/reference/abi.html#the-used-attribute"), WarnFollowing, EncodeCrossCrate::No ), ungated!( link_ordinal, Normal, - template!(List: &["ordinal"], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_ordinal-attribute"), ErrorPreceding, EncodeCrossCrate::Yes ), ungated!( unsafe naked, Normal, - template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-naked-attribute"), WarnFollowing, EncodeCrossCrate::No ), // See `TyAndLayout::pass_indirectly_in_non_rustic_abis` for details. rustc_attr!( - rustc_pass_indirectly_in_non_rustic_abis, Normal, template!(Word), ErrorFollowing, + rustc_pass_indirectly_in_non_rustic_abis, Normal, ErrorFollowing, EncodeCrossCrate::No, "types marked with `#[rustc_pass_indirectly_in_non_rustic_abis]` are always passed indirectly by non-Rustic ABIs" ), @@ -679,134 +568,102 @@ pub struct BuiltinAttribute { // Limits: ungated!( recursion_limit, CrateLevel, - template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute"), FutureWarnFollowing, EncodeCrossCrate::No ), ungated!( type_length_limit, CrateLevel, - template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-type_length_limit-attribute"), FutureWarnFollowing, EncodeCrossCrate::No ), gated!( - move_size_limit, CrateLevel, template!(NameValueStr: "N"), ErrorFollowing, + move_size_limit, CrateLevel, ErrorFollowing, EncodeCrossCrate::No, large_assignments, experimental!(move_size_limit) ), // Entry point: ungated!( no_main, CrateLevel, - template!(Word, "https://doc.rust-lang.org/reference/crates-and-source-files.html#the-no_main-attribute"), WarnFollowing, EncodeCrossCrate::No ), // Modules, prelude, and resolution: ungated!( path, Normal, - template!(NameValueStr: "file", "https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute"), FutureWarnFollowing, EncodeCrossCrate::No ), ungated!( no_std, CrateLevel, - template!(Word, "https://doc.rust-lang.org/reference/names/preludes.html#the-no_std-attribute"), WarnFollowing, EncodeCrossCrate::No ), ungated!( no_implicit_prelude, Normal, - template!(Word, "https://doc.rust-lang.org/reference/names/preludes.html#the-no_implicit_prelude-attribute"), WarnFollowing, EncodeCrossCrate::No ), ungated!( non_exhaustive, Normal, - template!(Word, "https://doc.rust-lang.org/reference/attributes/type_system.html#the-non_exhaustive-attribute"), WarnFollowing, EncodeCrossCrate::Yes ), // Runtime ungated!( windows_subsystem, CrateLevel, - template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute"), FutureWarnFollowing, EncodeCrossCrate::No ), ungated!( // RFC 2070 panic_handler, Normal, - template!(Word, "https://doc.rust-lang.org/reference/panic.html#the-panic_handler-attribute"), WarnFollowing, EncodeCrossCrate::Yes ), // Code generation: ungated!( inline, Normal, - template!( - Word, - List: &["always", "never"], - "https://doc.rust-lang.org/reference/attributes/codegen.html#the-inline-attribute" - ), FutureWarnFollowing, EncodeCrossCrate::No ), ungated!( cold, Normal, - template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-cold-attribute"), WarnFollowing, EncodeCrossCrate::No ), ungated!( no_builtins, CrateLevel, - template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-no_builtins-attribute"), WarnFollowing, EncodeCrossCrate::Yes ), ungated!( target_feature, Normal, - template!(List: &[r#"enable = "name""#], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-target_feature-attribute"), DuplicatesOk, EncodeCrossCrate::No, ), ungated!( track_caller, Normal, - template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-track_caller-attribute"), WarnFollowing, EncodeCrossCrate::Yes ), ungated!( instruction_set, Normal, - template!(List: &["set"], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute"), ErrorPreceding, EncodeCrossCrate::No ), gated!( - unsafe force_target_feature, Normal, template!(List: &[r#"enable = "name""#]), + unsafe force_target_feature, Normal, DuplicatesOk, EncodeCrossCrate::No, effective_target_features, experimental!(force_target_feature) ), gated!( - sanitize, Normal, template!(List: &[r#"address = "on|off""#, r#"kernel_address = "on|off""#, r#"cfi = "on|off""#, r#"hwaddress = "on|off""#, r#"kernel_hwaddress = "on|off""#, r#"kcfi = "on|off""#, r#"memory = "on|off""#, r#"memtag = "on|off""#, r#"shadow_call_stack = "on|off""#, r#"thread = "on|off""#]), ErrorPreceding, + sanitize, Normal, ErrorPreceding, EncodeCrossCrate::No, sanitize, experimental!(sanitize), ), gated!( - coverage, Normal, template!(OneOf: &[sym::off, sym::on]), + coverage, Normal, ErrorPreceding, EncodeCrossCrate::No, coverage_attribute, experimental!(coverage) ), ungated!( doc, Normal, - template!( - List: &["hidden", "inline"], - NameValueStr: "string", - "https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html" - ), DuplicatesOk, EncodeCrossCrate::Yes ), // Debugging ungated!( debugger_visualizer, Normal, - template!( - List: &[r#"natvis_file = "...", gdb_script_file = "...""#], - "https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute" - ), DuplicatesOk, EncodeCrossCrate::No ), ungated!( collapse_debuginfo, Normal, - template!( - List: &["no", "external", "yes"], - "https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute" - ), ErrorFollowing, EncodeCrossCrate::Yes ), @@ -816,70 +673,70 @@ pub struct BuiltinAttribute { // Linking: gated!( - export_stable, Normal, template!(Word), WarnFollowing, + export_stable, Normal, WarnFollowing, EncodeCrossCrate::No, experimental!(export_stable) ), // Testing: gated!( - test_runner, CrateLevel, template!(List: &["path"]), ErrorFollowing, + test_runner, CrateLevel, ErrorFollowing, EncodeCrossCrate::Yes, custom_test_frameworks, "custom test frameworks are an unstable feature", ), gated!( - reexport_test_harness_main, CrateLevel, template!(NameValueStr: "name"), ErrorFollowing, + reexport_test_harness_main, CrateLevel, ErrorFollowing, EncodeCrossCrate::No, custom_test_frameworks, "custom test frameworks are an unstable feature", ), // RFC #1268 gated!( - marker, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, + marker, Normal, WarnFollowing, EncodeCrossCrate::No, marker_trait_attr, experimental!(marker) ), gated!( - thread_local, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, + thread_local, Normal, WarnFollowing, EncodeCrossCrate::No, "`#[thread_local]` is an experimental feature, and does not currently handle destructors", ), gated!( - no_core, CrateLevel, template!(Word), WarnFollowing, + no_core, CrateLevel, WarnFollowing, EncodeCrossCrate::No, experimental!(no_core) ), // RFC 2412 gated!( - optimize, Normal, template!(List: &["none", "size", "speed"]), ErrorPreceding, + optimize, Normal, ErrorPreceding, EncodeCrossCrate::No, optimize_attribute, experimental!(optimize) ), gated!( - unsafe ffi_pure, Normal, template!(Word), WarnFollowing, + unsafe ffi_pure, Normal, WarnFollowing, EncodeCrossCrate::No, experimental!(ffi_pure) ), gated!( - unsafe ffi_const, Normal, template!(Word), WarnFollowing, + unsafe ffi_const, Normal, WarnFollowing, EncodeCrossCrate::No, experimental!(ffi_const) ), gated!( - register_tool, CrateLevel, template!(List: &["tool1, tool2, ..."]), DuplicatesOk, + register_tool, CrateLevel, DuplicatesOk, EncodeCrossCrate::No, experimental!(register_tool), ), // `#[cfi_encoding = ""]` gated!( - cfi_encoding, Normal, template!(NameValueStr: "encoding"), ErrorPreceding, + cfi_encoding, Normal, ErrorPreceding, EncodeCrossCrate::Yes, experimental!(cfi_encoding) ), // `#[coroutine]` attribute to be applied to closures to make them coroutines instead gated!( - coroutine, Normal, template!(Word), ErrorFollowing, + coroutine, Normal, ErrorFollowing, EncodeCrossCrate::No, coroutines, experimental!(coroutine) ), // RFC 3543 // `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` gated!( - patchable_function_entry, Normal, template!(List: &["prefix_nops = m, entry_nops = n"]), ErrorPreceding, + patchable_function_entry, Normal, ErrorPreceding, EncodeCrossCrate::Yes, experimental!(patchable_function_entry) ), @@ -888,11 +745,11 @@ pub struct BuiltinAttribute { // // - https://github.com/rust-lang/rust/issues/132306 gated!( - const_continue, Normal, template!(Word), ErrorFollowing, + const_continue, Normal, ErrorFollowing, EncodeCrossCrate::No, loop_match, experimental!(const_continue) ), gated!( - loop_match, Normal, template!(Word), ErrorFollowing, + loop_match, Normal, ErrorFollowing, EncodeCrossCrate::No, loop_match, experimental!(loop_match) ), @@ -901,7 +758,7 @@ pub struct BuiltinAttribute { // // - https://github.com/rust-lang/rust/issues/130494 gated!( - pin_v2, Normal, template!(Word), ErrorFollowing, + pin_v2, Normal, ErrorFollowing, EncodeCrossCrate::Yes, pin_ergonomics, experimental!(pin_v2), ), @@ -911,62 +768,61 @@ pub struct BuiltinAttribute { ungated!( feature, CrateLevel, - template!(List: &["name1, name2, ..."]), DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, EncodeCrossCrate::No, ), // DuplicatesOk since it has its own validation ungated!( stable, Normal, - template!(List: &[r#"feature = "name", since = "version""#]), DuplicatesOk, EncodeCrossCrate::No, - ), - ungated!( - unstable, Normal, - template!(List: &[r#"feature = "name", reason = "...", issue = "N""#]), DuplicatesOk, - EncodeCrossCrate::Yes - ), - ungated!( - unstable_feature_bound, Normal, template!(Word, List: &["feat1, feat2, ..."]), DuplicatesOk, EncodeCrossCrate::No, ), ungated!( - rustc_const_unstable, Normal, template!(List: &[r#"feature = "name""#]), + unstable, Normal, + DuplicatesOk, + EncodeCrossCrate::Yes + ), + ungated!( + unstable_feature_bound, Normal, + DuplicatesOk, EncodeCrossCrate::No, + ), + ungated!( + rustc_const_unstable, Normal, DuplicatesOk, EncodeCrossCrate::Yes ), ungated!( rustc_const_stable, Normal, - template!(List: &[r#"feature = "name""#]), DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, EncodeCrossCrate::No, ), ungated!( rustc_default_body_unstable, Normal, - template!(List: &[r#"feature = "name", reason = "...", issue = "N""#]), DuplicatesOk, EncodeCrossCrate::No ), gated!( - allow_internal_unstable, Normal, template!(Word, List: &["feat1, feat2, ..."]), + allow_internal_unstable, Normal, DuplicatesOk, EncodeCrossCrate::Yes, "allow_internal_unstable side-steps feature gating and stability checks", ), gated!( - allow_internal_unsafe, Normal, template!(Word), WarnFollowing, + allow_internal_unsafe, Normal, WarnFollowing, EncodeCrossCrate::No, "allow_internal_unsafe side-steps the unsafe_code lint", ), gated!( - rustc_eii_foreign_item, Normal, template!(Word), + rustc_eii_foreign_item, Normal, ErrorFollowing, EncodeCrossCrate::Yes, eii_internals, "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", ), rustc_attr!( - rustc_allowed_through_unstable_modules, Normal, template!(NameValueStr: "deprecation message"), + rustc_allowed_through_unstable_modules, Normal, WarnFollowing, EncodeCrossCrate::No, "rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \ through unstable paths" ), rustc_attr!( - rustc_deprecated_safe_2024, Normal, template!(List: &[r#"audit_that = "...""#]), + rustc_deprecated_safe_2024, Normal, ErrorFollowing, EncodeCrossCrate::Yes, "`#[rustc_deprecated_safe_2024]` is used to declare functions unsafe across the edition 2024 boundary", ), rustc_attr!( - rustc_pub_transparent, Normal, template!(Word), + rustc_pub_transparent, Normal, ErrorFollowing, EncodeCrossCrate::Yes, "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", ), @@ -976,9 +832,9 @@ pub struct BuiltinAttribute { // Internal attributes: Type system related: // ========================================================================== - gated!(fundamental, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, experimental!(fundamental)), + gated!(fundamental, Normal, WarnFollowing, EncodeCrossCrate::Yes, experimental!(fundamental)), gated!( - may_dangle, Normal, template!(Word), WarnFollowing, + may_dangle, Normal, WarnFollowing, EncodeCrossCrate::No, dropck_eyepatch, "`may_dangle` has unstable semantics and may be removed in the future", ), @@ -986,13 +842,6 @@ pub struct BuiltinAttribute { rustc_attr!( rustc_never_type_options, Normal, - template!(List: &[ - "", - r#"fallback = "unit""#, - r#"fallback = "niko""#, - r#"fallback = "never""#, - r#"fallback = "no""#, - ]), ErrorFollowing, EncodeCrossCrate::No, "`rustc_never_type_options` is used to experiment with never type fallback and work on \ @@ -1004,53 +853,53 @@ pub struct BuiltinAttribute { // ========================================================================== rustc_attr!( - rustc_allocator, Normal, template!(Word), WarnFollowing, + rustc_allocator, Normal, WarnFollowing, EncodeCrossCrate::No, ), rustc_attr!( - rustc_nounwind, Normal, template!(Word), WarnFollowing, + rustc_nounwind, Normal, WarnFollowing, EncodeCrossCrate::No, ), rustc_attr!( - rustc_reallocator, Normal, template!(Word), WarnFollowing, + rustc_reallocator, Normal, WarnFollowing, EncodeCrossCrate::No, ), rustc_attr!( - rustc_deallocator, Normal, template!(Word), WarnFollowing, + rustc_deallocator, Normal, WarnFollowing, EncodeCrossCrate::No, ), rustc_attr!( - rustc_allocator_zeroed, Normal, template!(Word), WarnFollowing, + rustc_allocator_zeroed, Normal, WarnFollowing, EncodeCrossCrate::No, ), rustc_attr!( - rustc_allocator_zeroed_variant, Normal, template!(NameValueStr: "function"), ErrorPreceding, + rustc_allocator_zeroed_variant, Normal, ErrorPreceding, EncodeCrossCrate::Yes, ), gated!( - default_lib_allocator, Normal, template!(Word), WarnFollowing, + default_lib_allocator, Normal, WarnFollowing, EncodeCrossCrate::No, allocator_internals, experimental!(default_lib_allocator), ), gated!( - needs_allocator, Normal, template!(Word), WarnFollowing, + needs_allocator, Normal, WarnFollowing, EncodeCrossCrate::No, allocator_internals, experimental!(needs_allocator), ), gated!( - panic_runtime, CrateLevel, template!(Word), WarnFollowing, + panic_runtime, CrateLevel, WarnFollowing, EncodeCrossCrate::No, experimental!(panic_runtime) ), gated!( - needs_panic_runtime, CrateLevel, template!(Word), WarnFollowing, + needs_panic_runtime, CrateLevel, WarnFollowing, EncodeCrossCrate::No, experimental!(needs_panic_runtime) ), gated!( - compiler_builtins, CrateLevel, template!(Word), WarnFollowing, + compiler_builtins, CrateLevel, WarnFollowing, EncodeCrossCrate::No, "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \ which contains compiler-rt intrinsics and will never be stable", ), gated!( - profiler_runtime, CrateLevel, template!(Word), WarnFollowing, + profiler_runtime, CrateLevel, WarnFollowing, EncodeCrossCrate::No, "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \ which contains the profiler runtime and will never be stable", @@ -1061,30 +910,20 @@ pub struct BuiltinAttribute { // ========================================================================== gated!( - linkage, Normal, template!(NameValueStr: [ - "available_externally", - "common", - "extern_weak", - "external", - "internal", - "linkonce", - "linkonce_odr", - "weak", - "weak_odr", - ], "https://doc.rust-lang.org/reference/linkage.html"), + linkage, Normal, ErrorPreceding, EncodeCrossCrate::No, "the `linkage` attribute is experimental and not portable across platforms", ), rustc_attr!( - rustc_std_internal_symbol, Normal, template!(Word), WarnFollowing, + rustc_std_internal_symbol, Normal, WarnFollowing, EncodeCrossCrate::No, ), rustc_attr!( - rustc_objc_class, Normal, template!(NameValueStr: "ClassName"), ErrorPreceding, + rustc_objc_class, Normal, ErrorPreceding, EncodeCrossCrate::No, ), rustc_attr!( - rustc_objc_selector, Normal, template!(NameValueStr: "methodName"), ErrorPreceding, + rustc_objc_selector, Normal, ErrorPreceding, EncodeCrossCrate::No, ), @@ -1094,26 +933,26 @@ pub struct BuiltinAttribute { rustc_attr!( rustc_builtin_macro, Normal, - template!(Word, List: &["name", "name, /*opt*/ attributes(name1, name2, ...)"]), ErrorFollowing, + ErrorFollowing, EncodeCrossCrate::Yes, ), rustc_attr!( - rustc_proc_macro_decls, Normal, template!(Word), WarnFollowing, + rustc_proc_macro_decls, Normal, WarnFollowing, EncodeCrossCrate::No, ), rustc_attr!( rustc_macro_transparency, Normal, - template!(NameValueStr: ["transparent", "semiopaque", "opaque"]), ErrorFollowing, + ErrorFollowing, EncodeCrossCrate::Yes, "used internally for testing macro hygiene", ), rustc_attr!( rustc_autodiff, Normal, - template!(Word, List: &[r#""...""#]), DuplicatesOk, + DuplicatesOk, EncodeCrossCrate::Yes, ), rustc_attr!( rustc_offload_kernel, Normal, - template!(Word), DuplicatesOk, + DuplicatesOk, EncodeCrossCrate::Yes, ), // Traces that are left when `cfg` and `cfg_attr` attributes are expanded. @@ -1121,11 +960,11 @@ pub struct BuiltinAttribute { // or unstable code directly because `sym::cfg_(attr_)trace` are not valid identifiers, they // can only be generated by the compiler. ungated!( - cfg_trace, Normal, template!(Word /* irrelevant */), DuplicatesOk, + cfg_trace, Normal, DuplicatesOk, EncodeCrossCrate::Yes ), ungated!( - cfg_attr_trace, Normal, template!(Word /* irrelevant */), DuplicatesOk, + cfg_attr_trace, Normal, DuplicatesOk, EncodeCrossCrate::No ), @@ -1135,51 +974,46 @@ pub struct BuiltinAttribute { rustc_attr!( rustc_on_unimplemented, Normal, - template!( - List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#], - NameValueStr: "message" - ), ErrorFollowing, EncodeCrossCrate::Yes, "see `#[diagnostic::on_unimplemented]` for the stable equivalent of this attribute" ), rustc_attr!( rustc_confusables, Normal, - template!(List: &[r#""name1", "name2", ..."#]), ErrorFollowing, EncodeCrossCrate::Yes, ), // Enumerates "identity-like" conversion methods to suggest on type mismatch. rustc_attr!( - rustc_conversion_suggestion, Normal, template!(Word), + rustc_conversion_suggestion, Normal, WarnFollowing, EncodeCrossCrate::Yes, ), // Prevents field reads in the marked trait or method to be considered // during dead code analysis. rustc_attr!( - rustc_trivial_field_reads, Normal, template!(Word), + rustc_trivial_field_reads, Normal, WarnFollowing, EncodeCrossCrate::Yes, ), // Used by the `rustc::potential_query_instability` lint to warn methods which // might not be stable during incremental compilation. rustc_attr!( - rustc_lint_query_instability, Normal, template!(Word), + rustc_lint_query_instability, Normal, WarnFollowing, EncodeCrossCrate::Yes, ), // Used by the `rustc::untracked_query_information` lint to warn methods which // might not be stable during incremental compilation. rustc_attr!( - rustc_lint_untracked_query_information, Normal, template!(Word), + rustc_lint_untracked_query_information, Normal, WarnFollowing, EncodeCrossCrate::Yes, ), // Used by the `rustc::bad_opt_access` lint to identify `DebuggingOptions` and `CodegenOptions` // types (as well as any others in future). rustc_attr!( - rustc_lint_opt_ty, Normal, template!(Word), + rustc_lint_opt_ty, Normal, WarnFollowing, EncodeCrossCrate::Yes, ), // Used by the `rustc::bad_opt_access` lint on fields // types (as well as any others in future). rustc_attr!( - rustc_lint_opt_deny_field_access, Normal, template!(List: &["message"]), + rustc_lint_opt_deny_field_access, Normal, WarnFollowing, EncodeCrossCrate::Yes, ), @@ -1188,31 +1022,30 @@ pub struct BuiltinAttribute { // ========================================================================== rustc_attr!( - rustc_promotable, Normal, template!(Word), WarnFollowing, + rustc_promotable, Normal, WarnFollowing, EncodeCrossCrate::No, ), rustc_attr!( - rustc_legacy_const_generics, Normal, template!(List: &["N"]), ErrorFollowing, + rustc_legacy_const_generics, Normal, ErrorFollowing, EncodeCrossCrate::Yes, ), // Do not const-check this function's body. It will always get replaced during CTFE via `hook_special_const_fn`. rustc_attr!( - rustc_do_not_const_check, Normal, template!(Word), WarnFollowing, + rustc_do_not_const_check, Normal, WarnFollowing, EncodeCrossCrate::Yes, "`#[rustc_do_not_const_check]` skips const-check for this function's body", ), rustc_attr!( rustc_const_stable_indirect, Normal, - template!(Word), WarnFollowing, EncodeCrossCrate::No, "this is an internal implementation detail", ), rustc_attr!( rustc_intrinsic_const_stable_indirect, Normal, - template!(Word), WarnFollowing, EncodeCrossCrate::No, "this is an internal implementation detail", + WarnFollowing, EncodeCrossCrate::No, "this is an internal implementation detail", ), rustc_attr!( rustc_allow_const_fn_unstable, Normal, - template!(Word, List: &["feat1, feat2, ..."]), DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, EncodeCrossCrate::No, "rustc_allow_const_fn_unstable side-steps feature gating and stability checks" ), @@ -1221,25 +1054,25 @@ pub struct BuiltinAttribute { // ========================================================================== rustc_attr!( - rustc_layout_scalar_valid_range_start, Normal, template!(List: &["value"]), ErrorFollowing, + rustc_layout_scalar_valid_range_start, Normal, ErrorFollowing, EncodeCrossCrate::Yes, "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \ niche optimizations in the standard library", ), rustc_attr!( - rustc_layout_scalar_valid_range_end, Normal, template!(List: &["value"]), ErrorFollowing, + rustc_layout_scalar_valid_range_end, Normal, ErrorFollowing, EncodeCrossCrate::Yes, "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \ niche optimizations in the standard library", ), rustc_attr!( - rustc_simd_monomorphize_lane_limit, Normal, template!(NameValueStr: "N"), ErrorFollowing, + rustc_simd_monomorphize_lane_limit, Normal, ErrorFollowing, EncodeCrossCrate::Yes, "the `#[rustc_simd_monomorphize_lane_limit]` attribute is just used by std::simd \ for better error messages", ), rustc_attr!( - rustc_nonnull_optimization_guaranteed, Normal, template!(Word), WarnFollowing, + rustc_nonnull_optimization_guaranteed, Normal, WarnFollowing, EncodeCrossCrate::Yes, "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document \ guaranteed niche optimizations in the standard library", @@ -1251,53 +1084,52 @@ pub struct BuiltinAttribute { // Internal attributes, Misc: // ========================================================================== gated!( - lang, Normal, template!(NameValueStr: "name"), DuplicatesOk, EncodeCrossCrate::No, lang_items, + lang, Normal, DuplicatesOk, EncodeCrossCrate::No, lang_items, "lang items are subject to change", ), rustc_attr!( - rustc_as_ptr, Normal, template!(Word), ErrorFollowing, + rustc_as_ptr, Normal, ErrorFollowing, EncodeCrossCrate::Yes, "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations" ), rustc_attr!( - rustc_should_not_be_called_on_const_items, Normal, template!(Word), ErrorFollowing, + rustc_should_not_be_called_on_const_items, Normal, ErrorFollowing, EncodeCrossCrate::Yes, "`#[rustc_should_not_be_called_on_const_items]` is used to mark methods that don't make sense to be called on interior mutable consts" ), rustc_attr!( - rustc_pass_by_value, Normal, template!(Word), ErrorFollowing, + rustc_pass_by_value, Normal, ErrorFollowing, EncodeCrossCrate::Yes, "`#[rustc_pass_by_value]` is used to mark types that must be passed by value instead of reference" ), rustc_attr!( - rustc_never_returns_null_ptr, Normal, template!(Word), ErrorFollowing, + rustc_never_returns_null_ptr, Normal, ErrorFollowing, EncodeCrossCrate::Yes, "`#[rustc_never_returns_null_ptr]` is used to mark functions returning non-null pointers" ), rustc_attr!( - rustc_no_implicit_autorefs, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, + rustc_no_implicit_autorefs, AttributeType::Normal, ErrorFollowing, EncodeCrossCrate::Yes, "`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument" ), rustc_attr!( - rustc_coherence_is_core, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No, + rustc_coherence_is_core, AttributeType::CrateLevel, ErrorFollowing, EncodeCrossCrate::No, "`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`" ), rustc_attr!( - rustc_coinductive, AttributeType::Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, + rustc_coinductive, AttributeType::Normal, WarnFollowing, EncodeCrossCrate::No, "`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver" ), rustc_attr!( - rustc_allow_incoherent_impl, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No, + rustc_allow_incoherent_impl, AttributeType::Normal, ErrorFollowing, EncodeCrossCrate::No, "`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl" ), rustc_attr!( - rustc_preserve_ub_checks, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No, + rustc_preserve_ub_checks, AttributeType::CrateLevel, ErrorFollowing, EncodeCrossCrate::No, "`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR", ), rustc_attr!( rustc_deny_explicit_impl, AttributeType::Normal, - template!(Word), ErrorFollowing, EncodeCrossCrate::No, "`#[rustc_deny_explicit_impl]` enforces that a trait can have no user-provided impls" @@ -1305,20 +1137,19 @@ pub struct BuiltinAttribute { rustc_attr!( rustc_dyn_incompatible_trait, AttributeType::Normal, - template!(Word), ErrorFollowing, EncodeCrossCrate::No, "`#[rustc_dyn_incompatible_trait]` marks a trait as dyn-incompatible, \ even if it otherwise satisfies the requirements to be dyn-compatible." ), rustc_attr!( - rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word), + rustc_has_incoherent_inherent_impls, AttributeType::Normal, ErrorFollowing, EncodeCrossCrate::Yes, "`#[rustc_has_incoherent_inherent_impls]` allows the addition of incoherent inherent impls for \ the given type by annotating all impl items with `#[rustc_allow_incoherent_impl]`" ), rustc_attr!( - rustc_non_const_trait_method, AttributeType::Normal, template!(Word), + rustc_non_const_trait_method, AttributeType::Normal, ErrorFollowing, EncodeCrossCrate::No, "`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods \ as non-const to allow large traits an easier transition to const" @@ -1330,7 +1161,6 @@ pub struct BuiltinAttribute { encode_cross_crate: EncodeCrossCrate::Yes, type_: Normal, safety: AttributeSafety::Normal, - template: template!(NameValueStr: "name"), duplicates: ErrorFollowing, gate: Gated { feature: sym::rustc_attrs, @@ -1342,76 +1172,76 @@ pub struct BuiltinAttribute { }, gated!( // Used in resolve: - prelude_import, Normal, template!(Word), WarnFollowing, + prelude_import, Normal, WarnFollowing, EncodeCrossCrate::No, "`#[prelude_import]` is for use by rustc only", ), gated!( - rustc_paren_sugar, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, + rustc_paren_sugar, Normal, WarnFollowing, EncodeCrossCrate::No, unboxed_closures, "unboxed_closures are still evolving", ), rustc_attr!( - rustc_inherit_overflow_checks, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, + rustc_inherit_overflow_checks, Normal, WarnFollowing, EncodeCrossCrate::No, "the `#[rustc_inherit_overflow_checks]` attribute is just used to control \ overflow checking behavior of several functions in the standard library that are inlined \ across crates", ), rustc_attr!( rustc_reservation_impl, Normal, - template!(NameValueStr: "reservation message"), ErrorFollowing, EncodeCrossCrate::Yes, + ErrorFollowing, EncodeCrossCrate::Yes, "the `#[rustc_reservation_impl]` attribute is internally used \ for reserving `impl From for T` as part of the effort to stabilize `!`" ), rustc_attr!( - rustc_test_marker, Normal, template!(NameValueStr: "name"), WarnFollowing, + rustc_test_marker, Normal, WarnFollowing, EncodeCrossCrate::No, "the `#[rustc_test_marker]` attribute is used internally to track tests", ), rustc_attr!( - rustc_unsafe_specialization_marker, Normal, template!(Word), + rustc_unsafe_specialization_marker, Normal, WarnFollowing, EncodeCrossCrate::No, "the `#[rustc_unsafe_specialization_marker]` attribute is used to check specializations" ), rustc_attr!( - rustc_specialization_trait, Normal, template!(Word), + rustc_specialization_trait, Normal, WarnFollowing, EncodeCrossCrate::No, "the `#[rustc_specialization_trait]` attribute is used to check specializations" ), rustc_attr!( - rustc_main, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, + rustc_main, Normal, WarnFollowing, EncodeCrossCrate::No, "the `#[rustc_main]` attribute is used internally to specify test entry point function", ), rustc_attr!( - rustc_skip_during_method_dispatch, Normal, template!(List: &["array, boxed_slice"]), ErrorFollowing, + rustc_skip_during_method_dispatch, Normal, ErrorFollowing, EncodeCrossCrate::No, "the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \ from method dispatch when the receiver is of the following type, for compatibility in \ editions < 2021 (array) or editions < 2024 (boxed_slice)" ), rustc_attr!( - rustc_must_implement_one_of, Normal, template!(List: &["function1, function2, ..."]), + rustc_must_implement_one_of, Normal, ErrorFollowing, EncodeCrossCrate::No, "the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \ definition of a trait. Its syntax and semantics are highly experimental and will be \ subject to change before stabilization", ), rustc_attr!( - rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing, + rustc_doc_primitive, Normal, ErrorFollowing, EncodeCrossCrate::Yes, "the `#[rustc_doc_primitive]` attribute is used by the standard library \ to provide a way to generate documentation for primitive types", ), gated!( - rustc_intrinsic, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics, + rustc_intrinsic, Normal, ErrorFollowing, EncodeCrossCrate::Yes, intrinsics, "the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items", ), rustc_attr!( - rustc_no_mir_inline, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, + rustc_no_mir_inline, Normal, WarnFollowing, EncodeCrossCrate::Yes, "`#[rustc_no_mir_inline]` prevents the MIR inliner from inlining a function while not affecting codegen" ), rustc_attr!( - rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes, + rustc_force_inline, Normal, WarnFollowing, EncodeCrossCrate::Yes, "`#[rustc_force_inline]` forces a free function to be inlined" ), rustc_attr!( - rustc_scalable_vector, Normal, template!(List: &["count"]), WarnFollowing, EncodeCrossCrate::Yes, + rustc_scalable_vector, Normal, WarnFollowing, EncodeCrossCrate::Yes, "`#[rustc_scalable_vector]` defines a scalable vector type" ), @@ -1419,133 +1249,131 @@ pub struct BuiltinAttribute { // Internal attributes, Testing: // ========================================================================== - rustc_attr!(TEST, rustc_effective_visibility, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes), + rustc_attr!(TEST, rustc_effective_visibility, Normal, WarnFollowing, EncodeCrossCrate::Yes), rustc_attr!( - TEST, rustc_dump_inferred_outlives, Normal, template!(Word), + TEST, rustc_dump_inferred_outlives, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_capture_analysis, Normal, template!(Word), + TEST, rustc_capture_analysis, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_insignificant_dtor, Normal, template!(Word), + TEST, rustc_insignificant_dtor, Normal, WarnFollowing, EncodeCrossCrate::Yes ), rustc_attr!( - TEST, rustc_no_implicit_bounds, CrateLevel, template!(Word), + TEST, rustc_no_implicit_bounds, CrateLevel, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_strict_coherence, Normal, template!(Word), + TEST, rustc_strict_coherence, Normal, WarnFollowing, EncodeCrossCrate::Yes ), rustc_attr!( - TEST, rustc_dump_variances, Normal, template!(Word), + TEST, rustc_dump_variances, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_dump_variances_of_opaques, Normal, template!(Word), + TEST, rustc_dump_variances_of_opaques, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_hidden_type_of_opaques, Normal, template!(Word), + TEST, rustc_hidden_type_of_opaques, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_layout, Normal, template!(List: &["field1, field2, ..."]), + TEST, rustc_layout, Normal, WarnFollowing, EncodeCrossCrate::Yes ), rustc_attr!( - TEST, rustc_abi, Normal, template!(List: &["field1, field2, ..."]), + TEST, rustc_abi, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_regions, Normal, template!(Word), + TEST, rustc_regions, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( TEST, rustc_delayed_bug_from_inside_query, Normal, - template!(Word), WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_dump_user_args, Normal, template!(Word), + TEST, rustc_dump_user_args, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing, + TEST, rustc_evaluate_where_clauses, Normal, WarnFollowing, EncodeCrossCrate::Yes ), rustc_attr!( - TEST, rustc_if_this_changed, Normal, template!(Word, List: &["DepNode"]), DuplicatesOk, + TEST, rustc_if_this_changed, Normal, DuplicatesOk, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_then_this_would_need, Normal, template!(List: &["DepNode"]), DuplicatesOk, + TEST, rustc_then_this_would_need, Normal, DuplicatesOk, EncodeCrossCrate::No ), rustc_attr!( TEST, rustc_clean, Normal, - template!(List: &[r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#]), DuplicatesOk, EncodeCrossCrate::No ), rustc_attr!( TEST, rustc_partition_reused, Normal, - template!(List: &[r#"cfg = "...", module = "...""#]), DuplicatesOk, EncodeCrossCrate::No + DuplicatesOk, EncodeCrossCrate::No ), rustc_attr!( TEST, rustc_partition_codegened, Normal, - template!(List: &[r#"cfg = "...", module = "...""#]), DuplicatesOk, EncodeCrossCrate::No + DuplicatesOk, EncodeCrossCrate::No ), rustc_attr!( TEST, rustc_expected_cgu_reuse, Normal, - template!(List: &[r#"cfg = "...", module = "...", kind = "...""#]), DuplicatesOk, + DuplicatesOk, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_symbol_name, Normal, template!(Word), + TEST, rustc_symbol_name, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_def_path, Normal, template!(Word), + TEST, rustc_def_path, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_mir, Normal, template!(List: &["arg1, arg2, ..."]), + TEST, rustc_mir, Normal, DuplicatesOk, EncodeCrossCrate::Yes ), gated!( - custom_mir, Normal, template!(List: &[r#"dialect = "...", phase = "...""#]), + custom_mir, Normal, ErrorFollowing, EncodeCrossCrate::No, "the `#[custom_mir]` attribute is just used for the Rust test suite", ), rustc_attr!( - TEST, rustc_dump_item_bounds, Normal, template!(Word), + TEST, rustc_dump_item_bounds, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_dump_predicates, Normal, template!(Word), + TEST, rustc_dump_predicates, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_dump_def_parents, Normal, template!(Word), + TEST, rustc_dump_def_parents, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_dump_object_lifetime_defaults, Normal, template!(Word), + TEST, rustc_dump_object_lifetime_defaults, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_dump_vtable, Normal, template!(Word), + TEST, rustc_dump_vtable, Normal, WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( - TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/), + TEST, rustc_dummy, Normal, DuplicatesOk, EncodeCrossCrate::No ), rustc_attr!( - TEST, pattern_complexity_limit, CrateLevel, template!(NameValueStr: "N"), + TEST, pattern_complexity_limit, CrateLevel, ErrorFollowing, EncodeCrossCrate::No, ), ]; From f967bf3f29da94f32d58e6bf3f30fea3699fe86a Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 4 Apr 2026 13:35:23 +0200 Subject: [PATCH 16/37] Remove EncodeCrossCrate from BUILTIN_ATTRIBUTES --- compiler/rustc_feature/src/builtin_attrs.rs | 452 +++++++------------ compiler/rustc_feature/src/lib.rs | 3 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 4 - 3 files changed, 169 insertions(+), 290 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 675a817890cb..0c6dfcd98b7e 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -7,7 +7,6 @@ use AttributeType::*; use rustc_data_structures::fx::FxHashMap; use rustc_hir::AttrStyle; -use rustc_hir::attrs::EncodeCrossCrate; use rustc_span::edition::Edition; use rustc_span::{Symbol, sym}; @@ -266,30 +265,27 @@ macro_rules! template { } macro_rules! ungated { - (unsafe($edition:ident) $attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { + (unsafe($edition:ident) $attr:ident, $typ:expr, $duplicates:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, - encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: Some(Edition::$edition) }, gate: Ungated, duplicates: $duplicates, } }; - (unsafe $attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { + (unsafe $attr:ident, $typ:expr, $duplicates:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, - encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: None }, gate: Ungated, duplicates: $duplicates, } }; - ($attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => { + ($attr:ident, $typ:expr, $duplicates:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, - encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Normal, gate: Ungated, @@ -299,10 +295,9 @@ macro_rules! ungated { } macro_rules! gated { - (unsafe $attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $message:expr $(,)?) => { + (unsafe $attr:ident, $typ:expr, $duplicates:expr, $gate:ident, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, - encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: None }, duplicates: $duplicates, @@ -314,10 +309,9 @@ macro_rules! gated { }, } }; - (unsafe $attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr, $message:expr $(,)?) => { + (unsafe $attr:ident, $typ:expr, $duplicates:expr, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, - encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: None }, duplicates: $duplicates, @@ -329,10 +323,9 @@ macro_rules! gated { }, } }; - ($attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $message:expr $(,)?) => { + ($attr:ident, $typ:expr, $duplicates:expr, $gate:ident, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, - encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Normal, duplicates: $duplicates, @@ -344,10 +337,9 @@ macro_rules! gated { }, } }; - ($attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr, $message:expr $(,)?) => { + ($attr:ident, $typ:expr, $duplicates:expr, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, - encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Normal, duplicates: $duplicates, @@ -362,12 +354,11 @@ macro_rules! gated { } macro_rules! rustc_attr { - (TEST, $attr:ident, $typ:expr, $duplicate:expr, $encode_cross_crate:expr $(,)?) => { + (TEST, $attr:ident, $typ:expr, $duplicate:expr $(,)?) => { rustc_attr!( $attr, $typ, $duplicate, - $encode_cross_crate, concat!( "the `#[", stringify!($attr), @@ -375,10 +366,9 @@ macro_rules! rustc_attr { ), ) }; - ($attr:ident, $typ:expr, $duplicates:expr, $encode_cross_crate:expr, $($notes:expr),* $(,)?) => { + ($attr:ident, $typ:expr, $duplicates:expr, $($notes:expr),* $(,)?) => { BuiltinAttribute { name: sym::$attr, - encode_cross_crate: $encode_cross_crate, type_: $typ, safety: AttributeSafety::Normal, duplicates: $duplicates, @@ -405,11 +395,6 @@ macro_rules! experimental { pub struct BuiltinAttribute { pub name: Symbol, - /// Whether this attribute is encode cross crate. - /// - /// If so, it is encoded in the crate metadata. - /// Otherwise, it can only be used in the local crate. - pub encode_cross_crate: EncodeCrossCrate, pub type_: AttributeType, pub safety: AttributeSafety, pub duplicates: AttributeDuplicates, @@ -426,245 +411,242 @@ pub struct BuiltinAttribute { // Conditional compilation: ungated!( cfg, Normal, - DuplicatesOk, EncodeCrossCrate::No + DuplicatesOk, ), ungated!( cfg_attr, Normal, - DuplicatesOk, EncodeCrossCrate::No + DuplicatesOk, ), // Testing: ungated!( ignore, Normal, - WarnFollowing, EncodeCrossCrate::No, + WarnFollowing, ), ungated!( should_panic, Normal, - FutureWarnFollowing, EncodeCrossCrate::No, + FutureWarnFollowing, ), // Macros: ungated!( automatically_derived, Normal, - WarnFollowing, EncodeCrossCrate::Yes + WarnFollowing, ), ungated!( macro_use, Normal, - WarnFollowingWordOnly, EncodeCrossCrate::No, + WarnFollowingWordOnly, ), - ungated!(macro_escape, Normal, WarnFollowing, EncodeCrossCrate::No), // Deprecated synonym for `macro_use`. + ungated!(macro_escape, Normal, WarnFollowing,), // Deprecated synonym for `macro_use`. ungated!( macro_export, Normal, - WarnFollowing, EncodeCrossCrate::Yes + WarnFollowing, ), ungated!( proc_macro, Normal, - ErrorFollowing, EncodeCrossCrate::No + ErrorFollowing, ), ungated!( proc_macro_derive, Normal, - ErrorFollowing, EncodeCrossCrate::No, + ErrorFollowing, ), ungated!( proc_macro_attribute, Normal, - ErrorFollowing, EncodeCrossCrate::No + ErrorFollowing, ), // Lints: ungated!( warn, Normal, - DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, ), ungated!( allow, Normal, - DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, ), ungated!( expect, Normal, - DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, ), ungated!( forbid, Normal, - DuplicatesOk, EncodeCrossCrate::No + DuplicatesOk, ), ungated!( deny, Normal, - DuplicatesOk, EncodeCrossCrate::No + DuplicatesOk, ), ungated!( must_use, Normal, - FutureWarnFollowing, EncodeCrossCrate::Yes + FutureWarnFollowing, ), gated!( - must_not_suspend, Normal, WarnFollowing, - EncodeCrossCrate::Yes, experimental!(must_not_suspend) + must_not_suspend, Normal, WarnFollowing, experimental!(must_not_suspend) ), ungated!( deprecated, Normal, - ErrorFollowing, EncodeCrossCrate::Yes + ErrorFollowing, ), // Crate properties: ungated!( crate_name, CrateLevel, - FutureWarnFollowing, EncodeCrossCrate::No, + FutureWarnFollowing, ), ungated!( crate_type, CrateLevel, - DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, ), // ABI, linking, symbols, and FFI ungated!( link, Normal, - DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, ), ungated!( link_name, Normal, - FutureWarnPreceding, EncodeCrossCrate::Yes + FutureWarnPreceding, ), ungated!( no_link, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), ungated!( repr, Normal, - DuplicatesOk, EncodeCrossCrate::No + DuplicatesOk, ), // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity - gated!(rustc_align, Normal, DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(rustc_align)), - gated!(rustc_align_static, Normal, DuplicatesOk, EncodeCrossCrate::No, static_align, experimental!(rustc_align_static)), + gated!(rustc_align, Normal, DuplicatesOk, fn_align, experimental!(rustc_align)), + gated!(rustc_align_static, Normal, DuplicatesOk, static_align, experimental!(rustc_align_static)), ungated!( unsafe(Edition2024) export_name, Normal, - FutureWarnPreceding, EncodeCrossCrate::No + FutureWarnPreceding, ), ungated!( unsafe(Edition2024) link_section, Normal, - FutureWarnPreceding, EncodeCrossCrate::No + FutureWarnPreceding, ), ungated!( unsafe(Edition2024) no_mangle, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), ungated!( used, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), ungated!( link_ordinal, Normal, - ErrorPreceding, EncodeCrossCrate::Yes + ErrorPreceding, ), ungated!( unsafe naked, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), // See `TyAndLayout::pass_indirectly_in_non_rustic_abis` for details. rustc_attr!( rustc_pass_indirectly_in_non_rustic_abis, Normal, ErrorFollowing, - EncodeCrossCrate::No, "types marked with `#[rustc_pass_indirectly_in_non_rustic_abis]` are always passed indirectly by non-Rustic ABIs" ), // Limits: ungated!( recursion_limit, CrateLevel, - FutureWarnFollowing, EncodeCrossCrate::No + FutureWarnFollowing, ), ungated!( type_length_limit, CrateLevel, - FutureWarnFollowing, EncodeCrossCrate::No + FutureWarnFollowing, ), gated!( - move_size_limit, CrateLevel, ErrorFollowing, - EncodeCrossCrate::No, large_assignments, experimental!(move_size_limit) + move_size_limit, CrateLevel, ErrorFollowing, large_assignments, experimental!(move_size_limit) ), // Entry point: ungated!( no_main, CrateLevel, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), // Modules, prelude, and resolution: ungated!( path, Normal, - FutureWarnFollowing, EncodeCrossCrate::No + FutureWarnFollowing, ), ungated!( no_std, CrateLevel, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), ungated!( no_implicit_prelude, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), ungated!( non_exhaustive, Normal, - WarnFollowing, EncodeCrossCrate::Yes + WarnFollowing, ), // Runtime ungated!( windows_subsystem, CrateLevel, - FutureWarnFollowing, EncodeCrossCrate::No + FutureWarnFollowing, ), ungated!( // RFC 2070 panic_handler, Normal, - WarnFollowing, EncodeCrossCrate::Yes + WarnFollowing, ), // Code generation: ungated!( inline, Normal, - FutureWarnFollowing, EncodeCrossCrate::No + FutureWarnFollowing, ), ungated!( cold, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), ungated!( no_builtins, CrateLevel, - WarnFollowing, EncodeCrossCrate::Yes + WarnFollowing, ), ungated!( target_feature, Normal, - DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, ), ungated!( track_caller, Normal, - WarnFollowing, EncodeCrossCrate::Yes + WarnFollowing, ), ungated!( instruction_set, Normal, - ErrorPreceding, EncodeCrossCrate::No + ErrorPreceding, ), gated!( unsafe force_target_feature, Normal, - DuplicatesOk, EncodeCrossCrate::No, effective_target_features, experimental!(force_target_feature) + DuplicatesOk, effective_target_features, experimental!(force_target_feature) ), gated!( sanitize, Normal, ErrorPreceding, - EncodeCrossCrate::No, sanitize, experimental!(sanitize), + sanitize, experimental!(sanitize), ), gated!( coverage, Normal, - ErrorPreceding, EncodeCrossCrate::No, + ErrorPreceding, coverage_attribute, experimental!(coverage) ), ungated!( doc, Normal, - DuplicatesOk, EncodeCrossCrate::Yes + DuplicatesOk, ), // Debugging ungated!( debugger_visualizer, Normal, - DuplicatesOk, EncodeCrossCrate::No + DuplicatesOk, ), ungated!( collapse_debuginfo, Normal, - ErrorFollowing, EncodeCrossCrate::Yes + ErrorFollowing, ), // ========================================================================== @@ -673,71 +655,62 @@ pub struct BuiltinAttribute { // Linking: gated!( - export_stable, Normal, WarnFollowing, - EncodeCrossCrate::No, experimental!(export_stable) + export_stable, Normal, WarnFollowing, experimental!(export_stable) ), // Testing: gated!( - test_runner, CrateLevel, ErrorFollowing, - EncodeCrossCrate::Yes, custom_test_frameworks, + test_runner, CrateLevel, ErrorFollowing, custom_test_frameworks, "custom test frameworks are an unstable feature", ), gated!( - reexport_test_harness_main, CrateLevel, ErrorFollowing, - EncodeCrossCrate::No, custom_test_frameworks, + reexport_test_harness_main, CrateLevel, ErrorFollowing, custom_test_frameworks, "custom test frameworks are an unstable feature", ), // RFC #1268 gated!( - marker, Normal, WarnFollowing, EncodeCrossCrate::No, - marker_trait_attr, experimental!(marker) + marker, Normal, WarnFollowing,marker_trait_attr, experimental!(marker) ), gated!( - thread_local, Normal, WarnFollowing, EncodeCrossCrate::No, - "`#[thread_local]` is an experimental feature, and does not currently handle destructors", + thread_local, Normal, WarnFollowing,"`#[thread_local]` is an experimental feature, and does not currently handle destructors", ), gated!( - no_core, CrateLevel, WarnFollowing, - EncodeCrossCrate::No, experimental!(no_core) + no_core, CrateLevel, WarnFollowing, experimental!(no_core) ), // RFC 2412 gated!( optimize, Normal, ErrorPreceding, - EncodeCrossCrate::No, optimize_attribute, experimental!(optimize) + optimize_attribute, experimental!(optimize) ), gated!( - unsafe ffi_pure, Normal, WarnFollowing, - EncodeCrossCrate::No, experimental!(ffi_pure) + unsafe ffi_pure, Normal, WarnFollowing, experimental!(ffi_pure) ), gated!( - unsafe ffi_const, Normal, WarnFollowing, - EncodeCrossCrate::No, experimental!(ffi_const) + unsafe ffi_const, Normal, WarnFollowing, experimental!(ffi_const) ), gated!( register_tool, CrateLevel, DuplicatesOk, - EncodeCrossCrate::No, experimental!(register_tool), + experimental!(register_tool), ), // `#[cfi_encoding = ""]` gated!( cfi_encoding, Normal, ErrorPreceding, - EncodeCrossCrate::Yes, experimental!(cfi_encoding) + experimental!(cfi_encoding) ), // `#[coroutine]` attribute to be applied to closures to make them coroutines instead gated!( - coroutine, Normal, ErrorFollowing, - EncodeCrossCrate::No, coroutines, experimental!(coroutine) + coroutine, Normal, ErrorFollowing, coroutines, experimental!(coroutine) ), // RFC 3543 // `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` gated!( patchable_function_entry, Normal, ErrorPreceding, - EncodeCrossCrate::Yes, experimental!(patchable_function_entry) + experimental!(patchable_function_entry) ), // The `#[loop_match]` and `#[const_continue]` attributes are part of the @@ -745,12 +718,10 @@ pub struct BuiltinAttribute { // // - https://github.com/rust-lang/rust/issues/132306 gated!( - const_continue, Normal, ErrorFollowing, - EncodeCrossCrate::No, loop_match, experimental!(const_continue) + const_continue, Normal, ErrorFollowing, loop_match, experimental!(const_continue) ), gated!( - loop_match, Normal, ErrorFollowing, - EncodeCrossCrate::No, loop_match, experimental!(loop_match) + loop_match, Normal, ErrorFollowing, loop_match, experimental!(loop_match) ), // The `#[pin_v2]` attribute is part of the `pin_ergonomics` experiment @@ -758,8 +729,7 @@ pub struct BuiltinAttribute { // // - https://github.com/rust-lang/rust/issues/130494 gated!( - pin_v2, Normal, ErrorFollowing, - EncodeCrossCrate::Yes, pin_ergonomics, experimental!(pin_v2), + pin_v2, Normal, ErrorFollowing, pin_ergonomics, experimental!(pin_v2), ), // ========================================================================== @@ -768,63 +738,58 @@ pub struct BuiltinAttribute { ungated!( feature, CrateLevel, - DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, ), // DuplicatesOk since it has its own validation ungated!( stable, Normal, - DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, ), ungated!( unstable, Normal, DuplicatesOk, - EncodeCrossCrate::Yes ), ungated!( unstable_feature_bound, Normal, - DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, ), ungated!( rustc_const_unstable, Normal, - DuplicatesOk, EncodeCrossCrate::Yes + DuplicatesOk, ), ungated!( rustc_const_stable, Normal, - DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, ), ungated!( rustc_default_body_unstable, Normal, - DuplicatesOk, EncodeCrossCrate::No + DuplicatesOk, ), gated!( allow_internal_unstable, Normal, - DuplicatesOk, EncodeCrossCrate::Yes, + DuplicatesOk, "allow_internal_unstable side-steps feature gating and stability checks", ), gated!( - allow_internal_unsafe, Normal, WarnFollowing, - EncodeCrossCrate::No, "allow_internal_unsafe side-steps the unsafe_code lint", + allow_internal_unsafe, Normal, WarnFollowing, "allow_internal_unsafe side-steps the unsafe_code lint", ), gated!( rustc_eii_foreign_item, Normal, - ErrorFollowing, EncodeCrossCrate::Yes, eii_internals, + ErrorFollowing, eii_internals, "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", ), rustc_attr!( rustc_allowed_through_unstable_modules, Normal, - WarnFollowing, EncodeCrossCrate::No, - "rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \ + WarnFollowing,"rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \ through unstable paths" ), rustc_attr!( rustc_deprecated_safe_2024, Normal, - ErrorFollowing, EncodeCrossCrate::Yes, - "`#[rustc_deprecated_safe_2024]` is used to declare functions unsafe across the edition 2024 boundary", + ErrorFollowing,"`#[rustc_deprecated_safe_2024]` is used to declare functions unsafe across the edition 2024 boundary", ), rustc_attr!( rustc_pub_transparent, Normal, - ErrorFollowing, EncodeCrossCrate::Yes, - "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", + ErrorFollowing,"used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", ), @@ -832,10 +797,9 @@ pub struct BuiltinAttribute { // Internal attributes: Type system related: // ========================================================================== - gated!(fundamental, Normal, WarnFollowing, EncodeCrossCrate::Yes, experimental!(fundamental)), + gated!(fundamental, Normal, WarnFollowing, experimental!(fundamental)), gated!( - may_dangle, Normal, WarnFollowing, - EncodeCrossCrate::No, dropck_eyepatch, + may_dangle, Normal, WarnFollowing, dropck_eyepatch, "`may_dangle` has unstable semantics and may be removed in the future", ), @@ -843,7 +807,6 @@ pub struct BuiltinAttribute { rustc_never_type_options, Normal, ErrorFollowing, - EncodeCrossCrate::No, "`rustc_never_type_options` is used to experiment with never type fallback and work on \ never type stabilization" ), @@ -854,53 +817,41 @@ pub struct BuiltinAttribute { rustc_attr!( rustc_allocator, Normal, WarnFollowing, - EncodeCrossCrate::No, ), rustc_attr!( rustc_nounwind, Normal, WarnFollowing, - EncodeCrossCrate::No, ), rustc_attr!( rustc_reallocator, Normal, WarnFollowing, - EncodeCrossCrate::No, ), rustc_attr!( rustc_deallocator, Normal, WarnFollowing, - EncodeCrossCrate::No, ), rustc_attr!( rustc_allocator_zeroed, Normal, WarnFollowing, - EncodeCrossCrate::No, ), rustc_attr!( rustc_allocator_zeroed_variant, Normal, ErrorPreceding, - EncodeCrossCrate::Yes, ), gated!( - default_lib_allocator, Normal, WarnFollowing, - EncodeCrossCrate::No, allocator_internals, experimental!(default_lib_allocator), + default_lib_allocator, Normal, WarnFollowing, allocator_internals, experimental!(default_lib_allocator), ), gated!( - needs_allocator, Normal, WarnFollowing, - EncodeCrossCrate::No, allocator_internals, experimental!(needs_allocator), + needs_allocator, Normal, WarnFollowing, allocator_internals, experimental!(needs_allocator), ), gated!( - panic_runtime, CrateLevel, WarnFollowing, - EncodeCrossCrate::No, experimental!(panic_runtime) + panic_runtime, CrateLevel, WarnFollowing, experimental!(panic_runtime) ), gated!( - needs_panic_runtime, CrateLevel, WarnFollowing, - EncodeCrossCrate::No, experimental!(needs_panic_runtime) + needs_panic_runtime, CrateLevel, WarnFollowing, experimental!(needs_panic_runtime) ), gated!( compiler_builtins, CrateLevel, WarnFollowing, - EncodeCrossCrate::No, "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \ which contains compiler-rt intrinsics and will never be stable", ), gated!( profiler_runtime, CrateLevel, WarnFollowing, - EncodeCrossCrate::No, "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \ which contains the profiler runtime and will never be stable", ), @@ -911,20 +862,17 @@ pub struct BuiltinAttribute { gated!( linkage, Normal, - ErrorPreceding, EncodeCrossCrate::No, + ErrorPreceding, "the `linkage` attribute is experimental and not portable across platforms", ), rustc_attr!( rustc_std_internal_symbol, Normal, WarnFollowing, - EncodeCrossCrate::No, ), rustc_attr!( rustc_objc_class, Normal, ErrorPreceding, - EncodeCrossCrate::No, ), rustc_attr!( rustc_objc_selector, Normal, ErrorPreceding, - EncodeCrossCrate::No, ), // ========================================================================== @@ -934,38 +882,31 @@ pub struct BuiltinAttribute { rustc_attr!( rustc_builtin_macro, Normal, ErrorFollowing, - EncodeCrossCrate::Yes, ), rustc_attr!( rustc_proc_macro_decls, Normal, WarnFollowing, - EncodeCrossCrate::No, ), rustc_attr!( rustc_macro_transparency, Normal, - ErrorFollowing, - EncodeCrossCrate::Yes, "used internally for testing macro hygiene", + ErrorFollowing, "used internally for testing macro hygiene", ), rustc_attr!( rustc_autodiff, Normal, DuplicatesOk, - EncodeCrossCrate::Yes, ), rustc_attr!( rustc_offload_kernel, Normal, DuplicatesOk, - EncodeCrossCrate::Yes, ), // Traces that are left when `cfg` and `cfg_attr` attributes are expanded. // The attributes are not gated, to avoid stability errors, but they cannot be used in stable // or unstable code directly because `sym::cfg_(attr_)trace` are not valid identifiers, they // can only be generated by the compiler. ungated!( - cfg_trace, Normal, DuplicatesOk, - EncodeCrossCrate::Yes + cfg_trace, Normal, DuplicatesOk ), ungated!( - cfg_attr_trace, Normal, DuplicatesOk, - EncodeCrossCrate::No + cfg_attr_trace, Normal, DuplicatesOk ), // ========================================================================== @@ -974,47 +915,46 @@ pub struct BuiltinAttribute { rustc_attr!( rustc_on_unimplemented, Normal, - ErrorFollowing, EncodeCrossCrate::Yes, - "see `#[diagnostic::on_unimplemented]` for the stable equivalent of this attribute" + ErrorFollowing,"see `#[diagnostic::on_unimplemented]` for the stable equivalent of this attribute" ), rustc_attr!( rustc_confusables, Normal, - ErrorFollowing, EncodeCrossCrate::Yes, + ErrorFollowing, ), // Enumerates "identity-like" conversion methods to suggest on type mismatch. rustc_attr!( rustc_conversion_suggestion, Normal, - WarnFollowing, EncodeCrossCrate::Yes, + WarnFollowing, ), // Prevents field reads in the marked trait or method to be considered // during dead code analysis. rustc_attr!( rustc_trivial_field_reads, Normal, - WarnFollowing, EncodeCrossCrate::Yes, + WarnFollowing, ), // Used by the `rustc::potential_query_instability` lint to warn methods which // might not be stable during incremental compilation. rustc_attr!( rustc_lint_query_instability, Normal, - WarnFollowing, EncodeCrossCrate::Yes, + WarnFollowing, ), // Used by the `rustc::untracked_query_information` lint to warn methods which // might not be stable during incremental compilation. rustc_attr!( rustc_lint_untracked_query_information, Normal, - WarnFollowing, EncodeCrossCrate::Yes, + WarnFollowing, ), // Used by the `rustc::bad_opt_access` lint to identify `DebuggingOptions` and `CodegenOptions` // types (as well as any others in future). rustc_attr!( rustc_lint_opt_ty, Normal, - WarnFollowing, EncodeCrossCrate::Yes, + WarnFollowing, ), // Used by the `rustc::bad_opt_access` lint on fields // types (as well as any others in future). rustc_attr!( rustc_lint_opt_deny_field_access, Normal, - WarnFollowing, EncodeCrossCrate::Yes, + WarnFollowing, ), // ========================================================================== @@ -1022,30 +962,25 @@ pub struct BuiltinAttribute { // ========================================================================== rustc_attr!( - rustc_promotable, Normal, WarnFollowing, - EncodeCrossCrate::No, ), + rustc_promotable, Normal, WarnFollowing, ), rustc_attr!( rustc_legacy_const_generics, Normal, ErrorFollowing, - EncodeCrossCrate::Yes, ), // Do not const-check this function's body. It will always get replaced during CTFE via `hook_special_const_fn`. rustc_attr!( - rustc_do_not_const_check, Normal, WarnFollowing, - EncodeCrossCrate::Yes, "`#[rustc_do_not_const_check]` skips const-check for this function's body", + rustc_do_not_const_check, Normal, WarnFollowing, "`#[rustc_do_not_const_check]` skips const-check for this function's body", ), rustc_attr!( rustc_const_stable_indirect, Normal, - WarnFollowing, - EncodeCrossCrate::No, - "this is an internal implementation detail", + WarnFollowing,"this is an internal implementation detail", ), rustc_attr!( rustc_intrinsic_const_stable_indirect, Normal, - WarnFollowing, EncodeCrossCrate::No, "this is an internal implementation detail", + WarnFollowing, "this is an internal implementation detail", ), rustc_attr!( rustc_allow_const_fn_unstable, Normal, - DuplicatesOk, EncodeCrossCrate::No, + DuplicatesOk, "rustc_allow_const_fn_unstable side-steps feature gating and stability checks" ), @@ -1055,25 +990,21 @@ pub struct BuiltinAttribute { rustc_attr!( rustc_layout_scalar_valid_range_start, Normal, ErrorFollowing, - EncodeCrossCrate::Yes, "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \ niche optimizations in the standard library", ), rustc_attr!( rustc_layout_scalar_valid_range_end, Normal, ErrorFollowing, - EncodeCrossCrate::Yes, "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \ niche optimizations in the standard library", ), rustc_attr!( rustc_simd_monomorphize_lane_limit, Normal, ErrorFollowing, - EncodeCrossCrate::Yes, "the `#[rustc_simd_monomorphize_lane_limit]` attribute is just used by std::simd \ for better error messages", ), rustc_attr!( rustc_nonnull_optimization_guaranteed, Normal, WarnFollowing, - EncodeCrossCrate::Yes, "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document \ guaranteed niche optimizations in the standard library", "the compiler does not even check whether the type indeed is being non-null-optimized; \ @@ -1084,85 +1015,67 @@ pub struct BuiltinAttribute { // Internal attributes, Misc: // ========================================================================== gated!( - lang, Normal, DuplicatesOk, EncodeCrossCrate::No, lang_items, + lang, Normal, DuplicatesOk, lang_items, "lang items are subject to change", ), rustc_attr!( rustc_as_ptr, Normal, ErrorFollowing, - EncodeCrossCrate::Yes, "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations" ), rustc_attr!( rustc_should_not_be_called_on_const_items, Normal, ErrorFollowing, - EncodeCrossCrate::Yes, "`#[rustc_should_not_be_called_on_const_items]` is used to mark methods that don't make sense to be called on interior mutable consts" ), rustc_attr!( rustc_pass_by_value, Normal, ErrorFollowing, - EncodeCrossCrate::Yes, "`#[rustc_pass_by_value]` is used to mark types that must be passed by value instead of reference" ), rustc_attr!( rustc_never_returns_null_ptr, Normal, ErrorFollowing, - EncodeCrossCrate::Yes, "`#[rustc_never_returns_null_ptr]` is used to mark functions returning non-null pointers" ), rustc_attr!( - rustc_no_implicit_autorefs, AttributeType::Normal, ErrorFollowing, EncodeCrossCrate::Yes, - "`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument" + rustc_no_implicit_autorefs, AttributeType::Normal, ErrorFollowing,"`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument" ), rustc_attr!( - rustc_coherence_is_core, AttributeType::CrateLevel, ErrorFollowing, EncodeCrossCrate::No, - "`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`" + rustc_coherence_is_core, AttributeType::CrateLevel, ErrorFollowing,"`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`" ), rustc_attr!( - rustc_coinductive, AttributeType::Normal, WarnFollowing, EncodeCrossCrate::No, - "`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver" + rustc_coinductive, AttributeType::Normal, WarnFollowing,"`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver" ), rustc_attr!( - rustc_allow_incoherent_impl, AttributeType::Normal, ErrorFollowing, EncodeCrossCrate::No, - "`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl" + rustc_allow_incoherent_impl, AttributeType::Normal, ErrorFollowing,"`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl" ), rustc_attr!( - rustc_preserve_ub_checks, AttributeType::CrateLevel, ErrorFollowing, EncodeCrossCrate::No, - "`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR", + rustc_preserve_ub_checks, AttributeType::CrateLevel, ErrorFollowing,"`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR", ), rustc_attr!( rustc_deny_explicit_impl, AttributeType::Normal, - ErrorFollowing, - EncodeCrossCrate::No, - "`#[rustc_deny_explicit_impl]` enforces that a trait can have no user-provided impls" + ErrorFollowing,"`#[rustc_deny_explicit_impl]` enforces that a trait can have no user-provided impls" ), rustc_attr!( rustc_dyn_incompatible_trait, AttributeType::Normal, - ErrorFollowing, - EncodeCrossCrate::No, - "`#[rustc_dyn_incompatible_trait]` marks a trait as dyn-incompatible, \ + ErrorFollowing,"`#[rustc_dyn_incompatible_trait]` marks a trait as dyn-incompatible, \ even if it otherwise satisfies the requirements to be dyn-compatible." ), rustc_attr!( rustc_has_incoherent_inherent_impls, AttributeType::Normal, - ErrorFollowing, EncodeCrossCrate::Yes, - "`#[rustc_has_incoherent_inherent_impls]` allows the addition of incoherent inherent impls for \ + ErrorFollowing,"`#[rustc_has_incoherent_inherent_impls]` allows the addition of incoherent inherent impls for \ the given type by annotating all impl items with `#[rustc_allow_incoherent_impl]`" ), rustc_attr!( rustc_non_const_trait_method, AttributeType::Normal, - ErrorFollowing, EncodeCrossCrate::No, - "`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods \ + ErrorFollowing,"`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods \ as non-const to allow large traits an easier transition to const" ), BuiltinAttribute { name: sym::rustc_diagnostic_item, - // FIXME: This can be `true` once we always use `tcx.is_diagnostic_item`. - encode_cross_crate: EncodeCrossCrate::Yes, type_: Normal, safety: AttributeSafety::Normal, - duplicates: ErrorFollowing, - gate: Gated { + duplicates: ErrorFollowing,gate: Gated { feature: sym::rustc_attrs, message: "use of an internal attribute", check: Features::rustc_attrs, @@ -1172,209 +1085,190 @@ pub struct BuiltinAttribute { }, gated!( // Used in resolve: - prelude_import, Normal, WarnFollowing, - EncodeCrossCrate::No, "`#[prelude_import]` is for use by rustc only", + prelude_import, Normal, WarnFollowing, "`#[prelude_import]` is for use by rustc only", ), gated!( - rustc_paren_sugar, Normal, WarnFollowing, EncodeCrossCrate::No, - unboxed_closures, "unboxed_closures are still evolving", + rustc_paren_sugar, Normal, WarnFollowing,unboxed_closures, "unboxed_closures are still evolving", ), rustc_attr!( - rustc_inherit_overflow_checks, Normal, WarnFollowing, EncodeCrossCrate::No, - "the `#[rustc_inherit_overflow_checks]` attribute is just used to control \ + rustc_inherit_overflow_checks, Normal, WarnFollowing,"the `#[rustc_inherit_overflow_checks]` attribute is just used to control \ overflow checking behavior of several functions in the standard library that are inlined \ across crates", ), rustc_attr!( rustc_reservation_impl, Normal, - ErrorFollowing, EncodeCrossCrate::Yes, - "the `#[rustc_reservation_impl]` attribute is internally used \ + ErrorFollowing,"the `#[rustc_reservation_impl]` attribute is internally used \ for reserving `impl From for T` as part of the effort to stabilize `!`" ), rustc_attr!( - rustc_test_marker, Normal, WarnFollowing, - EncodeCrossCrate::No, "the `#[rustc_test_marker]` attribute is used internally to track tests", + rustc_test_marker, Normal, WarnFollowing, "the `#[rustc_test_marker]` attribute is used internally to track tests", ), rustc_attr!( rustc_unsafe_specialization_marker, Normal, - WarnFollowing, EncodeCrossCrate::No, - "the `#[rustc_unsafe_specialization_marker]` attribute is used to check specializations" + WarnFollowing,"the `#[rustc_unsafe_specialization_marker]` attribute is used to check specializations" ), rustc_attr!( rustc_specialization_trait, Normal, - WarnFollowing, EncodeCrossCrate::No, - "the `#[rustc_specialization_trait]` attribute is used to check specializations" + WarnFollowing,"the `#[rustc_specialization_trait]` attribute is used to check specializations" ), rustc_attr!( - rustc_main, Normal, WarnFollowing, EncodeCrossCrate::No, - "the `#[rustc_main]` attribute is used internally to specify test entry point function", + rustc_main, Normal, WarnFollowing,"the `#[rustc_main]` attribute is used internally to specify test entry point function", ), rustc_attr!( rustc_skip_during_method_dispatch, Normal, ErrorFollowing, - EncodeCrossCrate::No, "the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \ from method dispatch when the receiver is of the following type, for compatibility in \ editions < 2021 (array) or editions < 2024 (boxed_slice)" ), rustc_attr!( rustc_must_implement_one_of, Normal, - ErrorFollowing, EncodeCrossCrate::No, - "the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \ + ErrorFollowing,"the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \ definition of a trait. Its syntax and semantics are highly experimental and will be \ subject to change before stabilization", ), rustc_attr!( - rustc_doc_primitive, Normal, ErrorFollowing, - EncodeCrossCrate::Yes, "the `#[rustc_doc_primitive]` attribute is used by the standard library \ + rustc_doc_primitive, Normal, ErrorFollowing, "the `#[rustc_doc_primitive]` attribute is used by the standard library \ to provide a way to generate documentation for primitive types", ), gated!( - rustc_intrinsic, Normal, ErrorFollowing, EncodeCrossCrate::Yes, intrinsics, + rustc_intrinsic, Normal, ErrorFollowing, intrinsics, "the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items", ), rustc_attr!( - rustc_no_mir_inline, Normal, WarnFollowing, EncodeCrossCrate::Yes, - "`#[rustc_no_mir_inline]` prevents the MIR inliner from inlining a function while not affecting codegen" + rustc_no_mir_inline, Normal, WarnFollowing,"`#[rustc_no_mir_inline]` prevents the MIR inliner from inlining a function while not affecting codegen" ), rustc_attr!( - rustc_force_inline, Normal, WarnFollowing, EncodeCrossCrate::Yes, - "`#[rustc_force_inline]` forces a free function to be inlined" + rustc_force_inline, Normal, WarnFollowing,"`#[rustc_force_inline]` forces a free function to be inlined" ), rustc_attr!( - rustc_scalable_vector, Normal, WarnFollowing, EncodeCrossCrate::Yes, - "`#[rustc_scalable_vector]` defines a scalable vector type" + rustc_scalable_vector, Normal, WarnFollowing,"`#[rustc_scalable_vector]` defines a scalable vector type" ), // ========================================================================== // Internal attributes, Testing: // ========================================================================== - rustc_attr!(TEST, rustc_effective_visibility, Normal, WarnFollowing, EncodeCrossCrate::Yes), + rustc_attr!(TEST, rustc_effective_visibility, Normal, WarnFollowing,), rustc_attr!( TEST, rustc_dump_inferred_outlives, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_capture_analysis, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_insignificant_dtor, Normal, - WarnFollowing, EncodeCrossCrate::Yes + WarnFollowing, ), rustc_attr!( TEST, rustc_no_implicit_bounds, CrateLevel, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_strict_coherence, Normal, - WarnFollowing, EncodeCrossCrate::Yes + WarnFollowing, ), rustc_attr!( TEST, rustc_dump_variances, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_dump_variances_of_opaques, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_hidden_type_of_opaques, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_layout, Normal, - WarnFollowing, EncodeCrossCrate::Yes + WarnFollowing, ), rustc_attr!( TEST, rustc_abi, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_regions, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_delayed_bug_from_inside_query, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_dump_user_args, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_evaluate_where_clauses, Normal, WarnFollowing, - EncodeCrossCrate::Yes ), rustc_attr!( TEST, rustc_if_this_changed, Normal, DuplicatesOk, - EncodeCrossCrate::No ), rustc_attr!( TEST, rustc_then_this_would_need, Normal, DuplicatesOk, - EncodeCrossCrate::No ), rustc_attr!( TEST, rustc_clean, Normal, - DuplicatesOk, EncodeCrossCrate::No + DuplicatesOk, ), rustc_attr!( TEST, rustc_partition_reused, Normal, - DuplicatesOk, EncodeCrossCrate::No + DuplicatesOk, ), rustc_attr!( TEST, rustc_partition_codegened, Normal, - DuplicatesOk, EncodeCrossCrate::No + DuplicatesOk, ), rustc_attr!( TEST, rustc_expected_cgu_reuse, Normal, DuplicatesOk, - EncodeCrossCrate::No ), rustc_attr!( TEST, rustc_symbol_name, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_def_path, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_mir, Normal, - DuplicatesOk, EncodeCrossCrate::Yes + DuplicatesOk, ), gated!( custom_mir, Normal, - ErrorFollowing, EncodeCrossCrate::No, - "the `#[custom_mir]` attribute is just used for the Rust test suite", + ErrorFollowing,"the `#[custom_mir]` attribute is just used for the Rust test suite", ), rustc_attr!( TEST, rustc_dump_item_bounds, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_dump_predicates, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_dump_def_parents, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_dump_object_lifetime_defaults, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_dump_vtable, Normal, - WarnFollowing, EncodeCrossCrate::No + WarnFollowing, ), rustc_attr!( TEST, rustc_dummy, Normal, - DuplicatesOk, EncodeCrossCrate::No + DuplicatesOk, ), rustc_attr!( TEST, pattern_complexity_limit, CrateLevel, - ErrorFollowing, EncodeCrossCrate::No, + ErrorFollowing, ), ]; @@ -1382,16 +1276,6 @@ pub fn is_builtin_attr_name(name: Symbol) -> bool { BUILTIN_ATTRIBUTE_MAP.get(&name).is_some() } -/// Whether this builtin attribute is encoded cross crate. -/// This means it can be used cross crate. -pub fn encode_cross_crate(name: Symbol) -> bool { - if let Some(attr) = BUILTIN_ATTRIBUTE_MAP.get(&name) { - attr.encode_cross_crate == EncodeCrossCrate::Yes - } else { - true - } -} - pub fn is_valid_for_get_attr(name: Symbol) -> bool { BUILTIN_ATTRIBUTE_MAP.get(&name).is_some_and(|attr| match attr.duplicates { WarnFollowing | ErrorFollowing | ErrorPreceding | FutureWarnFollowing diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 9d046bdef1cf..3a5b153d6be3 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -131,8 +131,7 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option) -> bool && p.encode_cross_crate() == EncodeCrossCrate::No { // Attributes not marked encode-cross-crate don't need to be encoded for downstream crates. - } else if let Some(name) = attr.name() - && !rustc_feature::encode_cross_crate(name) - { - // Attributes not marked encode-cross-crate don't need to be encoded for downstream crates. } else if let hir::Attribute::Parsed(AttributeKind::DocComment { .. }) = attr { // We keep all doc comments reachable to rustdoc because they might be "imported" into // downstream crates if they use `#[doc(inline)]` to copy an item's documentation into From eecf63c1253de928ef8ecd0477f725ac7e5bc560 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 4 Apr 2026 13:47:12 +0200 Subject: [PATCH 17/37] Remove AttributeDuplicates from BUILTIN_ATTRIBUTES --- compiler/rustc_feature/src/builtin_attrs.rs | 568 +++++++------------- compiler/rustc_feature/src/lib.rs | 6 +- compiler/rustc_middle/src/ty/mod.rs | 9 +- compiler/rustc_passes/src/check_attr.rs | 79 +-- compiler/rustc_passes/src/errors.rs | 24 - 5 files changed, 196 insertions(+), 490 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 0c6dfcd98b7e..3e8e71c2d683 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -2,7 +2,6 @@ use std::sync::LazyLock; -use AttributeDuplicates::*; use AttributeGate::*; use AttributeType::*; use rustc_data_structures::fx::FxHashMap; @@ -74,7 +73,7 @@ pub fn find_gated_cfg(pred: impl Fn(Symbol) -> bool) -> Option<&'static GatedCfg #[derive(Copy, Clone, PartialEq, Debug)] pub enum AttributeType { - /// Normal, builtin attribute that is consumed + /// Normal,builtin attribute that is consumed /// by the compiler before the unused_attribute check Normal, /// Builtin attribute that is only allowed at the crate level @@ -178,57 +177,6 @@ pub fn suggestions( } } -/// How to handle multiple duplicate attributes on the same item. -#[derive(Clone, Copy, Default)] -pub enum AttributeDuplicates { - /// Duplicates of this attribute are allowed. - /// - /// This should only be used with attributes where duplicates have semantic - /// meaning, or some kind of "additive" behavior. For example, `#[warn(..)]` - /// can be specified multiple times, and it combines all the entries. Or use - /// this if there is validation done elsewhere. - #[default] - DuplicatesOk, - /// Duplicates after the first attribute will be an unused_attribute warning. - /// - /// This is usually used for "word" attributes, where they are used as a - /// boolean marker, like `#[used]`. It is not necessarily wrong that there - /// are duplicates, but the others should probably be removed. - WarnFollowing, - /// Same as `WarnFollowing`, but only issues warnings for word-style attributes. - /// - /// This is only for special cases, for example multiple `#[macro_use]` can - /// be warned, but multiple `#[macro_use(...)]` should not because the list - /// form has different meaning from the word form. - WarnFollowingWordOnly, - /// Duplicates after the first attribute will be an error. - /// - /// This should be used where duplicates would be ignored, but carry extra - /// meaning that could cause confusion. For example, `#[stable(since="1.0")] - /// #[stable(since="2.0")]`, which version should be used for `stable`? - ErrorFollowing, - /// Duplicates preceding the last instance of the attribute will be an error. - /// - /// This is the same as `ErrorFollowing`, except the last attribute is the - /// one that is "used". This is typically used in cases like codegen - /// attributes which usually only honor the last attribute. - ErrorPreceding, - /// Duplicates after the first attribute will be an unused_attribute warning - /// with a note that this will be an error in the future. - /// - /// This should be used for attributes that should be `ErrorFollowing`, but - /// because older versions of rustc silently accepted (and ignored) the - /// attributes, this is used to transition. - FutureWarnFollowing, - /// Duplicates preceding the last instance of the attribute will be a - /// warning, with a note that this will be an error in the future. - /// - /// This is the same as `FutureWarnFollowing`, except the last attribute is - /// the one that is "used". Ideally these can eventually migrate to - /// `ErrorPreceding`. - FutureWarnPreceding, -} - /// A convenience macro for constructing attribute templates. /// E.g., `template!(Word, List: "description")` means that the attribute /// supports forms `#[attr]` and `#[attr(description)]`. @@ -265,42 +213,39 @@ macro_rules! template { } macro_rules! ungated { - (unsafe($edition:ident) $attr:ident, $typ:expr, $duplicates:expr $(,)?) => { + (unsafe($edition:ident) $attr:ident, $typ:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: Some(Edition::$edition) }, gate: Ungated, - duplicates: $duplicates, } }; - (unsafe $attr:ident, $typ:expr, $duplicates:expr $(,)?) => { + (unsafe $attr:ident, $typ:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: None }, gate: Ungated, - duplicates: $duplicates, } }; - ($attr:ident, $typ:expr, $duplicates:expr $(,)?) => { + ($attr:ident, $typ:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, type_: $typ, safety: AttributeSafety::Normal, gate: Ungated, - duplicates: $duplicates, } }; } macro_rules! gated { - (unsafe $attr:ident, $typ:expr, $duplicates:expr, $gate:ident, $message:expr $(,)?) => { + (unsafe $attr:ident, $typ:expr, $gate:ident, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: None }, - duplicates: $duplicates, + gate: Gated { feature: sym::$gate, message: $message, @@ -309,12 +254,12 @@ macro_rules! gated { }, } }; - (unsafe $attr:ident, $typ:expr, $duplicates:expr, $message:expr $(,)?) => { + (unsafe $attr:ident, $typ:expr, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: None }, - duplicates: $duplicates, + gate: Gated { feature: sym::$attr, message: $message, @@ -323,12 +268,12 @@ macro_rules! gated { }, } }; - ($attr:ident, $typ:expr, $duplicates:expr, $gate:ident, $message:expr $(,)?) => { + ($attr:ident, $typ:expr, $gate:ident, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, type_: $typ, safety: AttributeSafety::Normal, - duplicates: $duplicates, + gate: Gated { feature: sym::$gate, message: $message, @@ -337,12 +282,12 @@ macro_rules! gated { }, } }; - ($attr:ident, $typ:expr, $duplicates:expr, $message:expr $(,)?) => { + ($attr:ident, $typ:expr, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, type_: $typ, safety: AttributeSafety::Normal, - duplicates: $duplicates, + gate: Gated { feature: sym::$attr, message: $message, @@ -354,11 +299,10 @@ macro_rules! gated { } macro_rules! rustc_attr { - (TEST, $attr:ident, $typ:expr, $duplicate:expr $(,)?) => { + (TEST, $attr:ident, $typ:expr, $(,)?) => { rustc_attr!( $attr, $typ, - $duplicate, concat!( "the `#[", stringify!($attr), @@ -366,12 +310,12 @@ macro_rules! rustc_attr { ), ) }; - ($attr:ident, $typ:expr, $duplicates:expr, $($notes:expr),* $(,)?) => { + ($attr:ident, $typ:expr, $($notes:expr),* $(,)?) => { BuiltinAttribute { name: sym::$attr, type_: $typ, safety: AttributeSafety::Normal, - duplicates: $duplicates, + gate: Gated { feature: sym::rustc_attrs, message: "use of an internal attribute", @@ -397,7 +341,6 @@ pub struct BuiltinAttribute { pub name: Symbol, pub type_: AttributeType, pub safety: AttributeSafety, - pub duplicates: AttributeDuplicates, pub gate: AttributeGate, } @@ -411,243 +354,194 @@ pub struct BuiltinAttribute { // Conditional compilation: ungated!( cfg, Normal, - DuplicatesOk, - ), + ), ungated!( cfg_attr, Normal, - DuplicatesOk, - ), + ), // Testing: ungated!( ignore, Normal, - WarnFollowing, - ), + ), ungated!( should_panic, Normal, - FutureWarnFollowing, ), // Macros: ungated!( automatically_derived, Normal, - WarnFollowing, - ), + ), ungated!( macro_use, Normal, - WarnFollowingWordOnly, ), - ungated!(macro_escape, Normal, WarnFollowing,), // Deprecated synonym for `macro_use`. + ungated!(macro_escape, Normal,), // Deprecated synonym for `macro_use`. ungated!( macro_export, Normal, - WarnFollowing, - ), + ), ungated!( proc_macro, Normal, - ErrorFollowing, - ), + ), ungated!( proc_macro_derive, Normal, - ErrorFollowing, - ), + ), ungated!( proc_macro_attribute, Normal, - ErrorFollowing, - ), + ), // Lints: ungated!( warn, Normal, - DuplicatesOk, - ), + ), ungated!( allow, Normal, - DuplicatesOk, - ), + ), ungated!( expect, Normal, - DuplicatesOk, - ), + ), ungated!( forbid, Normal, - DuplicatesOk, - ), + ), ungated!( deny, Normal, - DuplicatesOk, - ), + ), ungated!( must_use, Normal, - FutureWarnFollowing, ), gated!( - must_not_suspend, Normal, WarnFollowing, experimental!(must_not_suspend) + must_not_suspend, Normal, experimental!(must_not_suspend) ), ungated!( deprecated, Normal, - ErrorFollowing, - ), + ), // Crate properties: ungated!( crate_name, CrateLevel, - FutureWarnFollowing, ), ungated!( crate_type, CrateLevel, - DuplicatesOk, - ), + ), // ABI, linking, symbols, and FFI ungated!( link, Normal, - DuplicatesOk, - ), + ), ungated!( link_name, Normal, - FutureWarnPreceding, ), ungated!( no_link, Normal, - WarnFollowing, - ), + ), ungated!( repr, Normal, - DuplicatesOk, - ), + ), // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity - gated!(rustc_align, Normal, DuplicatesOk, fn_align, experimental!(rustc_align)), - gated!(rustc_align_static, Normal, DuplicatesOk, static_align, experimental!(rustc_align_static)), + gated!(rustc_align, Normal,fn_align, experimental!(rustc_align)), + gated!(rustc_align_static, Normal,static_align, experimental!(rustc_align_static)), ungated!( unsafe(Edition2024) export_name, Normal, - FutureWarnPreceding, ), ungated!( unsafe(Edition2024) link_section, Normal, - FutureWarnPreceding, ), ungated!( unsafe(Edition2024) no_mangle, Normal, - WarnFollowing, - ), + ), ungated!( used, Normal, - WarnFollowing, - ), + ), ungated!( link_ordinal, Normal, - ErrorPreceding, ), ungated!( unsafe naked, Normal, - WarnFollowing, - ), + ), // See `TyAndLayout::pass_indirectly_in_non_rustic_abis` for details. rustc_attr!( - rustc_pass_indirectly_in_non_rustic_abis, Normal, ErrorFollowing, - "types marked with `#[rustc_pass_indirectly_in_non_rustic_abis]` are always passed indirectly by non-Rustic ABIs" + rustc_pass_indirectly_in_non_rustic_abis, Normal, "types marked with `#[rustc_pass_indirectly_in_non_rustic_abis]` are always passed indirectly by non-Rustic ABIs" ), // Limits: ungated!( recursion_limit, CrateLevel, - FutureWarnFollowing, ), ungated!( type_length_limit, CrateLevel, - FutureWarnFollowing, ), gated!( - move_size_limit, CrateLevel, ErrorFollowing, large_assignments, experimental!(move_size_limit) + move_size_limit, CrateLevel, large_assignments, experimental!(move_size_limit) ), // Entry point: ungated!( no_main, CrateLevel, - WarnFollowing, - ), + ), // Modules, prelude, and resolution: ungated!( path, Normal, - FutureWarnFollowing, ), ungated!( no_std, CrateLevel, - WarnFollowing, - ), + ), ungated!( no_implicit_prelude, Normal, - WarnFollowing, - ), + ), ungated!( non_exhaustive, Normal, - WarnFollowing, - ), + ), // Runtime ungated!( windows_subsystem, CrateLevel, - FutureWarnFollowing, ), ungated!( // RFC 2070 panic_handler, Normal, - WarnFollowing, - ), + ), // Code generation: ungated!( inline, Normal, - FutureWarnFollowing, ), ungated!( cold, Normal, - WarnFollowing, ), ungated!( no_builtins, CrateLevel, - WarnFollowing, - ), + ), ungated!( target_feature, Normal, - DuplicatesOk, - ), + ), ungated!( track_caller, Normal, - WarnFollowing, - ), + ), ungated!( instruction_set, Normal, - ErrorPreceding, ), gated!( unsafe force_target_feature, Normal, - DuplicatesOk, effective_target_features, experimental!(force_target_feature) + effective_target_features, experimental!(force_target_feature) ), gated!( - sanitize, Normal, ErrorPreceding, + sanitize, Normal, sanitize, experimental!(sanitize), ), gated!( coverage, Normal, - ErrorPreceding, coverage_attribute, experimental!(coverage) ), ungated!( doc, Normal, - DuplicatesOk, - ), + ), // Debugging ungated!( debugger_visualizer, Normal, - DuplicatesOk, - ), + ), ungated!( collapse_debuginfo, Normal, - ErrorFollowing, - ), + ), // ========================================================================== // Unstable attributes: @@ -655,61 +549,60 @@ pub struct BuiltinAttribute { // Linking: gated!( - export_stable, Normal, WarnFollowing, experimental!(export_stable) + export_stable, Normal, experimental!(export_stable) ), // Testing: gated!( - test_runner, CrateLevel, ErrorFollowing, custom_test_frameworks, + test_runner, CrateLevel, custom_test_frameworks, "custom test frameworks are an unstable feature", ), gated!( - reexport_test_harness_main, CrateLevel, ErrorFollowing, custom_test_frameworks, + reexport_test_harness_main, CrateLevel, custom_test_frameworks, "custom test frameworks are an unstable feature", ), // RFC #1268 gated!( - marker, Normal, WarnFollowing,marker_trait_attr, experimental!(marker) + marker, Normal,marker_trait_attr, experimental!(marker) ), gated!( - thread_local, Normal, WarnFollowing,"`#[thread_local]` is an experimental feature, and does not currently handle destructors", + thread_local, Normal,"`#[thread_local]` is an experimental feature, and does not currently handle destructors", ), gated!( - no_core, CrateLevel, WarnFollowing, experimental!(no_core) + no_core, CrateLevel, experimental!(no_core) ), // RFC 2412 gated!( - optimize, Normal, ErrorPreceding, + optimize, Normal, optimize_attribute, experimental!(optimize) ), gated!( - unsafe ffi_pure, Normal, WarnFollowing, experimental!(ffi_pure) + unsafe ffi_pure, Normal, experimental!(ffi_pure) ), gated!( - unsafe ffi_const, Normal, WarnFollowing, experimental!(ffi_const) + unsafe ffi_const, Normal, experimental!(ffi_const) ), gated!( - register_tool, CrateLevel, DuplicatesOk, - experimental!(register_tool), + register_tool, CrateLevel, experimental!(register_tool), ), // `#[cfi_encoding = ""]` gated!( - cfi_encoding, Normal, ErrorPreceding, + cfi_encoding, Normal, experimental!(cfi_encoding) ), // `#[coroutine]` attribute to be applied to closures to make them coroutines instead gated!( - coroutine, Normal, ErrorFollowing, coroutines, experimental!(coroutine) + coroutine, Normal,coroutines, experimental!(coroutine) ), // RFC 3543 // `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` gated!( - patchable_function_entry, Normal, ErrorPreceding, + patchable_function_entry, Normal, experimental!(patchable_function_entry) ), @@ -718,10 +611,10 @@ pub struct BuiltinAttribute { // // - https://github.com/rust-lang/rust/issues/132306 gated!( - const_continue, Normal, ErrorFollowing, loop_match, experimental!(const_continue) + const_continue, Normal,loop_match, experimental!(const_continue) ), gated!( - loop_match, Normal, ErrorFollowing, loop_match, experimental!(loop_match) + loop_match, Normal,loop_match, experimental!(loop_match) ), // The `#[pin_v2]` attribute is part of the `pin_ergonomics` experiment @@ -729,7 +622,7 @@ pub struct BuiltinAttribute { // // - https://github.com/rust-lang/rust/issues/130494 gated!( - pin_v2, Normal, ErrorFollowing, pin_ergonomics, experimental!(pin_v2), + pin_v2, Normal,pin_ergonomics, experimental!(pin_v2), ), // ========================================================================== @@ -738,58 +631,48 @@ pub struct BuiltinAttribute { ungated!( feature, CrateLevel, - DuplicatesOk, - ), + ), // DuplicatesOk since it has its own validation ungated!( stable, Normal, - DuplicatesOk, - ), + ), ungated!( unstable, Normal, - DuplicatesOk, - ), + ), ungated!( unstable_feature_bound, Normal, - DuplicatesOk, - ), + ), ungated!( rustc_const_unstable, Normal, - DuplicatesOk, - ), + ), ungated!( rustc_const_stable, Normal, - DuplicatesOk, - ), + ), ungated!( rustc_default_body_unstable, Normal, - DuplicatesOk, - ), + ), gated!( allow_internal_unstable, Normal, - DuplicatesOk, - "allow_internal_unstable side-steps feature gating and stability checks", + "allow_internal_unstable side-steps feature gating and stability checks", ), gated!( - allow_internal_unsafe, Normal, WarnFollowing, "allow_internal_unsafe side-steps the unsafe_code lint", + allow_internal_unsafe, Normal, "allow_internal_unsafe side-steps the unsafe_code lint", ), gated!( rustc_eii_foreign_item, Normal, - ErrorFollowing, eii_internals, + eii_internals, "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", ), rustc_attr!( rustc_allowed_through_unstable_modules, Normal, - WarnFollowing,"rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \ + "rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \ through unstable paths" ), rustc_attr!( - rustc_deprecated_safe_2024, Normal, - ErrorFollowing,"`#[rustc_deprecated_safe_2024]` is used to declare functions unsafe across the edition 2024 boundary", + rustc_deprecated_safe_2024, Normal,"`#[rustc_deprecated_safe_2024]` is used to declare functions unsafe across the edition 2024 boundary", ), rustc_attr!( - rustc_pub_transparent, Normal, - ErrorFollowing,"used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", + rustc_pub_transparent, Normal,"used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", ), @@ -797,17 +680,16 @@ pub struct BuiltinAttribute { // Internal attributes: Type system related: // ========================================================================== - gated!(fundamental, Normal, WarnFollowing, experimental!(fundamental)), + gated!(fundamental, Normal, experimental!(fundamental)), gated!( - may_dangle, Normal, WarnFollowing, dropck_eyepatch, + may_dangle, Normal, dropck_eyepatch, "`may_dangle` has unstable semantics and may be removed in the future", ), rustc_attr!( rustc_never_type_options, Normal, - ErrorFollowing, - "`rustc_never_type_options` is used to experiment with never type fallback and work on \ + "`rustc_never_type_options` is used to experiment with never type fallback and work on \ never type stabilization" ), @@ -816,42 +698,42 @@ pub struct BuiltinAttribute { // ========================================================================== rustc_attr!( - rustc_allocator, Normal, WarnFollowing, + rustc_allocator, Normal, ), rustc_attr!( - rustc_nounwind, Normal, WarnFollowing, + rustc_nounwind, Normal, ), rustc_attr!( - rustc_reallocator, Normal, WarnFollowing, + rustc_reallocator, Normal, ), rustc_attr!( - rustc_deallocator, Normal, WarnFollowing, + rustc_deallocator, Normal, ), rustc_attr!( - rustc_allocator_zeroed, Normal, WarnFollowing, + rustc_allocator_zeroed, Normal, ), rustc_attr!( - rustc_allocator_zeroed_variant, Normal, ErrorPreceding, + rustc_allocator_zeroed_variant, Normal, ), gated!( - default_lib_allocator, Normal, WarnFollowing, allocator_internals, experimental!(default_lib_allocator), + default_lib_allocator, Normal, allocator_internals, experimental!(default_lib_allocator), ), gated!( - needs_allocator, Normal, WarnFollowing, allocator_internals, experimental!(needs_allocator), + needs_allocator, Normal, allocator_internals, experimental!(needs_allocator), ), gated!( - panic_runtime, CrateLevel, WarnFollowing, experimental!(panic_runtime) + panic_runtime, CrateLevel, experimental!(panic_runtime) ), gated!( - needs_panic_runtime, CrateLevel, WarnFollowing, experimental!(needs_panic_runtime) + needs_panic_runtime, CrateLevel, experimental!(needs_panic_runtime) ), gated!( - compiler_builtins, CrateLevel, WarnFollowing, + compiler_builtins, CrateLevel, "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \ which contains compiler-rt intrinsics and will never be stable", ), gated!( - profiler_runtime, CrateLevel, WarnFollowing, + profiler_runtime, CrateLevel, "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \ which contains the profiler runtime and will never be stable", ), @@ -862,17 +744,16 @@ pub struct BuiltinAttribute { gated!( linkage, Normal, - ErrorPreceding, "the `linkage` attribute is experimental and not portable across platforms", ), rustc_attr!( - rustc_std_internal_symbol, Normal, WarnFollowing, + rustc_std_internal_symbol, Normal, ), rustc_attr!( - rustc_objc_class, Normal, ErrorPreceding, + rustc_objc_class, Normal, ), rustc_attr!( - rustc_objc_selector, Normal, ErrorPreceding, + rustc_objc_selector, Normal, ), // ========================================================================== @@ -881,32 +762,29 @@ pub struct BuiltinAttribute { rustc_attr!( rustc_builtin_macro, Normal, - ErrorFollowing, - ), + ), rustc_attr!( - rustc_proc_macro_decls, Normal, WarnFollowing, + rustc_proc_macro_decls, Normal, ), rustc_attr!( rustc_macro_transparency, Normal, - ErrorFollowing, "used internally for testing macro hygiene", + "used internally for testing macro hygiene", ), rustc_attr!( rustc_autodiff, Normal, - DuplicatesOk, - ), + ), rustc_attr!( rustc_offload_kernel, Normal, - DuplicatesOk, - ), + ), // Traces that are left when `cfg` and `cfg_attr` attributes are expanded. // The attributes are not gated, to avoid stability errors, but they cannot be used in stable // or unstable code directly because `sym::cfg_(attr_)trace` are not valid identifiers, they // can only be generated by the compiler. ungated!( - cfg_trace, Normal, DuplicatesOk + cfg_trace, Normal ), ungated!( - cfg_attr_trace, Normal, DuplicatesOk + cfg_attr_trace, Normal ), // ========================================================================== @@ -914,74 +792,64 @@ pub struct BuiltinAttribute { // ========================================================================== rustc_attr!( - rustc_on_unimplemented, Normal, - ErrorFollowing,"see `#[diagnostic::on_unimplemented]` for the stable equivalent of this attribute" + rustc_on_unimplemented, Normal,"see `#[diagnostic::on_unimplemented]` for the stable equivalent of this attribute" ), rustc_attr!( rustc_confusables, Normal, - ErrorFollowing, - ), + ), // Enumerates "identity-like" conversion methods to suggest on type mismatch. rustc_attr!( rustc_conversion_suggestion, Normal, - WarnFollowing, - ), + ), // Prevents field reads in the marked trait or method to be considered // during dead code analysis. rustc_attr!( rustc_trivial_field_reads, Normal, - WarnFollowing, - ), + ), // Used by the `rustc::potential_query_instability` lint to warn methods which // might not be stable during incremental compilation. rustc_attr!( rustc_lint_query_instability, Normal, - WarnFollowing, - ), + ), // Used by the `rustc::untracked_query_information` lint to warn methods which // might not be stable during incremental compilation. rustc_attr!( rustc_lint_untracked_query_information, Normal, - WarnFollowing, - ), + ), // Used by the `rustc::bad_opt_access` lint to identify `DebuggingOptions` and `CodegenOptions` // types (as well as any others in future). rustc_attr!( rustc_lint_opt_ty, Normal, - WarnFollowing, - ), + ), // Used by the `rustc::bad_opt_access` lint on fields // types (as well as any others in future). rustc_attr!( rustc_lint_opt_deny_field_access, Normal, - WarnFollowing, - ), + ), // ========================================================================== // Internal attributes, Const related: // ========================================================================== rustc_attr!( - rustc_promotable, Normal, WarnFollowing, ), + rustc_promotable, Normal, ), rustc_attr!( - rustc_legacy_const_generics, Normal, ErrorFollowing, - ), + rustc_legacy_const_generics, Normal, ), // Do not const-check this function's body. It will always get replaced during CTFE via `hook_special_const_fn`. rustc_attr!( - rustc_do_not_const_check, Normal, WarnFollowing, "`#[rustc_do_not_const_check]` skips const-check for this function's body", + rustc_do_not_const_check, Normal, "`#[rustc_do_not_const_check]` skips const-check for this function's body", ), rustc_attr!( rustc_const_stable_indirect, Normal, - WarnFollowing,"this is an internal implementation detail", + "this is an internal implementation detail", ), rustc_attr!( rustc_intrinsic_const_stable_indirect, Normal, - WarnFollowing, "this is an internal implementation detail", + "this is an internal implementation detail", ), rustc_attr!( rustc_allow_const_fn_unstable, Normal, - DuplicatesOk, - "rustc_allow_const_fn_unstable side-steps feature gating and stability checks" + "rustc_allow_const_fn_unstable side-steps feature gating and stability checks" ), // ========================================================================== @@ -989,22 +857,19 @@ pub struct BuiltinAttribute { // ========================================================================== rustc_attr!( - rustc_layout_scalar_valid_range_start, Normal, ErrorFollowing, - "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \ + rustc_layout_scalar_valid_range_start, Normal, "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \ niche optimizations in the standard library", ), rustc_attr!( - rustc_layout_scalar_valid_range_end, Normal, ErrorFollowing, - "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \ + rustc_layout_scalar_valid_range_end, Normal, "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \ niche optimizations in the standard library", ), rustc_attr!( - rustc_simd_monomorphize_lane_limit, Normal, ErrorFollowing, - "the `#[rustc_simd_monomorphize_lane_limit]` attribute is just used by std::simd \ + rustc_simd_monomorphize_lane_limit, Normal, "the `#[rustc_simd_monomorphize_lane_limit]` attribute is just used by std::simd \ for better error messages", ), rustc_attr!( - rustc_nonnull_optimization_guaranteed, Normal, WarnFollowing, + rustc_nonnull_optimization_guaranteed, Normal, "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document \ guaranteed niche optimizations in the standard library", "the compiler does not even check whether the type indeed is being non-null-optimized; \ @@ -1015,59 +880,51 @@ pub struct BuiltinAttribute { // Internal attributes, Misc: // ========================================================================== gated!( - lang, Normal, DuplicatesOk, lang_items, + lang, Normal,lang_items, "lang items are subject to change", ), rustc_attr!( - rustc_as_ptr, Normal, ErrorFollowing, - "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations" + rustc_as_ptr, Normal, "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations" ), rustc_attr!( - rustc_should_not_be_called_on_const_items, Normal, ErrorFollowing, - "`#[rustc_should_not_be_called_on_const_items]` is used to mark methods that don't make sense to be called on interior mutable consts" + rustc_should_not_be_called_on_const_items, Normal, "`#[rustc_should_not_be_called_on_const_items]` is used to mark methods that don't make sense to be called on interior mutable consts" ), rustc_attr!( - rustc_pass_by_value, Normal, ErrorFollowing, - "`#[rustc_pass_by_value]` is used to mark types that must be passed by value instead of reference" + rustc_pass_by_value, Normal, "`#[rustc_pass_by_value]` is used to mark types that must be passed by value instead of reference" ), rustc_attr!( - rustc_never_returns_null_ptr, Normal, ErrorFollowing, - "`#[rustc_never_returns_null_ptr]` is used to mark functions returning non-null pointers" + rustc_never_returns_null_ptr, Normal, "`#[rustc_never_returns_null_ptr]` is used to mark functions returning non-null pointers" ), rustc_attr!( - rustc_no_implicit_autorefs, AttributeType::Normal, ErrorFollowing,"`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument" + rustc_no_implicit_autorefs, AttributeType::Normal, "`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument" ), rustc_attr!( - rustc_coherence_is_core, AttributeType::CrateLevel, ErrorFollowing,"`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`" + rustc_coherence_is_core, AttributeType::CrateLevel, "`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`" ), rustc_attr!( - rustc_coinductive, AttributeType::Normal, WarnFollowing,"`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver" + rustc_coinductive, AttributeType::Normal,"`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver" ), rustc_attr!( - rustc_allow_incoherent_impl, AttributeType::Normal, ErrorFollowing,"`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl" + rustc_allow_incoherent_impl, AttributeType::Normal, "`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl" ), rustc_attr!( - rustc_preserve_ub_checks, AttributeType::CrateLevel, ErrorFollowing,"`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR", + rustc_preserve_ub_checks, AttributeType::CrateLevel, "`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR", ), rustc_attr!( rustc_deny_explicit_impl, - AttributeType::Normal, - ErrorFollowing,"`#[rustc_deny_explicit_impl]` enforces that a trait can have no user-provided impls" + AttributeType::Normal,"`#[rustc_deny_explicit_impl]` enforces that a trait can have no user-provided impls" ), rustc_attr!( rustc_dyn_incompatible_trait, - AttributeType::Normal, - ErrorFollowing,"`#[rustc_dyn_incompatible_trait]` marks a trait as dyn-incompatible, \ + AttributeType::Normal,"`#[rustc_dyn_incompatible_trait]` marks a trait as dyn-incompatible, \ even if it otherwise satisfies the requirements to be dyn-compatible." ), rustc_attr!( - rustc_has_incoherent_inherent_impls, AttributeType::Normal, - ErrorFollowing,"`#[rustc_has_incoherent_inherent_impls]` allows the addition of incoherent inherent impls for \ + rustc_has_incoherent_inherent_impls, AttributeType::Normal,"`#[rustc_has_incoherent_inherent_impls]` allows the addition of incoherent inherent impls for \ the given type by annotating all impl items with `#[rustc_allow_incoherent_impl]`" ), rustc_attr!( - rustc_non_const_trait_method, AttributeType::Normal, - ErrorFollowing,"`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods \ + rustc_non_const_trait_method, AttributeType::Normal,"`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods \ as non-const to allow large traits an easier transition to const" ), @@ -1075,7 +932,7 @@ pub struct BuiltinAttribute { name: sym::rustc_diagnostic_item, type_: Normal, safety: AttributeSafety::Normal, - duplicates: ErrorFollowing,gate: Gated { + gate: Gated { feature: sym::rustc_attrs, message: "use of an internal attribute", check: Features::rustc_attrs, @@ -1085,205 +942,160 @@ pub struct BuiltinAttribute { }, gated!( // Used in resolve: - prelude_import, Normal, WarnFollowing, "`#[prelude_import]` is for use by rustc only", + prelude_import, Normal, "`#[prelude_import]` is for use by rustc only", ), gated!( - rustc_paren_sugar, Normal, WarnFollowing,unboxed_closures, "unboxed_closures are still evolving", + rustc_paren_sugar, Normal,unboxed_closures, "unboxed_closures are still evolving", ), rustc_attr!( - rustc_inherit_overflow_checks, Normal, WarnFollowing,"the `#[rustc_inherit_overflow_checks]` attribute is just used to control \ + rustc_inherit_overflow_checks, Normal,"the `#[rustc_inherit_overflow_checks]` attribute is just used to control \ overflow checking behavior of several functions in the standard library that are inlined \ across crates", ), rustc_attr!( - rustc_reservation_impl, Normal, - ErrorFollowing,"the `#[rustc_reservation_impl]` attribute is internally used \ + rustc_reservation_impl, Normal,"the `#[rustc_reservation_impl]` attribute is internally used \ for reserving `impl From for T` as part of the effort to stabilize `!`" ), rustc_attr!( - rustc_test_marker, Normal, WarnFollowing, "the `#[rustc_test_marker]` attribute is used internally to track tests", + rustc_test_marker, Normal, "the `#[rustc_test_marker]` attribute is used internally to track tests", ), rustc_attr!( rustc_unsafe_specialization_marker, Normal, - WarnFollowing,"the `#[rustc_unsafe_specialization_marker]` attribute is used to check specializations" + "the `#[rustc_unsafe_specialization_marker]` attribute is used to check specializations" ), rustc_attr!( rustc_specialization_trait, Normal, - WarnFollowing,"the `#[rustc_specialization_trait]` attribute is used to check specializations" + "the `#[rustc_specialization_trait]` attribute is used to check specializations" ), rustc_attr!( - rustc_main, Normal, WarnFollowing,"the `#[rustc_main]` attribute is used internally to specify test entry point function", + rustc_main, Normal,"the `#[rustc_main]` attribute is used internally to specify test entry point function", ), rustc_attr!( - rustc_skip_during_method_dispatch, Normal, ErrorFollowing, - "the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \ + rustc_skip_during_method_dispatch, Normal, "the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \ from method dispatch when the receiver is of the following type, for compatibility in \ editions < 2021 (array) or editions < 2024 (boxed_slice)" ), rustc_attr!( - rustc_must_implement_one_of, Normal, - ErrorFollowing,"the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \ + rustc_must_implement_one_of, Normal,"the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \ definition of a trait. Its syntax and semantics are highly experimental and will be \ subject to change before stabilization", ), rustc_attr!( - rustc_doc_primitive, Normal, ErrorFollowing, "the `#[rustc_doc_primitive]` attribute is used by the standard library \ + rustc_doc_primitive, Normal,"the `#[rustc_doc_primitive]` attribute is used by the standard library \ to provide a way to generate documentation for primitive types", ), gated!( - rustc_intrinsic, Normal, ErrorFollowing, intrinsics, + rustc_intrinsic, Normal,intrinsics, "the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items", ), rustc_attr!( - rustc_no_mir_inline, Normal, WarnFollowing,"`#[rustc_no_mir_inline]` prevents the MIR inliner from inlining a function while not affecting codegen" + rustc_no_mir_inline, Normal,"`#[rustc_no_mir_inline]` prevents the MIR inliner from inlining a function while not affecting codegen" ), rustc_attr!( - rustc_force_inline, Normal, WarnFollowing,"`#[rustc_force_inline]` forces a free function to be inlined" + rustc_force_inline, Normal,"`#[rustc_force_inline]` forces a free function to be inlined" ), rustc_attr!( - rustc_scalable_vector, Normal, WarnFollowing,"`#[rustc_scalable_vector]` defines a scalable vector type" + rustc_scalable_vector, Normal,"`#[rustc_scalable_vector]` defines a scalable vector type" ), // ========================================================================== // Internal attributes, Testing: // ========================================================================== - rustc_attr!(TEST, rustc_effective_visibility, Normal, WarnFollowing,), + rustc_attr!(TEST, rustc_effective_visibility, Normal,), rustc_attr!( TEST, rustc_dump_inferred_outlives, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_capture_analysis, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_insignificant_dtor, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_no_implicit_bounds, CrateLevel, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_strict_coherence, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_dump_variances, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_dump_variances_of_opaques, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_hidden_type_of_opaques, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_layout, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_abi, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_regions, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_delayed_bug_from_inside_query, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_dump_user_args, Normal, - WarnFollowing, + ), + rustc_attr!( + TEST, rustc_evaluate_where_clauses, Normal, ), rustc_attr!( - TEST, rustc_evaluate_where_clauses, Normal, WarnFollowing, - ), + TEST, rustc_if_this_changed, Normal, ), rustc_attr!( - TEST, rustc_if_this_changed, Normal, DuplicatesOk, - ), - rustc_attr!( - TEST, rustc_then_this_would_need, Normal, DuplicatesOk, - ), + TEST, rustc_then_this_would_need, Normal, ), rustc_attr!( TEST, rustc_clean, Normal, - DuplicatesOk, - ), + ), rustc_attr!( TEST, rustc_partition_reused, Normal, - DuplicatesOk, - ), + ), rustc_attr!( TEST, rustc_partition_codegened, Normal, - DuplicatesOk, - ), + ), rustc_attr!( TEST, rustc_expected_cgu_reuse, Normal, - DuplicatesOk, - ), + ), rustc_attr!( TEST, rustc_symbol_name, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_def_path, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_mir, Normal, - DuplicatesOk, - ), + ), gated!( - custom_mir, Normal, - ErrorFollowing,"the `#[custom_mir]` attribute is just used for the Rust test suite", + custom_mir, Normal,"the `#[custom_mir]` attribute is just used for the Rust test suite", ), rustc_attr!( TEST, rustc_dump_item_bounds, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_dump_predicates, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_dump_def_parents, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_dump_object_lifetime_defaults, Normal, - WarnFollowing, - ), + ), rustc_attr!( TEST, rustc_dump_vtable, Normal, - WarnFollowing, - ), - rustc_attr!( - TEST, rustc_dummy, Normal, - DuplicatesOk, - ), - rustc_attr!( - TEST, pattern_complexity_limit, CrateLevel, - ErrorFollowing, - ), + ), + rustc_attr!(TEST, rustc_dummy, Normal,), + rustc_attr!(TEST, pattern_complexity_limit, CrateLevel, ), ]; pub fn is_builtin_attr_name(name: Symbol) -> bool { BUILTIN_ATTRIBUTE_MAP.get(&name).is_some() } -pub fn is_valid_for_get_attr(name: Symbol) -> bool { - BUILTIN_ATTRIBUTE_MAP.get(&name).is_some_and(|attr| match attr.duplicates { - WarnFollowing | ErrorFollowing | ErrorPreceding | FutureWarnFollowing - | FutureWarnPreceding => true, - DuplicatesOk | WarnFollowingWordOnly => false, - }) -} - pub static BUILTIN_ATTRIBUTE_MAP: LazyLock> = LazyLock::new(|| { let mut map = FxHashMap::default(); diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 3a5b153d6be3..db37e4534df9 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -129,9 +129,9 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option, attr: Symbol) -> Option<&'tcx hir::Attribute> { - if cfg!(debug_assertions) && !rustc_feature::is_valid_for_get_attr(attr) { - let did: DefId = did.into(); - bug!("get_attr: unexpected called with DefId `{:?}`, attr `{:?}`", did, attr); - } else { - #[allow(deprecated)] - self.get_attrs(did, attr).next() - } + #[allow(deprecated)] + self.get_attrs(did, attr).next() } /// Determines whether an item is annotated with an attribute. diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 12b583d8fee1..4dca461f8aa5 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -6,17 +6,15 @@ //! item. use std::cell::Cell; -use std::collections::hash_map::Entry; use std::slice; use rustc_abi::ExternAbi; use rustc_ast::ast; use rustc_attr_parsing::{AttributeParser, Late}; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::unord::UnordMap; use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, msg}; -use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute}; +use rustc_feature::{AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute}; use rustc_hir::attrs::diagnostic::Directive; use rustc_hir::attrs::{ AttributeKind, CrateType, DocAttribute, DocInline, EiiDecl, EiiImpl, EiiImplResolution, @@ -137,7 +135,6 @@ fn check_attributes( target: Target, item: Option>, ) { - let mut seen = FxHashMap::default(); let attrs = self.tcx.hir_attrs(hir_id); for attr in attrs { match attr { @@ -449,19 +446,6 @@ fn check_attributes( } } - if let Attribute::Unparsed(unparsed_attr) = attr - && let Some(BuiltinAttribute { duplicates, .. }) = - attr.name().and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name)) - { - check_duplicates( - self.tcx, - unparsed_attr.span, - attr, - hir_id, - *duplicates, - &mut seen, - ); - } self.check_unused_attribute(hir_id, attr) } @@ -1994,67 +1978,6 @@ pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { check_mod_attrs, ..*providers }; } -// FIXME(jdonszelmann): remove, check during parsing -fn check_duplicates( - tcx: TyCtxt<'_>, - attr_span: Span, - attr: &Attribute, - hir_id: HirId, - duplicates: AttributeDuplicates, - seen: &mut FxHashMap, -) { - use AttributeDuplicates::*; - if matches!(duplicates, WarnFollowingWordOnly) && !attr.is_word() { - return; - } - let attr_name = attr.name().unwrap(); - match duplicates { - DuplicatesOk => {} - WarnFollowing | FutureWarnFollowing | WarnFollowingWordOnly | FutureWarnPreceding => { - match seen.entry(attr_name) { - Entry::Occupied(mut entry) => { - let (this, other) = if matches!(duplicates, FutureWarnPreceding) { - let to_remove = entry.insert(attr_span); - (to_remove, attr_span) - } else { - (attr_span, *entry.get()) - }; - tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - this, - errors::UnusedDuplicate { - this, - other, - warning: matches!( - duplicates, - FutureWarnFollowing | FutureWarnPreceding - ), - }, - ); - } - Entry::Vacant(entry) => { - entry.insert(attr_span); - } - } - } - ErrorFollowing | ErrorPreceding => match seen.entry(attr_name) { - Entry::Occupied(mut entry) => { - let (this, other) = if matches!(duplicates, ErrorPreceding) { - let to_remove = entry.insert(attr_span); - (to_remove, attr_span) - } else { - (attr_span, *entry.get()) - }; - tcx.dcx().emit_err(errors::UnusedMultiple { this, other, name: attr_name }); - } - Entry::Vacant(entry) => { - entry.insert(attr_span); - } - }, - } -} - fn doc_fake_variadic_is_allowed_self_ty(self_ty: &hir::Ty<'_>) -> bool { matches!(&self_ty.kind, hir::TyKind::Tup([_])) || if let hir::TyKind::FnPtr(fn_ptr_ty) = &self_ty.kind { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 628d0b0c961a..46b96ff1da35 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -326,30 +326,6 @@ pub(crate) struct InvalidMayDangle { pub attr_span: Span, } -#[derive(Diagnostic)] -#[diag("unused attribute")] -pub(crate) struct UnusedDuplicate { - #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] - pub this: Span, - #[note("attribute also specified here")] - pub other: Span, - #[warning( - "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" - )] - pub warning: bool, -} - -#[derive(Diagnostic)] -#[diag("multiple `{$name}` attributes")] -pub(crate) struct UnusedMultiple { - #[primary_span] - #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] - pub this: Span, - #[note("attribute also specified here")] - pub other: Span, - pub name: Symbol, -} - #[derive(Diagnostic)] #[diag("this `#[deprecated]` annotation has no effect")] pub(crate) struct DeprecatedAnnotationHasNoEffect { From 9058b5fce2e0390fdb00d69c6aeeb0242d70d741 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 4 Apr 2026 13:54:20 +0200 Subject: [PATCH 18/37] Remove AttributeType from BUILTIN_ATTRIBUTES --- compiler/rustc_feature/src/builtin_attrs.rs | 751 ++++++-------------- compiler/rustc_feature/src/lib.rs | 6 +- compiler/rustc_passes/src/check_attr.rs | 47 +- 3 files changed, 228 insertions(+), 576 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 3e8e71c2d683..db29b19b78cf 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -3,7 +3,6 @@ use std::sync::LazyLock; use AttributeGate::*; -use AttributeType::*; use rustc_data_structures::fx::FxHashMap; use rustc_hir::AttrStyle; use rustc_span::edition::Edition; @@ -71,15 +70,6 @@ pub fn find_gated_cfg(pred: impl Fn(Symbol) -> bool) -> Option<&'static GatedCfg // move that documentation into the relevant place in the other docs, and // remove the chapter on the flag. -#[derive(Copy, Clone, PartialEq, Debug)] -pub enum AttributeType { - /// Normal,builtin attribute that is consumed - /// by the compiler before the unused_attribute check - Normal, - /// Builtin attribute that is only allowed at the crate level - CrateLevel, -} - #[derive(Copy, Clone, PartialEq, Debug)] pub enum AttributeSafety { /// Normal attribute that does not need `#[unsafe(...)]` @@ -213,37 +203,29 @@ macro_rules! template { } macro_rules! ungated { - (unsafe($edition:ident) $attr:ident, $typ:expr $(,)?) => { + (unsafe($edition:ident) $attr:ident $(,)?) => { BuiltinAttribute { name: sym::$attr, - type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: Some(Edition::$edition) }, gate: Ungated, } }; - (unsafe $attr:ident, $typ:expr $(,)?) => { + (unsafe $attr:ident $(,)?) => { BuiltinAttribute { name: sym::$attr, - type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: None }, gate: Ungated, } }; - ($attr:ident, $typ:expr $(,)?) => { - BuiltinAttribute { - name: sym::$attr, - type_: $typ, - safety: AttributeSafety::Normal, - gate: Ungated, - } + ($attr:ident $(,)?) => { + BuiltinAttribute { name: sym::$attr, safety: AttributeSafety::Normal, gate: Ungated } }; } macro_rules! gated { - (unsafe $attr:ident, $typ:expr, $gate:ident, $message:expr $(,)?) => { + (unsafe $attr:ident, $gate:ident, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, - type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: None }, gate: Gated { @@ -254,10 +236,9 @@ macro_rules! gated { }, } }; - (unsafe $attr:ident, $typ:expr, $message:expr $(,)?) => { + (unsafe $attr:ident, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, - type_: $typ, safety: AttributeSafety::Unsafe { unsafe_since: None }, gate: Gated { @@ -268,10 +249,9 @@ macro_rules! gated { }, } }; - ($attr:ident, $typ:expr, $gate:ident, $message:expr $(,)?) => { + ($attr:ident, $gate:ident, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, - type_: $typ, safety: AttributeSafety::Normal, gate: Gated { @@ -282,10 +262,9 @@ macro_rules! gated { }, } }; - ($attr:ident, $typ:expr, $message:expr $(,)?) => { + ($attr:ident, $message:expr $(,)?) => { BuiltinAttribute { name: sym::$attr, - type_: $typ, safety: AttributeSafety::Normal, gate: Gated { @@ -299,10 +278,8 @@ macro_rules! gated { } macro_rules! rustc_attr { - (TEST, $attr:ident, $typ:expr, $(,)?) => { - rustc_attr!( - $attr, - $typ, + (TEST, $attr:ident, $(,)?) => { + rustc_attr!( $attr, concat!( "the `#[", stringify!($attr), @@ -310,12 +287,10 @@ macro_rules! rustc_attr { ), ) }; - ($attr:ident, $typ:expr, $($notes:expr),* $(,)?) => { + ($attr:ident, $($notes:expr),* $(,)?) => { BuiltinAttribute { name: sym::$attr, - type_: $typ, safety: AttributeSafety::Normal, - gate: Gated { feature: sym::rustc_attrs, message: "use of an internal attribute", @@ -339,7 +314,6 @@ macro_rules! experimental { pub struct BuiltinAttribute { pub name: Symbol, - pub type_: AttributeType, pub safety: AttributeSafety, pub gate: AttributeGate, } @@ -352,196 +326,98 @@ pub struct BuiltinAttribute { // ========================================================================== // Conditional compilation: - ungated!( - cfg, Normal, - ), - ungated!( - cfg_attr, Normal, - ), + ungated!(cfg,), + ungated!(cfg_attr,), // Testing: - ungated!( - ignore, Normal, - ), - ungated!( - should_panic, Normal, - ), + ungated!(ignore,), + ungated!(should_panic,), // Macros: - ungated!( - automatically_derived, Normal, - ), - ungated!( - macro_use, Normal, - ), - ungated!(macro_escape, Normal,), // Deprecated synonym for `macro_use`. - ungated!( - macro_export, Normal, - ), - ungated!( - proc_macro, Normal, - ), - ungated!( - proc_macro_derive, Normal, - ), - ungated!( - proc_macro_attribute, Normal, - ), + ungated!(automatically_derived,), + ungated!(macro_use,), + ungated!(macro_escape,), // Deprecated synonym for `macro_use`. + ungated!(macro_export,), + ungated!(proc_macro,), + ungated!(proc_macro_derive,), + ungated!(proc_macro_attribute,), // Lints: - ungated!( - warn, Normal, - ), - ungated!( - allow, Normal, - ), - ungated!( - expect, Normal, - ), - ungated!( - forbid, Normal, - ), - ungated!( - deny, Normal, - ), - ungated!( - must_use, Normal, - ), - gated!( - must_not_suspend, Normal, experimental!(must_not_suspend) - ), - ungated!( - deprecated, Normal, - ), + ungated!(warn,), + ungated!(allow,), + ungated!(expect,), + ungated!(forbid,), + ungated!(deny,), + ungated!(must_use,), + gated!(must_not_suspend, experimental!(must_not_suspend)), + ungated!(deprecated,), // Crate properties: - ungated!( - crate_name, CrateLevel, - ), - ungated!( - crate_type, CrateLevel, - ), + ungated!(crate_name,), + ungated!(crate_type,), // ABI, linking, symbols, and FFI - ungated!( - link, Normal, - ), - ungated!( - link_name, Normal, - ), - ungated!( - no_link, Normal, - ), - ungated!( - repr, Normal, - ), + ungated!(link,), + ungated!(link_name,), + ungated!(no_link,), + ungated!(repr,), // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity - gated!(rustc_align, Normal,fn_align, experimental!(rustc_align)), - gated!(rustc_align_static, Normal,static_align, experimental!(rustc_align_static)), - ungated!( - unsafe(Edition2024) export_name, Normal, - ), - ungated!( - unsafe(Edition2024) link_section, Normal, - ), - ungated!( - unsafe(Edition2024) no_mangle, Normal, - ), - ungated!( - used, Normal, - ), - ungated!( - link_ordinal, Normal, - ), - ungated!( - unsafe naked, Normal, - ), + gated!(rustc_align,fn_align, experimental!(rustc_align)), + gated!(rustc_align_static,static_align, experimental!(rustc_align_static)), + ungated!(unsafe(Edition2024) export_name,), + ungated!(unsafe(Edition2024) link_section,), + ungated!(unsafe(Edition2024) no_mangle,), + ungated!(used,), + ungated!(link_ordinal,), + ungated!(unsafe naked,), // See `TyAndLayout::pass_indirectly_in_non_rustic_abis` for details. - rustc_attr!( - rustc_pass_indirectly_in_non_rustic_abis, Normal, "types marked with `#[rustc_pass_indirectly_in_non_rustic_abis]` are always passed indirectly by non-Rustic ABIs" - ), + rustc_attr!(rustc_pass_indirectly_in_non_rustic_abis, "types marked with `#[rustc_pass_indirectly_in_non_rustic_abis]` are always passed indirectly by non-Rustic ABIs"), // Limits: - ungated!( - recursion_limit, CrateLevel, - ), - ungated!( - type_length_limit, CrateLevel, - ), + ungated!(recursion_limit,), + ungated!(type_length_limit,), gated!( - move_size_limit, CrateLevel, large_assignments, experimental!(move_size_limit) + move_size_limit, large_assignments, experimental!(move_size_limit) ), // Entry point: - ungated!( - no_main, CrateLevel, - ), + ungated!(no_main,), // Modules, prelude, and resolution: - ungated!( - path, Normal, - ), - ungated!( - no_std, CrateLevel, - ), - ungated!( - no_implicit_prelude, Normal, - ), - ungated!( - non_exhaustive, Normal, - ), + ungated!(path,), + ungated!(no_std,), + ungated!(no_implicit_prelude,), + ungated!(non_exhaustive,), // Runtime - ungated!( - windows_subsystem, CrateLevel, - ), - ungated!( // RFC 2070 - panic_handler, Normal, - ), + ungated!(windows_subsystem,), + ungated!(// RFC 2070 + panic_handler,), // Code generation: - ungated!( - inline, Normal, - ), - ungated!( - cold, Normal, - ), - ungated!( - no_builtins, CrateLevel, - ), - ungated!( - target_feature, Normal, - ), - ungated!( - track_caller, Normal, - ), - ungated!( - instruction_set, Normal, - ), + ungated!(inline,), + ungated!(cold,), + ungated!(no_builtins,), + ungated!(target_feature,), + ungated!(track_caller,), + ungated!(instruction_set,), gated!( - unsafe force_target_feature, Normal, + unsafe force_target_feature, effective_target_features, experimental!(force_target_feature) ), gated!( - sanitize, Normal, - sanitize, experimental!(sanitize), - ), + sanitize, + sanitize, experimental!(sanitize),), gated!( - coverage, Normal, + coverage, coverage_attribute, experimental!(coverage) ), - ungated!( - doc, Normal, - ), + ungated!(doc,), // Debugging - ungated!( - debugger_visualizer, Normal, - ), - ungated!( - collapse_debuginfo, Normal, - ), + ungated!(debugger_visualizer,), + ungated!(collapse_debuginfo,), // ========================================================================== // Unstable attributes: @@ -549,60 +425,56 @@ pub struct BuiltinAttribute { // Linking: gated!( - export_stable, Normal, experimental!(export_stable) + export_stable, experimental!(export_stable) ), // Testing: gated!( - test_runner, CrateLevel, custom_test_frameworks, - "custom test frameworks are an unstable feature", - ), + test_runner, custom_test_frameworks, + "custom test frameworks are an unstable feature",), gated!( - reexport_test_harness_main, CrateLevel, custom_test_frameworks, - "custom test frameworks are an unstable feature", - ), + reexport_test_harness_main, custom_test_frameworks, + "custom test frameworks are an unstable feature",), // RFC #1268 gated!( - marker, Normal,marker_trait_attr, experimental!(marker) + marker,marker_trait_attr, experimental!(marker) ), gated!( - thread_local, Normal,"`#[thread_local]` is an experimental feature, and does not currently handle destructors", - ), + thread_local,"`#[thread_local]` is an experimental feature, and does not currently handle destructors",), gated!( - no_core, CrateLevel, experimental!(no_core) + no_core, experimental!(no_core) ), // RFC 2412 gated!( - optimize, Normal, + optimize, optimize_attribute, experimental!(optimize) ), gated!( - unsafe ffi_pure, Normal, experimental!(ffi_pure) + unsafe ffi_pure, experimental!(ffi_pure) ), gated!( - unsafe ffi_const, Normal, experimental!(ffi_const) + unsafe ffi_const, experimental!(ffi_const) ), gated!( - register_tool, CrateLevel, experimental!(register_tool), - ), + register_tool, experimental!(register_tool),), // `#[cfi_encoding = ""]` gated!( - cfi_encoding, Normal, + cfi_encoding, experimental!(cfi_encoding) ), // `#[coroutine]` attribute to be applied to closures to make them coroutines instead gated!( - coroutine, Normal,coroutines, experimental!(coroutine) + coroutine,coroutines, experimental!(coroutine) ), // RFC 3543 // `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` gated!( - patchable_function_entry, Normal, + patchable_function_entry, experimental!(patchable_function_entry) ), @@ -611,10 +483,10 @@ pub struct BuiltinAttribute { // // - https://github.com/rust-lang/rust/issues/132306 gated!( - const_continue, Normal,loop_match, experimental!(const_continue) + const_continue,loop_match, experimental!(const_continue) ), gated!( - loop_match, Normal,loop_match, experimental!(loop_match) + loop_match,loop_match, experimental!(loop_match) ), // The `#[pin_v2]` attribute is part of the `pin_ergonomics` experiment @@ -622,57 +494,40 @@ pub struct BuiltinAttribute { // // - https://github.com/rust-lang/rust/issues/130494 gated!( - pin_v2, Normal,pin_ergonomics, experimental!(pin_v2), + pin_v2,pin_ergonomics, experimental!(pin_v2), ), // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: // ========================================================================== - ungated!( - feature, CrateLevel, - ), + ungated!(feature,), // DuplicatesOk since it has its own validation - ungated!( - stable, Normal, - ), - ungated!( - unstable, Normal, - ), - ungated!( - unstable_feature_bound, Normal, - ), - ungated!( - rustc_const_unstable, Normal, - ), - ungated!( - rustc_const_stable, Normal, - ), - ungated!( - rustc_default_body_unstable, Normal, - ), + ungated!(stable,), + ungated!(unstable,), + ungated!(unstable_feature_bound,), + ungated!(rustc_const_unstable,), + ungated!(rustc_const_stable,), + ungated!(rustc_default_body_unstable,), gated!( - allow_internal_unstable, Normal, - "allow_internal_unstable side-steps feature gating and stability checks", + allow_internal_unstable, + "allow_internal_unstable side-steps feature gating and stability checks", ), gated!( - allow_internal_unsafe, Normal, "allow_internal_unsafe side-steps the unsafe_code lint", + allow_internal_unsafe, "allow_internal_unsafe side-steps the unsafe_code lint", ), gated!( - rustc_eii_foreign_item, Normal, + rustc_eii_foreign_item, eii_internals, "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", ), - rustc_attr!( - rustc_allowed_through_unstable_modules, Normal, + rustc_attr!(rustc_allowed_through_unstable_modules, "rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \ through unstable paths" ), - rustc_attr!( - rustc_deprecated_safe_2024, Normal,"`#[rustc_deprecated_safe_2024]` is used to declare functions unsafe across the edition 2024 boundary", + rustc_attr!(rustc_deprecated_safe_2024,"`#[rustc_deprecated_safe_2024]` is used to declare functions unsafe across the edition 2024 boundary", ), - rustc_attr!( - rustc_pub_transparent, Normal,"used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", + rustc_attr!(rustc_pub_transparent,"used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", ), @@ -680,16 +535,13 @@ pub struct BuiltinAttribute { // Internal attributes: Type system related: // ========================================================================== - gated!(fundamental, Normal, experimental!(fundamental)), + gated!(fundamental, experimental!(fundamental)), gated!( - may_dangle, Normal, dropck_eyepatch, - "`may_dangle` has unstable semantics and may be removed in the future", - ), + may_dangle, dropck_eyepatch, + "`may_dangle` has unstable semantics and may be removed in the future",), - rustc_attr!( - rustc_never_type_options, - Normal, - "`rustc_never_type_options` is used to experiment with never type fallback and work on \ + rustc_attr!(rustc_never_type_options, + "`rustc_never_type_options` is used to experiment with never type fallback and work on \ never type stabilization" ), @@ -697,158 +549,101 @@ pub struct BuiltinAttribute { // Internal attributes: Runtime related: // ========================================================================== - rustc_attr!( - rustc_allocator, Normal, - ), - rustc_attr!( - rustc_nounwind, Normal, - ), - rustc_attr!( - rustc_reallocator, Normal, - ), - rustc_attr!( - rustc_deallocator, Normal, - ), - rustc_attr!( - rustc_allocator_zeroed, Normal, - ), - rustc_attr!( - rustc_allocator_zeroed_variant, Normal, + rustc_attr!(rustc_allocator,), + rustc_attr!(rustc_nounwind,), + rustc_attr!(rustc_reallocator,), + rustc_attr!(rustc_deallocator,), + rustc_attr!(rustc_allocator_zeroed,), + rustc_attr!(rustc_allocator_zeroed_variant,), + gated!( + default_lib_allocator, allocator_internals, experimental!(default_lib_allocator), ), gated!( - default_lib_allocator, Normal, allocator_internals, experimental!(default_lib_allocator), + needs_allocator, allocator_internals, experimental!(needs_allocator), ), gated!( - needs_allocator, Normal, allocator_internals, experimental!(needs_allocator), + panic_runtime, experimental!(panic_runtime) ), gated!( - panic_runtime, CrateLevel, experimental!(panic_runtime) + needs_panic_runtime, experimental!(needs_panic_runtime) ), gated!( - needs_panic_runtime, CrateLevel, experimental!(needs_panic_runtime) - ), - gated!( - compiler_builtins, CrateLevel, + compiler_builtins, "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \ - which contains compiler-rt intrinsics and will never be stable", - ), + which contains compiler-rt intrinsics and will never be stable",), gated!( - profiler_runtime, CrateLevel, + profiler_runtime, "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \ - which contains the profiler runtime and will never be stable", - ), + which contains the profiler runtime and will never be stable",), // ========================================================================== // Internal attributes, Linkage: // ========================================================================== gated!( - linkage, Normal, - "the `linkage` attribute is experimental and not portable across platforms", - ), - rustc_attr!( - rustc_std_internal_symbol, Normal, - ), - rustc_attr!( - rustc_objc_class, Normal, - ), - rustc_attr!( - rustc_objc_selector, Normal, - ), + linkage, + "the `linkage` attribute is experimental and not portable across platforms",), + rustc_attr!(rustc_std_internal_symbol,), + rustc_attr!(rustc_objc_class,), + rustc_attr!(rustc_objc_selector,), // ========================================================================== // Internal attributes, Macro related: // ========================================================================== - rustc_attr!( - rustc_builtin_macro, Normal, - ), - rustc_attr!( - rustc_proc_macro_decls, Normal, - ), - rustc_attr!( - rustc_macro_transparency, Normal, - "used internally for testing macro hygiene", - ), - rustc_attr!( - rustc_autodiff, Normal, - ), - rustc_attr!( - rustc_offload_kernel, Normal, - ), + rustc_attr!(rustc_builtin_macro,), + rustc_attr!(rustc_proc_macro_decls,), + rustc_attr!(rustc_macro_transparency, + "used internally for testing macro hygiene",), + rustc_attr!(rustc_autodiff,), + rustc_attr!(rustc_offload_kernel,), // Traces that are left when `cfg` and `cfg_attr` attributes are expanded. // The attributes are not gated, to avoid stability errors, but they cannot be used in stable // or unstable code directly because `sym::cfg_(attr_)trace` are not valid identifiers, they // can only be generated by the compiler. - ungated!( - cfg_trace, Normal + ungated!(cfg_trace ), - ungated!( - cfg_attr_trace, Normal + ungated!(cfg_attr_trace ), // ========================================================================== // Internal attributes, Diagnostics related: // ========================================================================== - rustc_attr!( - rustc_on_unimplemented, Normal,"see `#[diagnostic::on_unimplemented]` for the stable equivalent of this attribute" + rustc_attr!(rustc_on_unimplemented,"see `#[diagnostic::on_unimplemented]` for the stable equivalent of this attribute" ), - rustc_attr!( - rustc_confusables, Normal, - ), + rustc_attr!(rustc_confusables,), // Enumerates "identity-like" conversion methods to suggest on type mismatch. - rustc_attr!( - rustc_conversion_suggestion, Normal, - ), + rustc_attr!(rustc_conversion_suggestion,), // Prevents field reads in the marked trait or method to be considered // during dead code analysis. - rustc_attr!( - rustc_trivial_field_reads, Normal, - ), + rustc_attr!(rustc_trivial_field_reads,), // Used by the `rustc::potential_query_instability` lint to warn methods which // might not be stable during incremental compilation. - rustc_attr!( - rustc_lint_query_instability, Normal, - ), + rustc_attr!(rustc_lint_query_instability,), // Used by the `rustc::untracked_query_information` lint to warn methods which // might not be stable during incremental compilation. - rustc_attr!( - rustc_lint_untracked_query_information, Normal, - ), + rustc_attr!(rustc_lint_untracked_query_information,), // Used by the `rustc::bad_opt_access` lint to identify `DebuggingOptions` and `CodegenOptions` // types (as well as any others in future). - rustc_attr!( - rustc_lint_opt_ty, Normal, - ), + rustc_attr!(rustc_lint_opt_ty,), // Used by the `rustc::bad_opt_access` lint on fields // types (as well as any others in future). - rustc_attr!( - rustc_lint_opt_deny_field_access, Normal, - ), + rustc_attr!(rustc_lint_opt_deny_field_access,), // ========================================================================== // Internal attributes, Const related: // ========================================================================== - rustc_attr!( - rustc_promotable, Normal, ), - rustc_attr!( - rustc_legacy_const_generics, Normal, ), + rustc_attr!(rustc_promotable,), + rustc_attr!(rustc_legacy_const_generics,), // Do not const-check this function's body. It will always get replaced during CTFE via `hook_special_const_fn`. - rustc_attr!( - rustc_do_not_const_check, Normal, "`#[rustc_do_not_const_check]` skips const-check for this function's body", - ), - rustc_attr!( - rustc_const_stable_indirect, Normal, - "this is an internal implementation detail", - ), - rustc_attr!( - rustc_intrinsic_const_stable_indirect, Normal, - "this is an internal implementation detail", - ), - rustc_attr!( - rustc_allow_const_fn_unstable, Normal, + rustc_attr!(rustc_do_not_const_check, "`#[rustc_do_not_const_check]` skips const-check for this function's body",), + rustc_attr!(rustc_const_stable_indirect, + "this is an internal implementation detail",), + rustc_attr!(rustc_intrinsic_const_stable_indirect, + "this is an internal implementation detail",), + rustc_attr!(rustc_allow_const_fn_unstable, "rustc_allow_const_fn_unstable side-steps feature gating and stability checks" ), @@ -856,81 +651,57 @@ pub struct BuiltinAttribute { // Internal attributes, Layout related: // ========================================================================== - rustc_attr!( - rustc_layout_scalar_valid_range_start, Normal, "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \ - niche optimizations in the standard library", - ), - rustc_attr!( - rustc_layout_scalar_valid_range_end, Normal, "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \ - niche optimizations in the standard library", - ), - rustc_attr!( - rustc_simd_monomorphize_lane_limit, Normal, "the `#[rustc_simd_monomorphize_lane_limit]` attribute is just used by std::simd \ - for better error messages", - ), - rustc_attr!( - rustc_nonnull_optimization_guaranteed, Normal, + rustc_attr!(rustc_layout_scalar_valid_range_start, "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \ + niche optimizations in the standard library",), + rustc_attr!(rustc_layout_scalar_valid_range_end, "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \ + niche optimizations in the standard library",), + rustc_attr!(rustc_simd_monomorphize_lane_limit, "the `#[rustc_simd_monomorphize_lane_limit]` attribute is just used by std::simd \ + for better error messages",), + rustc_attr!(rustc_nonnull_optimization_guaranteed, "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document \ guaranteed niche optimizations in the standard library", "the compiler does not even check whether the type indeed is being non-null-optimized; \ - it is your responsibility to ensure that the attribute is only used on types that are optimized", - ), + it is your responsibility to ensure that the attribute is only used on types that are optimized",), // ========================================================================== // Internal attributes, Misc: // ========================================================================== gated!( - lang, Normal,lang_items, - "lang items are subject to change", + lang,lang_items, + "lang items are subject to change",), + rustc_attr!(rustc_as_ptr, "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations" ), - rustc_attr!( - rustc_as_ptr, Normal, "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations" + rustc_attr!(rustc_should_not_be_called_on_const_items, "`#[rustc_should_not_be_called_on_const_items]` is used to mark methods that don't make sense to be called on interior mutable consts" ), - rustc_attr!( - rustc_should_not_be_called_on_const_items, Normal, "`#[rustc_should_not_be_called_on_const_items]` is used to mark methods that don't make sense to be called on interior mutable consts" + rustc_attr!(rustc_pass_by_value, "`#[rustc_pass_by_value]` is used to mark types that must be passed by value instead of reference" ), - rustc_attr!( - rustc_pass_by_value, Normal, "`#[rustc_pass_by_value]` is used to mark types that must be passed by value instead of reference" + rustc_attr!(rustc_never_returns_null_ptr, "`#[rustc_never_returns_null_ptr]` is used to mark functions returning non-null pointers" ), - rustc_attr!( - rustc_never_returns_null_ptr, Normal, "`#[rustc_never_returns_null_ptr]` is used to mark functions returning non-null pointers" + rustc_attr!(rustc_no_implicit_autorefs, "`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument" ), - rustc_attr!( - rustc_no_implicit_autorefs, AttributeType::Normal, "`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument" + rustc_attr!(rustc_coherence_is_core, "`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`" ), - rustc_attr!( - rustc_coherence_is_core, AttributeType::CrateLevel, "`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`" + rustc_attr!(rustc_coinductive, "`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver" ), - rustc_attr!( - rustc_coinductive, AttributeType::Normal,"`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver" + rustc_attr!(rustc_allow_incoherent_impl, "`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl" ), - rustc_attr!( - rustc_allow_incoherent_impl, AttributeType::Normal, "`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl" + rustc_attr!(rustc_preserve_ub_checks, "`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR",), + rustc_attr!(rustc_deny_explicit_impl, + "`#[rustc_deny_explicit_impl]` enforces that a trait can have no user-provided impls" ), - rustc_attr!( - rustc_preserve_ub_checks, AttributeType::CrateLevel, "`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR", - ), - rustc_attr!( - rustc_deny_explicit_impl, - AttributeType::Normal,"`#[rustc_deny_explicit_impl]` enforces that a trait can have no user-provided impls" - ), - rustc_attr!( - rustc_dyn_incompatible_trait, - AttributeType::Normal,"`#[rustc_dyn_incompatible_trait]` marks a trait as dyn-incompatible, \ + rustc_attr!(rustc_dyn_incompatible_trait, + "`#[rustc_dyn_incompatible_trait]` marks a trait as dyn-incompatible, \ even if it otherwise satisfies the requirements to be dyn-compatible." ), - rustc_attr!( - rustc_has_incoherent_inherent_impls, AttributeType::Normal,"`#[rustc_has_incoherent_inherent_impls]` allows the addition of incoherent inherent impls for \ + rustc_attr!(rustc_has_incoherent_inherent_impls, "`#[rustc_has_incoherent_inherent_impls]` allows the addition of incoherent inherent impls for \ the given type by annotating all impl items with `#[rustc_allow_incoherent_impl]`" ), - rustc_attr!( - rustc_non_const_trait_method, AttributeType::Normal,"`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods \ + rustc_attr!(rustc_non_const_trait_method, "`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods \ as non-const to allow large traits an easier transition to const" ), BuiltinAttribute { name: sym::rustc_diagnostic_item, - type_: Normal, safety: AttributeSafety::Normal, gate: Gated { feature: sym::rustc_attrs, @@ -942,154 +713,80 @@ pub struct BuiltinAttribute { }, gated!( // Used in resolve: - prelude_import, Normal, "`#[prelude_import]` is for use by rustc only", + prelude_import, "`#[prelude_import]` is for use by rustc only", ), gated!( - rustc_paren_sugar, Normal,unboxed_closures, "unboxed_closures are still evolving", + rustc_paren_sugar,unboxed_closures, "unboxed_closures are still evolving", ), - rustc_attr!( - rustc_inherit_overflow_checks, Normal,"the `#[rustc_inherit_overflow_checks]` attribute is just used to control \ + rustc_attr!(rustc_inherit_overflow_checks,"the `#[rustc_inherit_overflow_checks]` attribute is just used to control \ overflow checking behavior of several functions in the standard library that are inlined \ - across crates", - ), - rustc_attr!( - rustc_reservation_impl, Normal,"the `#[rustc_reservation_impl]` attribute is internally used \ + across crates",), + rustc_attr!(rustc_reservation_impl,"the `#[rustc_reservation_impl]` attribute is internally used \ for reserving `impl From for T` as part of the effort to stabilize `!`" ), - rustc_attr!( - rustc_test_marker, Normal, "the `#[rustc_test_marker]` attribute is used internally to track tests", - ), - rustc_attr!( - rustc_unsafe_specialization_marker, Normal, + rustc_attr!(rustc_test_marker, "the `#[rustc_test_marker]` attribute is used internally to track tests",), + rustc_attr!(rustc_unsafe_specialization_marker, "the `#[rustc_unsafe_specialization_marker]` attribute is used to check specializations" ), - rustc_attr!( - rustc_specialization_trait, Normal, + rustc_attr!(rustc_specialization_trait, "the `#[rustc_specialization_trait]` attribute is used to check specializations" ), - rustc_attr!( - rustc_main, Normal,"the `#[rustc_main]` attribute is used internally to specify test entry point function", - ), - rustc_attr!( - rustc_skip_during_method_dispatch, Normal, "the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \ + rustc_attr!(rustc_main,"the `#[rustc_main]` attribute is used internally to specify test entry point function",), + rustc_attr!(rustc_skip_during_method_dispatch, "the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \ from method dispatch when the receiver is of the following type, for compatibility in \ editions < 2021 (array) or editions < 2024 (boxed_slice)" ), - rustc_attr!( - rustc_must_implement_one_of, Normal,"the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \ + rustc_attr!(rustc_must_implement_one_of,"the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \ definition of a trait. Its syntax and semantics are highly experimental and will be \ subject to change before stabilization", ), - rustc_attr!( - rustc_doc_primitive, Normal,"the `#[rustc_doc_primitive]` attribute is used by the standard library \ + rustc_attr!(rustc_doc_primitive,"the `#[rustc_doc_primitive]` attribute is used by the standard library \ to provide a way to generate documentation for primitive types", ), gated!( - rustc_intrinsic, Normal,intrinsics, - "the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items", - ), - rustc_attr!( - rustc_no_mir_inline, Normal,"`#[rustc_no_mir_inline]` prevents the MIR inliner from inlining a function while not affecting codegen" - ), - rustc_attr!( - rustc_force_inline, Normal,"`#[rustc_force_inline]` forces a free function to be inlined" - ), - rustc_attr!( - rustc_scalable_vector, Normal,"`#[rustc_scalable_vector]` defines a scalable vector type" + rustc_intrinsic,intrinsics, + "the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items",), + rustc_attr!(rustc_no_mir_inline,"`#[rustc_no_mir_inline]` prevents the MIR inliner from inlining a function while not affecting codegen" ), + rustc_attr!(rustc_force_inline,"`#[rustc_force_inline]` forces a free function to be inlined"), + rustc_attr!(rustc_scalable_vector,"`#[rustc_scalable_vector]` defines a scalable vector type"), // ========================================================================== // Internal attributes, Testing: // ========================================================================== - rustc_attr!(TEST, rustc_effective_visibility, Normal,), - rustc_attr!( - TEST, rustc_dump_inferred_outlives, Normal, - ), - rustc_attr!( - TEST, rustc_capture_analysis, Normal, - ), - rustc_attr!( - TEST, rustc_insignificant_dtor, Normal, - ), - rustc_attr!( - TEST, rustc_no_implicit_bounds, CrateLevel, - ), - rustc_attr!( - TEST, rustc_strict_coherence, Normal, - ), - rustc_attr!( - TEST, rustc_dump_variances, Normal, - ), - rustc_attr!( - TEST, rustc_dump_variances_of_opaques, Normal, - ), - rustc_attr!( - TEST, rustc_hidden_type_of_opaques, Normal, - ), - rustc_attr!( - TEST, rustc_layout, Normal, - ), - rustc_attr!( - TEST, rustc_abi, Normal, - ), - rustc_attr!( - TEST, rustc_regions, Normal, - ), - rustc_attr!( - TEST, rustc_delayed_bug_from_inside_query, Normal, - ), - rustc_attr!( - TEST, rustc_dump_user_args, Normal, - ), - rustc_attr!( - TEST, rustc_evaluate_where_clauses, Normal, - ), - rustc_attr!( - TEST, rustc_if_this_changed, Normal, ), - rustc_attr!( - TEST, rustc_then_this_would_need, Normal, ), - rustc_attr!( - TEST, rustc_clean, Normal, - ), - rustc_attr!( - TEST, rustc_partition_reused, Normal, - ), - rustc_attr!( - TEST, rustc_partition_codegened, Normal, - ), - rustc_attr!( - TEST, rustc_expected_cgu_reuse, Normal, - ), - rustc_attr!( - TEST, rustc_symbol_name, Normal, - ), - rustc_attr!( - TEST, rustc_def_path, Normal, - ), - rustc_attr!( - TEST, rustc_mir, Normal, - ), - gated!( - custom_mir, Normal,"the `#[custom_mir]` attribute is just used for the Rust test suite", - ), - rustc_attr!( - TEST, rustc_dump_item_bounds, Normal, - ), - rustc_attr!( - TEST, rustc_dump_predicates, Normal, - ), - rustc_attr!( - TEST, rustc_dump_def_parents, Normal, - ), - rustc_attr!( - TEST, rustc_dump_object_lifetime_defaults, Normal, - ), - rustc_attr!( - TEST, rustc_dump_vtable, Normal, - ), - rustc_attr!(TEST, rustc_dummy, Normal,), - rustc_attr!(TEST, pattern_complexity_limit, CrateLevel, ), + rustc_attr!(TEST, rustc_effective_visibility,), + rustc_attr!(TEST, rustc_dump_inferred_outlives,), + rustc_attr!(TEST, rustc_capture_analysis,), + rustc_attr!(TEST, rustc_insignificant_dtor,), + rustc_attr!(TEST, rustc_no_implicit_bounds,), + rustc_attr!(TEST, rustc_strict_coherence,), + rustc_attr!(TEST, rustc_dump_variances,), + rustc_attr!(TEST, rustc_dump_variances_of_opaques,), + rustc_attr!(TEST, rustc_hidden_type_of_opaques,), + rustc_attr!(TEST, rustc_layout,), + rustc_attr!(TEST, rustc_abi,), + rustc_attr!(TEST, rustc_regions,), + rustc_attr!(TEST, rustc_delayed_bug_from_inside_query,), + rustc_attr!(TEST, rustc_dump_user_args,), + rustc_attr!(TEST, rustc_evaluate_where_clauses,), + rustc_attr!(TEST, rustc_if_this_changed,), + rustc_attr!(TEST, rustc_then_this_would_need,), + rustc_attr!(TEST, rustc_clean,), + rustc_attr!(TEST, rustc_partition_reused,), + rustc_attr!(TEST, rustc_partition_codegened,), + rustc_attr!(TEST, rustc_expected_cgu_reuse,), + rustc_attr!(TEST, rustc_symbol_name,), + rustc_attr!(TEST, rustc_def_path,), + rustc_attr!(TEST, rustc_mir,), + gated!(custom_mir,"the `#[custom_mir]` attribute is just used for the Rust test suite",), + rustc_attr!(TEST, rustc_dump_item_bounds,), + rustc_attr!(TEST, rustc_dump_predicates,), + rustc_attr!(TEST, rustc_dump_def_parents,), + rustc_attr!(TEST, rustc_dump_object_lifetime_defaults,), + rustc_attr!(TEST, rustc_dump_vtable,), + rustc_attr!(TEST, rustc_dummy,), + rustc_attr!(TEST, pattern_complexity_limit,), ]; pub fn is_builtin_attr_name(name: Symbol) -> bool { diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index db37e4534df9..40a637bfa0b8 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -129,9 +129,9 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option { /* Already validated. */ } - Attribute::Unparsed(attr) => { - // FIXME(jdonszelmann): remove once all crate-level attrs are parsed and caught by - // the above - if let Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) = - attr.path - .segments - .first() - .and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name)) - { - match attr.style { - ast::AttrStyle::Outer => { - let attr_span = attr.span; - let bang_position = self - .tcx - .sess - .source_map() - .span_until_char(attr_span, '[') - .shrink_to_hi(); - - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::OuterCrateLevelAttr { - suggestion: errors::OuterCrateLevelAttrSuggestion { - bang_position, - }, - }, - ) - } - ast::AttrStyle::Inner => self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::InnerCrateLevelAttr, - ), - } - } - } - } - } - self.check_unused_attribute(hir_id, attr) } From efbc1550944f741a7623b493cd8fd2024113babf Mon Sep 17 00:00:00 2001 From: ujjwalVishwakarma2006 <2023ucs0116@iitjammu.ac.in> Date: Mon, 6 Apr 2026 10:39:54 +0530 Subject: [PATCH 19/37] Move test files into appropriate directories --- .../transmute-phantomdata-generic-unequal-size.rs} | 0 .../transmute-phantomdata-generic-unequal-size.stderr} | 0 .../transmute-bool-u8.rs} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-32377.rs => intrinsics/transmute-phantomdata-generic-unequal-size.rs} (100%) rename tests/ui/{issues/issue-32377.stderr => intrinsics/transmute-phantomdata-generic-unequal-size.stderr} (100%) rename tests/ui/{issues/issue-25746-bool-transmute.rs => transmute/transmute-bool-u8.rs} (100%) diff --git a/tests/ui/issues/issue-32377.rs b/tests/ui/intrinsics/transmute-phantomdata-generic-unequal-size.rs similarity index 100% rename from tests/ui/issues/issue-32377.rs rename to tests/ui/intrinsics/transmute-phantomdata-generic-unequal-size.rs diff --git a/tests/ui/issues/issue-32377.stderr b/tests/ui/intrinsics/transmute-phantomdata-generic-unequal-size.stderr similarity index 100% rename from tests/ui/issues/issue-32377.stderr rename to tests/ui/intrinsics/transmute-phantomdata-generic-unequal-size.stderr diff --git a/tests/ui/issues/issue-25746-bool-transmute.rs b/tests/ui/transmute/transmute-bool-u8.rs similarity index 100% rename from tests/ui/issues/issue-25746-bool-transmute.rs rename to tests/ui/transmute/transmute-bool-u8.rs From 9181351d077ed698421ba79eab84eaaf54baae58 Mon Sep 17 00:00:00 2001 From: ujjwalVishwakarma2006 <2023ucs0116@iitjammu.ac.in> Date: Mon, 6 Apr 2026 11:47:13 +0530 Subject: [PATCH 20/37] Add issue links at the top --- .../intrinsics/transmute-phantomdata-generic-unequal-size.rs | 1 + .../transmute-phantomdata-generic-unequal-size.stderr | 2 +- tests/ui/transmute/transmute-bool-u8.rs | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/ui/intrinsics/transmute-phantomdata-generic-unequal-size.rs b/tests/ui/intrinsics/transmute-phantomdata-generic-unequal-size.rs index 6737f9820efd..203894a7217a 100644 --- a/tests/ui/intrinsics/transmute-phantomdata-generic-unequal-size.rs +++ b/tests/ui/intrinsics/transmute-phantomdata-generic-unequal-size.rs @@ -1,3 +1,4 @@ +//! regression test for //@ normalize-stderr: "\d+ bits" -> "N bits" use std::mem; diff --git a/tests/ui/intrinsics/transmute-phantomdata-generic-unequal-size.stderr b/tests/ui/intrinsics/transmute-phantomdata-generic-unequal-size.stderr index 01a81cea1eca..76fda2f2c417 100644 --- a/tests/ui/intrinsics/transmute-phantomdata-generic-unequal-size.stderr +++ b/tests/ui/intrinsics/transmute-phantomdata-generic-unequal-size.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/issue-32377.rs:15:14 + --> $DIR/transmute-phantomdata-generic-unequal-size.rs:16:14 | LL | unsafe { mem::transmute(x) } | ^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute/transmute-bool-u8.rs b/tests/ui/transmute/transmute-bool-u8.rs index 046dcf83f62d..502683b6d136 100644 --- a/tests/ui/transmute/transmute-bool-u8.rs +++ b/tests/ui/transmute/transmute-bool-u8.rs @@ -1,4 +1,5 @@ -//@ run-pass +//! regression test for +//@ build-pass #![allow(unnecessary_transmutes)] use std::mem::transmute; From 9d96a269bf2950668bba30bf95779ac6180a3faa Mon Sep 17 00:00:00 2001 From: Shagun Agrawal Date: Mon, 6 Apr 2026 16:52:33 +0530 Subject: [PATCH 21/37] Re-use existing Fira(Sans) license for Mono fonts --- license-metadata.json | 3 +- src/librustdoc/html/static/COPYRIGHT.txt | 17 +--- ...{FiraSans-LICENSE.txt => Fira-LICENSE.txt} | 0 .../html/static/fonts/FiraMono-LICENSE.txt | 97 ------------------- 4 files changed, 5 insertions(+), 112 deletions(-) rename src/librustdoc/html/static/fonts/{FiraSans-LICENSE.txt => Fira-LICENSE.txt} (100%) delete mode 100644 src/librustdoc/html/static/fonts/FiraMono-LICENSE.txt diff --git a/license-metadata.json b/license-metadata.json index 298b453b24ae..e8e13fa8d859 100644 --- a/license-metadata.json +++ b/license-metadata.json @@ -114,11 +114,10 @@ { "directories": [], "files": [ - "FiraMono-LICENSE.txt", + "Fira-LICENSE.txt", "FiraMono-Medium.woff2", "FiraMono-Regular.woff2", "FiraSans-Italic.woff2", - "FiraSans-LICENSE.txt", "FiraSans-Medium.woff2", "FiraSans-MediumItalic.woff2", "FiraSans-Regular.woff2" diff --git a/src/librustdoc/html/static/COPYRIGHT.txt b/src/librustdoc/html/static/COPYRIGHT.txt index e20c9cff0acc..0c295b4b0168 100644 --- a/src/librustdoc/html/static/COPYRIGHT.txt +++ b/src/librustdoc/html/static/COPYRIGHT.txt @@ -4,25 +4,16 @@ These documentation pages include resources by third parties. This copyright file applies only to those resources. The following third party resources are included, and carry their own copyright notices and license terms: -* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2): +* Fira (FiraSans-Regular.woff2, FiraSans-Medium.woff2, + FiraMono-Regular.woff2, FiraMono-Medium.woff2): Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ - with Reserved Font Name Fira Sans. + with Reserved Font Name < Fira >. Copyright (c) 2014, Telefonica S.A. Licensed under the SIL Open Font License, Version 1.1. - See FiraSans-LICENSE.txt. - -* Fira Mono (FiraMono-Regular.woff2, FiraMono-Medium.woff2): - - Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ - with Reserved Font Name Fira Mono. - - Copyright (c) 2014, Telefonica S.A. - - Licensed under the SIL Open Font License, Version 1.1. - See FiraMono-LICENSE.txt. + See Fira-LICENSE.txt. * rustdoc.css, main.js, and playpen.js: diff --git a/src/librustdoc/html/static/fonts/FiraSans-LICENSE.txt b/src/librustdoc/html/static/fonts/Fira-LICENSE.txt similarity index 100% rename from src/librustdoc/html/static/fonts/FiraSans-LICENSE.txt rename to src/librustdoc/html/static/fonts/Fira-LICENSE.txt diff --git a/src/librustdoc/html/static/fonts/FiraMono-LICENSE.txt b/src/librustdoc/html/static/fonts/FiraMono-LICENSE.txt deleted file mode 100644 index 4737fa435f8f..000000000000 --- a/src/librustdoc/html/static/fonts/FiraMono-LICENSE.txt +++ /dev/null @@ -1,97 +0,0 @@ -// REUSE-IgnoreStart - -Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. - -// REUSE-IgnoreEnd From 057b24ee8174d784c93722eed07a465862d8564e Mon Sep 17 00:00:00 2001 From: Shagun Agrawal Date: Mon, 6 Apr 2026 16:54:52 +0530 Subject: [PATCH 22/37] Update static_files to only include fira_license --- src/librustdoc/html/static_files.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index 33969597bd29..84d0162d990b 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -97,8 +97,7 @@ pub(crate) fn for_each(f: impl Fn(&StaticFile) -> Result<(), E>) -> Result<() fira_sans_medium_italic => "static/fonts/FiraSans-MediumItalic.woff2", fira_mono_regular => "static/fonts/FiraMono-Regular.woff2", fira_mono_medium => "static/fonts/FiraMono-Medium.woff2", - fira_sans_license => "static/fonts/FiraSans-LICENSE.txt", - fira_mono_license => "static/fonts/FiraMono-LICENSE.txt", + fira_license => "static/fonts/Fira-LICENSE.txt", source_serif_4_regular => "static/fonts/SourceSerif4-Regular.ttf.woff2", source_serif_4_semibold => "static/fonts/SourceSerif4-Semibold.ttf.woff2", source_serif_4_bold => "static/fonts/SourceSerif4-Bold.ttf.woff2", From adaff7315de473b231c783b1cd256e2e3d35a3ed Mon Sep 17 00:00:00 2001 From: Shagun Agrawal Date: Mon, 6 Apr 2026 16:57:32 +0530 Subject: [PATCH 23/37] fixes rustdoc build script --- src/librustdoc/build.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/build.rs b/src/librustdoc/build.rs index d1217f712689..94bb0e30fcdb 100644 --- a/src/librustdoc/build.rs +++ b/src/librustdoc/build.rs @@ -27,8 +27,7 @@ fn main() { "static/fonts/FiraSans-MediumItalic.woff2", "static/fonts/FiraMono-Regular.woff2", "static/fonts/FiraMono-Medium.woff2", - "static/fonts/FiraSans-LICENSE.txt", - "static/fonts/FiraMono-LICENSE.txt", + "static/fonts/Fira-LICENSE.txt", "static/fonts/SourceSerif4-Regular.ttf.woff2", "static/fonts/SourceSerif4-Semibold.ttf.woff2", "static/fonts/SourceSerif4-Bold.ttf.woff2", From 262d35bda5af19fb4dda41623963639428b6ad8e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 6 Apr 2026 07:17:00 -0700 Subject: [PATCH 24/37] Update wasm-component-ld to 0.5.22 Same as 147495, just keeping it up-to-date. --- Cargo.lock | 52 +++++++++++++------------- src/tools/wasm-component-ld/Cargo.toml | 2 +- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd7aa3d68324..57ed13f32c3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6221,9 +6221,9 @@ dependencies = [ [[package]] name = "wasi-preview1-component-adapter-provider" -version = "40.0.0" +version = "43.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb5e2b9858989c3a257de4ca169977f4f79897b64e4f482f188f4fcf8ac557d1" +checksum = "93759d6fd0db242718bdcc6e4626eff8b0f3124ee7e58e47177a59f561baf164" [[package]] name = "wasm-bindgen" @@ -6272,9 +6272,9 @@ dependencies = [ [[package]] name = "wasm-component-ld" -version = "0.5.21" +version = "0.5.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59dcd765f510df84d1677a502c49057761486597a95950b4c92153e5707af091" +checksum = "216ca7b603f362831b31db4e2cdea1fa3609edd7177792fa64f62a80e10aa917" dependencies = [ "anyhow", "clap", @@ -6283,7 +6283,7 @@ dependencies = [ "libc", "tempfile", "wasi-preview1-component-adapter-provider", - "wasmparser 0.245.1", + "wasmparser 0.246.2", "wat", "windows-sys 0.61.2", "winsplit", @@ -6310,24 +6310,24 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.245.1" +version = "0.246.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9dca005e69bf015e45577e415b9af8c67e8ee3c0e38b5b0add5aa92581ed5c" +checksum = "61fb705ce81adde29d2a8e99d87995e39a6e927358c91398f374474746070ef7" dependencies = [ "leb128fmt", - "wasmparser 0.245.1", + "wasmparser 0.246.2", ] [[package]] name = "wasm-metadata" -version = "0.245.1" +version = "0.246.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da55e60097e8b37b475a0fa35c3420dd71d9eb7bd66109978ab55faf56a57efb" +checksum = "e3e4c2aa916c425dcca61a6887d3e135acdee2c6d0ed51fd61c08d41ddaf62b1" dependencies = [ "anyhow", "indexmap", - "wasm-encoder 0.245.1", - "wasmparser 0.245.1", + "wasm-encoder 0.246.2", + "wasmparser 0.246.2", ] [[package]] @@ -6352,9 +6352,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.245.1" +version = "0.246.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f08c9adee0428b7bddf3890fc27e015ac4b761cc608c822667102b8bfd6995e" +checksum = "71cde4757396defafd25417cfb36aa3161027d06d865b0c24baaae229aac005d" dependencies = [ "bitflags", "hashbrown 0.16.1", @@ -6365,22 +6365,22 @@ dependencies = [ [[package]] name = "wast" -version = "245.0.1" +version = "246.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cf1149285569120b8ce39db8b465e8a2b55c34cbb586bd977e43e2bc7300bf" +checksum = "fe3fe8e3bf88ad96d031b4181ddbd64634b17cb0d06dfc3de589ef43591a9a62" dependencies = [ "bumpalo", "leb128fmt", "memchr", "unicode-width 0.2.2", - "wasm-encoder 0.245.1", + "wasm-encoder 0.246.2", ] [[package]] name = "wat" -version = "1.245.1" +version = "1.246.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd48d1679b6858988cb96b154dda0ec5bbb09275b71db46057be37332d5477be" +checksum = "4bd7fda1199b94fff395c2d19a153f05dbe7807630316fa9673367666fd2ad8c" dependencies = [ "wast", ] @@ -6811,9 +6811,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.245.1" +version = "0.246.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4894f10d2d5cbc17c77e91f86a1e48e191a788da4425293b55c98b44ba3fcac9" +checksum = "1936c26cb24b93dc36bf78fb5dc35c55cd37f66ecdc2d2663a717d9fb3ee951e" dependencies = [ "anyhow", "bitflags", @@ -6822,17 +6822,17 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "wasm-encoder 0.245.1", + "wasm-encoder 0.246.2", "wasm-metadata", - "wasmparser 0.245.1", + "wasmparser 0.246.2", "wit-parser", ] [[package]] name = "wit-parser" -version = "0.245.1" +version = "0.246.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330698718e82983499419494dd1e3d7811a457a9bf9f69734e8c5f07a2547929" +checksum = "fd979042b5ff288607ccf3b314145435453f20fc67173195f91062d2289b204d" dependencies = [ "anyhow", "hashbrown 0.16.1", @@ -6844,7 +6844,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.245.1", + "wasmparser 0.246.2", ] [[package]] diff --git a/src/tools/wasm-component-ld/Cargo.toml b/src/tools/wasm-component-ld/Cargo.toml index 3f20b9e3fa12..99e84b4562f6 100644 --- a/src/tools/wasm-component-ld/Cargo.toml +++ b/src/tools/wasm-component-ld/Cargo.toml @@ -10,4 +10,4 @@ name = "wasm-component-ld" path = "src/main.rs" [dependencies] -wasm-component-ld = "0.5.21" +wasm-component-ld = "0.5.22" From 43ec6207bb0ccf54d4692b98cb8110930c344b7c Mon Sep 17 00:00:00 2001 From: yukang Date: Mon, 6 Apr 2026 21:26:03 +0800 Subject: [PATCH 25/37] stabilize check-cfg suggestions --- compiler/rustc_lint/src/early/diagnostics/check_cfg.rs | 8 +++++--- tests/ui/cfg/suggest-alternative-name-on-target.rs | 2 +- tests/ui/cfg/suggest-alternative-name-on-target.stderr | 10 +++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs index a211a1aaa6bd..9fcabfa623d8 100644 --- a/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs +++ b/compiler/rustc_lint/src/early/diagnostics/check_cfg.rs @@ -438,10 +438,10 @@ pub(super) fn unexpected_cfg_value( } } -/// Ordering of the output is not stable, use this only in diagnostic code. fn possible_well_known_names_for_cfg_value(sess: &Session, value: Symbol) -> Vec { #[allow(rustc::potential_query_instability)] - sess.psess + let mut names = sess + .psess .check_config .well_known_names .iter() @@ -454,5 +454,7 @@ fn possible_well_known_names_for_cfg_value(sess: &Session, value: Symbol) -> Vec .unwrap_or_default() }) .copied() - .collect() + .collect::>(); + names.sort_by(|a, b| a.as_str().cmp(b.as_str())); + names } diff --git a/tests/ui/cfg/suggest-alternative-name-on-target.rs b/tests/ui/cfg/suggest-alternative-name-on-target.rs index e3810dbbc9c3..297321a0e2fe 100644 --- a/tests/ui/cfg/suggest-alternative-name-on-target.rs +++ b/tests/ui/cfg/suggest-alternative-name-on-target.rs @@ -32,8 +32,8 @@ #[cfg(target_abi = "windows")] //~^ ERROR unexpected `cfg` condition value: //~| NOTE see for more information about checking conditional configuration -help: `windows` is an expected value for `target_os` - | -LL - #[cfg(target_abi = "windows")] -LL + #[cfg(target_os = "windows")] - | help: `windows` is an expected value for `target_family` | LL - #[cfg(target_abi = "windows")] LL + #[cfg(target_family = "windows")] | +help: `windows` is an expected value for `target_os` + | +LL - #[cfg(target_abi = "windows")] +LL + #[cfg(target_os = "windows")] + | error: aborting due to 5 previous errors From 8930f50b9601f897f770c1c23098d6428777e686 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 6 Apr 2026 23:15:21 -0500 Subject: [PATCH 26/37] c-b: Export inverse hyperbolic trigonometric functions Since a1feab16381b ("Use libm for acosh and asinh"), the standard library may link these functions to get a more accurate approximation; however, some targets do not have the needed symbols available. Add them to the compiler-builtins export list to make sure the fallback is usable. --- library/compiler-builtins/compiler-builtins/src/math/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/compiler-builtins/compiler-builtins/src/math/mod.rs b/library/compiler-builtins/compiler-builtins/src/math/mod.rs index 61dfad213cbe..3dfa3863bb77 100644 --- a/library/compiler-builtins/compiler-builtins/src/math/mod.rs +++ b/library/compiler-builtins/compiler-builtins/src/math/mod.rs @@ -144,8 +144,12 @@ pub mod partial_availability { libm_intrinsics! { fn acos(x: f64) -> f64; fn acosf(n: f32) -> f32; + fn acosh(x: f64) -> f64; + fn acoshf(x: f32) -> f32; fn asin(x: f64) -> f64; fn asinf(n: f32) -> f32; + fn asinh(x: f64) -> f64; + fn asinhf(x: f32) -> f32; fn atan(x: f64) -> f64; fn atan2(x: f64, y: f64) -> f64; fn atan2f(a: f32, b: f32) -> f32; From 6b6bf8def8e5e121ca6f74195b7aa65ada3affe6 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 4 Apr 2026 14:56:30 +0200 Subject: [PATCH 27/37] Remove unused attribute check for unparsed builtin attributes --- compiler/rustc_expand/src/errors.rs | 18 ------------------ compiler/rustc_expand/src/expand.rs | 21 +++------------------ compiler/rustc_expand/src/module.rs | 1 + 3 files changed, 4 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index 6c5732f497f8..cee333e0a59f 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -603,21 +603,3 @@ pub(crate) struct TrailingMacro { pub is_trailing: bool, pub name: Ident, } - -#[derive(Diagnostic)] -#[diag("unused attribute `{$attr_name}`")] -pub(crate) struct UnusedBuiltinAttribute { - #[note( - "the built-in attribute `{$attr_name}` will be ignored, since it's applied to the macro invocation `{$macro_name}`" - )] - pub invoc_span: Span, - pub attr_name: Symbol, - pub macro_name: String, - #[suggestion( - "remove the attribute", - code = "", - applicability = "machine-applicable", - style = "tool-only" - )] - pub attr_span: Span, -} diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index e3a15f193e58..4ed87fc83b23 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -15,8 +15,8 @@ use rustc_ast_pretty::pprust; use rustc_attr_parsing::parser::AllowExprMetavar; use rustc_attr_parsing::{ - AttributeParser, CFG_TEMPLATE, Early, EvalConfigResult, ShouldEmit, eval_config_entry, - parse_cfg, validate_attr, + AttributeParser, CFG_TEMPLATE, EvalConfigResult, ShouldEmit, eval_config_entry, parse_cfg, + validate_attr, }; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -30,7 +30,7 @@ RecoverColon, RecoverComma, Recovery, token_descr, }; use rustc_session::Session; -use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS}; +use rustc_session::lint::builtin::UNUSED_DOC_COMMENTS; use rustc_session::parse::feature_err; use rustc_span::hygiene::SyntaxContext; use rustc_span::{ErrorGuaranteed, FileName, Ident, LocalExpnId, Span, Symbol, sym}; @@ -2274,21 +2274,6 @@ fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall) { self.cx.current_expansion.lint_node_id, crate::errors::MacroCallUnusedDocComment { span: attr.span }, ); - } else if rustc_attr_parsing::is_builtin_attr(attr) - && !AttributeParser::::is_parsed_attribute(&attr.path()) - { - let attr_name = attr.name().unwrap(); - self.cx.sess.psess.buffer_lint( - UNUSED_ATTRIBUTES, - attr.span, - self.cx.current_expansion.lint_node_id, - crate::errors::UnusedBuiltinAttribute { - attr_name, - macro_name: pprust::path_to_string(&call.path), - invoc_span: call.path.span, - attr_span: attr.span, - }, - ); } } } diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index 6f0ecfb1cf1c..803803ec3f6c 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -186,6 +186,7 @@ pub(crate) fn mod_file_path_from_attr( attrs: &[Attribute], dir_path: &Path, ) -> Option { + // FIXME(154781) use a parsed attribute here // Extract path string from first `#[path = "path_string"]` attribute. let first_path = attrs.iter().find(|at| at.has_name(sym::path))?; let Some(path_sym) = first_path.value_str() else { From 89db636d6fdbd346d5aea603b20b918da878755c Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Tue, 7 Apr 2026 08:57:41 +0200 Subject: [PATCH 28/37] Reformat builtin_attrs.rs --- compiler/rustc_feature/src/builtin_attrs.rs | 303 ++++++++++---------- 1 file changed, 154 insertions(+), 149 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index db29b19b78cf..b8b9226cc602 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -278,7 +278,7 @@ macro_rules! gated { } macro_rules! rustc_attr { - (TEST, $attr:ident, $(,)?) => { + (TEST, $attr:ident $(,)?) => { rustc_attr!( $attr, concat!( "the `#[", @@ -287,7 +287,7 @@ macro_rules! rustc_attr { ), ) }; - ($attr:ident, $($notes:expr),* $(,)?) => { + ($attr:ident $(, $notes:expr)* $(,)?) => { BuiltinAttribute { name: sym::$attr, safety: AttributeSafety::Normal, @@ -326,98 +326,100 @@ pub struct BuiltinAttribute { // ========================================================================== // Conditional compilation: - ungated!(cfg,), - ungated!(cfg_attr,), + ungated!(cfg), + ungated!(cfg_attr), // Testing: - ungated!(ignore,), - ungated!(should_panic,), + ungated!(ignore), + ungated!(should_panic), // Macros: - ungated!(automatically_derived,), - ungated!(macro_use,), - ungated!(macro_escape,), // Deprecated synonym for `macro_use`. - ungated!(macro_export,), - ungated!(proc_macro,), - ungated!(proc_macro_derive,), - ungated!(proc_macro_attribute,), + ungated!(automatically_derived), + ungated!(macro_use), + ungated!(macro_escape), // Deprecated synonym for `macro_use`. + ungated!(macro_export), + ungated!(proc_macro), + ungated!(proc_macro_derive), + ungated!(proc_macro_attribute), // Lints: - ungated!(warn,), - ungated!(allow,), - ungated!(expect,), - ungated!(forbid,), - ungated!(deny,), - ungated!(must_use,), + ungated!(warn), + ungated!(allow), + ungated!(expect), + ungated!(forbid), + ungated!(deny), + ungated!(must_use), gated!(must_not_suspend, experimental!(must_not_suspend)), - ungated!(deprecated,), + ungated!(deprecated), // Crate properties: - ungated!(crate_name,), - ungated!(crate_type,), + ungated!(crate_name), + ungated!(crate_type), // ABI, linking, symbols, and FFI - ungated!(link,), - ungated!(link_name,), - ungated!(no_link,), - ungated!(repr,), + ungated!(link), + ungated!(link_name), + ungated!(no_link), + ungated!(repr), // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity gated!(rustc_align,fn_align, experimental!(rustc_align)), gated!(rustc_align_static,static_align, experimental!(rustc_align_static)), - ungated!(unsafe(Edition2024) export_name,), - ungated!(unsafe(Edition2024) link_section,), - ungated!(unsafe(Edition2024) no_mangle,), - ungated!(used,), - ungated!(link_ordinal,), - ungated!(unsafe naked,), + ungated!(unsafe(Edition2024) export_name), + ungated!(unsafe(Edition2024) link_section), + ungated!(unsafe(Edition2024) no_mangle), + ungated!(used), + ungated!(link_ordinal), + ungated!(unsafe naked), // See `TyAndLayout::pass_indirectly_in_non_rustic_abis` for details. rustc_attr!(rustc_pass_indirectly_in_non_rustic_abis, "types marked with `#[rustc_pass_indirectly_in_non_rustic_abis]` are always passed indirectly by non-Rustic ABIs"), // Limits: - ungated!(recursion_limit,), - ungated!(type_length_limit,), + ungated!(recursion_limit), + ungated!(type_length_limit), gated!( move_size_limit, large_assignments, experimental!(move_size_limit) ), // Entry point: - ungated!(no_main,), + ungated!(no_main), // Modules, prelude, and resolution: - ungated!(path,), - ungated!(no_std,), - ungated!(no_implicit_prelude,), - ungated!(non_exhaustive,), + ungated!(path), + ungated!(no_std), + ungated!(no_implicit_prelude), + ungated!(non_exhaustive), // Runtime - ungated!(windows_subsystem,), + ungated!(windows_subsystem), ungated!(// RFC 2070 - panic_handler,), + panic_handler + ), // Code generation: - ungated!(inline,), - ungated!(cold,), - ungated!(no_builtins,), - ungated!(target_feature,), - ungated!(track_caller,), - ungated!(instruction_set,), + ungated!(inline), + ungated!(cold), + ungated!(no_builtins), + ungated!(target_feature), + ungated!(track_caller), + ungated!(instruction_set), gated!( unsafe force_target_feature, effective_target_features, experimental!(force_target_feature) ), gated!( sanitize, - sanitize, experimental!(sanitize),), + sanitize, experimental!(sanitize) + ), gated!( coverage, coverage_attribute, experimental!(coverage) ), - ungated!(doc,), + ungated!(doc), // Debugging - ungated!(debugger_visualizer,), - ungated!(collapse_debuginfo,), + ungated!(debugger_visualizer), + ungated!(collapse_debuginfo), // ========================================================================== // Unstable attributes: @@ -431,18 +433,21 @@ pub struct BuiltinAttribute { // Testing: gated!( test_runner, custom_test_frameworks, - "custom test frameworks are an unstable feature",), + "custom test frameworks are an unstable feature" + ), gated!( reexport_test_harness_main, custom_test_frameworks, - "custom test frameworks are an unstable feature",), + "custom test frameworks are an unstable feature" + ), // RFC #1268 gated!( marker,marker_trait_attr, experimental!(marker) ), gated!( - thread_local,"`#[thread_local]` is an experimental feature, and does not currently handle destructors",), + thread_local,"`#[thread_local]` is an experimental feature, and does not currently handle destructors" + ), gated!( no_core, experimental!(no_core) ), @@ -459,7 +464,8 @@ pub struct BuiltinAttribute { unsafe ffi_const, experimental!(ffi_const) ), gated!( - register_tool, experimental!(register_tool),), + register_tool, experimental!(register_tool) + ), // `#[cfi_encoding = ""]` gated!( cfi_encoding, @@ -501,14 +507,14 @@ pub struct BuiltinAttribute { // Internal attributes: Stability, deprecation, and unsafe: // ========================================================================== - ungated!(feature,), + ungated!(feature), // DuplicatesOk since it has its own validation - ungated!(stable,), - ungated!(unstable,), - ungated!(unstable_feature_bound,), - ungated!(rustc_const_unstable,), - ungated!(rustc_const_stable,), - ungated!(rustc_default_body_unstable,), + ungated!(stable), + ungated!(unstable), + ungated!(unstable_feature_bound), + ungated!(rustc_const_unstable), + ungated!(rustc_const_stable), + ungated!(rustc_default_body_unstable), gated!( allow_internal_unstable, "allow_internal_unstable side-steps feature gating and stability checks", @@ -538,7 +544,8 @@ pub struct BuiltinAttribute { gated!(fundamental, experimental!(fundamental)), gated!( may_dangle, dropck_eyepatch, - "`may_dangle` has unstable semantics and may be removed in the future",), + "`may_dangle` has unstable semantics and may be removed in the future" + ), rustc_attr!(rustc_never_type_options, "`rustc_never_type_options` is used to experiment with never type fallback and work on \ @@ -549,12 +556,12 @@ pub struct BuiltinAttribute { // Internal attributes: Runtime related: // ========================================================================== - rustc_attr!(rustc_allocator,), - rustc_attr!(rustc_nounwind,), - rustc_attr!(rustc_reallocator,), - rustc_attr!(rustc_deallocator,), - rustc_attr!(rustc_allocator_zeroed,), - rustc_attr!(rustc_allocator_zeroed_variant,), + rustc_attr!(rustc_allocator), + rustc_attr!(rustc_nounwind), + rustc_attr!(rustc_reallocator), + rustc_attr!(rustc_deallocator), + rustc_attr!(rustc_allocator_zeroed), + rustc_attr!(rustc_allocator_zeroed_variant), gated!( default_lib_allocator, allocator_internals, experimental!(default_lib_allocator), ), @@ -570,11 +577,13 @@ pub struct BuiltinAttribute { gated!( compiler_builtins, "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \ - which contains compiler-rt intrinsics and will never be stable",), + which contains compiler-rt intrinsics and will never be stable" + ), gated!( profiler_runtime, "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \ - which contains the profiler runtime and will never be stable",), + which contains the profiler runtime and will never be stable" + ), // ========================================================================== // Internal attributes, Linkage: @@ -582,21 +591,23 @@ pub struct BuiltinAttribute { gated!( linkage, - "the `linkage` attribute is experimental and not portable across platforms",), - rustc_attr!(rustc_std_internal_symbol,), - rustc_attr!(rustc_objc_class,), - rustc_attr!(rustc_objc_selector,), + "the `linkage` attribute is experimental and not portable across platforms" + ), + rustc_attr!(rustc_std_internal_symbol), + rustc_attr!(rustc_objc_class), + rustc_attr!(rustc_objc_selector), // ========================================================================== // Internal attributes, Macro related: // ========================================================================== - rustc_attr!(rustc_builtin_macro,), - rustc_attr!(rustc_proc_macro_decls,), + rustc_attr!(rustc_builtin_macro), + rustc_attr!(rustc_proc_macro_decls), rustc_attr!(rustc_macro_transparency, - "used internally for testing macro hygiene",), - rustc_attr!(rustc_autodiff,), - rustc_attr!(rustc_offload_kernel,), + "used internally for testing macro hygiene" + ), + rustc_attr!(rustc_autodiff), + rustc_attr!(rustc_offload_kernel), // Traces that are left when `cfg` and `cfg_attr` attributes are expanded. // The attributes are not gated, to avoid stability errors, but they cannot be used in stable // or unstable code directly because `sym::cfg_(attr_)trace` are not valid identifiers, they @@ -612,37 +623,37 @@ pub struct BuiltinAttribute { rustc_attr!(rustc_on_unimplemented,"see `#[diagnostic::on_unimplemented]` for the stable equivalent of this attribute" ), - rustc_attr!(rustc_confusables,), + rustc_attr!(rustc_confusables), // Enumerates "identity-like" conversion methods to suggest on type mismatch. - rustc_attr!(rustc_conversion_suggestion,), + rustc_attr!(rustc_conversion_suggestion), // Prevents field reads in the marked trait or method to be considered // during dead code analysis. - rustc_attr!(rustc_trivial_field_reads,), + rustc_attr!(rustc_trivial_field_reads), // Used by the `rustc::potential_query_instability` lint to warn methods which // might not be stable during incremental compilation. - rustc_attr!(rustc_lint_query_instability,), + rustc_attr!(rustc_lint_query_instability), // Used by the `rustc::untracked_query_information` lint to warn methods which // might not be stable during incremental compilation. - rustc_attr!(rustc_lint_untracked_query_information,), + rustc_attr!(rustc_lint_untracked_query_information), // Used by the `rustc::bad_opt_access` lint to identify `DebuggingOptions` and `CodegenOptions` // types (as well as any others in future). - rustc_attr!(rustc_lint_opt_ty,), + rustc_attr!(rustc_lint_opt_ty), // Used by the `rustc::bad_opt_access` lint on fields // types (as well as any others in future). - rustc_attr!(rustc_lint_opt_deny_field_access,), + rustc_attr!(rustc_lint_opt_deny_field_access), // ========================================================================== // Internal attributes, Const related: // ========================================================================== - rustc_attr!(rustc_promotable,), - rustc_attr!(rustc_legacy_const_generics,), + rustc_attr!(rustc_promotable), + rustc_attr!(rustc_legacy_const_generics), // Do not const-check this function's body. It will always get replaced during CTFE via `hook_special_const_fn`. - rustc_attr!(rustc_do_not_const_check, "`#[rustc_do_not_const_check]` skips const-check for this function's body",), + rustc_attr!(rustc_do_not_const_check, "`#[rustc_do_not_const_check]` skips const-check for this function's body"), rustc_attr!(rustc_const_stable_indirect, - "this is an internal implementation detail",), + "this is an internal implementation detail"), rustc_attr!(rustc_intrinsic_const_stable_indirect, - "this is an internal implementation detail",), + "this is an internal implementation detail"), rustc_attr!(rustc_allow_const_fn_unstable, "rustc_allow_const_fn_unstable side-steps feature gating and stability checks" ), @@ -652,40 +663,33 @@ pub struct BuiltinAttribute { // ========================================================================== rustc_attr!(rustc_layout_scalar_valid_range_start, "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \ - niche optimizations in the standard library",), + niche optimizations in the standard library"), rustc_attr!(rustc_layout_scalar_valid_range_end, "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \ - niche optimizations in the standard library",), + niche optimizations in the standard library"), rustc_attr!(rustc_simd_monomorphize_lane_limit, "the `#[rustc_simd_monomorphize_lane_limit]` attribute is just used by std::simd \ - for better error messages",), + for better error messages"), rustc_attr!(rustc_nonnull_optimization_guaranteed, "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document \ guaranteed niche optimizations in the standard library", "the compiler does not even check whether the type indeed is being non-null-optimized; \ - it is your responsibility to ensure that the attribute is only used on types that are optimized",), + it is your responsibility to ensure that the attribute is only used on types that are optimized"), // ========================================================================== // Internal attributes, Misc: // ========================================================================== gated!( lang,lang_items, - "lang items are subject to change",), - rustc_attr!(rustc_as_ptr, "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations" + "lang items are subject to change" ), - rustc_attr!(rustc_should_not_be_called_on_const_items, "`#[rustc_should_not_be_called_on_const_items]` is used to mark methods that don't make sense to be called on interior mutable consts" - ), - rustc_attr!(rustc_pass_by_value, "`#[rustc_pass_by_value]` is used to mark types that must be passed by value instead of reference" - ), - rustc_attr!(rustc_never_returns_null_ptr, "`#[rustc_never_returns_null_ptr]` is used to mark functions returning non-null pointers" - ), - rustc_attr!(rustc_no_implicit_autorefs, "`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument" - ), - rustc_attr!(rustc_coherence_is_core, "`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`" - ), - rustc_attr!(rustc_coinductive, "`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver" - ), - rustc_attr!(rustc_allow_incoherent_impl, "`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl" - ), - rustc_attr!(rustc_preserve_ub_checks, "`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR",), + rustc_attr!(rustc_as_ptr, "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations"), + rustc_attr!(rustc_should_not_be_called_on_const_items, "`#[rustc_should_not_be_called_on_const_items]` is used to mark methods that don't make sense to be called on interior mutable consts"), + rustc_attr!(rustc_pass_by_value, "`#[rustc_pass_by_value]` is used to mark types that must be passed by value instead of reference"), + rustc_attr!(rustc_never_returns_null_ptr, "`#[rustc_never_returns_null_ptr]` is used to mark functions returning non-null pointers"), + rustc_attr!(rustc_no_implicit_autorefs, "`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument"), + rustc_attr!(rustc_coherence_is_core, "`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`"), + rustc_attr!(rustc_coinductive, "`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver"), + rustc_attr!(rustc_allow_incoherent_impl, "`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl"), + rustc_attr!(rustc_preserve_ub_checks, "`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR"), rustc_attr!(rustc_deny_explicit_impl, "`#[rustc_deny_explicit_impl]` enforces that a trait can have no user-provided impls" ), @@ -720,18 +724,19 @@ pub struct BuiltinAttribute { ), rustc_attr!(rustc_inherit_overflow_checks,"the `#[rustc_inherit_overflow_checks]` attribute is just used to control \ overflow checking behavior of several functions in the standard library that are inlined \ - across crates",), + across crates" + ), rustc_attr!(rustc_reservation_impl,"the `#[rustc_reservation_impl]` attribute is internally used \ for reserving `impl From for T` as part of the effort to stabilize `!`" ), - rustc_attr!(rustc_test_marker, "the `#[rustc_test_marker]` attribute is used internally to track tests",), + rustc_attr!(rustc_test_marker, "the `#[rustc_test_marker]` attribute is used internally to track tests"), rustc_attr!(rustc_unsafe_specialization_marker, "the `#[rustc_unsafe_specialization_marker]` attribute is used to check specializations" ), rustc_attr!(rustc_specialization_trait, "the `#[rustc_specialization_trait]` attribute is used to check specializations" ), - rustc_attr!(rustc_main,"the `#[rustc_main]` attribute is used internally to specify test entry point function",), + rustc_attr!(rustc_main,"the `#[rustc_main]` attribute is used internally to specify test entry point function"), rustc_attr!(rustc_skip_during_method_dispatch, "the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \ from method dispatch when the receiver is of the following type, for compatibility in \ editions < 2021 (array) or editions < 2024 (boxed_slice)" @@ -745,7 +750,7 @@ pub struct BuiltinAttribute { ), gated!( rustc_intrinsic,intrinsics, - "the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items",), + "the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items"), rustc_attr!(rustc_no_mir_inline,"`#[rustc_no_mir_inline]` prevents the MIR inliner from inlining a function while not affecting codegen" ), rustc_attr!(rustc_force_inline,"`#[rustc_force_inline]` forces a free function to be inlined"), @@ -755,38 +760,38 @@ pub struct BuiltinAttribute { // Internal attributes, Testing: // ========================================================================== - rustc_attr!(TEST, rustc_effective_visibility,), - rustc_attr!(TEST, rustc_dump_inferred_outlives,), - rustc_attr!(TEST, rustc_capture_analysis,), - rustc_attr!(TEST, rustc_insignificant_dtor,), - rustc_attr!(TEST, rustc_no_implicit_bounds,), - rustc_attr!(TEST, rustc_strict_coherence,), - rustc_attr!(TEST, rustc_dump_variances,), - rustc_attr!(TEST, rustc_dump_variances_of_opaques,), - rustc_attr!(TEST, rustc_hidden_type_of_opaques,), - rustc_attr!(TEST, rustc_layout,), - rustc_attr!(TEST, rustc_abi,), - rustc_attr!(TEST, rustc_regions,), - rustc_attr!(TEST, rustc_delayed_bug_from_inside_query,), - rustc_attr!(TEST, rustc_dump_user_args,), - rustc_attr!(TEST, rustc_evaluate_where_clauses,), - rustc_attr!(TEST, rustc_if_this_changed,), - rustc_attr!(TEST, rustc_then_this_would_need,), - rustc_attr!(TEST, rustc_clean,), - rustc_attr!(TEST, rustc_partition_reused,), - rustc_attr!(TEST, rustc_partition_codegened,), - rustc_attr!(TEST, rustc_expected_cgu_reuse,), - rustc_attr!(TEST, rustc_symbol_name,), - rustc_attr!(TEST, rustc_def_path,), - rustc_attr!(TEST, rustc_mir,), - gated!(custom_mir,"the `#[custom_mir]` attribute is just used for the Rust test suite",), - rustc_attr!(TEST, rustc_dump_item_bounds,), - rustc_attr!(TEST, rustc_dump_predicates,), - rustc_attr!(TEST, rustc_dump_def_parents,), - rustc_attr!(TEST, rustc_dump_object_lifetime_defaults,), - rustc_attr!(TEST, rustc_dump_vtable,), - rustc_attr!(TEST, rustc_dummy,), - rustc_attr!(TEST, pattern_complexity_limit,), + rustc_attr!(TEST, rustc_effective_visibility), + rustc_attr!(TEST, rustc_dump_inferred_outlives), + rustc_attr!(TEST, rustc_capture_analysis), + rustc_attr!(TEST, rustc_insignificant_dtor), + rustc_attr!(TEST, rustc_no_implicit_bounds), + rustc_attr!(TEST, rustc_strict_coherence), + rustc_attr!(TEST, rustc_dump_variances), + rustc_attr!(TEST, rustc_dump_variances_of_opaques), + rustc_attr!(TEST, rustc_hidden_type_of_opaques), + rustc_attr!(TEST, rustc_layout), + rustc_attr!(TEST, rustc_abi), + rustc_attr!(TEST, rustc_regions), + rustc_attr!(TEST, rustc_delayed_bug_from_inside_query), + rustc_attr!(TEST, rustc_dump_user_args), + rustc_attr!(TEST, rustc_evaluate_where_clauses), + rustc_attr!(TEST, rustc_if_this_changed), + rustc_attr!(TEST, rustc_then_this_would_need), + rustc_attr!(TEST, rustc_clean), + rustc_attr!(TEST, rustc_partition_reused), + rustc_attr!(TEST, rustc_partition_codegened), + rustc_attr!(TEST, rustc_expected_cgu_reuse), + rustc_attr!(TEST, rustc_symbol_name), + rustc_attr!(TEST, rustc_def_path), + rustc_attr!(TEST, rustc_mir), + gated!(custom_mir,"the `#[custom_mir]` attribute is just used for the Rust test suite"), + rustc_attr!(TEST, rustc_dump_item_bounds), + rustc_attr!(TEST, rustc_dump_predicates), + rustc_attr!(TEST, rustc_dump_def_parents), + rustc_attr!(TEST, rustc_dump_object_lifetime_defaults), + rustc_attr!(TEST, rustc_dump_vtable), + rustc_attr!(TEST, rustc_dummy), + rustc_attr!(TEST, pattern_complexity_limit), ]; pub fn is_builtin_attr_name(name: Symbol) -> bool { From 7f06f55bc29a984458179fceb72cac84e96202c7 Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Tue, 7 Apr 2026 10:37:23 +0300 Subject: [PATCH 29/37] Remove not needed PhantomData --- compiler/rustc_ast_lowering/src/delegation.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 022f9e3c83f1..3fc84cc27579 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -37,7 +37,6 @@ //! also be emitted during HIR ty lowering. use std::iter; -use std::marker::PhantomData; use ast::visit::Visitor; use hir::def::{DefKind, PartialRes, Res}; @@ -420,7 +419,6 @@ fn lower_delegation_body( resolver: this.resolver, path_id: delegation.id, self_param_id: pat_node_id, - phantom: PhantomData, }; self_resolver.visit_block(block); // Target expr needs to lower `self` path. @@ -673,14 +671,13 @@ fn mk_expr(&mut self, kind: hir::ExprKind<'hir>, span: Span) -> hir::Expr<'hir> } } -struct SelfResolver<'a, 'tcx, R> { +struct SelfResolver<'a, R> { resolver: &'a mut R, path_id: NodeId, self_param_id: NodeId, - phantom: PhantomData<&'tcx ()>, } -impl<'tcx, R: ResolverAstLoweringExt<'tcx>> SelfResolver<'_, 'tcx, R> { +impl<'tcx, R: ResolverAstLoweringExt<'tcx>> SelfResolver<'_, R> { fn try_replace_id(&mut self, id: NodeId) { if let Some(res) = self.resolver.get_partial_res(id) && let Some(Res::Local(sig_id)) = res.full_res() @@ -692,7 +689,7 @@ fn try_replace_id(&mut self, id: NodeId) { } } -impl<'ast, 'a, 'tcx, R: ResolverAstLoweringExt<'tcx>> Visitor<'ast> for SelfResolver<'a, 'tcx, R> { +impl<'ast, 'tcx, R: ResolverAstLoweringExt<'tcx>> Visitor<'ast> for SelfResolver<'_, R> { fn visit_id(&mut self, id: NodeId) { self.try_replace_id(id); } From 7ce2d51799b340d9ab41f643bc178a602ba6cd38 Mon Sep 17 00:00:00 2001 From: Kcang-gna Date: Mon, 6 Apr 2026 12:19:24 +0800 Subject: [PATCH 30/37] add regression test --- ...ociated-impl-trait-type-into-emplacable.rs | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 tests/ui/impl-trait/associated-impl-trait-type-into-emplacable.rs diff --git a/tests/ui/impl-trait/associated-impl-trait-type-into-emplacable.rs b/tests/ui/impl-trait/associated-impl-trait-type-into-emplacable.rs new file mode 100644 index 000000000000..2c63b2743a0c --- /dev/null +++ b/tests/ui/impl-trait/associated-impl-trait-type-into-emplacable.rs @@ -0,0 +1,52 @@ +//! add regression test for . + +//@ check-pass + +#![feature(impl_trait_in_assoc_type)] + +use std::marker::PhantomData; + +struct Emp { + phantom: PhantomData<(*const T, F)>, +} + +impl Emp { + fn from_fn(_: F) -> Emp { + loop {} + } + + fn unsize(self) -> Emp { + Emp::from_fn(|| ()) + } +} + +trait IntoEmplacable { + type Closure; + + fn into_emplacable(self) -> Emp; +} + +impl IntoEmplacable for Emp { + type Closure = impl Sized; + + fn into_emplacable(self) -> Emp { + self.unsize() + } +} + +impl Into as IntoEmplacable>::Closure>> for Emp { + fn into(self) -> Emp as IntoEmplacable>::Closure> { + self.into_emplacable() + } +} + +fn box_new_with(_: Emp) {} + +pub struct Arr; +pub struct Slice; + +pub fn foo() { + let e: Emp = Emp { phantom: PhantomData }; + box_new_with(e.into()); +} +fn main() {} From db373833ce6d49c593507db7cffd170826ed951f Mon Sep 17 00:00:00 2001 From: guiyuanju Date: Tue, 7 Apr 2026 14:01:23 +0800 Subject: [PATCH 31/37] Fix pin docs Split a long sentence to improve readability. --- library/core/src/pin.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index ea3ba8cf3a94..b65e40ef4675 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -474,9 +474,9 @@ //! //! In an intrusive doubly-linked list, the collection itself does not own the memory in which //! each of its elements is stored. Instead, each client is free to allocate space for elements it -//! adds to the list in whichever manner it likes, including on the stack! Elements can live on a -//! stack frame that lives shorter than the collection does provided the elements that live in a -//! given stack frame are removed from the list before going out of scope. +//! adds to the list in whichever manner it likes, including on the stack! Elements can be stored +//! in a stack frame shorter-lived than the collection, provided they are removed from the list +//! before that frame goes out of scope. //! //! To make such an intrusive data structure work, every element stores pointers to its predecessor //! and successor within its own data, rather than having the list structure itself managing those From 86f9e83b2de528fc8a54e0c3c6465079c0da7698 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 7 Apr 2026 09:41:56 +0000 Subject: [PATCH 32/37] intrinsics: no `cfg(target_arch)` on scalable These intrinsics don't technically need to be limited to a specific architecture, they'll probably only make sense to use on AArch64, but this just makes it harder to use them in stdarch where it is appropriate (such as on `arm64ec`), requiring a rustc patch to land and be on nightly before stdarch work can proceed - so just don't `cfg` them at all. --- library/core/src/intrinsics/simd/scalable.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/library/core/src/intrinsics/simd/scalable.rs b/library/core/src/intrinsics/simd/scalable.rs index f33831a30c07..b2b0fec487c0 100644 --- a/library/core/src/intrinsics/simd/scalable.rs +++ b/library/core/src/intrinsics/simd/scalable.rs @@ -19,7 +19,6 @@ /// * Not be `NaN` /// * Not be infinite /// * Be representable in the return type, after truncating off its fractional part -#[cfg(target_arch = "aarch64")] #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn sve_cast(x: T) -> U; @@ -31,7 +30,6 @@ /// type `SVec`. /// /// Corresponds to Clang's `__builtin_sve_svcreate2*` builtins. -#[cfg(target_arch = "aarch64")] #[rustc_nounwind] #[rustc_intrinsic] pub unsafe fn sve_tuple_create2(x0: SVec, x1: SVec) -> SVecTup; @@ -43,7 +41,6 @@ /// type `SVec`. /// /// Corresponds to Clang's `__builtin_sve_svcreate3*` builtins. -#[cfg(target_arch = "aarch64")] #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn sve_tuple_create3(x0: SVec, x1: SVec, x2: SVec) -> SVecTup; @@ -55,7 +52,6 @@ /// type `SVec`. /// /// Corresponds to Clang's `__builtin_sve_svcreate4*` builtins. -#[cfg(target_arch = "aarch64")] #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn sve_tuple_create4(x0: SVec, x1: SVec, x2: SVec, x3: SVec) -> SVecTup; @@ -71,7 +67,6 @@ /// # Safety /// /// `IDX` must be in-bounds of the tuple. -#[cfg(target_arch = "aarch64")] #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn sve_tuple_get(tuple: SVecTup) -> SVec; @@ -87,7 +82,6 @@ /// # Safety /// /// `IDX` must be in-bounds of the tuple. -#[cfg(target_arch = "aarch64")] #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn sve_tuple_set(tuple: SVecTup, x: SVec) -> SVecTup; From eacf5b85561628a24bcda3e8c277c7cfbb686cbe Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Tue, 7 Apr 2026 13:04:59 +0300 Subject: [PATCH 33/37] Generate more verbose error delegation --- compiler/rustc_ast_lowering/src/delegation.rs | 66 +++++++------- .../duplicate-definition-inside-trait-impl.rs | 2 + ...licate-definition-inside-trait-impl.stderr | 30 ++++++- tests/ui/delegation/glob-glob-conflict.rs | 4 + tests/ui/delegation/glob-glob-conflict.stderr | 59 ++++++++++++- tests/ui/delegation/ice-issue-124347.rs | 2 + tests/ui/delegation/ice-issue-124347.stderr | 34 +++++++- .../delegation/recursive-delegation-errors.rs | 6 ++ .../recursive-delegation-errors.stderr | 85 +++++++++++++++---- .../delegation/unlowered-path-ice-154820.rs | 12 +++ .../unlowered-path-ice-154820.stderr | 40 +++++++++ 11 files changed, 281 insertions(+), 59 deletions(-) create mode 100644 tests/ui/delegation/unlowered-path-ice-154820.rs create mode 100644 tests/ui/delegation/unlowered-path-ice-154820.stderr diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 022f9e3c83f1..eb005e49112b 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -128,14 +128,12 @@ pub(crate) fn lower_delegation( { self.get_sig_id(delegation_info.resolution_node, span) } else { - return self.generate_delegation_error( - self.dcx().span_delayed_bug( - span, - format!("LoweringContext: the delegation {:?} is unresolved", item_id), - ), + self.dcx().span_delayed_bug( span, - delegation, + format!("LoweringContext: the delegation {:?} is unresolved", item_id), ); + + return self.generate_delegation_error(span, delegation); }; match sig_id { @@ -172,7 +170,7 @@ pub(crate) fn lower_delegation( DelegationResults { body_id, sig, ident, generics } } - Err(err) => self.generate_delegation_error(err, span, delegation), + Err(_) => self.generate_delegation_error(span, delegation), } } @@ -604,7 +602,6 @@ fn process_segment( fn generate_delegation_error( &mut self, - err: ErrorGuaranteed, span: Span, delegation: &Delegation, ) -> DelegationResults<'hir> { @@ -622,36 +619,35 @@ fn generate_delegation_error( let ident = self.lower_ident(delegation.ident); let body_id = self.lower_body(|this| { - let body_expr = match delegation.body.as_ref() { - Some(box block) => { - // Generates a block when we failed to resolve delegation, where a target expression is its only statement, - // thus there will be no ICEs on further stages of analysis (see #144594) + let path = this.lower_qpath( + delegation.id, + &delegation.qself, + &delegation.path, + ParamMode::Optional, + AllowReturnTypeNotation::No, + ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, + ); - // As we generate a void function we want to convert target expression to statement to avoid additional - // errors, such as mismatched return type - let stmts = this.arena.alloc_from_iter([hir::Stmt { - hir_id: this.next_id(), - kind: rustc_hir::StmtKind::Semi( - this.arena.alloc(this.lower_target_expr(block)), - ), - span, - }]); - - let block = this.arena.alloc(hir::Block { - stmts, - expr: None, - hir_id: this.next_id(), - rules: hir::BlockCheckMode::DefaultBlock, - span, - targeted_by_break: false, - }); - - hir::ExprKind::Block(block, None) - } - None => hir::ExprKind::Err(err), + let callee_path = this.arena.alloc(this.mk_expr(hir::ExprKind::Path(path), span)); + let args = if let Some(box block) = delegation.body.as_ref() { + this.arena.alloc_slice(&[this.lower_target_expr(block)]) + } else { + &mut [] }; - (&[], this.mk_expr(body_expr, span)) + let call = this.arena.alloc(this.mk_expr(hir::ExprKind::Call(callee_path, args), span)); + + let block = this.arena.alloc(hir::Block { + stmts: &[], + expr: Some(call), + hir_id: this.next_id(), + rules: hir::BlockCheckMode::DefaultBlock, + span, + targeted_by_break: false, + }); + + (&[], this.mk_expr(hir::ExprKind::Block(block, None), span)) }); let generics = hir::Generics::empty(); diff --git a/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs b/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs index 9c7afcef3ec1..3c796b91d6fa 100644 --- a/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs +++ b/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs @@ -18,6 +18,8 @@ impl Trait for S { reuse to_reuse::foo { self } reuse Trait::foo; //~^ ERROR duplicate definitions with name `foo` + //~| ERROR: this function takes 1 argument but 0 arguments were supplied + //~| ERROR: mismatched types } fn main() {} diff --git a/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr b/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr index a0f157800cb5..83d69d2df600 100644 --- a/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr +++ b/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr @@ -9,6 +9,32 @@ LL | reuse to_reuse::foo { self } LL | reuse Trait::foo; | ^^^^^^^^^^^^^^^^^ duplicate definition -error: aborting due to 1 previous error +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/duplicate-definition-inside-trait-impl.rs:19:18 + | +LL | reuse Trait::foo; + | ^^^ argument #1 of type `&_` is missing + | +note: method defined here + --> $DIR/duplicate-definition-inside-trait-impl.rs:5:8 + | +LL | fn foo(&self) -> u32 { 0 } + | ^^^ ----- +help: provide the argument + | +LL | reuse Trait::foo(/* value */); + | +++++++++++++ -For more information about this error, try `rustc --explain E0201`. +error[E0308]: mismatched types + --> $DIR/duplicate-definition-inside-trait-impl.rs:19:18 + | +LL | reuse Trait::foo; + | ^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `u32` + | expected `()` because of default return type + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0061, E0201, E0308. +For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/glob-glob-conflict.rs b/tests/ui/delegation/glob-glob-conflict.rs index 2843bf8c4934..cb07a78b84fe 100644 --- a/tests/ui/delegation/glob-glob-conflict.rs +++ b/tests/ui/delegation/glob-glob-conflict.rs @@ -3,9 +3,13 @@ trait Trait1 { fn method(&self) -> u8; + //~^ ERROR: this function takes 1 argument but 0 arguments were supplied + //~| ERROR: mismatched types } trait Trait2 { fn method(&self) -> u8; + //~^ ERROR: this function takes 1 argument but 0 arguments were supplied + //~| ERROR: mismatched types } trait Trait { fn method(&self) -> u8; diff --git a/tests/ui/delegation/glob-glob-conflict.stderr b/tests/ui/delegation/glob-glob-conflict.stderr index 8c7e5a4b023c..4259d71117b7 100644 --- a/tests/ui/delegation/glob-glob-conflict.stderr +++ b/tests/ui/delegation/glob-glob-conflict.stderr @@ -1,5 +1,5 @@ error[E0201]: duplicate definitions with name `method`: - --> $DIR/glob-glob-conflict.rs:26:5 + --> $DIR/glob-glob-conflict.rs:30:5 | LL | fn method(&self) -> u8; | ----------------------- item in trait @@ -10,7 +10,7 @@ LL | reuse Trait2::*; | ^^^^^^^^^^^^^^^^ duplicate definition error[E0201]: duplicate definitions with name `method`: - --> $DIR/glob-glob-conflict.rs:30:5 + --> $DIR/glob-glob-conflict.rs:34:5 | LL | fn method(&self) -> u8; | ----------------------- item in trait @@ -20,6 +20,57 @@ LL | reuse Trait1::*; LL | reuse Trait1::*; | ^^^^^^^^^^^^^^^^ duplicate definition -error: aborting due to 2 previous errors +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/glob-glob-conflict.rs:10:8 + | +LL | fn method(&self) -> u8; + | ^^^^^^ argument #1 of type `&_` is missing + | +note: method defined here + --> $DIR/glob-glob-conflict.rs:10:8 + | +LL | fn method(&self) -> u8; + | ^^^^^^ ---- +help: provide the argument + | +LL | fn method(/* value */)(&self) -> u8; + | +++++++++++++ -For more information about this error, try `rustc --explain E0201`. +error[E0308]: mismatched types + --> $DIR/glob-glob-conflict.rs:10:8 + | +LL | fn method(&self) -> u8; + | ^^^^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `u8` + | expected `()` because of default return type + +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/glob-glob-conflict.rs:5:8 + | +LL | fn method(&self) -> u8; + | ^^^^^^ argument #1 of type `&_` is missing + | +note: method defined here + --> $DIR/glob-glob-conflict.rs:5:8 + | +LL | fn method(&self) -> u8; + | ^^^^^^ ---- +help: provide the argument + | +LL | fn method(/* value */)(&self) -> u8; + | +++++++++++++ + +error[E0308]: mismatched types + --> $DIR/glob-glob-conflict.rs:5:8 + | +LL | fn method(&self) -> u8; + | ^^^^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `u8` + | expected `()` because of default return type + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0061, E0201, E0308. +For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/ice-issue-124347.rs b/tests/ui/delegation/ice-issue-124347.rs index 6bf3a08ba5b4..271634711834 100644 --- a/tests/ui/delegation/ice-issue-124347.rs +++ b/tests/ui/delegation/ice-issue-124347.rs @@ -4,9 +4,11 @@ trait Trait { reuse Trait::foo { &self.0 } //~^ ERROR failed to resolve delegation callee + //~| ERROR: this function takes 0 arguments but 1 argument was supplied } reuse foo; //~^ ERROR failed to resolve delegation callee +//~| WARN: function cannot return without recursing fn main() {} diff --git a/tests/ui/delegation/ice-issue-124347.stderr b/tests/ui/delegation/ice-issue-124347.stderr index 40be6be4abfa..90ad839e662c 100644 --- a/tests/ui/delegation/ice-issue-124347.stderr +++ b/tests/ui/delegation/ice-issue-124347.stderr @@ -5,10 +5,40 @@ LL | reuse Trait::foo { &self.0 } | ^^^ error: failed to resolve delegation callee - --> $DIR/ice-issue-124347.rs:9:7 + --> $DIR/ice-issue-124347.rs:10:7 | LL | reuse foo; | ^^^ -error: aborting due to 2 previous errors +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/ice-issue-124347.rs:5:18 + | +LL | reuse Trait::foo { &self.0 } + | ^^^ ------- unexpected argument + | +note: associated function defined here + --> $DIR/ice-issue-124347.rs:5:18 + | +LL | reuse Trait::foo { &self.0 } + | ^^^ +help: remove the extra argument + | +LL - reuse Trait::foo { &self.0 } +LL + reuse Trait::fo&self.0 } + | +warning: function cannot return without recursing + --> $DIR/ice-issue-124347.rs:10:7 + | +LL | reuse foo; + | ^^^ + | | + | cannot return without recursing + | recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/delegation/recursive-delegation-errors.rs b/tests/ui/delegation/recursive-delegation-errors.rs index 194182e20ed0..da295b09caea 100644 --- a/tests/ui/delegation/recursive-delegation-errors.rs +++ b/tests/ui/delegation/recursive-delegation-errors.rs @@ -5,6 +5,7 @@ mod first_mod { reuse foo; //~^ ERROR failed to resolve delegation callee + //~| WARN: function cannot return without recursing } mod second_mod { @@ -33,8 +34,10 @@ mod fourth_mod { trait Trait { reuse Trait::foo as bar; //~^ ERROR encountered a cycle during delegation signature resolution + //~| ERROR: type annotations needed reuse Trait::bar as foo; //~^ ERROR encountered a cycle during delegation signature resolution + //~| ERROR: type annotations needed } } @@ -48,6 +51,9 @@ trait GlobReuse { //~^ ERROR encountered a cycle during delegation signature resolution //~| ERROR encountered a cycle during delegation signature resolution //~| ERROR encountered a cycle during delegation signature resolution + //~| ERROR: type annotations needed + //~| ERROR: type annotations needed + //~| ERROR: type annotations needed } } diff --git a/tests/ui/delegation/recursive-delegation-errors.stderr b/tests/ui/delegation/recursive-delegation-errors.stderr index 9c4e316745ae..bf446bd872f7 100644 --- a/tests/ui/delegation/recursive-delegation-errors.stderr +++ b/tests/ui/delegation/recursive-delegation-errors.stderr @@ -5,94 +5,147 @@ LL | reuse foo; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:11:11 + --> $DIR/recursive-delegation-errors.rs:12:11 | LL | reuse foo as bar; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:13:11 + --> $DIR/recursive-delegation-errors.rs:14:11 | LL | reuse bar as foo; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:18:11 + --> $DIR/recursive-delegation-errors.rs:19:11 | LL | reuse foo as foo1; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:20:11 + --> $DIR/recursive-delegation-errors.rs:21:11 | LL | reuse foo1 as foo2; | ^^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:22:11 + --> $DIR/recursive-delegation-errors.rs:23:11 | LL | reuse foo2 as foo3; | ^^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:24:11 + --> $DIR/recursive-delegation-errors.rs:25:11 | LL | reuse foo3 as foo4; | ^^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:26:11 + --> $DIR/recursive-delegation-errors.rs:27:11 | LL | reuse foo4 as foo5; | ^^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:28:11 + --> $DIR/recursive-delegation-errors.rs:29:11 | LL | reuse foo5 as foo; | ^^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:34:22 + --> $DIR/recursive-delegation-errors.rs:35:22 | LL | reuse Trait::foo as bar; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:36:22 + --> $DIR/recursive-delegation-errors.rs:38:22 | LL | reuse Trait::bar as foo; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:42:30 + --> $DIR/recursive-delegation-errors.rs:45:30 | LL | reuse super::fifth_mod::{bar as foo, foo as bar}; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:42:42 + --> $DIR/recursive-delegation-errors.rs:45:42 | LL | reuse super::fifth_mod::{bar as foo, foo as bar}; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:47:27 + --> $DIR/recursive-delegation-errors.rs:50:27 | LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:47:39 + --> $DIR/recursive-delegation-errors.rs:50:39 | LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; | ^^^ error: encountered a cycle during delegation signature resolution - --> $DIR/recursive-delegation-errors.rs:47:51 + --> $DIR/recursive-delegation-errors.rs:50:51 | LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; | ^^^ -error: aborting due to 16 previous errors +error[E0283]: type annotations needed + --> $DIR/recursive-delegation-errors.rs:35:22 + | +LL | reuse Trait::foo as bar; + | ^^^ cannot infer type + | + = note: the type must implement `fourth_mod::Trait` +error[E0283]: type annotations needed + --> $DIR/recursive-delegation-errors.rs:38:22 + | +LL | reuse Trait::bar as foo; + | ^^^ cannot infer type + | + = note: the type must implement `fourth_mod::Trait` + +error[E0283]: type annotations needed + --> $DIR/recursive-delegation-errors.rs:50:27 + | +LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + | ^^^ cannot infer type + | + = note: the type must implement `GlobReuse` + +error[E0283]: type annotations needed + --> $DIR/recursive-delegation-errors.rs:50:39 + | +LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + | ^^^ cannot infer type + | + = note: the type must implement `GlobReuse` + +error[E0283]: type annotations needed + --> $DIR/recursive-delegation-errors.rs:50:51 + | +LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + | ^^^ cannot infer type + | + = note: the type must implement `GlobReuse` + +warning: function cannot return without recursing + --> $DIR/recursive-delegation-errors.rs:6:11 + | +LL | reuse foo; + | ^^^ + | | + | cannot return without recursing + | recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +error: aborting due to 21 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/delegation/unlowered-path-ice-154820.rs b/tests/ui/delegation/unlowered-path-ice-154820.rs new file mode 100644 index 000000000000..a527b17cf6c4 --- /dev/null +++ b/tests/ui/delegation/unlowered-path-ice-154820.rs @@ -0,0 +1,12 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +reuse foo:: < { //~ ERROR: failed to resolve delegation callee + //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied + fn foo() {} + reuse foo; + //~^ ERROR: the name `foo` is defined multiple times + } + >; + +fn main() {} diff --git a/tests/ui/delegation/unlowered-path-ice-154820.stderr b/tests/ui/delegation/unlowered-path-ice-154820.stderr new file mode 100644 index 000000000000..fbcb3ca9c71c --- /dev/null +++ b/tests/ui/delegation/unlowered-path-ice-154820.stderr @@ -0,0 +1,40 @@ +error[E0428]: the name `foo` is defined multiple times + --> $DIR/unlowered-path-ice-154820.rs:7:5 + | +LL | fn foo() {} + | -------- previous definition of the value `foo` here +LL | reuse foo; + | ^^^^^^^^^^ `foo` redefined here + | + = note: `foo` must be defined only once in the value namespace of this block + +error: failed to resolve delegation callee + --> $DIR/unlowered-path-ice-154820.rs:4:7 + | +LL | reuse foo:: < { + | ^^^ + +error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/unlowered-path-ice-154820.rs:4:7 + | +LL | reuse foo:: < { + | _______^^^- + | | | + | | expected 0 generic arguments +LL | | +LL | | fn foo() {} +LL | | reuse foo; +... | +LL | | >; + | |___- help: remove the unnecessary generics + | +note: function defined here, with 0 generic parameters + --> $DIR/unlowered-path-ice-154820.rs:4:7 + | +LL | reuse foo:: < { + | ^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0428. +For more information about an error, try `rustc --explain E0107`. From 03b453cda3ec7cd3d656972340df933c7ea67691 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 7 Apr 2026 13:54:30 +0800 Subject: [PATCH 34/37] Fix no results when searching for == in doc --- src/librustdoc/html/static/js/search.js | 23 ++++++++------- .../doc-alias-symbols-150921.js | 24 +++++++++++++++ tests/rustdoc-js/doc-alias-symbols-150921.js | 29 +++++++++++++++++++ tests/rustdoc-js/doc-alias-symbols-150921.rs | 7 +++++ 4 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 tests/rustdoc-js-std/doc-alias-symbols-150921.js create mode 100644 tests/rustdoc-js/doc-alias-symbols-150921.js create mode 100644 tests/rustdoc-js/doc-alias-symbols-150921.rs diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index e8343b2e21c8..e9968bedebe0 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -4749,11 +4749,16 @@ class DocSearch { })(), "query": parsedQuery, }; - } else if (parsedQuery.error !== null) { + } else if (parsedQuery.error !== null || parsedQuery.foundElems === 0) { + // Symbol-only queries like `==` do not parse into type elements, + // but can still match exact item names or doc aliases. + const others = parsedQuery.userQuery.length === 0 ? + (async function*() {})() : + innerRunNameQuery(currentCrate); return { "in_args": (async function*() {})(), "returned": (async function*() {})(), - "others": innerRunNameQuery(currentCrate), + "others": others, "query": parsedQuery, }; } else { @@ -4764,14 +4769,12 @@ class DocSearch { return { "in_args": (async function*() {})(), "returned": (async function*() {})(), - "others": parsedQuery.foundElems === 0 ? - (async function*() {})() : - innerRunTypeQuery( - parsedQuery.elems, - parsedQuery.returned, - typeInfo, - currentCrate, - ), + "others": innerRunTypeQuery( + parsedQuery.elems, + parsedQuery.returned, + typeInfo, + currentCrate, + ), "query": parsedQuery, }; } diff --git a/tests/rustdoc-js-std/doc-alias-symbols-150921.js b/tests/rustdoc-js-std/doc-alias-symbols-150921.js new file mode 100644 index 000000000000..5183a7c19fe4 --- /dev/null +++ b/tests/rustdoc-js-std/doc-alias-symbols-150921.js @@ -0,0 +1,24 @@ +// exact-check +// Regression test for . + +const EXPECTED = [ + { + 'query': '==', + 'others': [ + { + 'path': 'std::cmp', + 'name': 'Eq', + 'alias': '==', + 'href': '../std/cmp/trait.Eq.html', + 'is_alias': true, + }, + { + 'path': 'std::cmp', + 'name': 'PartialEq', + 'alias': '==', + 'href': '../std/cmp/trait.PartialEq.html', + 'is_alias': true, + }, + ], + }, +]; diff --git a/tests/rustdoc-js/doc-alias-symbols-150921.js b/tests/rustdoc-js/doc-alias-symbols-150921.js new file mode 100644 index 000000000000..e51d70a28bfe --- /dev/null +++ b/tests/rustdoc-js/doc-alias-symbols-150921.js @@ -0,0 +1,29 @@ +// exact-check +// Regression test for . + +const EXPECTED = [ + { + 'query': '==', + 'others': [ + { + 'path': 'doc_alias_symbols_150921', + 'name': 'OperatorEqEqAlias', + 'alias': '==', + 'href': '../doc_alias_symbols_150921/struct.OperatorEqEqAlias.html', + 'is_alias': true, + }, + ], + }, + { + 'query': '!=', + 'others': [ + { + 'path': 'doc_alias_symbols_150921', + 'name': 'OperatorNotEqAlias', + 'alias': '!=', + 'href': '../doc_alias_symbols_150921/struct.OperatorNotEqAlias.html', + 'is_alias': true, + }, + ], + }, +]; diff --git a/tests/rustdoc-js/doc-alias-symbols-150921.rs b/tests/rustdoc-js/doc-alias-symbols-150921.rs new file mode 100644 index 000000000000..f67b1b3c04e6 --- /dev/null +++ b/tests/rustdoc-js/doc-alias-symbols-150921.rs @@ -0,0 +1,7 @@ +// Regression test for . + +#[doc(alias = "==")] +pub struct OperatorEqEqAlias; + +#[doc(alias = "!=")] +pub struct OperatorNotEqAlias; From e751cb8bd222a4956b31742b282ffc9e3aa23947 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Mon, 23 Mar 2026 10:03:50 +0100 Subject: [PATCH 35/37] bootstrap: Print why `if-unchanged` isn't downloading rustc Example output: ``` $ x b compiler Building bootstrap Finished `dev` profile [unoptimized] target(s) in 0.02s NOTE: detected 3 modifications that could affect a build of rustc - src/bootstrap/src/core/config/config.rs - src/bootstrap/src/core/download.rs - src/build_helper/src/git.rs skipping rustc download due to `download-rustc = 'if-unchanged'` Building stage1 compiler artifacts (stage0 -> stage1, aarch64-apple-darwin) Finished `release` profile [optimized] target(s) in 0.72s Creating a sysroot for stage1 compiler (use `rustup toolchain link 'name' build/host/stage1`) Build completed successfully in 0:00:05 ``` --- src/bootstrap/src/core/config/config.rs | 24 ++++++++++++++---- src/bootstrap/src/core/config/tests.rs | 30 +++++++++++----------- src/bootstrap/src/core/download.rs | 2 +- src/build_helper/src/git.rs | 33 +++++++++++++++++-------- 4 files changed, 57 insertions(+), 32 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 2c3b5251e12f..2b52e3b67235 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2237,11 +2237,7 @@ pub fn download_ci_rustc_commit<'a>( }); match freshness { PathFreshness::LastModifiedUpstream { upstream } => upstream, - PathFreshness::HasLocalModifications { upstream } => { - if if_unchanged { - return None; - } - + PathFreshness::HasLocalModifications { upstream, modifications } => { if dwn_ctx.is_running_on_ci() { eprintln!("CI rustc commit matches with HEAD and we are in CI."); eprintln!( @@ -2250,6 +2246,24 @@ pub fn download_ci_rustc_commit<'a>( return None; } + eprintln!( + "NOTE: detected {} modifications that could affect a build of rustc", + modifications.len() + ); + for file in modifications.iter().take(10) { + eprintln!("- {}", file.display()); + } + if modifications.len() > 10 { + eprintln!("- ... and {} more", modifications.len() - 10); + } + + if if_unchanged { + eprintln!("skipping rustc download due to `download-rustc = 'if-unchanged'`"); + return None; + } else { + eprintln!("downloading unconditionally due to `download-rustc = true`"); + } + upstream } PathFreshness::MissingUpstream => { diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 277ede8d7745..c281aa94f64e 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -32,6 +32,13 @@ fn get_toml(file: &Path) -> Result { toml::from_str(&contents).and_then(|table: toml::Value| TomlConfig::deserialize(table)) } +fn modified(upstream: impl Into, changes: &[&str]) -> PathFreshness { + PathFreshness::HasLocalModifications { + upstream: upstream.into(), + modifications: changes.iter().copied().map(PathBuf::from).collect(), + } +} + #[test] fn download_ci_llvm() { let config = TestCtx::new().config("check").create_config(); @@ -692,7 +699,7 @@ fn test_pr_ci_changed_in_pr() { let sha = ctx.create_upstream_merge(&["a"]); ctx.create_nonupstream_merge(&["b"]); let src = ctx.check_modifications(&["b"], CiEnv::GitHubActions); - assert_eq!(src, PathFreshness::HasLocalModifications { upstream: sha }); + assert_eq!(src, modified(sha, &["b"])); }); } @@ -712,7 +719,7 @@ fn test_auto_ci_changed_in_pr() { let sha = ctx.create_upstream_merge(&["a"]); ctx.create_upstream_merge(&["b", "c"]); let src = ctx.check_modifications(&["c", "d"], CiEnv::GitHubActions); - assert_eq!(src, PathFreshness::HasLocalModifications { upstream: sha }); + assert_eq!(src, modified(sha, &["c"])); }); } @@ -723,10 +730,7 @@ fn test_local_uncommitted_modifications() { ctx.create_branch("feature"); ctx.modify("a"); - assert_eq!( - ctx.check_modifications(&["a", "d"], CiEnv::None), - PathFreshness::HasLocalModifications { upstream: sha } - ); + assert_eq!(ctx.check_modifications(&["a", "d"], CiEnv::None), modified(sha, &["a"]),); }); } @@ -741,10 +745,7 @@ fn test_local_committed_modifications() { ctx.modify("a"); ctx.commit(); - assert_eq!( - ctx.check_modifications(&["a", "d"], CiEnv::None), - PathFreshness::HasLocalModifications { upstream: sha } - ); + assert_eq!(ctx.check_modifications(&["a", "d"], CiEnv::None), modified(sha, &["a"]),); }); } @@ -757,10 +758,7 @@ fn test_local_committed_modifications_subdirectory() { ctx.modify("a/b/d"); ctx.commit(); - assert_eq!( - ctx.check_modifications(&["a/b"], CiEnv::None), - PathFreshness::HasLocalModifications { upstream: sha } - ); + assert_eq!(ctx.check_modifications(&["a/b"], CiEnv::None), modified(sha, &["a/b/d"]),); }); } @@ -836,11 +834,11 @@ fn test_local_changes_negative_path() { ); assert_eq!( ctx.check_modifications(&[":!c"], CiEnv::None), - PathFreshness::HasLocalModifications { upstream: upstream.clone() } + modified(&upstream, &["b", "d"]), ); assert_eq!( ctx.check_modifications(&[":!d", ":!x"], CiEnv::None), - PathFreshness::HasLocalModifications { upstream } + modified(&upstream, &["b"]), ); }); } diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 389956f14599..b8e00c596f28 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -266,7 +266,7 @@ pub(crate) fn maybe_download_ci_llvm(&self) { }); let llvm_sha = match llvm_freshness { PathFreshness::LastModifiedUpstream { upstream } => upstream, - PathFreshness::HasLocalModifications { upstream } => upstream, + PathFreshness::HasLocalModifications { upstream, modifications: _ } => upstream, PathFreshness::MissingUpstream => { eprintln!("error: could not find commit hash for downloading LLVM"); eprintln!("HELP: maybe your repository history is too shallow?"); diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index 330fb465de42..87a52eee49b8 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -1,4 +1,4 @@ -use std::path::Path; +use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use crate::ci::CiEnv; @@ -38,7 +38,7 @@ pub enum PathFreshness { /// "Local" essentially means "not-upstream" here. /// `upstream` is the latest upstream merge commit that made modifications to the /// set of paths. - HasLocalModifications { upstream: String }, + HasLocalModifications { upstream: String, modifications: Vec }, /// No upstream commit was found. /// This should not happen in most reasonable circumstances, but one never knows. MissingUpstream, @@ -134,21 +134,34 @@ pub fn check_path_modifications( // However, that should be equivalent to checking if something has changed // from the latest upstream commit *that modified `target_paths`*, and // with this approach we do not need to invoke git an additional time. - if has_changed_since(git_dir, &upstream_sha, target_paths) { - Ok(PathFreshness::HasLocalModifications { upstream: upstream_sha }) + let modifications = changes_since(git_dir, &upstream_sha, target_paths)?; + if !modifications.is_empty() { + Ok(PathFreshness::HasLocalModifications { upstream: upstream_sha, modifications }) } else { Ok(PathFreshness::LastModifiedUpstream { upstream: upstream_sha }) } } /// Returns true if any of the passed `paths` have changed since the `base` commit. -pub fn has_changed_since(git_dir: &Path, base: &str, paths: &[&str]) -> bool { - run_git_diff_index(Some(git_dir), |cmd| { - cmd.args(["--quiet", base, "--"]).args(paths); +pub fn changes_since(git_dir: &Path, base: &str, paths: &[&str]) -> Result, String> { + use std::io::BufRead; - // Exit code 0 => no changes - // Exit code 1 => some changes were detected - !cmd.status().expect("cannot run git diff-index").success() + run_git_diff_index(Some(git_dir), |cmd| { + cmd.args([base, "--name-only", "--"]).args(paths); + + let output = cmd.stderr(Stdio::inherit()).output().expect("cannot run git diff-index"); + if !output.status.success() { + return Err(format!("failed to run: {cmd:?}: {:?}", output.status)); + } + + output + .stdout + .lines() + .map(|res| match res { + Ok(line) => Ok(PathBuf::from(line)), + Err(e) => Err(format!("invalid UTF-8 in diff-index: {e:?}")), + }) + .collect() }) } From 9b5e085d537030bbb9dce7344cc55cb83557ac86 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Mon, 23 Mar 2026 10:05:21 +0100 Subject: [PATCH 36/37] Don't consider `bootstrap/defaults` to invalidate the rustc cache Anything that can change there can also be changed in bootstrap.toml. We have a separate check to make sure that the local config is compatable with CI's config. --- src/bootstrap/src/core/config/config.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 2b52e3b67235..36e6432ee82a 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -78,6 +78,7 @@ ":!src/rustdoc-json-types", ":!tests", ":!triagebot.toml", + ":!src/bootstrap/defaults", ]; /// Global configuration for the entire build and/or bootstrap. From cdde49123f4b070545d1146663421abef8e82999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 7 Apr 2026 17:23:32 +0200 Subject: [PATCH 37/37] Document the `-quick` job suffix --- src/doc/rustc-dev-guide/src/tests/ci.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index 5581b7eb9d8d..b656d9495e0b 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -150,7 +150,10 @@ Such a try build will not execute any tests, and it will allow compilation warni It is useful when you want to get an optimized toolchain as fast as possible, for a Crater run or performance benchmarks, even if it might not be working fully correctly. -If you want to do a full build for the default try job, + +The CI job executed in fast try builds has a special suffix (`-quick`), +to distinguish it from a full build of the default try job. +If you want to do the full build instead, specify its job name in a job pattern (explained below). If you want to run custom CI jobs in a try build and make sure that they pass all tests and do