diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_attr_data_structures/src/attributes.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_attr_data_structures/src/encode_cross_crate.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_attr_data_structures/src/lib.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/attributes/mod.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs | 59 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/context.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/session_diagnostics.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 30 | ||||
| -rw-r--r-- | compiler/rustc_passes/messages.ftl | 3 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 27 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/errors.rs | 7 |
11 files changed, 108 insertions, 56 deletions
diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index d755afad59f..43a79d8456a 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -273,6 +273,12 @@ pub enum AttributeKind { /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). Repr(ThinVec<(ReprAttr, Span)>), + /// Represents `#[rustc_layout_scalar_valid_range_end]`. + RustcLayoutScalarValidRangeEnd(Box<u128>, Span), + + /// Represents `#[rustc_layout_scalar_valid_range_start]`. + RustcLayoutScalarValidRangeStart(Box<u128>, Span), + /// Represents `#[rustc_skip_during_method_dispatch]`. SkipDuringMethodDispatch { array: bool, boxed_slice: bool, span: Span }, diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index d4402f4e2e6..174aa5b85b5 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -36,6 +36,8 @@ impl AttributeKind { NoMangle(..) => No, Optimize(..) => No, PubTransparent(..) => Yes, + RustcLayoutScalarValidRangeEnd(..) => Yes, + RustcLayoutScalarValidRangeStart(..) => Yes, SkipDuringMethodDispatch { .. } => No, TrackCaller(..) => Yes, } diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs index 86c73f0d9a0..8f8ce575a18 100644 --- a/compiler/rustc_attr_data_structures/src/lib.rs +++ b/compiler/rustc_attr_data_structures/src/lib.rs @@ -49,6 +49,16 @@ pub trait PrintAttribute { fn print_attribute(&self, p: &mut Printer); } +impl PrintAttribute for u128 { + fn should_render(&self) -> bool { + true + } + + fn print_attribute(&self, p: &mut Printer) { + p.word(self.to_string()) + } +} + impl<T: PrintAttribute> PrintAttribute for &T { fn should_render(&self) -> bool { T::should_render(self) diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index d407669cb41..a7c17009653 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -35,6 +35,7 @@ pub(crate) mod lint_helpers; pub(crate) mod loop_match; pub(crate) mod must_use; pub(crate) mod repr; +pub(crate) mod rustc_internal; pub(crate) mod semantics; pub(crate) mod stability; pub(crate) mod traits; diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs new file mode 100644 index 00000000000..7364a3f20e2 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -0,0 +1,59 @@ +use rustc_ast::LitKind; +use rustc_attr_data_structures::AttributeKind; +use rustc_feature::{AttributeTemplate, template}; +use rustc_span::{Symbol, sym}; + +use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; +use crate::context::{AcceptContext, Stage}; +use crate::parser::ArgParser; + +pub(crate) struct RustcLayoutScalarValidRangeStart; + +impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeStart { + const PATH: &'static [Symbol] = &[sym::rustc_layout_scalar_valid_range_start]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const TEMPLATE: AttributeTemplate = template!(List: "start"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { + parse_rustc_layout_scalar_valid_range(cx, args) + .map(|n| AttributeKind::RustcLayoutScalarValidRangeStart(n, cx.attr_span)) + } +} + +pub(crate) struct RustcLayoutScalarValidRangeEnd; + +impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeEnd { + const PATH: &'static [Symbol] = &[sym::rustc_layout_scalar_valid_range_end]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const TEMPLATE: AttributeTemplate = template!(List: "end"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { + parse_rustc_layout_scalar_valid_range(cx, args) + .map(|n| AttributeKind::RustcLayoutScalarValidRangeEnd(n, cx.attr_span)) + } +} + +fn parse_rustc_layout_scalar_valid_range<S: Stage>( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser<'_>, +) -> Option<Box<u128>> { + let Some(list) = args.list() else { + cx.expected_list(cx.attr_span); + return None; + }; + let Some(single) = list.single() else { + cx.expected_single_argument(list.span); + return None; + }; + let Some(lit) = single.lit() else { + cx.expected_integer_literal(single.span()); + return None; + }; + let LitKind::Int(num, _ty) = lit.kind else { + cx.expected_integer_literal(single.span()); + return None; + }; + Some(Box::new(num.0)) +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 83e3c75dedb..659e21c97bc 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -25,6 +25,9 @@ use crate::attributes::lint_helpers::{AsPtrParser, PubTransparentParser}; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::must_use::MustUseParser; use crate::attributes::repr::{AlignParser, ReprParser}; +use crate::attributes::rustc_internal::{ + RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart, +}; use crate::attributes::semantics::MayDangleParser; use crate::attributes::stability::{ BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser, @@ -126,6 +129,8 @@ attribute_parsers!( Single<OptimizeParser>, Single<PubTransparentParser>, Single<RustcForceInlineParser>, + Single<RustcLayoutScalarValidRangeEnd>, + Single<RustcLayoutScalarValidRangeStart>, Single<SkipDuringMethodDispatchParser>, Single<TrackCallerParser>, Single<TransparencyParser>, @@ -269,6 +274,16 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { }) } + pub(crate) fn expected_integer_literal(&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::ExpectedIntegerLiteral, + }) + } + pub(crate) fn expected_list(&self, span: Span) -> ErrorGuaranteed { self.emit_err(AttributeParseError { span, diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 7cfce579979..0a5a42ce32e 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -503,6 +503,7 @@ pub(crate) struct NakedFunctionIncompatibleAttribute { pub(crate) enum AttributeParseErrorReason { ExpectedNoArgs, ExpectedStringLiteral { byte_string: Option<Span> }, + ExpectedIntegerLiteral, ExpectedAtLeastOneArgument, ExpectedSingleArgument, ExpectedList, @@ -543,6 +544,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError { diag.span_label(self.span, "expected a string literal here"); } } + AttributeParseErrorReason::ExpectedIntegerLiteral => { + diag.span_label(self.span, "expected an integer literal here"); + } AttributeParseErrorReason::ExpectedSingleArgument => { diag.span_label(self.span, "expected a single argument here"); diag.code(E0805); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 457a4f4d502..72810491214 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -17,6 +17,7 @@ use std::{fmt, iter, mem}; use rustc_abi::{ExternAbi, FieldIdx, Layout, LayoutData, TargetDataLayout, VariantIdx}; use rustc_ast as ast; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::defer; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; @@ -1648,32 +1649,9 @@ impl<'tcx> TyCtxt<'tcx> { /// `rustc_layout_scalar_valid_range` attribute. // FIXME(eddyb) this is an awkward spot for this method, maybe move it? pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound<u128>, Bound<u128>) { - let get = |name| { - let Some(attr) = self.get_attr(def_id, name) else { - return Bound::Unbounded; - }; - debug!("layout_scalar_valid_range: attr={:?}", attr); - if let Some( - &[ - ast::MetaItemInner::Lit(ast::MetaItemLit { - kind: ast::LitKind::Int(a, _), .. - }), - ], - ) = attr.meta_item_list().as_deref() - { - Bound::Included(a.get()) - } else { - self.dcx().span_delayed_bug( - attr.span(), - "invalid rustc_layout_scalar_valid_range attribute", - ); - Bound::Unbounded - } - }; - ( - get(sym::rustc_layout_scalar_valid_range_start), - get(sym::rustc_layout_scalar_valid_range_end), - ) + let start = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeStart(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded); + let end = find_attr!(self.get_all_attrs(def_id), AttributeKind::RustcLayoutScalarValidRangeEnd(n, _) => Bound::Included(**n)).unwrap_or(Bound::Unbounded); + (start, end) } pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> { diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index e2995daadfe..2a2948f78bd 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -618,9 +618,6 @@ passes_rustc_force_inline_coro = attribute cannot be applied to a `async`, `gen` or `async gen` function .label = `async`, `gen` or `async gen` function -passes_rustc_layout_scalar_valid_range_arg = - expected exactly one integer literal argument - passes_rustc_layout_scalar_valid_range_not_struct = attribute should be applied to a struct .label = not a struct diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 491b3699f4c..b5b297eaf85 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -9,7 +9,7 @@ use std::cell::Cell; use std::collections::hash_map::Entry; use rustc_abi::{Align, ExternAbi, Size}; -use rustc_ast::{AttrStyle, LitKind, MetaItemInner, MetaItemKind, MetaItemLit, ast}; +use rustc_ast::{AttrStyle, LitKind, MetaItemInner, MetaItemKind, ast}; use rustc_attr_data_structures::{AttributeKind, InlineAttr, ReprAttr, find_attr}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey}; @@ -184,6 +184,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_track_caller(hir_id, *attr_span, attrs, span, target) } 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::BodyStability { .. } | AttributeKind::ConstStabilityIndirect | AttributeKind::MacroTransparency(_), @@ -228,10 +232,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { &mut doc_aliases, ), [sym::no_link, ..] => self.check_no_link(hir_id, attr, span, target), - [sym::rustc_layout_scalar_valid_range_start, ..] - | [sym::rustc_layout_scalar_valid_range_end, ..] => { - self.check_rustc_layout_scalar_valid_range(attr, span, target) - } [sym::debugger_visualizer, ..] => self.check_debugger_visualizer(attr, target), [sym::rustc_std_internal_symbol, ..] => { self.check_rustc_std_internal_symbol(attr, span, target) @@ -1675,24 +1675,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_rustc_layout_scalar_valid_range(&self, attr: &Attribute, span: Span, target: Target) { + fn check_rustc_layout_scalar_valid_range(&self, attr_span: Span, span: Span, target: Target) { if target != Target::Struct { - self.dcx().emit_err(errors::RustcLayoutScalarValidRangeNotStruct { - attr_span: attr.span(), - span, - }); + self.dcx().emit_err(errors::RustcLayoutScalarValidRangeNotStruct { attr_span, span }); return; } - - let Some(list) = attr.meta_item_list() else { - return; - }; - - if !matches!(&list[..], &[MetaItemInner::Lit(MetaItemLit { kind: LitKind::Int(..), .. })]) { - self.tcx - .dcx() - .emit_err(errors::RustcLayoutScalarValidRangeArg { attr_span: attr.span() }); - } } /// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument. diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 3286ccc94f2..107fc17b536 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -536,13 +536,6 @@ pub(crate) struct RustcLayoutScalarValidRangeNotStruct { } #[derive(Diagnostic)] -#[diag(passes_rustc_layout_scalar_valid_range_arg)] -pub(crate) struct RustcLayoutScalarValidRangeArg { - #[primary_span] - pub attr_span: Span, -} - -#[derive(Diagnostic)] #[diag(passes_rustc_legacy_const_generics_only)] pub(crate) struct RustcLegacyConstGenericsOnly { #[primary_span] |
