From c0c48984b05e244fc93144d0c1d48db318639b3b Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 2 Aug 2025 17:28:17 +0000 Subject: [PATCH 1/5] Method probe: check doc aliases after edit distance. --- compiler/rustc_hir_typeck/src/method/probe.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 1f3969bd93c3c..f5584e0596a68 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -2373,17 +2373,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if !self.is_relevant_kind_for_mode(x.kind) { return false; } - if self.matches_by_doc_alias(x.def_id) { - return true; - } - match edit_distance_with_substrings( + if let Some(d) = edit_distance_with_substrings( name.as_str(), x.name().as_str(), max_dist, ) { - Some(d) => d > 0, - None => false, + return d > 0; } + self.matches_by_doc_alias(x.def_id) }) .copied() .collect() From bf644e9d14d4e088303041d4136daefaa8ae6f86 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 2 Aug 2025 19:03:46 +0000 Subject: [PATCH 2/5] Use codegen_fn_attrs to check if function is naked. --- compiler/rustc_hir_typeck/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index aae870f7ee3ee..72fd8db300bed 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -46,12 +46,12 @@ use rustc_data_structures::unord::UnordSet; use rustc_errors::codes::*; use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err}; use rustc_hir as hir; -use rustc_hir::attrs::AttributeKind; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{HirId, HirIdMap, Node, find_attr}; +use rustc_hir::{HirId, HirIdMap, Node}; use rustc_hir_analysis::check::{check_abi, check_custom_abi}; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc}; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; @@ -174,7 +174,7 @@ fn typeck_with_inspect<'tcx>( .map(|(idx, ty)| fcx.normalize(arg_span(idx), ty)), ); - if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::Naked(..)) { + if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NAKED) { naked_functions::typeck_naked_fn(tcx, def_id, body); } From dccc075d05f0c28fab5775f7efa5550f24382ec6 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 4 Aug 2025 23:47:40 +0000 Subject: [PATCH 3/5] Check for rustc_has_incoherent_inherent_impls in incoherent_impls query. --- compiler/rustc_hir_typeck/src/method/probe.rs | 21 +++---------------- compiler/rustc_middle/src/ty/trait_def.rs | 7 +++++++ 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index f5584e0596a68..51de661a2bb5c 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -777,31 +777,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.assemble_inherent_candidates_from_object(generalized_self_ty); self.assemble_inherent_impl_candidates_for_type(p.def_id(), receiver_steps); - if self.tcx.has_attr(p.def_id(), sym::rustc_has_incoherent_inherent_impls) { - self.assemble_inherent_candidates_for_incoherent_ty( - raw_self_ty, - receiver_steps, - ); - } + self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty, receiver_steps); } ty::Adt(def, _) => { let def_id = def.did(); self.assemble_inherent_impl_candidates_for_type(def_id, receiver_steps); - if self.tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) { - self.assemble_inherent_candidates_for_incoherent_ty( - raw_self_ty, - receiver_steps, - ); - } + self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty, receiver_steps); } ty::Foreign(did) => { self.assemble_inherent_impl_candidates_for_type(did, receiver_steps); - if self.tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) { - self.assemble_inherent_candidates_for_incoherent_ty( - raw_self_ty, - receiver_steps, - ); - } + self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty, receiver_steps); } ty::Param(_) => { self.assemble_inherent_candidates_from_param(raw_self_ty); diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 59e2b2a034def..4e38d969192f4 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -6,6 +6,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_macros::{Decodable, Encodable, HashStable}; +use rustc_span::symbol::sym; use tracing::debug; use crate::query::LocalCrate; @@ -239,6 +240,12 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait /// Query provider for `incoherent_impls`. pub(super) fn incoherent_impls_provider(tcx: TyCtxt<'_>, simp: SimplifiedType) -> &[DefId] { + if let Some(def_id) = simp.def() + && !tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) + { + return &[]; + } + let mut impls = Vec::new(); for cnum in iter::once(LOCAL_CRATE).chain(tcx.crates(()).iter().copied()) { for &impl_def_id in tcx.crate_incoherent_impls((cnum, simp)) { From 5073886181cb95bfe899a26404c57d2944f2a4d4 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 2 Aug 2025 18:21:16 +0000 Subject: [PATCH 4/5] Gate checking rustc attrs on the feature. --- compiler/rustc_hir_typeck/src/callee.rs | 6 ++++-- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 16 ++++++++++++---- compiler/rustc_hir_typeck/src/upvar.rs | 2 +- compiler/rustc_hir_typeck/src/writeback.rs | 3 ++- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 48bb45de53eb4..e19dd83f81d8b 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -511,7 +511,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Untranslatable diagnostics are okay for rustc internals #[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::diagnostic_outside_of_impl)] - if self.tcx.has_attr(def_id, sym::rustc_evaluate_where_clauses) { + if self.has_rustc_attrs + && self.tcx.has_attr(def_id, sym::rustc_evaluate_where_clauses) + { let predicates = self.tcx.predicates_of(def_id); let predicates = predicates.instantiate(self.tcx, args); for (predicate, predicate_span) in predicates { @@ -894,7 +896,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // If we have `rustc_do_not_const_check`, do not check `[const]` bounds. - if self.tcx.has_attr(self.body_id, sym::rustc_do_not_const_check) { + if self.has_rustc_attrs && self.tcx.has_attr(self.body_id, sym::rustc_do_not_const_check) { return; } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 0c6226ce71e78..74f27e85cba25 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -126,6 +126,10 @@ pub(crate) struct FnCtxt<'a, 'tcx> { /// These are stored here so we may collect them when canonicalizing user /// type ascriptions later. pub(super) trait_ascriptions: RefCell>>>, + + /// Whether the current crate enables the `rustc_attrs` feature. + /// This allows to skip processing attributes in many places. + pub(super) has_rustc_attrs: bool, } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -154,6 +158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { diverging_fallback_behavior, diverging_block_behavior, trait_ascriptions: Default::default(), + has_rustc_attrs: root_ctxt.tcx.features().rustc_attrs(), } } @@ -525,10 +530,13 @@ fn parse_never_type_options_attr( let mut fallback = None; let mut block = None; - let items = tcx - .get_attr(CRATE_DEF_ID, sym::rustc_never_type_options) - .map(|attr| attr.meta_item_list().unwrap()) - .unwrap_or_default(); + let items = if tcx.features().rustc_attrs() { + tcx.get_attr(CRATE_DEF_ID, sym::rustc_never_type_options) + .map(|attr| attr.meta_item_list().unwrap()) + } else { + None + }; + let items = items.unwrap_or_default(); for item in items { if item.has_name(sym::fallback) && fallback.is_none() { diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index df38c3a121436..8c0ec78e0af96 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1747,7 +1747,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } fn should_log_capture_analysis(&self, closure_def_id: LocalDefId) -> bool { - self.tcx.has_attr(closure_def_id, sym::rustc_capture_analysis) + self.has_rustc_attrs && self.tcx.has_attr(closure_def_id, sym::rustc_capture_analysis) } fn log_capture_analysis_first_pass( diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 093de950d6369..574406ecc8a29 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -45,7 +45,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This attribute causes us to dump some writeback information // in the form of errors, which is used for unit tests. - let rustc_dump_user_args = self.tcx.has_attr(item_def_id, sym::rustc_dump_user_args); + let rustc_dump_user_args = + self.has_rustc_attrs && self.tcx.has_attr(item_def_id, sym::rustc_dump_user_args); let mut wbcx = WritebackCx::new(self, body, rustc_dump_user_args); for param in body.params { From 6b7f8fbcc584f4dc46081b5c690aeca7def88019 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 5 Aug 2025 01:55:20 +0000 Subject: [PATCH 5/5] Promote crash test. --- tests/crashes/124352.rs | 4 ---- .../malformed-never-type-options.rs | 8 ++++++++ .../malformed-never-type-options.stderr | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) delete mode 100644 tests/crashes/124352.rs create mode 100644 tests/ui/attributes/malformed-never-type-options.rs create mode 100644 tests/ui/attributes/malformed-never-type-options.stderr diff --git a/tests/crashes/124352.rs b/tests/crashes/124352.rs deleted file mode 100644 index e9eb4419e6a4f..0000000000000 --- a/tests/crashes/124352.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ known-bug: #124352 -#![rustc_never_type_options(: Unsize = "hi")] - -fn main() {} diff --git a/tests/ui/attributes/malformed-never-type-options.rs b/tests/ui/attributes/malformed-never-type-options.rs new file mode 100644 index 0000000000000..0c384be0e2266 --- /dev/null +++ b/tests/ui/attributes/malformed-never-type-options.rs @@ -0,0 +1,8 @@ +//! Regression test for #124352 +//! The `rustc_*` attribute is malformed, but ICEing without a `feature(rustc_attrs)` is still bad. + +#![rustc_never_type_options(: Unsize = "hi")] +//~^ ERROR expected unsuffixed literal, found `:` +//~| ERROR use of an internal attribute + +fn main() {} diff --git a/tests/ui/attributes/malformed-never-type-options.stderr b/tests/ui/attributes/malformed-never-type-options.stderr new file mode 100644 index 0000000000000..0d2ff4881f2ae --- /dev/null +++ b/tests/ui/attributes/malformed-never-type-options.stderr @@ -0,0 +1,19 @@ +error: expected unsuffixed literal, found `:` + --> $DIR/malformed-never-type-options.rs:4:29 + | +LL | #![rustc_never_type_options(: Unsize = "hi")] + | ^ + +error[E0658]: use of an internal attribute + --> $DIR/malformed-never-type-options.rs:4:1 + | +LL | #![rustc_never_type_options(: Unsize = "hi")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable + = note: the `#[rustc_never_type_options]` attribute is an internal implementation detail that will never be stable + = note: `rustc_never_type_options` is used to experiment with never type fallback and work on never type stabilization + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`.