diff options
| author | Jana Dönszelmann <jana@donsz.nl> | 2025-06-12 13:52:23 +0200 |
|---|---|---|
| committer | Jana Dönszelmann <jana@donsz.nl> | 2025-06-20 15:06:29 +0200 |
| commit | de0fd27f347c783b45fc9764baa944455369cd33 (patch) | |
| tree | 120641693fe8b5dc067306b04808b44f27ceb138 | |
| parent | 3b97f1308ff72016a4aaa93fbe6d09d4d6427815 (diff) | |
| download | rust-de0fd27f347c783b45fc9764baa944455369cd33.tar.gz rust-de0fd27f347c783b45fc9764baa944455369cd33.zip | |
cold
8 files changed, 81 insertions, 33 deletions
diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 65061059a02..9ebf4c1793d 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -202,6 +202,9 @@ pub enum AttributeKind { span: Span, }, + /// Represents `#[cold]`. + Cold(Span), + /// Represents `#[rustc_confusables]`. Confusables { symbols: ThinVec<Symbol>, diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index ddcf82cbf7c..1509531ca98 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -38,3 +38,21 @@ impl<S: Stage> SingleAttributeParser<S> for OptimizeParser { Some(AttributeKind::Optimize(res, cx.attr_span)) } } + +pub(crate) struct ColdParser; + +impl<S: Stage> SingleAttributeParser<S> for ColdParser { + const PATH: &[rustc_span::Symbol] = &[sym::cold]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; + const TEMPLATE: AttributeTemplate = template!(Word); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { + if !args.no_args() { + cx.expected_no_args(cx.attr_span); + return None; + }; + + Some(AttributeKind::Cold(cx.attr_span)) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 1708fd72e58..e8bcf57e109 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -15,7 +15,7 @@ use rustc_session::Session; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser}; -use crate::attributes::codegen_attrs::OptimizeParser; +use crate::attributes::codegen_attrs::{ColdParser, OptimizeParser}; use crate::attributes::confusables::ConfusablesParser; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; @@ -106,6 +106,7 @@ attribute_parsers!( // tidy-alphabetical-start Single<AsPtrParser>, + Single<ColdParser>, Single<ConstStabilityIndirectParser>, Single<DeprecationParser>, Single<InlineParser>, @@ -234,6 +235,16 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { }) } + pub(crate) fn expected_no_args(&self, span: Span) -> ErrorGuaranteed { + self.emit_err(AttributeParseError { + span, + attr_span: self.attr_span, + template: self.template.clone(), + attribute: self.attr_path.clone(), + reason: AttributeParseErrorReason::ExpectedNoArgs, + }) + } + /// emit an error that a `name = value` pair was expected at this span. The symbol can be given for /// a nicer error message talking about the specific name that was found lacking a value. pub(crate) fn expected_name_value(&self, span: Span, name: Option<Symbol>) -> ErrorGuaranteed { diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 337921a318c..29f2e44a98a 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -474,6 +474,7 @@ pub(crate) struct UnrecognizedReprHint { } pub(crate) enum AttributeParseErrorReason { + ExpectedNoArgs, ExpectedStringLiteral { byte_string: Option<Span> }, ExpectedSingleArgument, ExpectedList, @@ -529,6 +530,10 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError { diag.span_label(self.span, format!("didn't expect a literal here")); diag.code(E0565); } + AttributeParseErrorReason::ExpectedNoArgs => { + diag.span_label(self.span, format!("didn't expect any arguments here")); + diag.code(E0565); + } AttributeParseErrorReason::ExpectedNameValue(None) => { diag.span_label( self.span, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index e855f1d3558..39818be5bde 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -4,7 +4,7 @@ use rustc_abi::ExternAbi; use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode}; use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr}; use rustc_attr_data_structures::{ - AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr, find_attr, + AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr, ReprAttr, find_attr, }; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; @@ -110,8 +110,20 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } }; - if let hir::Attribute::Parsed(AttributeKind::Align { align, .. }) = attr { - codegen_fn_attrs.alignment = Some(*align); + if let hir::Attribute::Parsed(p) = attr { + match p { + AttributeKind::Repr(reprs) => { + codegen_fn_attrs.alignment = reprs + .iter() + .filter_map( + |(r, _)| if let ReprAttr::ReprAlign(x) = r { Some(*x) } else { None }, + ) + .max(); + } + AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD, + AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align), + _ => {} + } } let Some(Ident { name, .. }) = attr.ident() else { @@ -119,7 +131,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { }; match name { - sym::cold => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD, 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, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a5d2ad4dc20..f25c9f353c2 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -149,10 +149,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */ } + Attribute::Parsed(AttributeKind::Cold(attr_span)) => { + self.check_cold(hir_id, *attr_span, span, target) + } Attribute::Parsed(AttributeKind::Align { align, span: repr_span }) => { self.check_align(span, target, *align, *repr_span) } - Attribute::Parsed( AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect @@ -245,7 +247,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::ffi_pure, ..] => self.check_ffi_pure(attr.span(), attrs, target), [sym::ffi_const, ..] => self.check_ffi_const(attr.span(), target), [sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, target), - [sym::cold, ..] => self.check_cold(hir_id, attr, span, target), [sym::link, ..] => self.check_link(hir_id, attr, span, target), [sym::link_name, ..] => self.check_link_name(hir_id, attr, span, target), [sym::link_section, ..] => self.check_link_section(hir_id, attr, span, target), @@ -651,8 +652,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { sym::repr, sym::align, sym::rustc_std_internal_symbol, - // code generation - sym::cold, // documentation sym::doc, ]; @@ -688,7 +687,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed( AttributeKind::Deprecation { .. } | AttributeKind::Repr { .. } - | AttributeKind::Align { .. }, + | AttributeKind::Align { .. } + | AttributeKind::Cold(..), ) => { continue; } @@ -1637,7 +1637,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } /// Checks if `#[cold]` is applied to a non-function. - fn check_cold(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { + fn check_cold(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) { match target { Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => {} // FIXME(#80564): We permit struct fields, match arms and macro defs to have an @@ -1645,7 +1645,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // 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(), "cold"); + self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "cold"); } _ => { // FIXME: #[cold] was previously allowed on non-functions and some crates used @@ -1653,7 +1653,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.tcx.emit_node_span_lint( UNUSED_ATTRIBUTES, hir_id, - attr.span(), + attr_span, errors::Cold { span, on_crate: hir_id == CRATE_HIR_ID }, ); } diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index 1c6868dc95d..9280dfdf92e 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -379,14 +379,6 @@ warning: `#[proc_macro_derive]` only has an effect on functions LL | #![proc_macro_derive()] | ^^^^^^^^^^^^^^^^^^^^^^^ -warning: attribute should be applied to a function definition - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1 - | -LL | #![cold] - | ^^^^^^^^ cannot be applied to crates - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1 | @@ -417,6 +409,14 @@ warning: `#[must_use]` has no effect when applied to a module LL | #![must_use] | ^^^^^^^^^^^^ +warning: attribute should be applied to a function definition + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1 + | +LL | #![cold] + | ^^^^^^^^ cannot be applied to crates + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + warning: `#[macro_use]` only has an effect on `extern crate` and modules --> $DIR/issue-43106-gating-of-builtin-attrs.rs:176:5 | diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index e1c45e832af..03ce9757014 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -103,18 +103,6 @@ LL | #[automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:77:1 - | -LL | #[cold] - | ^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:76:1 - | -LL | #[cold] - | ^^^^^^^ - -error: unused attribute --> $DIR/unused-attr-duplicate.rs:79:1 | LL | #[track_caller] @@ -289,5 +277,17 @@ LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:77:1 + | +LL | #[cold] + | ^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:76:1 + | +LL | #[cold] + | ^^^^^^^ + error: aborting due to 23 previous errors |
