diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index b656db3252823..f61efcf238852 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -198,6 +198,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), @@ -211,6 +214,12 @@ pub enum AttributeKind { span: Span, }, + /// Represents `#[rustc_coherence_is_core]`. + CoherenceIsCore, + + /// Represents `#[rustc_coinductive]`. + Coinductive(Span), + /// Represents `#[cold]`. Cold(Span), @@ -234,9 +243,18 @@ pub enum AttributeKind { /// Represents `#[rustc_const_stable_indirect]`. ConstStabilityIndirect, + /// Represents `#[const_trait]`. + ConstTrait(Span), + + ///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 }, @@ -260,6 +278,9 @@ pub enum AttributeKind { /// Represents `#[ffi_pure]`. FfiPure(Span), + /// Represents `#[fundamental]`. + Fundamental, + /// Represents `#[ignore]` Ignore { span: Span, @@ -282,6 +303,9 @@ pub enum AttributeKind { /// Represents `#[rustc_macro_transparency]`. MacroTransparency(Transparency), + /// Represents `#[marker]`. + Marker(Span), + /// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html). MayDangle(Span), @@ -307,6 +331,9 @@ pub enum AttributeKind { /// 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), @@ -331,6 +358,9 @@ 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, @@ -347,6 +377,12 @@ pub enum AttributeKind { /// Represents `#[track_caller]` TrackCaller(Span), + /// Represents `#[type_const]`. + TypeConst(Span), + + /// Represents `#[rustc_unsafe_specialization_marker]`. + UnsafeSpecializationMarker(Span), + /// Represents `#[used]` Used { used_by: UsedBy, span: Span }, // tidy-alphabetical-end 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 5414c7b103bcb..ad587523e0373 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -15,27 +15,35 @@ impl AttributeKind { // tidy-alphabetical-start Align { .. } => No, AllowConstFnUnstable(..) => No, + AllowIncoherentImpl(..) => No, AllowInternalUnstable(..) => Yes, AsPtr(..) => Yes, BodyStability { .. } => No, + CoherenceIsCore => No, + Coinductive(..) => No, Cold(..) => No, Confusables { .. } => Yes, ConstContinue(..) => No, ConstStability { .. } => Yes, ConstStabilityIndirect => No, + ConstTrait(..) => 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, LinkSection { .. } => No, LoopMatch(..) => No, MacroTransparency(..) => Yes, + Marker(..) => No, MayDangle(..) => No, MustUse { .. } => Yes, Naked(..) => No, @@ -43,6 +51,7 @@ impl AttributeKind { NoMangle(..) => No, NonExhaustive(..) => Yes, Optimize(..) => No, + ParenSugar(..) => No, PassByValue(..) => Yes, Path(..) => No, PubTransparent(..) => Yes, @@ -51,10 +60,13 @@ impl AttributeKind { RustcLayoutScalarValidRangeStart(..) => Yes, RustcObjectLifetimeDefault => No, SkipDuringMethodDispatch { .. } => No, + SpecializationTrait(..) => No, Stability { .. } => Yes, StdInternalSymbol(..) => No, TargetFeature(..) => No, TrackCaller(..) => Yes, + TypeConst(..) => Yes, + UnsafeSpecializationMarker(..) => No, Used { .. } => No, // tidy-alphabetical-end } diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index c29dbf4d1e9e2..ee8a33ae9c43d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -2,14 +2,15 @@ use core::mem; use rustc_attr_data_structures::AttributeKind; use rustc_feature::{AttributeTemplate, template}; -use rustc_span::{Symbol, sym}; +use rustc_span::{Span, Symbol, sym}; -use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; +use crate::attributes::{ + AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser, +}; use crate::context::{AcceptContext, Stage}; use crate::parser::ArgParser; pub(crate) struct SkipDuringMethodDispatchParser; - impl SingleAttributeParser for SkipDuringMethodDispatchParser { const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch]; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; @@ -52,3 +53,95 @@ impl SingleAttributeParser for SkipDuringMethodDispatchParser { Some(AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: cx.attr_span }) } } + +pub(crate) struct ParenSugarParser; +impl 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; +} + +// 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; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index dbe1a5b2ad03d..cc10bb3098a61 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -43,7 +43,12 @@ use crate::attributes::stability::{ BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser, }; use crate::attributes::test_attrs::IgnoreParser; -use crate::attributes::traits::SkipDuringMethodDispatchParser; +use crate::attributes::traits::{ + AllowIncoherentImplParser, CoherenceIsCoreParser, CoinductiveParser, ConstTraitParser, + DenyExplicitImplParser, DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, + ParenSugarParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, + UnsafeSpecializationMarkerParser, +}; use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; use crate::parser::{ArgParser, MetaItemParser, PathParser}; @@ -146,22 +151,34 @@ attribute_parsers!( 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 ]; ); diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 9c62244f3c9ff..74418adc43c1d 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -680,7 +680,7 @@ pub(crate) fn run_pass_manager( if attributes::has_string_attr(function, enzyme_marker) { // Sanity check: Ensure 'noinline' is present before replacing it. assert!( - !attributes::has_attr(function, Function, llvm::AttributeKind::NoInline), + attributes::has_attr(function, Function, llvm::AttributeKind::NoInline), "Expected __enzyme function to have 'noinline' before adding 'alwaysinline'" ); diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 1f266514f346f..bb53a8b5d28b4 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -554,12 +554,33 @@ pub trait BuilderMethods<'a, 'tcx>: /// Called for `StorageDead` fn lifetime_end(&mut self, ptr: Self::Value, size: Size); + /// "Finally codegen the call" + /// + /// ## Arguments + /// + /// The `fn_attrs`, `fn_abi`, and `instance` arguments are Options because they are advisory. + /// They relate to optional codegen enhancements like LLVM CFI, and do not affect ABI per se. + /// Any ABI-related transformations should be handled by different, earlier stages of codegen. + /// For instance, in the caller of `BuilderMethods::call`. + /// + /// This means that a codegen backend which disregards `fn_attrs`, `fn_abi`, and `instance` + /// should still do correct codegen, and code should not be miscompiled if they are omitted. + /// It is not a miscompilation in this sense if it fails to run under CFI, other sanitizers, or + /// in the context of other compiler-enhanced security features. + /// + /// The typical case that they are None is during the codegen of intrinsics and lang-items, + /// as those are "fake functions" with only a trivial ABI if any, et cetera. + /// + /// ## Return + /// + /// Must return the value the function will return so it can be written to the destination, + /// assuming the function does not explicitly pass the destination as a pointer in `args`. fn call( &mut self, llty: Self::Type, fn_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, - llfn: Self::Value, + fn_val: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, instance: Option>, diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index 7d0c6be4c650d..c5ecf43046c74 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -6,16 +6,22 @@ use crate::mir::operand::OperandRef; use crate::mir::place::PlaceRef; pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes { + /// Higher-level interface to emitting calls to intrinsics + /// /// Remember to add all intrinsics here, in `compiler/rustc_hir_analysis/src/check/mod.rs`, /// and in `library/core/src/intrinsics.rs`; if you need access to any LLVM intrinsics, /// add them to `compiler/rustc_codegen_llvm/src/context.rs`. /// Returns `Err` if another instance should be called instead. This is used to invoke /// intrinsic default bodies in case an intrinsic is not implemented by the backend. + /// + /// NOTE: allowed to call [`BuilderMethods::call`] + /// + /// [`BuilderMethods::call`]: super::builder::BuilderMethods::call fn codegen_intrinsic_call( &mut self, instance: ty::Instance<'tcx>, args: &[OperandRef<'tcx, Self::Value>], - result: PlaceRef<'tcx, Self::Value>, + result_dest: PlaceRef<'tcx, Self::Value>, span: Span, ) -> Result<(), ty::Instance<'tcx>>; diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index bd25b4a326086..80bf13dc4b7a3 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -7,6 +7,7 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -85,7 +86,10 @@ impl<'tcx> InherentCollect<'tcx> { } for &impl_item in items { - if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { + if !find_attr!( + self.tcx.get_all_attrs(impl_item), + AttributeKind::AllowIncoherentImpl(_) + ) { let impl_span = self.tcx.def_span(impl_def_id); return Err(self.tcx.dcx().emit_err(errors::InherentTyOutsideRelevant { span: impl_span, @@ -116,7 +120,10 @@ impl<'tcx> InherentCollect<'tcx> { if !self.tcx.hir_rustc_coherence_is_core() { if self.tcx.features().rustc_attrs() { for &impl_item in items { - if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { + if !find_attr!( + self.tcx.get_all_attrs(impl_item), + AttributeKind::AllowIncoherentImpl(_) + ) { let span = self.tcx.def_span(impl_def_id); return Err(self.tcx.dcx().emit_err(errors::InherentTyOutsidePrimitive { span, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index a185291887dc7..431d99a572d26 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -852,39 +852,41 @@ 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. - let constness = if !is_alias && tcx.has_attr(def_id, sym::const_trait) { + let constness = if !is_alias && find_attr!(attrs, AttributeKind::ConstTrait(_)) { hir::Constness::Const } else { hir::Constness::NotConst }; - let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar); + let paren_sugar = find_attr!(attrs, AttributeKind::ParenSugar(_)); 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 && tcx.has_attr(def_id, sym::marker); + let is_marker = !is_alias && find_attr!(attrs, AttributeKind::Marker(_)); - let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive); - let is_fundamental = tcx.has_attr(def_id, sym::fundamental); + let rustc_coinductive = find_attr!(attrs, AttributeKind::Coinductive(_)); + let is_fundamental = find_attr!(attrs, AttributeKind::Fundamental); let [skip_array_during_method_dispatch, skip_boxed_slice_during_method_dispatch] = find_attr!( - tcx.get_all_attrs(def_id), - AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span:_ } => [*array, *boxed_slice] + attrs, + AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: _ } => [*array, *boxed_slice] ) .unwrap_or([false; 2]); - let specialization_kind = if tcx.has_attr(def_id, sym::rustc_unsafe_specialization_marker) { + let specialization_kind = if find_attr!(attrs, AttributeKind::UnsafeSpecializationMarker(_)) { ty::trait_def::TraitSpecializationKind::Marker - } else if tcx.has_attr(def_id, sym::rustc_specialization_trait) { + } else if find_attr!(attrs, AttributeKind::SpecializationTrait(_)) { ty::trait_def::TraitSpecializationKind::AlwaysApplicable } else { ty::trait_def::TraitSpecializationKind::None }; - let must_implement_one_of = tcx - .get_attr(def_id, sym::rustc_must_implement_one_of) + let must_implement_one_of = attrs + .iter() + .find(|attr| attr.has_name(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() { @@ -958,8 +960,8 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { no_dups.then_some(list) }); - 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); + let deny_explicit_impl = find_attr!(attrs, AttributeKind::DenyExplicitImpl(_)); + let implement_via_object = !find_attr!(attrs, AttributeKind::DoNotImplementViaObject(_)); ty::TraitDef { def_id: def_id.to_def_id(), diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 291707878a342..84710e5e636e0 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -4,6 +4,7 @@ use rustc_abi::ExternAbi; use rustc_ast::visit::{VisitorResult, walk_list}; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::svh::Svh; @@ -15,7 +16,7 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::*; use rustc_hir_pretty as pprust_hir; use rustc_span::def_id::StableCrateId; -use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym, with_metavar_spans}; +use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, with_metavar_spans}; use crate::hir::{ModuleItems, nested_filter}; use crate::middle::debugger_visualizer::DebuggerVisualizerFile; @@ -369,7 +370,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn hir_rustc_coherence_is_core(self) -> bool { - self.hir_krate_attrs().iter().any(|attr| attr.has_name(sym::rustc_coherence_is_core)) + find_attr!(self.hir_krate_attrs(), AttributeKind::CoherenceIsCore) } pub fn hir_get_module(self, module: LocalModDefId) -> (&'tcx Mod<'tcx>, Span, HirId) { diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index d0dbf64dc5959..0d2e23609ce35 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -1,6 +1,5 @@ use std::sync::OnceLock; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph; use rustc_data_structures::graph::dominators::{Dominators, dominators}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -10,7 +9,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use smallvec::SmallVec; use crate::mir::traversal::Postorder; -use crate::mir::{BasicBlock, BasicBlockData, START_BLOCK, Terminator, TerminatorKind}; +use crate::mir::{BasicBlock, BasicBlockData, START_BLOCK}; #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)] pub struct BasicBlocks<'tcx> { @@ -21,15 +20,6 @@ pub struct BasicBlocks<'tcx> { // Typically 95%+ of basic blocks have 4 or fewer predecessors. type Predecessors = IndexVec>; -/// Each `(target, switch)` entry in the map contains a list of switch values -/// that lead to a `target` block from a `switch` block. -/// -/// Note: this type is currently never instantiated, because it's only used for -/// `BasicBlocks::switch_sources`, which is only called by backwards analyses -/// that do `SwitchInt` handling, and we don't have any of those, not even in -/// tests. See #95120 and #94576. -type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[SwitchTargetValue; 1]>>; - #[derive(Debug, Clone, Copy)] pub enum SwitchTargetValue { // A normal switch value. @@ -41,7 +31,6 @@ pub enum SwitchTargetValue { #[derive(Clone, Default, Debug)] struct Cache { predecessors: OnceLock, - switch_sources: OnceLock, reverse_postorder: OnceLock>, dominators: OnceLock>, } @@ -86,33 +75,6 @@ impl<'tcx> BasicBlocks<'tcx> { }) } - /// Returns info about switch values that lead from one block to another - /// block. See `SwitchSources`. - #[inline] - pub fn switch_sources(&self) -> &SwitchSources { - self.cache.switch_sources.get_or_init(|| { - let mut switch_sources: SwitchSources = FxHashMap::default(); - for (bb, data) in self.basic_blocks.iter_enumerated() { - if let Some(Terminator { - kind: TerminatorKind::SwitchInt { targets, .. }, .. - }) = &data.terminator - { - for (value, target) in targets.iter() { - switch_sources - .entry((target, bb)) - .or_default() - .push(SwitchTargetValue::Normal(value)); - } - switch_sources - .entry((targets.otherwise(), bb)) - .or_default() - .push(SwitchTargetValue::Otherwise); - } - } - switch_sources - }) - } - /// Returns mutable reference to basic blocks. Invalidates CFG cache. #[inline] pub fn as_mut(&mut self) -> &mut IndexVec> { diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 44165b06f1c33..275458fc85f8d 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -17,7 +17,6 @@ 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}; @@ -296,7 +295,7 @@ impl AdtDefData { flags |= AdtFlags::HAS_CTOR; } - if tcx.has_attr(did, sym::fundamental) { + if find_attr!(tcx.get_all_attrs(did), AttributeKind::Fundamental) { flags |= AdtFlags::IS_FUNDAMENTAL; } if tcx.is_lang_item(did, LangItem::PhantomData) { diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 78b2e265b488c..344a81f5e24d1 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -1,9 +1,10 @@ +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::sorted_map::SortedIndexMultiMap; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def_id::DefId; use rustc_macros::{Decodable, Encodable, HashStable}; -use rustc_span::{Ident, Symbol, sym}; +use rustc_span::{Ident, Symbol}; use super::{TyCtxt, Visibility}; use crate::ty; @@ -160,7 +161,7 @@ impl AssocItem { // Inherent impl but this attr is only applied to trait assoc items. (AssocItemContainer::Impl, None) => return true, }; - tcx.has_attr(def_id, sym::type_const) + find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) } } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 21b7500e46fe0..d5767ca3786e8 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -991,18 +991,16 @@ fn needs_fn_once_adapter_shim( Ok(false) } (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) => { - // The closure fn `llfn` is a `fn(&self, ...)`. We want a - // `fn(&mut self, ...)`. In fact, at codegen time, these are - // basically the same thing, so we can just return llfn. + // The closure fn is a `fn(&self, ...)`, but we want a `fn(&mut self, ...)`. + // At codegen time, these are basically the same, so we can just return the closure. Ok(false) } (ty::ClosureKind::Fn | ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => { - // The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut - // self, ...)`. We want a `fn(self, ...)`. We can produce - // this by doing something like: + // The closure fn is a `fn(&self, ...)` or `fn(&mut self, ...)`, but + // we want a `fn(self, ...)`. We can produce this by doing something like: // - // fn call_once(self, ...) { call_mut(&self, ...) } - // fn call_once(mut self, ...) { call_mut(&mut self, ...) } + // fn call_once(self, ...) { Fn::call(&self, ...) } + // fn call_once(mut self, ...) { FnMut::call_mut(&mut self, ...) } // // These are both the same at codegen time. Ok(true) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index b780b1c5776bc..0177a95498bcd 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1782,21 +1782,18 @@ impl<'tcx> TyCtxt<'tcx> { did: impl Into, attr: Symbol, ) -> impl Iterator { - self.get_all_attrs(did).filter(move |a: &&hir::Attribute| a.has_name(attr)) + self.get_all_attrs(did).iter().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_attr_data_structures::find_attr!`] so you can use matching. - pub fn get_all_attrs( - self, - did: impl Into, - ) -> impl Iterator { + pub fn get_all_attrs(self, did: impl Into) -> &'tcx [hir::Attribute] { let did: DefId = did.into(); if let Some(did) = did.as_local() { - self.hir_attrs(self.local_def_id_to_hir_id(did)).iter() + self.hir_attrs(self.local_def_id_to_hir_id(did)) } else { - self.attrs_for_def(did).iter() + self.attrs_for_def(did) } } diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index cb647476db8f3..79c0db7d72831 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -1,5 +1,6 @@ use std::ops::RangeInclusive; +use rustc_middle::bug; use rustc_middle::mir::{ self, BasicBlock, CallReturnPlaces, Location, SwitchTargetValue, TerminatorEdges, }; @@ -112,15 +113,11 @@ impl Direction for Backward { propagate(pred, &tmp); } - mir::TerminatorKind::SwitchInt { ref targets, ref discr } => { - if let Some(mut data) = analysis.get_switch_int_data(block, discr) { - let mut tmp = analysis.bottom_value(body); - for &value in &body.basic_blocks.switch_sources()[&(block, pred)] { - tmp.clone_from(exit_state); - analysis - .apply_switch_int_edge_effect(&mut data, &mut tmp, value, targets); - propagate(pred, &tmp); - } + mir::TerminatorKind::SwitchInt { ref discr, .. } => { + if let Some(_data) = analysis.get_switch_int_data(pred, discr) { + bug!( + "SwitchInt edge effects are unsupported in backward dataflow analyses" + ); } else { propagate(pred, exit_state) } diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 11424ec3724bf..bb5c1e0e653a7 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -283,6 +283,18 @@ pub fn check_builtin_meta_item( | sym::rustc_confusables | sym::rustc_skip_during_method_dispatch | sym::rustc_pass_by_value + | sym::rustc_deny_explicit_impl + | sym::rustc_do_not_implement_via_object + | sym::rustc_coinductive + | sym::const_trait + | sym::rustc_specialization_trait + | sym::rustc_unsafe_specialization_marker + | sym::rustc_allow_incoherent_impl + | sym::rustc_coherence_is_core + | sym::marker + | sym::fundamental + | sym::rustc_paren_sugar + | sym::type_const | sym::repr | sym::align | sym::deprecated diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 0aa6a2b41cfb6..2c95fead9e801 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -120,12 +120,35 @@ impl<'tcx> CheckAttrVisitor<'tcx> { for attr in attrs { let mut style = None; match attr { - Attribute::Parsed(AttributeKind::SkipDuringMethodDispatch { - span: attr_span, - .. - }) => { + Attribute::Parsed( + AttributeKind::SkipDuringMethodDispatch { span: attr_span, .. } + | AttributeKind::Coinductive(attr_span) + | AttributeKind::ConstTrait(attr_span) + | AttributeKind::DenyExplicitImpl(attr_span) + | AttributeKind::DoNotImplementViaObject(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); } @@ -259,7 +282,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::no_sanitize, ..] => { self.check_no_sanitize(attr, span, target) } - [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, @@ -297,16 +319,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | [sym::rustc_dirty, ..] | [sym::rustc_if_this_changed, ..] | [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr), - [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::rustc_must_implement_one_of, ..] => 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_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) } @@ -339,9 +354,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [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), [ // ok @@ -366,7 +378,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::prelude_import | sym::panic_handler | sym::allow_internal_unsafe - | sym::fundamental | sym::lang | sym::needs_allocator | sym::default_lib_allocator @@ -830,7 +841,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } /// Checks if the `#[marker]` attribute on an `item` is valid. - fn check_marker(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { + fn check_marker(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) { match target { Target::Trait => {} // FIXME(#80564): We permit struct fields, match arms and macro defs to have an @@ -838,13 +849,11 @@ 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(), "marker"); + self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "marker"); } _ => { - self.dcx().emit_err(errors::AttrShouldBeAppliedToTrait { - attr_span: attr.span(), - defn_span: span, - }); + self.dcx() + .emit_err(errors::AttrShouldBeAppliedToTrait { attr_span, defn_span: span }); } } } @@ -1489,11 +1498,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_allow_incoherent_impl(&self, attr: &Attribute, span: Span, target: Target) { + fn check_allow_incoherent_impl(&self, attr_span: Span, span: Span, target: Target) { match target { Target::Method(MethodKind::Inherent) => {} _ => { - self.dcx().emit_err(errors::AllowIncoherentImpl { attr_span: attr.span(), span }); + self.dcx().emit_err(errors::AllowIncoherentImpl { attr_span, span }); } } } @@ -2514,7 +2523,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_type_const(&self, hir_id: HirId, attr: &Attribute, target: Target) { + fn check_type_const(&self, hir_id: HirId, attr_span: Span, target: Target) { let tcx = self.tcx; if target == Target::AssocConst && let parent = tcx.parent(hir_id.expect_owner().to_def_id()) @@ -2524,7 +2533,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } else { self.dcx() .struct_span_err( - attr.span(), + attr_span, "`#[type_const]` must only be applied to trait associated constants", ) .emit(); diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index b7f4656fa3701..cce88d936b71b 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -11,7 +11,7 @@ //! This is because `sys_common` not only contains platform-independent code, //! but also code that is shared between the different platforms in `sys`. //! Ideally all that shared code should be moved to `sys::common`, -//! and the dependencies between `std`, `sys_common` and `sys` all would form a dag. +//! and the dependencies between `std`, `sys_common` and `sys` all would form a DAG. //! Progress on this is tracked in #84187. #![allow(missing_docs)] diff --git a/src/build_helper/src/ci.rs b/src/build_helper/src/ci.rs index 9d114c70a671b..b5e70eb84cc6c 100644 --- a/src/build_helper/src/ci.rs +++ b/src/build_helper/src/ci.rs @@ -9,7 +9,7 @@ pub enum CiEnv { impl CiEnv { /// Obtains the current CI environment. pub fn current() -> CiEnv { - if std::env::var("GITHUB_ACTIONS").map_or(false, |e| e == "true") { + if std::env::var("GITHUB_ACTIONS").is_ok_and(|e| e == "true") { CiEnv::GitHubActions } else { CiEnv::None diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index 9d1195aadf848..cbefb836c0044 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -13,7 +13,7 @@ pub struct GitConfig<'a> { pub fn output_result(cmd: &mut Command) -> Result { let output = match cmd.stderr(Stdio::inherit()).output() { Ok(status) => status, - Err(e) => return Err(format!("failed to run command: {:?}: {}", cmd, e)), + Err(e) => return Err(format!("failed to run command: {cmd:?}: {e}")), }; if !output.status.success() { return Err(format!( @@ -62,22 +62,22 @@ pub enum PathFreshness { /// The function behaves differently in CI and outside CI. /// /// - Outside CI, we want to find out if `target_paths` were modified in some local commit on -/// top of the latest upstream commit that is available in local git history. -/// If not, we try to find the most recent upstream commit (which we assume are commits -/// made by bors) that modified `target_paths`. -/// We don't want to simply take the latest master commit to avoid changing the output of -/// this function frequently after rebasing on the latest master branch even if `target_paths` -/// were not modified upstream in the meantime. In that case we would be redownloading CI -/// artifacts unnecessarily. +/// top of the latest upstream commit that is available in local git history. +/// If not, we try to find the most recent upstream commit (which we assume are commits +/// made by bors) that modified `target_paths`. +/// We don't want to simply take the latest master commit to avoid changing the output of +/// this function frequently after rebasing on the latest master branch even if `target_paths` +/// were not modified upstream in the meantime. In that case we would be redownloading CI +/// artifacts unnecessarily. /// /// - In CI, we use a shallow clone of depth 2, i.e., we fetch only a single parent commit -/// (which will be the most recent bors merge commit) and do not have access -/// to the full git history. Luckily, we only need to distinguish between two situations: -/// 1) The current PR made modifications to `target_paths`. -/// In that case, a build is typically necessary. -/// 2) The current PR did not make modifications to `target_paths`. -/// In that case we simply take the latest upstream commit, because on CI there is no need to avoid -/// redownloading. +/// (which will be the most recent bors merge commit) and do not have access +/// to the full git history. Luckily, we only need to distinguish between two situations: +/// 1) The current PR made modifications to `target_paths`. +/// In that case, a build is typically necessary. +/// 2) The current PR did not make modifications to `target_paths`. +/// In that case we simply take the latest upstream commit, because on CI there is no need to avoid +/// redownloading. pub fn check_path_modifications( git_dir: &Path, config: &GitConfig<'_>, @@ -232,7 +232,7 @@ pub fn get_closest_upstream_commit( "--author-date-order", &format!("--author={}", config.git_merge_commit_email), "-n1", - &base, + base, ]); let output = output_result(&mut git)?.trim().to_owned(); diff --git a/src/build_helper/src/metrics.rs b/src/build_helper/src/metrics.rs index 8b82e62a32770..07157e364158d 100644 --- a/src/build_helper/src/metrics.rs +++ b/src/build_helper/src/metrics.rs @@ -141,7 +141,7 @@ impl BuildStep { } => { let full_name = format!("{parent_name}-{kind}"); let children: Vec<_> = - children.into_iter().filter_map(|s| parse(s, &full_name)).collect(); + children.iter().filter_map(|s| parse(s, &full_name)).collect(); let children_duration = children.iter().map(|c| c.duration).sum::(); Some(BuildStep { r#type: kind.to_string(), diff --git a/src/build_helper/src/util.rs b/src/build_helper/src/util.rs index 80dd6813d136e..a8355f774e9d1 100644 --- a/src/build_helper/src/util.rs +++ b/src/build_helper/src/util.rs @@ -18,29 +18,28 @@ macro_rules! exit { pub fn detail_exit(code: i32, is_test: bool) -> ! { // if in test and code is an error code, panic with status code provided if is_test { - panic!("status code: {}", code); + panic!("status code: {code}"); } else { - // otherwise,exit with provided status code + // otherwise, exit with provided status code std::process::exit(code); } } pub fn fail(s: &str) -> ! { - eprintln!("\n\n{}\n\n", s); + eprintln!("\n\n{s}\n\n"); detail_exit(1, cfg!(test)); } pub fn try_run(cmd: &mut Command, print_cmd_on_fail: bool) -> Result<(), ()> { let status = match cmd.status() { Ok(status) => status, - Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), + Err(e) => fail(&format!("failed to execute command: {cmd:?}\nerror: {e}")), }; if !status.success() { if print_cmd_on_fail { println!( - "\n\ncommand did not execute successfully: {:?}\n\ - expected success, got: {}\n\n", - cmd, status + "\n\ncommand did not execute successfully: {cmd:?}\n\ + expected success, got: {status}\n\n" ); } Err(()) @@ -60,7 +59,7 @@ pub fn parse_gitmodules(target_dir: &Path) -> Vec { for line in BufReader::new(file).lines().map_while(Result::ok) { let line = line.trim(); if line.starts_with("path") { - let actual_path = line.split(' ').last().expect("Couldn't get value of path"); + let actual_path = line.split(' ').next_back().expect("Couldn't get value of path"); submodules_paths.push(actual_path.to_owned()); } } diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index e1742631f63cc..7c688e32bc0dd 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -46,6 +46,7 @@ - [\*-apple-watchos](platform-support/apple-watchos.md) - [\*-apple-visionos](platform-support/apple-visionos.md) - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md) + - [aarch64-unknown-linux-musl](platform-support/aarch64-unknown-linux-musl.md) - [amdgcn-amd-amdhsa](platform-support/amdgcn-amd-amdhsa.md) - [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md) - [arm-none-eabi](platform-support/arm-none-eabi.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index ed01de4c1c300..65b7063015388 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -90,7 +90,7 @@ target | notes -------|------- [`aarch64-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | ARM64 MinGW (Windows 10+), LLVM ABI [`aarch64-pc-windows-msvc`](platform-support/windows-msvc.md) | ARM64 Windows MSVC -`aarch64-unknown-linux-musl` | ARM64 Linux with musl 1.2.3 +[`aarch64-unknown-linux-musl`](platform-support/aarch64-unknown-linux-musl.md) | ARM64 Linux with musl 1.2.3 [`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ARM64 OpenHarmony `arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2+, glibc 2.17) `arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2+, glibc 2.17) diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-linux-musl.md b/src/doc/rustc/src/platform-support/aarch64-unknown-linux-musl.md new file mode 100644 index 0000000000000..5d9a552e4603f --- /dev/null +++ b/src/doc/rustc/src/platform-support/aarch64-unknown-linux-musl.md @@ -0,0 +1,49 @@ +# aarch64-unknown-linux-musl + +**Tier: 2** + +Target for 64-bit little endian ARMv8-A Linux programs using musl libc. + +## Target maintainers + +[@Gelbpunkt](https://github.com/Gelbpunkt) +[@famfo](https://github.com/famfo) + +## Requirements + +Building the target itself requires a 64-bit little endian ARMv8-A compiler +that is supported by `cc-rs`. + +## Building the target + +The target can be built by enabling it for a `rustc` build. + +```toml +[build] +target = ["aarch64-unknown-linux-musl"] +``` + +Make sure your C compiler is included in `$PATH`, then add it to the +`bootstrap.toml`: + +```toml +[target.aarch64-unknown-linux-musl] +cc = "aarch64-linux-musl-gcc" +cxx = "aarch64-linux-musl-g++" +ar = "aarch64-linux-musl-ar" +linker = "aarch64-linux-musl-gcc" +``` + +## Building Rust programs + +This target is distributed through `rustup`, and otherwise requires no +special configuration. + +## Cross-compilation + +This target can be cross-compiled from any host. + +## Testing + +This target can be tested as normal with `x.py` on a 64-bit little endian +ARMv8-A host or via QEMU emulation. diff --git a/src/tools/x/Cargo.toml b/src/tools/x/Cargo.toml index 84a42ca36ef1c..c59f5ff52a0f5 100644 --- a/src/tools/x/Cargo.toml +++ b/src/tools/x/Cargo.toml @@ -2,5 +2,5 @@ name = "x" version = "0.1.1" description = "Run x.py slightly more conveniently" -edition = "2021" +edition = "2024" publish = false diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs index b288cfcd5be9c..93167141d34dd 100644 --- a/src/tools/x/src/main.rs +++ b/src/tools/x/src/main.rs @@ -19,15 +19,14 @@ const PYTHON2: &str = "python2"; const PYTHON3: &str = "python3"; fn python() -> &'static str { - let val = match env::var_os("PATH") { - Some(val) => val, - None => return PYTHON, + let Some(path) = env::var_os("PATH") else { + return PYTHON; }; let mut python2 = false; let mut python3 = false; - for dir in env::split_paths(&val) { + for dir in env::split_paths(&path) { // `python` should always take precedence over python2 / python3 if it exists if dir.join(PYTHON).with_extension(EXE_EXTENSION).exists() { return PYTHON; @@ -89,7 +88,7 @@ fn exec_or_status(command: &mut Command) -> io::Result { fn handle_result(result: io::Result, cmd: Command) { match result { Err(error) => { - eprintln!("Failed to invoke `{:?}`: {}", cmd, error); + eprintln!("Failed to invoke `{cmd:?}`: {error}"); } Ok(status) => { process::exit(status.code().unwrap_or(1)); @@ -98,14 +97,12 @@ fn handle_result(result: io::Result, cmd: Command) { } fn main() { - match env::args().skip(1).next().as_deref() { - Some("--wrapper-version") => { - let version = env!("CARGO_PKG_VERSION"); - println!("{}", version); - return; - } - _ => {} + if env::args().nth(1).is_some_and(|s| s == "--wrapper-version") { + let version = env!("CARGO_PKG_VERSION"); + println!("{version}"); + return; } + let current = match env::current_dir() { Ok(dir) => dir, Err(err) => { @@ -113,7 +110,6 @@ fn main() { process::exit(1); } }; - for dir in current.ancestors() { let candidate = dir.join("x.py"); if candidate.exists() { diff --git a/tests/rustdoc-json/attrs/target_feature.rs b/tests/rustdoc-json/attrs/target_feature.rs index 80262d8e33257..5c8aeb84ee3cc 100644 --- a/tests/rustdoc-json/attrs/target_feature.rs +++ b/tests/rustdoc-json/attrs/target_feature.rs @@ -6,17 +6,17 @@ pub fn test1() {} //@ is "$.index[?(@.name=='test2')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]' -//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false +//@ is "$.index[?(@.name=='test2')].inner.function.header.is_unsafe" false #[target_feature(enable = "avx,avx2")] pub fn test2() {} //@ is "$.index[?(@.name=='test3')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]' -//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false +//@ is "$.index[?(@.name=='test3')].inner.function.header.is_unsafe" false #[target_feature(enable = "avx", enable = "avx2")] pub fn test3() {} //@ is "$.index[?(@.name=='test4')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\", enable=\"avx512f\")]"]' -//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false +//@ is "$.index[?(@.name=='test4')].inner.function.header.is_unsafe" false #[target_feature(enable = "avx", enable = "avx2,avx512f")] pub fn test4() {} diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 5bcb0c4dc0a4c..be529df3a4953 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -116,24 +116,6 @@ error: malformed `cfi_encoding` attribute input LL | #[cfi_encoding] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` -error: malformed `type_const` attribute input - --> $DIR/malformed-attrs.rs:143:5 - | -LL | #[type_const = 1] - | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]` - -error: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:155:1 - | -LL | #[marker = 3] - | ^^^^^^^^^^^^^ help: must be of the form: `#[marker]` - -error: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:157:1 - | -LL | #[fundamental()] - | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[fundamental]` - error: malformed `link_ordinal` attribute input --> $DIR/malformed-attrs.rs:167:5 | @@ -528,6 +510,24 @@ LL | #[rustc_layout_scalar_valid_range_end] | expected this to be a list | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` +error[E0565]: malformed `marker` attribute input + --> $DIR/malformed-attrs.rs:155:1 + | +LL | #[marker = 3] + | ^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[marker]` + +error[E0565]: malformed `fundamental` attribute input + --> $DIR/malformed-attrs.rs:157:1 + | +LL | #[fundamental()] + | ^^^^^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[fundamental]` + error[E0565]: malformed `ffi_pure` attribute input --> $DIR/malformed-attrs.rs:165:5 | @@ -555,6 +555,15 @@ LL | #[non_exhaustive = 1] | | didn't expect any arguments here | help: must be of the form: `#[non_exhaustive]` +error[E0565]: malformed `type_const` attribute input + --> $DIR/malformed-attrs.rs:143:5 + | +LL | #[type_const = 1] + | ^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[type_const]` + error: attribute should be applied to `const fn` --> $DIR/malformed-attrs.rs:34:1 | diff --git a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr index 579aff849d6e6..125c778ef1cd3 100644 --- a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr +++ b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr @@ -1,9 +1,3 @@ -error: malformed `type_const` attribute input - --> $DIR/bad-type_const-syntax.rs:2:5 - | -LL | #[type_const()] - | ^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]` - error[E0658]: the `#[type_const]` attribute is an experimental feature --> $DIR/bad-type_const-syntax.rs:2:5 | @@ -24,6 +18,15 @@ LL | #[type_const] = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error[E0565]: malformed `type_const` attribute input + --> $DIR/bad-type_const-syntax.rs:2:5 + | +LL | #[type_const()] + | ^^^^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[type_const]` + error: `#[type_const]` must only be applied to trait associated constants --> $DIR/bad-type_const-syntax.rs:11:5 | @@ -32,4 +35,5 @@ LL | #[type_const] error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0565, E0658. +For more information about an error, try `rustc --explain E0565`. diff --git a/tests/ui/marker_trait_attr/marker-attribute-with-values.stderr b/tests/ui/marker_trait_attr/marker-attribute-with-values.stderr index 6f9c9508e7e55..9a2e5add37b35 100644 --- a/tests/ui/marker_trait_attr/marker-attribute-with-values.stderr +++ b/tests/ui/marker_trait_attr/marker-attribute-with-values.stderr @@ -1,20 +1,30 @@ -error: malformed `marker` attribute input +error[E0565]: malformed `marker` attribute input --> $DIR/marker-attribute-with-values.rs:3:1 | LL | #[marker(always)] - | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]` + | ^^^^^^^^--------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[marker]` -error: malformed `marker` attribute input +error[E0565]: malformed `marker` attribute input --> $DIR/marker-attribute-with-values.rs:6:1 | LL | #[marker("never")] - | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]` + | ^^^^^^^^---------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[marker]` -error: malformed `marker` attribute input +error[E0565]: malformed `marker` attribute input --> $DIR/marker-attribute-with-values.rs:9:1 | LL | #[marker(key = "value")] - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[marker]` + | ^^^^^^^^---------------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[marker]` error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0565`.