diff --git a/mrustc/0001-do-not-download-rustc.patch b/mrustc/0001-do-not-download-rustc.patch new file mode 100644 index 0000000..e601229 --- /dev/null +++ b/mrustc/0001-do-not-download-rustc.patch @@ -0,0 +1,27 @@ +From 157772049aa7da13533026292cb4f67c1e8bf542 Mon Sep 17 00:00:00 2001 +From: nobody +Date: Sun, 19 Jul 2026 06:21:49 +0900 +Subject: [PATCH 1/3] do not download rustc + +The $(RUSTC_SRC_DL) file already exists, but for some reason Make wants +to rebuild this target when it has $(RUSTC_SRC_TARBALL) as a dependency. +--- + minicargo.mk | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/minicargo.mk b/minicargo.mk +index 5cd3489c..eb869a1b 100644 +--- a/minicargo.mk ++++ b/minicargo.mk +@@ -233,7 +233,7 @@ $(RUSTC_SRC_DL): rustc-$(RUSTC_VERSION)-src/extracted rustc-$(RUSTC_VERSION)-src + # - libstd, libpanic_unwind, libtest and libgetopts + # - libproc_macro (mrustc) + ifeq ($(USE_MERGED_BUILD),1) +-$(RUSTCSRC)mrustc-stdlib/Cargo.toml: $(RUSTC_SRC_DL) minicargo.mk ++$(RUSTCSRC)mrustc-stdlib/Cargo.toml: minicargo.mk + @mkdir -p $(dir $@) + @echo "#![no_core]" > $(dir $@)/lib.rs + @echo "[package]" > $@ +-- +2.55.0 + diff --git a/mrustc/0002-Revert-HIR-Typecheck-Optimise-by-doing-multiple-chec.patch b/mrustc/0002-Revert-HIR-Typecheck-Optimise-by-doing-multiple-chec.patch new file mode 100644 index 0000000..463bf2d --- /dev/null +++ b/mrustc/0002-Revert-HIR-Typecheck-Optimise-by-doing-multiple-chec.patch @@ -0,0 +1,96 @@ +From 6e66feb3b6ae698c3d29211847c71c00f87fbf78 Mon Sep 17 00:00:00 2001 +From: nobody +Date: Sun, 19 Jul 2026 06:23:12 +0900 +Subject: [PATCH 2/3] Revert "HIR Typecheck - Optimise by doing multiple checks + per pass" + +This reverts commit 99d9bd0c788b0c72fc2f4fee6187a462ceb059f2. +--- + src/hir_typeck/expr_cs.cpp | 71 ++++++++++++++++---------------------- + 1 file changed, 30 insertions(+), 41 deletions(-) + +diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp +index 366cf78e..874d25cc 100644 +--- a/src/hir_typeck/expr_cs.cpp ++++ b/src/hir_typeck/expr_cs.cpp +@@ -8001,47 +8001,36 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: + for(unsigned int i = 0; i < context.possible_ivar_vals.size(); i ++ ) + { + if( check_ivar_poss(context, i, context.possible_ivar_vals[i]) ) { +- // Look at all other ivar possibility sets, and disable processing if they depend on this ivar (prevents races) +- auto contains_ty = [&i](const HIR::TypeRef& t) { +- auto cb = [&](const HIR::TypeRef& t) { +- // TODO: Resolve ivars +- return TU_TEST1(t.data(), Infer, .index == i); +- }; +- return visit_ty_with( t, cb ); +- }; +- auto disable_in = [&context](const HIR::TypeRef& t)->bool { +- auto cb = [&](const HIR::TypeRef& tr) { +- const auto& t = context.m_ivars.get_type(tr); +- if(const auto* te = t.data().opt_Infer()) { +- DEBUG("Disable IVar " << te->index); +- context.possible_ivar_vals[te->index].force_disable = true; +- } +- return false; +- }; +- return visit_ty_with( t, cb ); +- }; +- for(const auto& r : context.link_assoc) { +- if( contains_ty(r.impl_ty) || contains_ty(r.left_ty) || ::std::any_of(r.params.m_types.begin(), r.params.m_types.end(), contains_ty) ) { +- disable_in(r.impl_ty); +- for(const auto& t : r.params.m_types) { +- disable_in(t); +- } +- } +- } +- for(auto& e : context.possible_ivar_vals) { +- bool references_this = false; +- for(const auto& t : e.types_coerce_from) { +- references_this |= contains_ty(t.ty); +- } +- for(const auto& t : e.types_coerce_to) { +- references_this |= contains_ty(t.ty); +- } +- for(const auto& t : e.bounded) { +- references_this |= contains_ty(t); +- } +- if(references_this) { +- DEBUG("Block IVar " << (&e - context.possible_ivar_vals.data())); +- e.force_disable = true; ++ // HACK: For `gix v0.73.0`, but really a good idea: only set one ivar per pass. ++ // - Ideally, would determine if this ivar is used in any other rules, and prevent ivars mentioned in those rules ++ // from also being guessed. ++ break; ++ static Span sp; ++ //assert( context.possible_ivar_vals[i].has_rules() ); ++ // Disable all metioned ivars in the possibilities ++ for(const auto& ty : context.possible_ivar_vals[i].types_coerce_to) ++ context.possible_equate_type_unknown(sp, ty.ty, Context::IvarUnknownType::From); ++ for(const auto& ty : context.possible_ivar_vals[i].types_coerce_from) ++ context.possible_equate_type_unknown(sp, ty.ty, Context::IvarUnknownType::To); ++ ++ // Also disable inferrence (for this pass) for all ivars in affected bounds ++ if(false) ++ for(const auto& la : context.link_assoc) ++ { ++ bool found = false; ++ auto cb = [&](const auto& t) { return TU_TEST1(t.data(), Infer, .index == i); }; ++ if( la.left_ty != ::HIR::TypeRef() ) ++ found |= visit_ty_with( la.left_ty, cb ); ++ found |= visit_ty_with( la.impl_ty, cb ); ++ for(const auto& t : la.params.m_types) ++ found |= visit_ty_with( t, cb ); ++ if( found ) ++ { ++ if(la.left_ty != ::HIR::TypeRef()) ++ context.possible_equate_type_unknown(sp, la.left_ty, Context::IvarUnknownType::From); ++ context.possible_equate_type_unknown(sp, la.impl_ty, Context::IvarUnknownType::From); ++ for(const auto& t : la.params.m_types) ++ context.possible_equate_type_unknown(sp, t, Context::IvarUnknownType::From); + } + } + } +-- +2.55.0 + diff --git a/mrustc/0003-rustc-src-enable-rustix-use-libc-feature-revert-port.patch b/mrustc/0003-rustc-src-enable-rustix-use-libc-feature-revert-port.patch new file mode 100644 index 0000000..0dcf181 --- /dev/null +++ b/mrustc/0003-rustc-src-enable-rustix-use-libc-feature-revert-port.patch @@ -0,0 +1,1975 @@ +From f6dfdcac94f6f686eb4eb8c940c9f867e8dab917 Mon Sep 17 00:00:00 2001 +From: nobody +Date: Sun, 19 Jul 2026 14:08:37 +0900 +Subject: [PATCH 3/3] rustc-src: enable rustix use-libc feature, revert ported + attributes + +Works around fatal runtime error: out of TLS keys, aborting. +--- + rustc-1.90.0-src.patch | 1937 +++++++++++++++++++++++++++++++++++++++- + 1 file changed, 1911 insertions(+), 26 deletions(-) + +diff --git a/rustc-1.90.0-src.patch b/rustc-1.90.0-src.patch +index 7566c00f..c23cda03 100644 +--- a/rustc-1.90.0-src.patch ++++ b/rustc-1.90.0-src.patch +@@ -1,41 +1,1194 @@ +-# Disable various struct size checks, as mrustc isn't as good at niche optimisations +---- compiler/rustc_hir/src/hir.rs +-+++ compiler/rustc_hir/src/hir.rs +-@@ -4938,4 +4938,5 @@ +- // Some nodes are used a lot. Make sure they don't unintentionally get bigger. +-+#[cfg(not(rust_compiler="mrustc"))] +- #[cfg(target_pointer_width = "64")] +- mod size_asserts { +- use rustc_data_structures::static_assert_size; ++--- vendor/crossterm-0.28.1/Cargo.toml +++++ vendor/crossterm-0.28.1/Cargo.toml ++@@ -177,6 +177,7 @@ features = [ ++ "std", ++ "stdio", ++ "termios", +++ "use-libc" ++ ] ++ default-features = false ++ ++--- vendor/fd-lock-4.0.4/Cargo.toml +++++ vendor/fd-lock-4.0.4/Cargo.toml ++@@ -56,7 +56,7 @@ version = "3.0.8" ++ ++ [target."cfg(unix)".dependencies.rustix] ++ version = "1.0.0" ++-features = ["fs"] +++features = ["fs", "use-libc"] ++ ++ [target."cfg(windows)".dependencies.windows-sys] ++ version = ">=0.52.0, <0.60.0" ++--- vendor/gix-index-0.38.0/Cargo.toml +++++ vendor/gix-index-0.38.0/Cargo.toml ++@@ -129,6 +129,7 @@ version = "0.38.20" ++ features = [ ++ "std", ++ "fs", +++ "use-libc" ++ ] ++ default-features = false ++ ++--- vendor/gix-index-0.41.0/Cargo.toml +++++ vendor/gix-index-0.41.0/Cargo.toml ++@@ -126,6 +126,7 @@ version = "1.0.7" ++ features = [ ++ "std", ++ "fs", +++ "use-libc" ++ ] ++ default-features = false ++ ++--- vendor/gix-prompt-0.11.1/Cargo.toml +++++ vendor/gix-prompt-0.11.1/Cargo.toml ++@@ -57,7 +57,7 @@ version = "0.12.4" ++ ++ [target."cfg(unix)".dependencies.rustix] ++ version = "1.0.7" ++-features = ["termios"] +++features = ["termios", "use-libc"] ++ ++ [lints.clippy] ++ bool_to_int_with_if = "allow" ++--- vendor/gix-prompt-0.9.1/Cargo.toml +++++ vendor/gix-prompt-0.9.1/Cargo.toml ++@@ -57,7 +57,7 @@ version = "0.12.1" ++ ++ [target."cfg(unix)".dependencies.rustix] ++ version = "0.38.4" ++-features = ["termios"] +++features = ["termios", "use-libc"] ++ ++ [lints.clippy] ++ bool_to_int_with_if = "allow" ++--- vendor/is-terminal-0.4.13/Cargo.toml +++++ vendor/is-terminal-0.4.13/Cargo.toml ++@@ -58,7 +58,7 @@ version = "0.2.110" ++ ++ [target.'cfg(any(unix, target_os = "wasi"))'.dev-dependencies.rustix] ++ version = "0.38.0" ++-features = ["termios"] +++features = ["termios", "use-libc"] ++ ++ [target.'cfg(not(any(windows, target_os = "hermit", target_os = "unknown")))'.dev-dependencies.rustix] ++ version = "0.38.0" ++--- vendor/is-terminal-0.4.15/Cargo.toml +++++ vendor/is-terminal-0.4.15/Cargo.toml ++@@ -59,7 +59,7 @@ version = "0.2.110" ++ ++ [target.'cfg(any(unix, target_os = "wasi"))'.dev-dependencies.rustix] ++ version = "0.38.44" ++-features = ["termios"] +++features = ["termios", "use-libc"] ++ ++ [target.'cfg(not(any(windows, target_os = "hermit", target_os = "unknown")))'.dev-dependencies.rustix] ++ version = "0.38.0" ++--- vendor/junction-1.2.0/Cargo.toml +++++ vendor/junction-1.2.0/Cargo.toml ++@@ -46,6 +46,7 @@ path = "src/lib.rs" ++ ++ [dev-dependencies.rustix] ++ version = "=0.38.9" +++features = ["use-libc"] ++ ++ [dev-dependencies.tempfile] ++ version = "=3.8.0" ++--- vendor/tempfile-3.14.0/Cargo.toml +++++ vendor/tempfile-3.14.0/Cargo.toml ++@@ -80,7 +80,7 @@ nightly = [] ++ ++ [target.'cfg(any(unix, target_os = "wasi"))'.dependencies.rustix] ++ version = "0.38.39" ++-features = ["fs"] +++features = ["fs", "use-libc"] ++ ++ [target."cfg(windows)".dependencies.windows-sys] ++ version = ">=0.52,<=0.59" ++--- vendor/tempfile-3.16.0/Cargo.toml +++++ vendor/tempfile-3.16.0/Cargo.toml ++@@ -82,7 +82,7 @@ nightly = [] ++ ++ [target.'cfg(any(unix, target_os = "wasi"))'.dependencies.rustix] ++ version = "0.38.39" ++-features = ["fs"] +++features = ["fs", "use-libc"] ++ ++ [target.'cfg(any(unix, windows, target_os = "wasi"))'.dependencies.getrandom] ++ version = "0.3.0" ++--- vendor/tempfile-3.19.0/Cargo.toml +++++ vendor/tempfile-3.19.0/Cargo.toml ++@@ -80,7 +80,7 @@ version = "0.3" ++ ++ [target.'cfg(any(unix, target_os = "wasi"))'.dependencies.rustix] ++ version = "1.0.0" ++-features = ["fs"] +++features = ["fs", "use-libc"] ++ ++ [target.'cfg(any(unix, windows, target_os = "wasi"))'.dependencies.getrandom] ++ version = "0.3.0" ++--- vendor/tempfile-3.19.1/Cargo.toml +++++ vendor/tempfile-3.19.1/Cargo.toml ++@@ -80,7 +80,7 @@ version = "0.3" ++ ++ [target.'cfg(any(unix, target_os = "wasi"))'.dependencies.rustix] ++ version = "1.0.0" ++-features = ["fs"] +++features = ["fs", "use-libc"] ++ ++ [target.'cfg(any(unix, windows, target_os = "wasi"))'.dependencies.getrandom] ++ version = "0.3.0" ++--- vendor/tempfile-3.20.0/Cargo.toml +++++ vendor/tempfile-3.20.0/Cargo.toml ++@@ -83,7 +83,7 @@ version = "0.3" ++ ++ [target.'cfg(any(unix, target_os = "wasi"))'.dependencies.rustix] ++ version = "1.0.0" ++-features = ["fs"] +++features = ["fs", "use-libc"] ++ ++ [target.'cfg(any(unix, windows, target_os = "wasi"))'.dependencies.getrandom] ++ version = "0.3.0" ++--- vendor/terminal_size-0.4.1/Cargo.toml +++++ vendor/terminal_size-0.4.1/Cargo.toml ++@@ -44,7 +44,7 @@ path = "examples/get_size.rs" ++ ++ [target."cfg(unix)".dependencies.rustix] ++ version = "0.38.0" ++-features = ["termios"] +++features = ["termios", "use-libc"] ++ ++ [target."cfg(windows)".dependencies.windows-sys] ++ version = "0.59.0" ++--- vendor/terminal_size-0.4.2/Cargo.toml +++++ vendor/terminal_size-0.4.2/Cargo.toml ++@@ -44,7 +44,7 @@ path = "examples/get_size.rs" ++ ++ [target."cfg(unix)".dependencies.rustix] ++ version = "1.0.1" ++-features = ["termios"] +++features = ["termios", "use-libc"] ++ ++ [target."cfg(windows)".dependencies.windows-sys] ++ version = "0.59.0" ++--- vendor/xattr-1.5.0/Cargo.toml +++++ vendor/xattr-1.5.0/Cargo.toml ++@@ -51,6 +51,7 @@ version = "1.0.0" ++ features = [ ++ "fs", ++ "std", +++ "use-libc" ++ ] ++ default-features = false ++ ++--- vendor/xattr-1.5.1/Cargo.toml +++++ vendor/xattr-1.5.1/Cargo.toml ++@@ -51,6 +51,7 @@ version = "1.0.0" ++ features = [ ++ "fs", ++ "std", +++ "use-libc" ++ ] ++ default-features = false ++ ++--- Cargo.lock +++++ Cargo.lock ++@@ -4344,7 +4344,6 @@ dependencies = [ ++ "rustc-literal-escaper", ++ "rustc_ast", ++ "rustc_ast_pretty", ++- "rustc_attr_parsing", ++ "rustc_data_structures", ++ "rustc_errors", ++ "rustc_feature", ++--- compiler/rustc_ast/src/attr/mod.rs +++++ compiler/rustc_ast/src/attr/mod.rs ++@@ -217,10 +217,6 @@ fn doc_resolution_scope(&self) -> Option { ++ _ => None, ++ } ++ } ++- ++- fn is_automatically_derived_attr(&self) -> bool { ++- self.has_name(sym::automatically_derived) ++- } ++ } ++ ++ impl Attribute { ++@@ -814,7 +810,6 @@ fn is_proc_macro_attr(&self) -> bool { ++ .iter() ++ .any(|kind| self.has_name(*kind)) ++ } ++- fn is_automatically_derived_attr(&self) -> bool; ++ ++ /// Returns the documentation and its kind if this is a doc comment or a sugared doc comment. ++ /// * `///doc` returns `Some(("doc", CommentKind::Line))`. ++--- compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++++ compiler/rustc_attr_parsing/src/attributes/link_attrs.rs ++@@ -60,27 +60,6 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option NoArgsAttributeParser for ExportStableParser { ++- const PATH: &[Symbol] = &[sym::export_stable]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; ++- const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ExportStable; ++-} ++- ++-pub(crate) struct FfiConstParser; ++-impl NoArgsAttributeParser for FfiConstParser { ++- const PATH: &[Symbol] = &[sym::ffi_const]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiConst; ++-} ++- ++-pub(crate) struct FfiPureParser; ++-impl NoArgsAttributeParser for FfiPureParser { ++- const PATH: &[Symbol] = &[sym::ffi_pure]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure; ++-} ++- ++ pub(crate) struct StdInternalSymbolParser; ++ impl NoArgsAttributeParser for StdInternalSymbolParser { ++ const PATH: &[Symbol] = &[sym::rustc_std_internal_symbol]; ++--- compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs +++++ /dev/null ++@@ -1,33 +0,0 @@ ++-use rustc_hir::attrs::AttributeKind; ++-use rustc_span::{Span, Symbol, sym}; ++- ++-use crate::attributes::{NoArgsAttributeParser, OnDuplicate}; ++-use crate::context::Stage; ++- ++-pub(crate) struct AsPtrParser; ++-impl NoArgsAttributeParser for AsPtrParser { ++- const PATH: &[Symbol] = &[sym::rustc_as_ptr]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::AsPtr; ++-} ++- ++-pub(crate) struct PubTransparentParser; ++-impl NoArgsAttributeParser for PubTransparentParser { ++- const PATH: &[Symbol] = &[sym::rustc_pub_transparent]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::PubTransparent; ++-} ++- ++-pub(crate) struct PassByValueParser; ++-impl NoArgsAttributeParser for PassByValueParser { ++- const PATH: &[Symbol] = &[sym::rustc_pass_by_value]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::PassByValue; ++-} ++- ++-pub(crate) struct AutomaticallyDerivedParser; ++-impl NoArgsAttributeParser for AutomaticallyDerivedParser { ++- const PATH: &[Symbol] = &[sym::automatically_derived]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::AutomaticallyDerived; ++-} ++--- compiler/rustc_attr_parsing/src/attributes/mod.rs +++++ compiler/rustc_attr_parsing/src/attributes/mod.rs ++@@ -34,19 +34,15 @@ ++ pub(crate) mod dummy; ++ pub(crate) mod inline; ++ pub(crate) mod link_attrs; ++-pub(crate) mod lint_helpers; ++ pub(crate) mod loop_match; ++ pub(crate) mod macro_attrs; ++ pub(crate) mod must_use; ++ pub(crate) mod no_implicit_prelude; ++-pub(crate) mod non_exhaustive; ++-pub(crate) mod path; ++ pub(crate) mod proc_macro_attrs; ++ pub(crate) mod repr; ++ pub(crate) mod rustc_internal; ++ pub(crate) mod semantics; ++ pub(crate) mod stability; ++-pub(crate) mod test_attrs; ++ pub(crate) mod traits; ++ pub(crate) mod transparency; ++ pub(crate) mod util; ++--- compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs +++++ /dev/null ++@@ -1,13 +0,0 @@ ++-use rustc_hir::attrs::AttributeKind; ++-use rustc_span::{Span, Symbol, sym}; ++- ++-use crate::attributes::{NoArgsAttributeParser, OnDuplicate}; ++-use crate::context::Stage; ++- ++-pub(crate) struct NonExhaustiveParser; ++- ++-impl NoArgsAttributeParser for NonExhaustiveParser { ++- const PATH: &[Symbol] = &[sym::non_exhaustive]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::NonExhaustive; ++-} ++--- compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++++ /dev/null ++@@ -1,46 +0,0 @@ ++-use rustc_feature::{AttributeTemplate, template}; ++-use rustc_hir::attrs::AttributeKind; ++-use rustc_hir::lints::AttributeLintKind; ++-use rustc_span::{Symbol, sym}; ++- ++-use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; ++-use crate::context::{AcceptContext, Stage}; ++-use crate::parser::ArgParser; ++- ++-pub(crate) struct IgnoreParser; ++- ++-impl SingleAttributeParser for IgnoreParser { ++- const PATH: &[Symbol] = &[sym::ignore]; ++- const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; ++- const TEMPLATE: AttributeTemplate = template!(Word, NameValueStr: "reason"); ++- ++- fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { ++- Some(AttributeKind::Ignore { ++- span: cx.attr_span, ++- reason: match args { ++- ArgParser::NoArgs => None, ++- ArgParser::NameValue(name_value) => { ++- let Some(str_value) = name_value.value_as_str() else { ++- let suggestions = >::TEMPLATE ++- .suggestions(false, "ignore"); ++- let span = cx.attr_span; ++- cx.emit_lint( ++- AttributeLintKind::IllFormedAttributeInput { suggestions }, ++- span, ++- ); ++- return None; ++- }; ++- Some(str_value) ++- } ++- ArgParser::List(_) => { ++- let suggestions = ++- >::TEMPLATE.suggestions(false, "ignore"); ++- let span = cx.attr_span; ++- cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span); ++- return None; ++- } ++- }, ++- }) ++- } ++-} ++--- compiler/rustc_attr_parsing/src/attributes/traits.rs +++++ compiler/rustc_attr_parsing/src/attributes/traits.rs ++@@ -4,9 +4,7 @@ ++ use rustc_hir::attrs::AttributeKind; ++ use rustc_span::{Span, Symbol, sym}; ++ ++-use crate::attributes::{ ++- AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser, ++-}; +++use crate::attributes::{AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser}; ++ use crate::context::{AcceptContext, Stage}; ++ use crate::parser::ArgParser; ++ ++@@ -54,99 +52,11 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option NoArgsAttributeParser for ParenSugarParser { ++- const PATH: &[Symbol] = &[sym::rustc_paren_sugar]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::ParenSugar; ++-} ++- ++-pub(crate) struct TypeConstParser; ++-impl NoArgsAttributeParser for TypeConstParser { ++- const PATH: &[Symbol] = &[sym::type_const]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::TypeConst; ++-} ++- ++-// Markers ++- ++-pub(crate) struct MarkerParser; ++-impl NoArgsAttributeParser for MarkerParser { ++- const PATH: &[Symbol] = &[sym::marker]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::Marker; ++-} ++- ++-pub(crate) struct DenyExplicitImplParser; ++-impl NoArgsAttributeParser for DenyExplicitImplParser { ++- const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::DenyExplicitImpl; ++-} ++- ++-pub(crate) struct DoNotImplementViaObjectParser; ++-impl NoArgsAttributeParser for DoNotImplementViaObjectParser { ++- const PATH: &[Symbol] = &[sym::rustc_do_not_implement_via_object]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::DoNotImplementViaObject; ++-} ++- ++ // FIXME(const_trait_impl): remove this ++ // Const traits ++ ++-pub(crate) struct ConstTraitParser; ++-impl NoArgsAttributeParser for ConstTraitParser { ++- const PATH: &[Symbol] = &[sym::const_trait]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstTrait; ++-} ++- ++-// Specialization ++- ++-pub(crate) struct SpecializationTraitParser; ++-impl NoArgsAttributeParser for SpecializationTraitParser { ++- const PATH: &[Symbol] = &[sym::rustc_specialization_trait]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::SpecializationTrait; ++-} ++- ++-pub(crate) struct UnsafeSpecializationMarkerParser; ++-impl NoArgsAttributeParser for UnsafeSpecializationMarkerParser { ++- const PATH: &[Symbol] = &[sym::rustc_unsafe_specialization_marker]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::UnsafeSpecializationMarker; ++-} ++- ++ // Coherence ++ ++-pub(crate) struct CoinductiveParser; ++-impl NoArgsAttributeParser for CoinductiveParser { ++- const PATH: &[Symbol] = &[sym::rustc_coinductive]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::Coinductive; ++-} ++- ++-pub(crate) struct AllowIncoherentImplParser; ++-impl NoArgsAttributeParser for AllowIncoherentImplParser { ++- const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; ++- const CREATE: fn(Span) -> AttributeKind = AttributeKind::AllowIncoherentImpl; ++-} ++- ++-pub(crate) struct CoherenceIsCoreParser; ++-impl NoArgsAttributeParser for CoherenceIsCoreParser { ++- const PATH: &[Symbol] = &[sym::rustc_coherence_is_core]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; ++- const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::CoherenceIsCore; ++-} ++- ++-pub(crate) struct FundamentalParser; ++-impl NoArgsAttributeParser for FundamentalParser { ++- const PATH: &[Symbol] = &[sym::fundamental]; ++- const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; ++- const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental; ++-} ++- ++ pub(crate) struct PointeeParser; ++ impl NoArgsAttributeParser for PointeeParser { ++ const PATH: &[Symbol] = &[sym::pointee]; ++--- compiler/rustc_attr_parsing/src/context.rs +++++ compiler/rustc_attr_parsing/src/context.rs ++@@ -26,18 +26,14 @@ ++ use crate::attributes::dummy::DummyParser; ++ use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; ++ use crate::attributes::link_attrs::{ ++- ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkOrdinalParser, +++ LinkNameParser, LinkOrdinalParser, ++ LinkSectionParser, StdInternalSymbolParser, ++ }; ++-use crate::attributes::lint_helpers::{ ++- AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser, ++-}; +++ ++ use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; ++ use crate::attributes::macro_attrs::{MacroEscapeParser, MacroUseParser}; ++ use crate::attributes::must_use::MustUseParser; ++ use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; ++-use crate::attributes::non_exhaustive::NonExhaustiveParser; ++-use crate::attributes::path::PathParser as PathAttributeParser; ++ use crate::attributes::proc_macro_attrs::{ ++ ProcMacroAttributeParser, ProcMacroDeriveParser, ProcMacroParser, RustcBuiltinMacroParser, ++ }; ++@@ -50,12 +46,8 @@ ++ use crate::attributes::stability::{ ++ BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser, ++ }; ++-use crate::attributes::test_attrs::IgnoreParser; ++ use crate::attributes::traits::{ ++- AllowIncoherentImplParser, CoherenceIsCoreParser, CoinductiveParser, ConstTraitParser, ++- DenyExplicitImplParser, DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, ++- ParenSugarParser, PointeeParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, ++- TypeConstParser, UnsafeSpecializationMarkerParser, +++ PointeeParser, SkipDuringMethodDispatchParser, ++ }; ++ use crate::attributes::transparency::TransparencyParser; ++ use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; ++@@ -149,14 +141,12 @@ mod late { ++ Single, ++ Single, ++ Single, ++- Single, ++ Single, ++ Single, ++ Single, ++ Single, ++ Single, ++ Single, ++- Single, ++ Single, ++ Single, ++ Single, ++@@ -165,40 +155,20 @@ mod late { ++ Single, ++ Single, ++ Single, ++- Single>, ++- Single>, ++- Single>, ++- Single>, ++- Single>, ++ Single>, ++ Single>, ++ Single>, ++- Single>, ++- Single>, ++- Single>, ++- Single>, ++- Single>, ++- Single>, ++- Single>, ++ Single>, ++ Single>, ++- Single>, ++ Single>, ++ Single>, ++ Single>, ++- Single>, ++ Single>, ++- Single>, ++- Single>, ++ Single>, ++ Single>, ++ Single>, ++- Single>, ++- Single>, ++ Single>, ++ Single>, ++- Single>, ++- Single>, ++ // tidy-alphabetical-end ++ ]; ++ ); ++--- compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++++ compiler/rustc_codegen_ssa/src/codegen_attrs.rs ++@@ -325,10 +325,6 @@ fn process_builtin_attrs( ++ UsedBy::Compiler => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_COMPILER, ++ UsedBy::Linker => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER, ++ }, ++- AttributeKind::FfiConst(_) => { ++- codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST ++- } ++- AttributeKind::FfiPure(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE, ++ AttributeKind::StdInternalSymbol(_) => { ++ codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL ++ } ++@@ -342,6 +338,8 @@ fn process_builtin_attrs( ++ ++ match name { ++ sym::rustc_allocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR, +++ sym::ffi_pure => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE, +++ sym::ffi_const => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST, ++ sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND, ++ sym::rustc_reallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR, ++ sym::rustc_deallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR, + --- compiler/rustc_errors/src/lib.rs + +++ compiler/rustc_errors/src/lib.rs +-@@ -102,5 +102,6 @@ ++@@ -102,6 +102,7 @@ + // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger. + #[cfg(target_pointer_width = "64")] + rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24); + +#[cfg(not(rust_compiler="mrustc"))] + #[cfg(target_pointer_width = "64")] + rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24); +---- compiler/rustc_parse/src/parser/mod.rs +-+++ compiler/rustc_parse/src/parser/mod.rs +-@@ -229,3 +229,4 @@ +- // though, because `TokenTypeSet(u128)` alignment varies on others, changing the total size. ++ ++--- compiler/rustc_feature/src/builtin_attrs.rs +++++ compiler/rustc_feature/src/builtin_attrs.rs ++@@ -724,7 +724,7 @@ pub struct BuiltinAttribute { ++ ), ++ rustc_attr!( ++ rustc_pub_transparent, Normal, template!(Word), ++- ErrorFollowing, EncodeCrossCrate::Yes, +++ WarnFollowing, EncodeCrossCrate::Yes, ++ "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation", ++ ), ++ ++--- compiler/rustc_hir/src/attrs/data_structures.rs +++++ compiler/rustc_hir/src/attrs/data_structures.rs ++@@ -246,18 +246,9 @@ pub enum AttributeKind { ++ /// Represents `#[rustc_allow_const_fn_unstable]`. ++ AllowConstFnUnstable(ThinVec, Span), ++ ++- /// Represents `#[rustc_allow_incoherent_impl]`. ++- AllowIncoherentImpl(Span), ++- ++ /// Represents `#[allow_internal_unstable]`. ++ AllowInternalUnstable(ThinVec<(Symbol, Span)>, Span), ++ ++- /// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint). ++- AsPtr(Span), ++- ++- /// Represents `#[automatically_derived]` ++- AutomaticallyDerived(Span), ++- ++ /// Represents `#[rustc_default_body_unstable]`. ++ BodyStability { ++ stability: DefaultBodyStability, ++@@ -265,12 +256,6 @@ pub enum AttributeKind { ++ span: Span, ++ }, ++ ++- /// Represents `#[rustc_coherence_is_core]`. ++- CoherenceIsCore, ++- ++- /// Represents `#[rustc_coinductive]`. ++- Coinductive(Span), ++- ++ /// Represents `#[cold]`. ++ Cold(Span), ++ ++@@ -294,21 +279,12 @@ pub enum AttributeKind { ++ /// Represents `#[rustc_const_stable_indirect]`. ++ ConstStabilityIndirect, ++ ++- /// Represents `#[const_trait]`. ++- ConstTrait(Span), ++- ++ /// Represents `#[coverage(..)]`. ++ Coverage(Span, CoverageAttrKind), ++ ++- ///Represents `#[rustc_deny_explicit_impl]`. ++- DenyExplicitImpl(Span), ++- ++ /// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute). ++ Deprecation { deprecation: Deprecation, span: Span }, ++ ++- /// Represents `#[rustc_do_not_implement_via_object]`. ++- DoNotImplementViaObject(Span), ++- ++ /// Represents [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html). ++ DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol }, ++ ++@@ -323,25 +299,6 @@ pub enum AttributeKind { ++ span: Span, ++ }, ++ ++- /// Represents `#[export_stable]`. ++- ExportStable, ++- ++- /// Represents `#[ffi_const]`. ++- FfiConst(Span), ++- ++- /// Represents `#[ffi_pure]`. ++- FfiPure(Span), ++- ++- /// Represents `#[fundamental]`. ++- Fundamental, ++- ++- /// Represents `#[ignore]` ++- Ignore { ++- span: Span, ++- /// ignore can optionally have a reason: `#[ignore = "reason this is ignored"]` ++- reason: Option, ++- }, ++- ++ /// Represents `#[inline]` and `#[rustc_force_inline]`. ++ Inline(InlineAttr, Span), ++ ++@@ -366,9 +323,6 @@ pub enum AttributeKind { ++ /// Represents `#[macro_use]`. ++ MacroUse { span: Span, arguments: MacroUseArgs }, ++ ++- /// Represents `#[marker]`. ++- Marker(Span), ++- ++ /// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html). ++ MayDangle(Span), ++ ++@@ -388,24 +342,12 @@ pub enum AttributeKind { ++ /// Represents `#[no_mangle]` ++ NoMangle(Span), ++ ++- /// Represents `#[non_exhaustive]` ++- NonExhaustive(Span), ++- ++ /// Represents `#[omit_gdb_pretty_printer_section]` ++ OmitGdbPrettyPrinterSection, ++ ++ /// Represents `#[optimize(size|speed)]` ++ Optimize(OptimizeAttr, Span), ++ ++- /// Represents `#[rustc_paren_sugar]`. ++- ParenSugar(Span), ++- ++- /// Represents `#[rustc_pass_by_value]` (used by the `rustc_pass_by_value` lint). ++- PassByValue(Span), ++- ++- /// Represents `#[path]` ++- Path(Symbol, Span), ++- ++ /// Represents `#[pointee]` ++ Pointee(Span), ++ ++@@ -418,9 +360,6 @@ pub enum AttributeKind { ++ /// Represents `#[proc_macro_derive]` ++ ProcMacroDerive { trait_name: Symbol, helper_attrs: ThinVec, span: Span }, ++ ++- /// Represents `#[rustc_pub_transparent]` (used by the `repr_transparent_external_private_fields` lint). ++- PubTransparent(Span), ++- ++ /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). ++ Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span }, ++ ++@@ -439,9 +378,6 @@ pub enum AttributeKind { ++ /// Represents `#[rustc_skip_during_method_dispatch]`. ++ SkipDuringMethodDispatch { array: bool, boxed_slice: bool, span: Span }, ++ ++- /// Represents `#[rustc_specialization_trait]`. ++- SpecializationTrait(Span), ++- ++ /// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`. ++ Stability { ++ stability: Stability, ++@@ -458,12 +394,6 @@ pub enum AttributeKind { ++ /// Represents `#[track_caller]` ++ TrackCaller(Span), ++ ++- /// Represents `#[type_const]`. ++- TypeConst(Span), ++- ++- /// Represents `#[rustc_unsafe_specialization_marker]`. ++- UnsafeSpecializationMarker(Span), ++- ++ /// Represents `#[unstable_feature_bound]`. ++ UnstableFeatureBound(ThinVec<(Symbol, Span)>), ++ ++--- compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++++ compiler/rustc_hir/src/attrs/encode_cross_crate.rs ++@@ -15,31 +15,18 @@ pub fn encode_cross_crate(&self) -> EncodeCrossCrate { ++ // tidy-alphabetical-start ++ Align { .. } => No, ++ AllowConstFnUnstable(..) => No, ++- AllowIncoherentImpl(..) => No, ++ AllowInternalUnstable(..) => Yes, ++- AsPtr(..) => Yes, ++- AutomaticallyDerived(..) => Yes, ++ BodyStability { .. } => No, ++- CoherenceIsCore => No, ++- Coinductive(..) => No, ++ Cold(..) => No, ++ Confusables { .. } => Yes, ++ ConstContinue(..) => No, ++ ConstStability { .. } => Yes, ++ ConstStabilityIndirect => No, ++- ConstTrait(..) => No, ++ Coverage(..) => No, ++- DenyExplicitImpl(..) => No, ++ Deprecation { .. } => Yes, ++- DoNotImplementViaObject(..) => No, ++ DocComment { .. } => Yes, ++ Dummy => No, ++ ExportName { .. } => Yes, ++- ExportStable => No, ++- FfiConst(..) => No, ++- FfiPure(..) => No, ++- Fundamental { .. } => Yes, ++- Ignore { .. } => No, ++ Inline(..) => No, ++ LinkName { .. } => Yes, // Needed for rustdoc ++ LinkOrdinal { .. } => No, ++@@ -48,36 +35,27 @@ pub fn encode_cross_crate(&self) -> EncodeCrossCrate { ++ MacroEscape(..) => No, ++ MacroTransparency(..) => Yes, ++ MacroUse { .. } => No, ++- Marker(..) => No, ++ MayDangle(..) => No, ++ MustUse { .. } => Yes, ++ Naked(..) => No, ++ NoImplicitPrelude(..) => No, ++ NoMangle(..) => Yes, // Needed for rustdoc ++- NonExhaustive(..) => Yes, // Needed for rustdoc ++ OmitGdbPrettyPrinterSection => No, ++ Optimize(..) => No, ++- ParenSugar(..) => No, ++- PassByValue(..) => Yes, ++- Path(..) => No, ++ Pointee(..) => No, ++ ProcMacro(..) => No, ++ ProcMacroAttribute(..) => No, ++ ProcMacroDerive { .. } => No, ++- PubTransparent(..) => Yes, ++ Repr { .. } => No, ++ RustcBuiltinMacro { .. } => Yes, ++ RustcLayoutScalarValidRangeEnd(..) => Yes, ++ RustcLayoutScalarValidRangeStart(..) => Yes, ++ RustcObjectLifetimeDefault => No, ++ SkipDuringMethodDispatch { .. } => No, ++- SpecializationTrait(..) => No, ++ Stability { .. } => Yes, ++ StdInternalSymbol(..) => No, ++ TargetFeature(..) => No, ++ TrackCaller(..) => Yes, ++- TypeConst(..) => Yes, ++- UnsafeSpecializationMarker(..) => No, ++ UnstableFeatureBound(..) => No, ++ Used { .. } => No, ++ // tidy-alphabetical-end ++--- compiler/rustc_hir/src/hir.rs +++++ compiler/rustc_hir/src/hir.rs ++@@ -1309,8 +1309,6 @@ fn span(&self) -> Span { ++ Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span, ++ Attribute::Parsed(AttributeKind::MacroUse { span, .. }) => *span, ++ Attribute::Parsed(AttributeKind::MayDangle(span)) => *span, ++- Attribute::Parsed(AttributeKind::Ignore { span, .. }) => *span, ++- Attribute::Parsed(AttributeKind::AutomaticallyDerived(span)) => *span, ++ a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"), ++ } ++ } ++@@ -1341,11 +1339,6 @@ fn doc_str(&self) -> Option { ++ _ => None, ++ } ++ } ++- ++- fn is_automatically_derived_attr(&self) -> bool { ++- matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived(..))) ++- } ++- ++ #[inline] ++ fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { ++ match &self { ++@@ -4936,6 +4929,7 @@ pub fn fn_kind(self) -> Option> { ++ } ++ ++ // Some nodes are used a lot. Make sure they don't unintentionally get bigger. + +#[cfg(not(rust_compiler="mrustc"))] +- #[cfg(all(target_pointer_width = "64", any(target_arch = "aarch64", target_arch = "x86_64")))] +- rustc_data_structures::static_assert_size!(Parser<'_>, 288); +- +-# Workaround for some strange cases of method lookups +---- compiler/rustc_middle/src/ty/sty.rs +-+++ compiler/rustc_middle/src/ty/sty.rs +-@@ -2026,4 +2026,4 @@ +- impl<'tcx> rustc_type_ir::inherent::Tys> for &'tcx ty::List> { +- fn inputs(self) -> &'tcx [Ty<'tcx>] { +-- self.split_last().unwrap().1 +-+ (**self).split_last().unwrap().1 ++ #[cfg(target_pointer_width = "64")] ++ mod size_asserts { ++ use rustc_data_structures::static_assert_size; ++--- compiler/rustc_hir_analysis/src/check/check.rs +++++ compiler/rustc_hir_analysis/src/check/check.rs ++@@ -1535,11 +1535,7 @@ fn check_non_exhaustive<'tcx>( ++ ty::Tuple(list) => list.iter().try_for_each(|t| check_non_exhaustive(tcx, t)), ++ ty::Array(ty, _) => check_non_exhaustive(tcx, *ty), ++ ty::Adt(def, args) => { ++- if !def.did().is_local() ++- && !find_attr!( ++- tcx.get_all_attrs(def.did()), ++- AttributeKind::PubTransparent(_) ++- ) +++ if !def.did().is_local() && !tcx.has_attr(def.did(), sym::rustc_pub_transparent) ++ { ++ let non_exhaustive = def.is_variant_list_non_exhaustive() ++ || def ++--- compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++++ compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs ++@@ -8,10 +8,8 @@ ++ //! is computed by selecting an idea from this table. ++ ++ use rustc_hir as hir; ++-use rustc_hir::attrs::AttributeKind; ++ use rustc_hir::def::DefKind; ++ use rustc_hir::def_id::{DefId, LocalDefId}; ++-use rustc_hir::find_attr; ++ use rustc_middle::bug; ++ use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams, simplify_type}; ++ use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt}; ++@@ -87,10 +85,7 @@ fn check_def_id( ++ } ++ ++ for &impl_item in items { ++- if !find_attr!( ++- self.tcx.get_all_attrs(impl_item), ++- AttributeKind::AllowIncoherentImpl(_) ++- ) { +++ if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { ++ let impl_span = self.tcx.def_span(impl_def_id); ++ return Err(self.tcx.dcx().emit_err(errors::InherentTyOutsideRelevant { ++ span: impl_span, ++@@ -121,10 +116,7 @@ fn check_primitive_impl( ++ if !self.tcx.hir_rustc_coherence_is_core() { ++ if self.tcx.features().rustc_attrs() { ++ for &impl_item in items { ++- if !find_attr!( ++- self.tcx.get_all_attrs(impl_item), ++- AttributeKind::AllowIncoherentImpl(_) ++- ) { +++ if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { ++ let span = self.tcx.def_span(impl_def_id); ++ return Err(self.tcx.dcx().emit_err(errors::InherentTyOutsidePrimitive { ++ span, ++--- compiler/rustc_hir_analysis/src/collect.rs +++++ compiler/rustc_hir_analysis/src/collect.rs ++@@ -772,11 +772,9 @@ fn lower_variant<'tcx>( ++ fields, ++ parent_did.to_def_id(), ++ recovered, ++- adt_kind == AdtKind::Struct ++- && find_attr!(tcx.get_all_attrs(parent_did), AttributeKind::NonExhaustive(..)) ++- || variant_did.is_some_and(|variant_did| { ++- find_attr!(tcx.get_all_attrs(variant_did), AttributeKind::NonExhaustive(..)) ++- }), +++ adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive) +++ || variant_did +++ .is_some_and(|variant_did| tcx.has_attr(variant_did, sym::non_exhaustive)), ++ ) ++ } ++ ++@@ -851,44 +849,42 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { ++ _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"), ++ }; ++ ++- let attrs = tcx.get_all_attrs(def_id); ++ // Only regular traits can be const. ++ // FIXME(const_trait_impl): remove this ++ let constness = if constness == hir::Constness::Const ++- || !is_alias && find_attr!(attrs, AttributeKind::ConstTrait(_)) +++ || !is_alias && tcx.has_attr(def_id, sym::const_trait) ++ { ++ hir::Constness::Const ++ } else { ++ hir::Constness::NotConst ++ }; ++ ++- let paren_sugar = find_attr!(attrs, AttributeKind::ParenSugar(_)); +++ let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar); ++ if paren_sugar && !tcx.features().unboxed_closures() { ++ tcx.dcx().emit_err(errors::ParenSugarAttribute { span: item.span }); ++ } ++ ++ // Only regular traits can be marker. ++- let is_marker = !is_alias && find_attr!(attrs, AttributeKind::Marker(_)); +++ let is_marker = !is_alias && tcx.has_attr(def_id, sym::marker); ++ ++- let rustc_coinductive = find_attr!(attrs, AttributeKind::Coinductive(_)); ++- let is_fundamental = find_attr!(attrs, AttributeKind::Fundamental); +++ let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive); +++ let is_fundamental = tcx.has_attr(def_id, sym::fundamental); ++ ++ let [skip_array_during_method_dispatch, skip_boxed_slice_during_method_dispatch] = find_attr!( ++- attrs, ++- AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: _ } => [*array, *boxed_slice] +++ tcx.get_all_attrs(def_id), +++ AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span:_ } => [*array, *boxed_slice] ++ ) ++ .unwrap_or([false; 2]); ++ ++- let specialization_kind = if find_attr!(attrs, AttributeKind::UnsafeSpecializationMarker(_)) { +++ let specialization_kind = if tcx.has_attr(def_id, sym::rustc_unsafe_specialization_marker) { ++ ty::trait_def::TraitSpecializationKind::Marker ++- } else if find_attr!(attrs, AttributeKind::SpecializationTrait(_)) { +++ } else if tcx.has_attr(def_id, sym::rustc_specialization_trait) { ++ ty::trait_def::TraitSpecializationKind::AlwaysApplicable ++ } else { ++ ty::trait_def::TraitSpecializationKind::None ++ }; ++- let must_implement_one_of = attrs ++- .iter() ++- .find(|attr| attr.has_name(sym::rustc_must_implement_one_of)) +++ let must_implement_one_of = tcx +++ .get_attr(def_id, sym::rustc_must_implement_one_of) ++ // Check that there are at least 2 arguments of `#[rustc_must_implement_one_of]` ++ // and that they are all identifiers ++ .and_then(|attr| match attr.meta_item_list() { ++@@ -965,8 +961,8 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { ++ no_dups.then_some(list) ++ }); ++ ++- let deny_explicit_impl = find_attr!(attrs, AttributeKind::DenyExplicitImpl(_)); ++- let implement_via_object = !find_attr!(attrs, AttributeKind::DoNotImplementViaObject(_)); +++ let deny_explicit_impl = tcx.has_attr(def_id, sym::rustc_deny_explicit_impl); +++ let implement_via_object = !tcx.has_attr(def_id, sym::rustc_do_not_implement_via_object); ++ ++ ty::TraitDef { ++ def_id: def_id.to_def_id(), ++--- compiler/rustc_lint/src/dangling.rs +++++ compiler/rustc_lint/src/dangling.rs ++@@ -1,8 +1,7 @@ ++ use rustc_ast::visit::{visit_opt, walk_list}; ++-use rustc_hir::attrs::AttributeKind; ++ use rustc_hir::def_id::LocalDefId; ++ use rustc_hir::intravisit::{FnKind, Visitor, walk_expr}; ++-use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, LangItem, find_attr}; +++use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, LangItem}; ++ use rustc_middle::ty::{Ty, TyCtxt}; ++ use rustc_session::{declare_lint, impl_lint_pass}; ++ use rustc_span::{Span, sym}; ++@@ -134,7 +133,7 @@ fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) { ++ && let ty = cx.typeck_results().expr_ty(receiver) ++ && owns_allocation(cx.tcx, ty) ++ && let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) ++- && find_attr!(cx.tcx.get_all_attrs(fn_id), AttributeKind::AsPtr(_)) +++ && cx.tcx.has_attr(fn_id, sym::rustc_as_ptr) ++ { ++ // FIXME: use `emit_node_lint` when `#[primary_span]` is added. ++ cx.tcx.emit_node_span_lint( ++--- compiler/rustc_lint/src/default_could_be_derived.rs +++++ compiler/rustc_lint/src/default_could_be_derived.rs ++@@ -1,8 +1,6 @@ ++ use rustc_data_structures::fx::FxHashMap; ++ use rustc_errors::{Applicability, Diag}; ++ use rustc_hir as hir; ++-use rustc_hir::attrs::AttributeKind; ++-use rustc_hir::find_attr; ++ use rustc_middle::ty; ++ use rustc_middle::ty::TyCtxt; ++ use rustc_session::{declare_lint, impl_lint_pass}; ++@@ -64,7 +62,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_ ++ let hir::ImplItemKind::Fn(_sig, body_id) = impl_item.kind else { return }; ++ let assoc = cx.tcx.associated_item(impl_item.owner_id); ++ let parent = assoc.container_id(cx.tcx); ++- if find_attr!(cx.tcx.get_all_attrs(parent), AttributeKind::AutomaticallyDerived(..)) { +++ if cx.tcx.has_attr(parent, sym::automatically_derived) { ++ // We don't care about what `#[derive(Default)]` produces in this lint. ++ return; ++ } ++--- compiler/rustc_lint/src/levels.rs +++++ compiler/rustc_lint/src/levels.rs ++@@ -644,7 +644,7 @@ fn add( ++ ) { ++ let sess = self.sess; ++ for (attr_index, attr) in attrs.iter().enumerate() { ++- if attr.is_automatically_derived_attr() { +++ if attr.has_name(sym::automatically_derived) { ++ self.insert( ++ LintId::of(SINGLE_USE_LIFETIMES), ++ LevelAndSource { ++--- compiler/rustc_lint/src/pass_by_value.rs +++++ compiler/rustc_lint/src/pass_by_value.rs ++@@ -1,8 +1,8 @@ ++-use rustc_hir::attrs::AttributeKind; ++ use rustc_hir::def::Res; ++-use rustc_hir::{self as hir, AmbigArg, GenericArg, PathSegment, QPath, TyKind, find_attr}; +++use rustc_hir::{self as hir, AmbigArg, GenericArg, PathSegment, QPath, TyKind}; ++ use rustc_middle::ty; ++ use rustc_session::{declare_lint_pass, declare_tool_lint}; +++use rustc_span::sym; ++ ++ use crate::lints::PassByValueDiag; ++ use crate::{LateContext, LateLintPass, LintContext}; ++@@ -45,16 +45,14 @@ fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx, AmbigArg>) ++ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option { ++ if let TyKind::Path(QPath::Resolved(_, path)) = &ty.kind { ++ match path.res { ++- Res::Def(_, def_id) ++- if find_attr!(cx.tcx.get_all_attrs(def_id), AttributeKind::PassByValue(_)) => ++- { +++ Res::Def(_, def_id) if cx.tcx.has_attr(def_id, sym::rustc_pass_by_value) => { ++ let name = cx.tcx.item_ident(def_id); ++ let path_segment = path.segments.last().unwrap(); ++ return Some(format!("{}{}", name, gen_args(cx, path_segment))); ++ } ++ Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => { ++ if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() { ++- if find_attr!(cx.tcx.get_all_attrs(adt.did()), AttributeKind::PassByValue(_)) { +++ if cx.tcx.has_attr(adt.did(), sym::rustc_pass_by_value) { ++ return Some(cx.tcx.def_path_str_with_args(adt.did(), args)); ++ } ++ } ++--- compiler/rustc_middle/src/hir/map.rs +++++ compiler/rustc_middle/src/hir/map.rs ++@@ -8,7 +8,6 @@ ++ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; ++ use rustc_data_structures::svh::Svh; ++ use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, try_par_for_each_in}; ++-use rustc_hir::attrs::AttributeKind; ++ use rustc_hir::def::{DefKind, Res}; ++ use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId}; ++ use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; ++@@ -16,7 +15,7 @@ ++ use rustc_hir::*; ++ use rustc_hir_pretty as pprust_hir; ++ use rustc_span::def_id::StableCrateId; ++-use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, with_metavar_spans}; +++use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym, with_metavar_spans}; ++ ++ use crate::hir::{ModuleItems, nested_filter}; ++ use crate::middle::debugger_visualizer::DebuggerVisualizerFile; ++@@ -370,7 +369,7 @@ pub fn hir_krate_attrs(self) -> &'tcx [Attribute] { ++ } ++ ++ pub fn hir_rustc_coherence_is_core(self) -> bool { ++- find_attr!(self.hir_krate_attrs(), AttributeKind::CoherenceIsCore) +++ self.hir_krate_attrs().iter().any(|attr| attr.has_name(sym::rustc_coherence_is_core)) + } ++ ++ pub fn hir_get_module(self, module: LocalModDefId) -> (&'tcx Mod<'tcx>, Span, HirId) { ++--- compiler/rustc_middle/src/ty/adt.rs +++++ compiler/rustc_middle/src/ty/adt.rs ++@@ -9,14 +9,14 @@ ++ use rustc_data_structures::intern::Interned; ++ use rustc_data_structures::stable_hasher::{HashStable, HashingControls, StableHasher}; ++ use rustc_errors::ErrorGuaranteed; ++-use rustc_hir::attrs::AttributeKind; ++ use rustc_hir::def::{CtorKind, DefKind, Res}; ++ use rustc_hir::def_id::DefId; ++-use rustc_hir::{self as hir, LangItem, find_attr}; +++use rustc_hir::{self as hir, LangItem}; ++ use rustc_index::{IndexSlice, IndexVec}; ++ use rustc_macros::{HashStable, TyDecodable, TyEncodable}; ++ use rustc_query_system::ich::StableHashingContext; ++ use rustc_session::DataTypeKind; +++use rustc_span::sym; ++ use rustc_type_ir::solve::AdtDestructorKind; ++ use tracing::{debug, info, trace}; ++ ++@@ -278,9 +278,7 @@ pub(super) fn new( ++ debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr); ++ let mut flags = AdtFlags::NO_ADT_FLAGS; ++ ++- if kind == AdtKind::Enum ++- && find_attr!(tcx.get_all_attrs(did), AttributeKind::NonExhaustive(..)) ++- { +++ if kind == AdtKind::Enum && tcx.has_attr(did, sym::non_exhaustive) { ++ debug!("found non-exhaustive variant list for {:?}", did); ++ flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE; ++ } ++@@ -295,7 +293,7 @@ pub(super) fn new( ++ flags |= AdtFlags::HAS_CTOR; ++ } ++ ++- if find_attr!(tcx.get_all_attrs(did), AttributeKind::Fundamental) { +++ if tcx.has_attr(did, sym::fundamental) { ++ flags |= AdtFlags::IS_FUNDAMENTAL; ++ } ++ if tcx.is_lang_item(did, LangItem::PhantomData) { ++--- compiler/rustc_middle/src/ty/assoc.rs +++++ compiler/rustc_middle/src/ty/assoc.rs ++@@ -1,11 +1,9 @@ ++ use rustc_data_structures::sorted_map::SortedIndexMultiMap; ++ use rustc_hir as hir; ++-use rustc_hir::attrs::AttributeKind; ++ use rustc_hir::def::{DefKind, Namespace}; ++ use rustc_hir::def_id::DefId; ++-use rustc_hir::find_attr; ++ use rustc_macros::{Decodable, Encodable, HashStable}; ++-use rustc_span::{Ident, Symbol}; +++use rustc_span::{Ident, Symbol, sym}; ++ ++ use super::{TyCtxt, Visibility}; ++ use crate::ty; ++@@ -162,7 +160,7 @@ pub fn is_type_const_capable(&self, tcx: TyCtxt<'_>) -> bool { ++ // Inherent impl but this attr is only applied to trait assoc items. ++ (AssocItemContainer::Impl, None) => return true, ++ }; ++- find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) +++ tcx.has_attr(def_id, sym::type_const) ++ } ++ } ++ + --- compiler/rustc_middle/src/ty/generic_args.rs + +++ compiler/rustc_middle/src/ty/generic_args.rs +-@@ -703,7 +703,7 @@ ++@@ -703,7 +703,7 @@ fn fold_with>>(self, folder: &mut F) -> Self { + impl<'tcx, T: TypeVisitable>> TypeVisitable> for &'tcx ty::List { + #[inline] + fn visit_with>>(&self, visitor: &mut V) -> V::Result { +@@ -44,3 +1197,735 @@ + V::Result::output() + } + } ++--- compiler/rustc_middle/src/ty/mod.rs +++++ compiler/rustc_middle/src/ty/mod.rs ++@@ -1710,19 +1710,21 @@ pub fn get_attrs( ++ did: impl Into, ++ attr: Symbol, ++ ) -> impl Iterator { ++- self.get_all_attrs(did).iter().filter(move |a: &&hir::Attribute| a.has_name(attr)) +++ self.get_all_attrs(did).filter(move |a: &&hir::Attribute| a.has_name(attr)) ++ } ++ ++ /// Gets all attributes. ++ /// ++- /// To see if an item has a specific attribute, you should use ++- /// [`rustc_hir::find_attr!`] so you can use matching. ++- pub fn get_all_attrs(self, did: impl Into) -> &'tcx [hir::Attribute] { +++ /// To see if an item has a specific attribute, you should use [`rustc_attr_data_structures::find_attr!`] so you can use matching. +++ pub fn get_all_attrs( +++ self, +++ did: impl Into, +++ ) -> impl Iterator { ++ let did: DefId = did.into(); ++ if let Some(did) = did.as_local() { ++- self.hir_attrs(self.local_def_id_to_hir_id(did)) +++ self.hir_attrs(self.local_def_id_to_hir_id(did)).iter() ++ } else { ++- self.attrs_for_def(did) +++ self.attrs_for_def(did).iter() ++ } ++ } ++ ++@@ -1955,7 +1957,7 @@ pub fn is_builtin_derived(self, def_id: DefId) -> bool { ++ ++ /// Check if the given `DefId` is `#\[automatically_derived\]`. ++ pub fn is_automatically_derived(self, def_id: DefId) -> bool { ++- find_attr!(self.get_all_attrs(def_id), AttributeKind::AutomaticallyDerived(..)) +++ self.has_attr(def_id, sym::automatically_derived) ++ } ++ ++ /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err` ++--- compiler/rustc_middle/src/ty/sty.rs +++++ compiler/rustc_middle/src/ty/sty.rs ++@@ -2025,7 +2025,7 @@ pub fn walk(self) -> TypeWalker> { ++ ++ impl<'tcx> rustc_type_ir::inherent::Tys> for &'tcx ty::List> { ++ fn inputs(self) -> &'tcx [Ty<'tcx>] { ++- self.split_last().unwrap().1 +++ (**self).split_last().unwrap().1 ++ } ++ ++ fn output(self) -> Ty<'tcx> { ++--- compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++++ compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs ++@@ -5,8 +5,6 @@ ++ use rustc_data_structures::fx::FxHashSet; ++ use rustc_errors::Diag; ++ use rustc_hir as hir; ++-use rustc_hir::attrs::AttributeKind; ++-use rustc_hir::find_attr; ++ use rustc_index::Idx; ++ use rustc_infer::infer::TyCtxtInferExt; ++ use rustc_infer::traits::Obligation; ++@@ -17,7 +15,7 @@ ++ }; ++ use rustc_middle::{mir, span_bug}; ++ use rustc_span::def_id::DefId; ++-use rustc_span::{DUMMY_SP, Span}; +++use rustc_span::{DUMMY_SP, Span, sym}; ++ use rustc_trait_selection::traits::ObligationCause; ++ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; ++ use tracing::{debug, instrument, trace}; ++@@ -497,8 +495,7 @@ fn type_has_partial_eq_impl<'tcx>( ++ let mut structural_peq = false; ++ let mut impl_def_id = None; ++ for def_id in tcx.non_blanket_impls_for_ty(partial_eq_trait_id, ty) { ++- automatically_derived = ++- find_attr!(tcx.get_all_attrs(def_id), AttributeKind::AutomaticallyDerived(..)); +++ automatically_derived = tcx.has_attr(def_id, sym::automatically_derived); ++ impl_def_id = Some(def_id); ++ } ++ for _ in tcx.non_blanket_impls_for_ty(structural_partial_eq_trait_id, ty) { ++--- compiler/rustc_parse/Cargo.toml +++++ compiler/rustc_parse/Cargo.toml ++@@ -9,7 +9,6 @@ bitflags = "2.4.1" ++ rustc-literal-escaper = "0.0.5" ++ rustc_ast = { path = "../rustc_ast" } ++ rustc_ast_pretty = { path = "../rustc_ast_pretty" } ++-rustc_attr_parsing = { path = "../rustc_attr_parsing" } ++ rustc_data_structures = { path = "../rustc_data_structures" } ++ rustc_errors = { path = "../rustc_errors" } ++ rustc_feature = { path = "../rustc_feature" } ++--- compiler/rustc_parse/src/parser/mod.rs +++++ compiler/rustc_parse/src/parser/mod.rs ++@@ -227,6 +227,7 @@ pub struct Parser<'a> { ++ // This type is used a lot, e.g. it's cloned when matching many declarative macro rules with ++ // nonterminals. Make sure it doesn't unintentionally get bigger. We only check a few arches ++ // though, because `TokenTypeSet(u128)` alignment varies on others, changing the total size. +++#[cfg(not(rust_compiler="mrustc"))] ++ #[cfg(all(target_pointer_width = "64", any(target_arch = "aarch64", target_arch = "x86_64")))] ++ rustc_data_structures::static_assert_size!(Parser<'_>, 288); ++ ++--- compiler/rustc_parse/src/validate_attr.rs +++++ compiler/rustc_parse/src/validate_attr.rs ++@@ -1,14 +1,11 @@ ++ //! Meta-syntax validation logic of attributes for post-expansion. ++ ++-use std::slice; ++- ++ use rustc_ast::token::Delimiter; ++ use rustc_ast::tokenstream::DelimSpan; ++ use rustc_ast::{ ++ self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, NodeId, ++ Path, Safety, ++ }; ++-use rustc_attr_parsing::{AttributeParser, Late}; ++ use rustc_errors::{Applicability, DiagCtxtHandle, FatalError, PResult}; ++ use rustc_feature::{AttributeSafety, AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute}; ++ use rustc_session::errors::report_lit_error; ++@@ -269,7 +266,39 @@ pub fn check_builtin_meta_item( ++ ) { ++ if !is_attr_template_compatible(&template, &meta.kind) { ++ // attrs with new parsers are locally validated so excluded here ++- if AttributeParser::::is_parsed_attribute(slice::from_ref(&name)) { +++ if matches!( +++ name, +++ sym::inline +++ | sym::ffi_const +++ | sym::ffi_pure +++ | sym::rustc_std_internal_symbol +++ | sym::may_dangle +++ | sym::rustc_as_ptr +++ | sym::rustc_pub_transparent +++ | sym::rustc_const_stable_indirect +++ | sym::rustc_force_inline +++ | sym::rustc_confusables +++ | sym::rustc_skip_during_method_dispatch +++ | sym::repr +++ | sym::align +++ | sym::deprecated +++ | sym::optimize +++ | sym::cold +++ | sym::target_feature +++ | sym::rustc_allow_const_fn_unstable +++ | sym::naked +++ | sym::no_mangle +++ | sym::ignore +++ | sym::must_use +++ | sym::track_caller +++ | sym::link_name +++ | sym::export_name +++ | sym::rustc_macro_transparency +++ | sym::link_section +++ | sym::rustc_layout_scalar_valid_range_start +++ | sym::rustc_layout_scalar_valid_range_end +++ | sym::no_implicit_prelude +++ ) { ++ return; ++ } ++ emit_malformed_attribute(psess, style, meta.span, name, template); ++@@ -289,7 +318,8 @@ fn emit_malformed_attribute( ++ ) { ++ // Some of previously accepted forms were used in practice, ++ // report them as warnings for now. ++- let should_warn = |name| matches!(name, sym::doc | sym::link | sym::test | sym::bench); +++ let should_warn = +++ |name| matches!(name, sym::doc | sym::ignore | sym::link | sym::test | sym::bench); ++ ++ let error_msg = format!("malformed `{name}` attribute input"); ++ let mut suggestions = vec![]; ++--- compiler/rustc_passes/src/check_attr.rs +++++ compiler/rustc_passes/src/check_attr.rs ++@@ -144,46 +144,15 @@ fn check_attributes( ++ ); ++ self.check_proc_macro(hir_id, target, ProcMacroKind::Derive) ++ } ++- Attribute::Parsed( ++- AttributeKind::SkipDuringMethodDispatch { span: attr_span, .. } ++- | AttributeKind::Coinductive(attr_span) ++- | AttributeKind::ConstTrait(attr_span) ++- | AttributeKind::DenyExplicitImpl(attr_span) ++- | AttributeKind::DoNotImplementViaObject(attr_span), ++- ) => { +++ Attribute::Parsed(AttributeKind::SkipDuringMethodDispatch { +++ span: attr_span, +++ .. +++ }) => { ++ self.check_must_be_applied_to_trait(*attr_span, span, target); ++ } ++- &Attribute::Parsed( ++- AttributeKind::SpecializationTrait(attr_span) ++- | AttributeKind::UnsafeSpecializationMarker(attr_span) ++- | AttributeKind::ParenSugar(attr_span), ++- ) => { ++- // FIXME: more validation is needed ++- self.check_must_be_applied_to_trait(attr_span, span, target); ++- } ++- &Attribute::Parsed(AttributeKind::TypeConst(attr_span)) => { ++- self.check_type_const(hir_id, attr_span, target) ++- } ++- &Attribute::Parsed(AttributeKind::Marker(attr_span)) => { ++- self.check_marker(hir_id, attr_span, span, target) ++- } ++- Attribute::Parsed(AttributeKind::Fundamental | AttributeKind::CoherenceIsCore) => { ++- // FIXME: add validation ++- } ++- &Attribute::Parsed(AttributeKind::AllowIncoherentImpl(attr_span)) => { ++- self.check_allow_incoherent_impl(attr_span, span, target) ++- } ++ Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { ++ self.check_confusables(*first_span, target); ++ } ++- Attribute::Parsed(AttributeKind::AutomaticallyDerived(attr_span)) => self ++- .check_generic_attr( ++- hir_id, ++- sym::automatically_derived, ++- *attr_span, ++- target, ++- Target::Impl { of_trait: true }, ++- ), ++ Attribute::Parsed( ++ AttributeKind::Stability { ++ span: attr_span, ++@@ -226,9 +195,6 @@ fn check_attributes( ++ Attribute::Parsed(AttributeKind::RustcObjectLifetimeDefault) => { ++ self.check_object_lifetime_default(hir_id); ++ } ++- &Attribute::Parsed(AttributeKind::PubTransparent(attr_span)) => { ++- self.check_rustc_pub_transparent(attr_span, span, attrs) ++- } ++ Attribute::Parsed(AttributeKind::Cold(attr_span)) => { ++ self.check_cold(hir_id, *attr_span, span, target) ++ } ++@@ -258,28 +224,13 @@ fn check_attributes( ++ target, ++ Target::Mod, ++ ), ++- Attribute::Parsed(AttributeKind::Path(_, attr_span)) => { ++- self.check_generic_attr(hir_id, sym::path, *attr_span, target, Target::Mod) ++- } ++ Attribute::Parsed(AttributeKind::TrackCaller(attr_span)) => { ++ self.check_track_caller(hir_id, *attr_span, attrs, span, target) ++ } ++- Attribute::Parsed(AttributeKind::NonExhaustive(attr_span)) => { ++- self.check_non_exhaustive(hir_id, *attr_span, span, target, item) ++- } ++ Attribute::Parsed( ++ AttributeKind::RustcLayoutScalarValidRangeStart(_num, attr_span) ++ | AttributeKind::RustcLayoutScalarValidRangeEnd(_num, attr_span), ++ ) => self.check_rustc_layout_scalar_valid_range(*attr_span, span, target), ++- Attribute::Parsed(AttributeKind::ExportStable) => { ++- // handled in `check_export` ++- } ++- &Attribute::Parsed(AttributeKind::FfiConst(attr_span)) => { ++- self.check_ffi_const(attr_span, target) ++- } ++- &Attribute::Parsed(AttributeKind::FfiPure(attr_span)) => { ++- self.check_ffi_pure(attr_span, attrs, target) ++- } ++ Attribute::Parsed(AttributeKind::UnstableFeatureBound(syms)) => { ++ self.check_unstable_feature_bound(syms.first().unwrap().1, span, target) ++ } ++@@ -292,9 +243,6 @@ fn check_attributes( ++ | AttributeKind::RustcBuiltinMacro { .. } ++ | AttributeKind::OmitGdbPrettyPrinterSection, ++ ) => { /* do nothing */ } ++- Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => { ++- self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target) ++- } ++ Attribute::Parsed(AttributeKind::LinkName { span: attr_span, name }) => { ++ self.check_link_name(hir_id, *attr_span, *name, span, target) ++ } ++@@ -304,9 +252,6 @@ fn check_attributes( ++ Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => { ++ self.check_may_dangle(hir_id, *attr_span) ++ } ++- Attribute::Parsed(AttributeKind::Ignore { span, .. }) => { ++- self.check_generic_attr(hir_id, sym::ignore, *span, target, Target::Fn) ++- } ++ Attribute::Parsed(AttributeKind::MustUse { span, .. }) => { ++ self.check_must_use(hir_id, *span, target) ++ } ++@@ -316,9 +261,6 @@ fn check_attributes( ++ Attribute::Parsed(AttributeKind::Used { span: attr_span, .. }) => { ++ self.check_used(*attr_span, target, span); ++ } ++- &Attribute::Parsed(AttributeKind::PassByValue(attr_span)) => { ++- self.check_pass_by_value(attr_span, span, target) ++- } ++ &Attribute::Parsed(AttributeKind::StdInternalSymbol(attr_span)) => { ++ self.check_rustc_std_internal_symbol(attr_span, span, target) ++ } ++@@ -337,6 +279,8 @@ fn check_attributes( ++ [sym::no_sanitize, ..] => { ++ self.check_no_sanitize(attr, span, target) ++ } +++ [sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target, item), +++ [sym::marker, ..] => self.check_marker(hir_id, attr, span, target), ++ [sym::thread_local, ..] => self.check_thread_local(attr, span, target), ++ [sym::doc, ..] => self.check_doc_attrs( ++ attr, ++@@ -348,6 +292,9 @@ fn check_attributes( ++ ), ++ [sym::no_link, ..] => self.check_no_link(hir_id, attr, span, target), ++ [sym::debugger_visualizer, ..] => self.check_debugger_visualizer(attr, target), +++ [sym::rustc_as_ptr, ..] => { +++ self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) +++ } ++ [sym::rustc_no_implicit_autorefs, ..] => { ++ self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) ++ } ++@@ -374,9 +321,17 @@ fn check_attributes( ++ | [sym::rustc_dirty, ..] ++ | [sym::rustc_if_this_changed, ..] ++ | [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr), ++- [sym::rustc_must_implement_one_of, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target), +++ [sym::rustc_coinductive, ..] +++ | [sym::rustc_must_implement_one_of, ..] +++ | [sym::rustc_deny_explicit_impl, ..] +++ | [sym::rustc_do_not_implement_via_object, ..] +++ | [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target), ++ [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), ++ [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), +++ [sym::rustc_pass_by_value, ..] => self.check_pass_by_value(attr, span, target), +++ [sym::rustc_allow_incoherent_impl, ..] => { +++ self.check_allow_incoherent_impl(attr, span, target) +++ } ++ [sym::rustc_has_incoherent_inherent_impls, ..] => { ++ self.check_has_incoherent_inherent_impls(attr, span, target) ++ } ++@@ -385,16 +340,33 @@ fn check_attributes( ++ [sym::link, ..] => self.check_link(hir_id, attr, span, target), ++ [sym::path, ..] => self.check_generic_attr_unparsed(hir_id, attr, target, Target::Mod), ++ [sym::macro_export, ..] => self.check_macro_export(hir_id, attr, target), ++- [sym::should_panic, ..] => { +++ [sym::ignore, ..] | [sym::should_panic, ..] => { ++ self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn) ++ } +++ [sym::automatically_derived, ..] => { +++ self.check_generic_attr_unparsed(hir_id, attr, target, Target::Impl { of_trait: true }) +++ } +++ [sym::proc_macro, ..] => { +++ self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike) +++ } +++ [sym::proc_macro_attribute, ..] => { +++ self.check_proc_macro(hir_id, target, ProcMacroKind::Attribute); +++ } +++ [sym::proc_macro_derive, ..] => { +++ self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn); +++ self.check_proc_macro(hir_id, target, ProcMacroKind::Derive) +++ } ++ [sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => { ++ self.check_autodiff(hir_id, attr, span, target) ++ } ++ [sym::coroutine, ..] => { ++ self.check_coroutine(attr, target); ++ } +++ [sym::type_const, ..] => { +++ self.check_type_const(hir_id,attr, target); +++ } ++ [sym::linkage, ..] => self.check_linkage(attr, span, target), +++ [sym::rustc_pub_transparent, ..] => self.check_rustc_pub_transparent(attr.span(), span, attrs), ++ [ ++ // ok ++ sym::allow ++@@ -406,6 +378,7 @@ fn check_attributes( ++ | sym::cfg_attr ++ | sym::cfg_trace ++ | sym::cfg_attr_trace +++ | sym::export_stable // handled in `check_export` ++ // need to be fixed ++ | sym::cfi_encoding // FIXME(cfi_encoding) ++ | sym::instruction_set // broken on stable!!! ++@@ -416,6 +389,7 @@ fn check_attributes( ++ | sym::prelude_import ++ | sym::panic_handler ++ | sym::allow_internal_unsafe +++ | sym::fundamental ++ | sym::lang ++ | sym::needs_allocator ++ | sym::default_lib_allocator ++@@ -849,7 +823,7 @@ fn check_track_caller( ++ fn check_non_exhaustive( ++ &self, ++ hir_id: HirId, ++- attr_span: Span, +++ attr: &Attribute, ++ span: Span, ++ target: Target, ++ item: Option>, ++@@ -864,7 +838,7 @@ fn check_non_exhaustive( ++ && fields.iter().any(|f| f.default.is_some()) ++ { ++ self.dcx().emit_err(errors::NonExhaustiveWithDefaultFieldValues { ++- attr_span, +++ attr_span: attr.span(), ++ defn_span: span, ++ }); ++ } ++@@ -875,17 +849,19 @@ fn check_non_exhaustive( ++ // erroneously allowed it and some crates used it accidentally, to be compatible ++ // with crates depending on them, we can't throw an error here. ++ Target::Field | Target::Arm | Target::MacroDef => { ++- self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "non_exhaustive"); +++ self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "non_exhaustive"); ++ } ++ _ => { ++- self.dcx() ++- .emit_err(errors::NonExhaustiveWrongLocation { attr_span, defn_span: span }); +++ self.dcx().emit_err(errors::NonExhaustiveWrongLocation { +++ attr_span: attr.span(), +++ defn_span: span, +++ }); ++ } ++ } ++ } ++ ++ /// Checks if the `#[marker]` attribute on an `item` is valid. ++- fn check_marker(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) { +++ fn check_marker(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { ++ match target { ++ Target::Trait => {} ++ // FIXME(#80564): We permit struct fields, match arms and macro defs to have an ++@@ -893,11 +869,13 @@ fn check_marker(&self, hir_id: HirId, attr_span: Span, span: Span, target: Targe ++ // erroneously allowed it and some crates used it accidentally, to be compatible ++ // with crates depending on them, we can't throw an error here. ++ Target::Field | Target::Arm | Target::MacroDef => { ++- self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "marker"); +++ self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "marker"); ++ } ++ _ => { ++- self.dcx() ++- .emit_err(errors::AttrShouldBeAppliedToTrait { attr_span, defn_span: span }); +++ self.dcx().emit_err(errors::AttrShouldBeAppliedToTrait { +++ attr_span: attr.span(), +++ defn_span: span, +++ }); ++ } ++ } ++ } ++@@ -1535,20 +1513,20 @@ fn check_doc_attrs( ++ } ++ ++ /// Warns against some misuses of `#[pass_by_value]` ++- fn check_pass_by_value(&self, attr_span: Span, span: Span, target: Target) { +++ fn check_pass_by_value(&self, attr: &Attribute, span: Span, target: Target) { ++ match target { ++ Target::Struct | Target::Enum | Target::TyAlias => {} ++ _ => { ++- self.dcx().emit_err(errors::PassByValue { attr_span, span }); +++ self.dcx().emit_err(errors::PassByValue { attr_span: attr.span(), span }); ++ } ++ } ++ } ++ ++- fn check_allow_incoherent_impl(&self, attr_span: Span, span: Span, target: Target) { +++ fn check_allow_incoherent_impl(&self, attr: &Attribute, span: Span, target: Target) { ++ match target { ++ Target::Method(MethodKind::Inherent) => {} ++ _ => { ++- self.dcx().emit_err(errors::AllowIncoherentImpl { attr_span, span }); +++ self.dcx().emit_err(errors::AllowIncoherentImpl { attr_span: attr.span(), span }); ++ } ++ } ++ } ++@@ -1569,7 +1547,7 @@ fn check_ffi_pure(&self, attr_span: Span, attrs: &[Attribute], target: Target) { ++ self.dcx().emit_err(errors::FfiPureInvalidTarget { attr_span }); ++ return; ++ } ++- if find_attr!(attrs, AttributeKind::FfiConst(_)) { +++ if attrs.iter().any(|a| a.has_name(sym::ffi_const)) { ++ // `#[ffi_const]` functions cannot be `#[ffi_pure]` ++ self.dcx().emit_err(errors::BothFfiConstAndPure { attr_span }); ++ } ++@@ -2661,7 +2639,7 @@ fn check_coroutine(&self, attr: &Attribute, target: Target) { ++ } ++ } ++ ++- fn check_type_const(&self, hir_id: HirId, attr_span: Span, target: Target) { +++ fn check_type_const(&self, hir_id: HirId, attr: &Attribute, target: Target) { ++ let tcx = self.tcx; ++ if target == Target::AssocConst ++ && let parent = tcx.parent(hir_id.expect_owner().to_def_id()) ++@@ -2671,7 +2649,7 @@ fn check_type_const(&self, hir_id: HirId, attr_span: Span, target: Target) { ++ } else { ++ self.dcx() ++ .struct_span_err( ++- attr_span, +++ attr.span(), ++ "`#[type_const]` must only be applied to trait associated constants", ++ ) ++ .emit(); ++@@ -2952,6 +2930,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { ++ // resolution for the attribute macro error. ++ const ATTRS_TO_CHECK: &[Symbol] = &[ ++ sym::macro_export, +++ sym::path, +++ sym::automatically_derived, ++ sym::rustc_main, ++ sym::derive, ++ sym::test, ++@@ -2972,10 +2952,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { ++ }) = attr ++ { ++ (*first_attr_span, sym::repr) ++- } else if let Attribute::Parsed(AttributeKind::Path(.., span)) = attr { ++- (*span, sym::path) ++- } else if let Attribute::Parsed(AttributeKind::AutomaticallyDerived(span)) = attr { ++- (*span, sym::automatically_derived) ++ } else { ++ continue; ++ }; ++--- compiler/rustc_passes/src/check_export.rs +++++ compiler/rustc_passes/src/check_export.rs ++@@ -4,10 +4,8 @@ ++ use rustc_abi::ExternAbi; ++ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; ++ use rustc_hir as hir; ++-use rustc_hir::attrs::AttributeKind; ++ use rustc_hir::def::DefKind; ++ use rustc_hir::def_id::{DefId, LocalDefId}; ++-use rustc_hir::find_attr; ++ use rustc_hir::intravisit::{self, Visitor}; ++ use rustc_middle::hir::nested_filter; ++ use rustc_middle::middle::privacy::{EffectiveVisibility, Level}; ++@@ -16,7 +14,7 @@ ++ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Visibility, ++ }; ++ use rustc_session::config::CrateType; ++-use rustc_span::Span; +++use rustc_span::{Span, sym}; ++ ++ use crate::errors::UnexportableItem; ++ ++@@ -46,7 +44,7 @@ fn report_wrong_site(&self, def_id: LocalDefId) { ++ } ++ ++ fn item_is_exportable(&self, def_id: LocalDefId) -> bool { ++- let has_attr = find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable); +++ let has_attr = self.tcx.has_attr(def_id, sym::export_stable); ++ if !self.in_exportable_mod && !has_attr { ++ return false; ++ } ++@@ -82,7 +80,7 @@ fn add_exportable(&mut self, def_id: LocalDefId) { ++ fn walk_item_with_mod(&mut self, item: &'tcx hir::Item<'tcx>) { ++ let def_id = item.hir_id().owner.def_id; ++ let old_exportable_mod = self.in_exportable_mod; ++- if find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable) { +++ if self.tcx.get_attr(def_id, sym::export_stable).is_some() { ++ self.in_exportable_mod = true; ++ } ++ let old_seen_exportable_in_mod = std::mem::replace(&mut self.seen_exportable_in_mod, false); ++--- compiler/rustc_passes/src/liveness.rs +++++ compiler/rustc_passes/src/liveness.rs ++@@ -97,7 +97,7 @@ ++ use rustc_middle::span_bug; ++ use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt}; ++ use rustc_session::lint; ++-use rustc_span::{BytePos, Span, Symbol}; +++use rustc_span::{BytePos, Span, Symbol, sym}; ++ use tracing::{debug, instrument}; ++ ++ use self::LiveNodeKind::*; ++@@ -140,7 +140,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { ++ // Don't run unused pass for #[derive()] ++ let parent = tcx.local_parent(def_id); ++ if let DefKind::Impl { .. } = tcx.def_kind(parent) ++- && find_attr!(tcx.get_all_attrs(parent), AttributeKind::AutomaticallyDerived(..)) +++ && tcx.has_attr(parent, sym::automatically_derived) ++ { ++ return; ++ } ++--- compiler/rustc_resolve/src/diagnostics.rs +++++ compiler/rustc_resolve/src/diagnostics.rs ++@@ -12,11 +12,11 @@ ++ report_ambiguity_error, struct_span_code_err, ++ }; ++ use rustc_feature::BUILTIN_ATTRIBUTES; ++-use rustc_hir::attrs::{AttributeKind, CfgEntry, StrippedCfgItem}; +++use rustc_hir::attrs::{CfgEntry, StrippedCfgItem}; ++ use rustc_hir::def::Namespace::{self, *}; ++ use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PerNS}; ++ use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; ++-use rustc_hir::{PrimTy, Stability, StabilityLevel, find_attr}; +++use rustc_hir::{PrimTy, Stability, StabilityLevel}; ++ use rustc_middle::bug; ++ use rustc_middle::ty::TyCtxt; ++ use rustc_session::Session; ++@@ -1998,9 +1998,9 @@ fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) { ++ // Otherwise, point out if the struct has any private fields. ++ if let Some(def_id) = res.opt_def_id() ++ && !def_id.is_local() ++- && let Some(attr_span) = find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::NonExhaustive(span) => *span) +++ && let Some(attr) = self.tcx.get_attr(def_id, sym::non_exhaustive) ++ { ++- non_exhaustive = Some(attr_span); +++ non_exhaustive = Some(attr.span()); ++ } else if let Some(span) = ctor_fields_span { ++ let label = errors::ConstructorPrivateIfAnyFieldPrivate { span }; ++ err.subdiagnostic(label); ++--- src/librustdoc/clean/types.rs +++++ src/librustdoc/clean/types.rs ++@@ -616,7 +616,7 @@ pub(crate) fn stable_since(&self, tcx: TyCtxt<'_>) -> Option { ++ } ++ ++ pub(crate) fn is_non_exhaustive(&self) -> bool { ++- find_attr!(&self.attrs.other_attrs, AttributeKind::NonExhaustive(..)) +++ self.attrs.other_attrs.iter().any(|a| a.has_name(sym::non_exhaustive)) ++ } ++ ++ /// Returns a documentation-level item type from the item. ++--- src/tools/clippy/clippy_lints/src/exhaustive_items.rs +++++ src/tools/clippy/clippy_lints/src/exhaustive_items.rs ++@@ -6,6 +6,7 @@ ++ use rustc_hir::{Item, ItemKind}; ++ use rustc_lint::{LateContext, LateLintPass}; ++ use rustc_session::declare_lint_pass; +++use rustc_span::sym; ++ ++ declare_clippy_lint! { ++ /// ### What it does ++@@ -86,7 +87,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { ++ }; ++ if cx.effective_visibilities.is_exported(item.owner_id.def_id) ++ && let attrs = cx.tcx.hir_attrs(item.hir_id()) ++- && !find_attr!(attrs, AttributeKind::NonExhaustive(..)) +++ && !attrs.iter().any(|a| a.has_name(sym::non_exhaustive)) ++ && fields.iter().all(|f| cx.tcx.visibility(f.def_id).is_public()) ++ { ++ span_lint_and_then(cx, lint, item.span, msg, |diag| { ++--- src/tools/clippy/clippy_lints/src/format_args.rs +++++ src/tools/clippy/clippy_lints/src/format_args.rs ++@@ -659,10 +659,7 @@ fn has_pointer_debug(&mut self, ty: Ty<'tcx>, depth: usize) -> bool { ++ }; ++ let selection = SelectionContext::new(&infcx).select(&obligation); ++ let derived = if let Ok(Some(Selection::UserDefined(data))) = selection { ++- find_attr!( ++- tcx.get_all_attrs(data.impl_def_id), ++- AttributeKind::AutomaticallyDerived(..) ++- ) +++ tcx.has_attr(data.impl_def_id, sym::automatically_derived) ++ } else { ++ false ++ }; ++--- src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++++ src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs ++@@ -6,14 +6,15 @@ ++ use itertools::Itertools; ++ use rustc_hir::attrs::{AttributeKind}; ++ use rustc_hir::find_attr; +++use rustc_ast::attr; ++ use rustc_data_structures::fx::FxHashSet; ++ use rustc_errors::Applicability; ++ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; ++ use rustc_hir::{Expr, ExprKind, Item, ItemKind, QPath, TyKind, VariantData}; ++ use rustc_lint::{LateContext, LateLintPass}; ++ use rustc_session::impl_lint_pass; ++-use rustc_span::Span; ++ use rustc_span::def_id::LocalDefId; +++use rustc_span::{Span, sym}; ++ ++ declare_clippy_lint! { ++ /// ### What it does ++@@ -94,7 +95,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { ++ .then_some((v.def_id, v.span)) ++ }); ++ if let Ok((id, span)) = iter.exactly_one() ++- && !find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::NonExhaustive(..)) +++ && !attr::contains_name(cx.tcx.hir_attrs(item.hir_id()), sym::non_exhaustive) ++ { ++ self.potential_enums.push((item.owner_id.def_id, id, item.span, span)); ++ } ++@@ -114,10 +115,10 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { ++ item.span, ++ "this seems like a manual implementation of the non-exhaustive pattern", ++ |diag| { ++- if let Some(non_exhaustive_span) = ++- find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::NonExhaustive(span) => *span) +++ if let Some(non_exhaustive) = +++ attr::find_by_name(cx.tcx.hir_attrs(item.hir_id()), sym::non_exhaustive) ++ { ++- diag.span_note(non_exhaustive_span, "the struct is already non-exhaustive"); +++ diag.span_note(non_exhaustive.span(), "the struct is already non-exhaustive"); ++ } else { ++ let indent = snippet_indent(cx, item.span).unwrap_or_default(); ++ diag.span_suggestion_verbose( ++--- src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs +++++ src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs ++@@ -89,10 +89,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { ++ } ++ ++ // Is it derived? ++- if !find_attr!( ++- cx.tcx.get_all_attrs(item.owner_id), ++- AttributeKind::AutomaticallyDerived(..) ++- ) { +++ if !cx.tcx.has_attr(item.owner_id, sym::automatically_derived) { ++ return; ++ } ++ ++--- src/tools/clippy/clippy_utils/src/attrs.rs +++++ src/tools/clippy/clippy_utils/src/attrs.rs ++@@ -166,14 +166,14 @@ pub fn is_doc_hidden(attrs: &[impl AttributeExt]) -> bool { ++ ++ pub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool { ++ adt.is_variant_list_non_exhaustive() ++- || find_attr!(tcx.get_all_attrs(adt.did()), AttributeKind::NonExhaustive(..)) +++ || tcx.has_attr(adt.did(), sym::non_exhaustive) ++ || adt.variants().iter().any(|variant_def| { ++ variant_def.is_field_list_non_exhaustive() ++- || find_attr!(tcx.get_all_attrs(variant_def.def_id), AttributeKind::NonExhaustive(..)) +++ || tcx.has_attr(variant_def.def_id, sym::non_exhaustive) ++ }) ++ || adt ++ .all_fields() ++- .any(|field_def| find_attr!(tcx.get_all_attrs(field_def.did), AttributeKind::NonExhaustive(..))) +++ .any(|field_def| tcx.has_attr(field_def.did, sym::non_exhaustive)) ++ } ++ ++ /// Checks if the given span contains a `#[cfg(..)]` attribute ++--- src/tools/clippy/clippy_utils/src/lib.rs +++++ src/tools/clippy/clippy_utils/src/lib.rs ++@@ -1786,9 +1786,9 @@ pub fn in_automatically_derived(tcx: TyCtxt<'_>, id: HirId) -> bool { ++ tcx.hir_parent_owner_iter(id) ++ .filter(|(_, node)| matches!(node, OwnerNode::Item(item) if matches!(item.kind, ItemKind::Impl(_)))) ++ .any(|(id, _)| { ++- find_attr!( +++ has_attr( ++ tcx.hir_attrs(tcx.local_def_id_to_hir_id(id.def_id)), ++- AttributeKind::AutomaticallyDerived(..) +++ sym::automatically_derived, ++ ) ++ }) ++ } +-- +2.55.0 + diff --git a/mrustc/package.az b/mrustc/package.az new file mode 100644 index 0000000..1f75b5d --- /dev/null +++ b/mrustc/package.az @@ -0,0 +1,122 @@ +package mrustc-source { + description = "patched mrustc source tree"; + exclude = true; + + version# = "0.12.0"; + output = remoteGitHub { + suffix = "thepowersgang/mrustc"; + tag = "v"+version; + checksum = "Db25OAKL_1yZIF6MlXOTHhrEJ-Pd-i-accVtt5rJollmpKm6B3bgS0xN7hoC1cVu"; + }; + chmod = true; + patches = [ + "0001-do-not-download-rustc.patch", + "0002-Revert-HIR-Typecheck-Optimise-by-doing-multiple-chec.patch", + "0003-rustc-src-enable-rustix-use-libc-feature-revert-port.patch", + + "remove-git-invocations.patch", + ]; +} + +package mrustc { + description = "alternative rust compiler (re-implementation)"; + website = "https://github.com/thepowersgang/mrustc"; + anitya = 391250; + + source = mrustc-source; + enterSource = true; + writable = true; + + minimal = true; + exec = make { + inPlace = true; + skipConfigure = true; + make = [ "CXX='g++ -w'" ]; + // test suite runs during rustc-bootstrap + skipCheck = true; + install = "install -vD bin/mrustc /work/system/bin/mrustc"; + }; + + inputs = [ + bash, + + // mrustc requires buggy gcc behaviour + gcc, + ]; + + runtime = [ gcc ]; +} + +package rustc-bootstrap-source { + description = "rustc source tree used by mrustc"; + exclude = true; + + version# = "1.90.0"; + output = remoteTar { + url = "https://static.rust-lang.org/dist/rustc-"+version+"-src.tar.gz"; + compress = gzip; + checksum = "kUjk5mOHRc7cTom0uJ5afFTkhFcXLYK8tJl_aqduffGSHc0TH_a-KKz6PI0nk_xK"; + }; + chmod = true; +} + +package rustc-bootstrap { + description = "rust toolchain bootstrapped via mrustc"; + exclude = true; + + source = mrustc-source; + extra = [ rustc-bootstrap-source ]; + + enterSource = true; + writable = true; + + exec = make { + inPlace = true; + skipConfigure = true; + preMake = ` +export PARLEVEL=`+jobsE+` +export RUSTC_SOURCE='../extra/rustc-bootstrap-source' +export RUSTC_VERSION="$(cut -d ' ' -f 1 "$RUSTC_SOURCE/version")" +export MRUSTC_TARGET_VER="$(cut -d '.' -f 1,2 <<< "$RUSTC_VERSION")" +export OUTDIR_SUF="-$RUSTC_VERSION" +patch -d "$RUSTC_SOURCE" -p0 < "rustc-$RUSTC_VERSION-src.patch" +touch "$RUSTC_SOURCE/dl-version" + +ln -s "$RUSTC_SOURCE" "rustc-$RUSTC_VERSION-src" +mkdir bin && ln -s /system/bin/mrustc bin/ +`; + make = [ + "-f", + "minicargo.mk", + "CC=gcc", + "CXX='g++ -w'", + "LIBS", + ]; + check = [ + "CC=gcc", + "CXX='g++ -w'", + "test", + "local_tests", + ]; + + install = ` +export CC=gcc CXX=g++ +OUTDIR="output-$RUSTC_VERSION" +make -f minicargo.mk "$OUTDIR/rustc" +make -f minicargo.mk "$OUTDIR/cargo" +make -C run_rustc +`; + }; + + inputs = [ + bash, + patch, + cmake, + pkg-config, + perl, + python, + mrustc, + + kernel-headers, + ]; +} diff --git a/mrustc/remove-git-invocations.patch b/mrustc/remove-git-invocations.patch new file mode 100644 index 0000000..8e11bfe --- /dev/null +++ b/mrustc/remove-git-invocations.patch @@ -0,0 +1,13 @@ +diff --git a/Makefile b/Makefile +index 4317d2c0..415427b4 100644 +--- a/Makefile ++++ b/Makefile +@@ -187,7 +187,7 @@ $(OBJDIR)%.o: src/%.cpp + $(OBJDIR)version.o: $(OBJDIR)%.o: src/%.cpp $(filter-out $(OBJDIR)version.o,$(OBJ)) Makefile + @+mkdir -p $(dir $@) + @echo [CXX] -o $@ +- $V$(CXX) -o $@ -c $< $(CXXFLAGS) $(CPPFLAGS) -MMD -MP -MF $@.dep -D VERSION_GIT_FULLHASH=\"$(shell git show --pretty=%H -s --no-show-signature)\" -D VERSION_GIT_BRANCH="\"$(shell git symbolic-ref -q --short HEAD || git describe --tags --exact-match)\"" -D VERSION_GIT_SHORTHASH=\"$(shell git show -s --pretty=%h --no-show-signature)\" -D VERSION_BUILDTIME="\"$(shell env LC_TIME=C date -u +"%a, %e %b %Y %T +0000")\"" -D VERSION_GIT_ISDIRTY=$(shell git diff-index --quiet HEAD; echo $$?) ++ $V$(CXX) -o $@ -c $< $(CXXFLAGS) $(CPPFLAGS) -MMD -MP -MF $@.dep -D VERSION_GIT_FULLHASH=\"unknown\" -D VERSION_GIT_BRANCH="\"v0.12.0\"" -D VERSION_GIT_SHORTHASH=\"unknown\" -D VERSION_BUILDTIME="\"Thu, 1 Jan 1970 00:00:00 +0000\"" -D VERSION_GIT_ISDIRTY=0 + + src/main.cpp: $(PCHS:%=src/%.gch) +