Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
9637774
ci: Begin running ui tests with `rust.debuginfo-level-tests=1`
Enselic Jul 26, 2025
825bb13
Enable LLVM tools for gnullvm dist
mati865 Aug 23, 2025
577e181
Enable LLVM download from CI for gnullvm dist
mati865 Aug 23, 2025
a8e9ca1
Use attribute name in message for "outer attr used as inner attr" errors
scrabsha Aug 23, 2025
6912064
rustc_codegen_ssa: Fix comment
a4lg Aug 25, 2025
cb8c905
rustc_codegen_ssa: More comprehensive RISC-V ELF flags
a4lg Aug 25, 2025
d66ca53
add a flag to codegen fn attrs for foreign items
jdonszelmann Aug 25, 2025
24b1fbe
platform-support: Fix LoongArch32 host column
heiher Aug 26, 2025
5ce678a
bootstrap: error early if any `codegen-backends` is set to `[]`
GuillaumeGomez Aug 26, 2025
2261968
bootstrap: Make `default_codegen_backend` return `&CodegenBackendKind…
GuillaumeGomez Aug 26, 2025
5cf9c13
Enable building/disting standard library in stage 0
Kobzol Aug 26, 2025
45296bb
Fix typo in comment
stoeckmann Aug 26, 2025
a4924f0
Rollup merge of #144499 - Enselic:ci-debuginfo-level-tests, r=davidtwco
samueltardieu Aug 26, 2025
87ab2c8
Rollup merge of #145790 - mati865:gnullvm-improve-dist, r=Kobzol
samueltardieu Aug 26, 2025
fbf247d
Rollup merge of #145792 - scrabsha:push-umpytyxunpxq, r=jdonszelmann
samueltardieu Aug 26, 2025
ac7f423
Rollup merge of #145840 - a4lg:riscv-elf-flags-for-internal-objs, r=W…
samueltardieu Aug 26, 2025
5ba3bfc
Rollup merge of #145876 - Kobzol:dist-std-build, r=jieyouxu
samueltardieu Aug 26, 2025
e84b354
Rollup merge of #145887 - GuillaumeGomez:bootstrap-codegen-backends, …
samueltardieu Aug 26, 2025
e005978
Rollup merge of #145888 - heiher:fix-platform-support-loong32, r=jiey…
samueltardieu Aug 26, 2025
fe5890e
Rollup merge of #145892 - jdonszelmann:codegen-fn-attrs-foreign-item,…
samueltardieu Aug 26, 2025
cefa84a
Rollup merge of #145901 - stoeckmann:raw_vec_typo, r=samueltardieu
samueltardieu Aug 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/rustc_attr_parsing/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ attr_parsing_invalid_repr_hint_no_value =
attr_parsing_invalid_since =
'since' must be a Rust version number, such as "1.31.0"
attr_parsing_invalid_style = {$is_used_as_inner ->
[false] crate-level attribute should be an inner attribute: add an exclamation mark: `#![{$name}]`
*[other] the `#![{$name}]` attribute can only be used at the crate root
}
.note = This attribute does not have an `!`, which means it is applied to this {$target}
attr_parsing_link_ordinal_out_of_range = ordinal value in `link_ordinal` is too large: `{$ordinal}`
.note = the value may not exceed `u16::MAX`
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/crate_level.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use rustc_feature::AttributeType;

use super::prelude::*;

pub(crate) struct CrateNameParser;
Expand All @@ -7,6 +9,7 @@ impl<S: Stage> SingleAttributeParser<S> for CrateNameParser {
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
const TYPE: AttributeType = AttributeType::CrateLevel;

// FIXME: crate name is allowed on all targets and ignored,
// even though it should only be valid on crates of course
Expand Down
17 changes: 16 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@
//! - [`CombineAttributeParser`](crate::attributes::CombineAttributeParser): makes it easy to implement an attribute which should combine the
//! contents of attributes, if an attribute appear multiple times in a list
//!
//! By default, attributes are allowed anywhere. When adding an attribute that should only be used
//! at the crate root, consider setting the `TYPE` in the parser trait to
//! [`AttributeType::CrateLevel`](rustc_feature::AttributeType::CrateLevel).
//!
//! Attributes should be added to `crate::context::ATTRIBUTE_PARSERS` to be parsed.
use std::marker::PhantomData;

use rustc_feature::{AttributeTemplate, template};
use rustc_feature::{AttributeTemplate, AttributeType, template};
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Span, Symbol};
use thin_vec::ThinVec;
Expand Down Expand Up @@ -88,6 +92,8 @@ pub(crate) trait AttributeParser<S: Stage>: Default + 'static {

const ALLOWED_TARGETS: AllowedTargets;

const TYPE: AttributeType = AttributeType::Normal;

/// The parser has gotten a chance to accept the attributes on an item,
/// here it can produce an attribute.
///
Expand Down Expand Up @@ -129,6 +135,8 @@ pub(crate) trait SingleAttributeParser<S: Stage>: 'static {
/// The template this attribute parser should implement. Used for diagnostics.
const TEMPLATE: AttributeTemplate;

const TYPE: AttributeType = AttributeType::Normal;

/// Converts a single syntactical attribute to a single semantic attribute, or [`AttributeKind`]
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind>;
}
Expand Down Expand Up @@ -175,6 +183,8 @@ impl<T: SingleAttributeParser<S>, S: Stage> AttributeParser<S> for Single<T, S>
)];
const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;

const TYPE: AttributeType = T::TYPE;

fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
Some(self.1?.0)
}
Expand Down Expand Up @@ -259,6 +269,7 @@ pub(crate) trait NoArgsAttributeParser<S: Stage>: 'static {
const PATH: &[Symbol];
const ON_DUPLICATE: OnDuplicate<S>;
const ALLOWED_TARGETS: AllowedTargets;
const TYPE: AttributeType = AttributeType::Normal;

/// Create the [`AttributeKind`] given attribute's [`Span`].
const CREATE: fn(Span) -> AttributeKind;
Expand All @@ -278,6 +289,7 @@ impl<T: NoArgsAttributeParser<S>, S: Stage> SingleAttributeParser<S> for Without
const ON_DUPLICATE: OnDuplicate<S> = T::ON_DUPLICATE;
const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;
const TEMPLATE: AttributeTemplate = template!(Word);
const TYPE: AttributeType = T::TYPE;

fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
if let Err(span) = args.no_args() {
Expand Down Expand Up @@ -311,6 +323,8 @@ pub(crate) trait CombineAttributeParser<S: Stage>: 'static {
/// The template this attribute parser should implement. Used for diagnostics.
const TEMPLATE: AttributeTemplate;

const TYPE: AttributeType = AttributeType::Normal;

/// Converts a single syntactical attribute to a number of elements of the semantic attribute, or [`AttributeKind`]
fn extend<'c>(
cx: &'c mut AcceptContext<'_, '_, S>,
Expand Down Expand Up @@ -346,6 +360,7 @@ impl<T: CombineAttributeParser<S>, S: Stage> AttributeParser<S> for Combine<T, S
group.items.extend(T::extend(cx, args))
})];
const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;
const TYPE: AttributeType = T::TYPE;

fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
if let Some(first_span) = self.first_span {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/traits.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::mem;

use rustc_feature::AttributeType;

use super::prelude::*;
use crate::attributes::{
AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
Expand Down Expand Up @@ -154,6 +156,7 @@ impl<S: Stage> NoArgsAttributeParser<S> for CoherenceIsCoreParser {
const PATH: &[Symbol] = &[sym::rustc_coherence_is_core];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const TYPE: AttributeType = AttributeType::CrateLevel;
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::CoherenceIsCore;
}

Expand Down
18 changes: 15 additions & 3 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use std::ops::{Deref, DerefMut};
use std::sync::LazyLock;

use private::Sealed;
use rustc_ast::{AttrStyle, MetaItemLit, NodeId};
use rustc_ast::{AttrStyle, CRATE_NODE_ID, MetaItemLit, NodeId};
use rustc_errors::{Diag, Diagnostic, Level};
use rustc_feature::AttributeTemplate;
use rustc_feature::{AttributeTemplate, AttributeType};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
use rustc_hir::{AttrPath, HirId};
use rustc_hir::{AttrPath, CRATE_HIR_ID, HirId};
use rustc_session::Session;
use rustc_span::{ErrorGuaranteed, Span, Symbol};

Expand Down Expand Up @@ -80,6 +80,7 @@ pub(super) struct GroupTypeInnerAccept<S: Stage> {
pub(super) template: AttributeTemplate,
pub(super) accept_fn: AcceptFn<S>,
pub(super) allowed_targets: AllowedTargets,
pub(super) attribute_type: AttributeType,
}

type AcceptFn<S> =
Expand Down Expand Up @@ -129,6 +130,7 @@ macro_rules! attribute_parsers {
})
}),
allowed_targets: <$names as crate::attributes::AttributeParser<$stage>>::ALLOWED_TARGETS,
attribute_type: <$names as crate::attributes::AttributeParser<$stage>>::TYPE,
});
}

Expand Down Expand Up @@ -250,6 +252,8 @@ pub trait Stage: Sized + 'static + Sealed {
) -> ErrorGuaranteed;

fn should_emit(&self) -> ShouldEmit;

fn id_is_crate_root(id: Self::Id) -> bool;
}

// allow because it's a sealed trait
Expand All @@ -271,6 +275,10 @@ impl Stage for Early {
fn should_emit(&self) -> ShouldEmit {
self.emit_errors
}

fn id_is_crate_root(id: Self::Id) -> bool {
id == CRATE_NODE_ID
}
}

// allow because it's a sealed trait
Expand All @@ -292,6 +300,10 @@ impl Stage for Late {
fn should_emit(&self) -> ShouldEmit {
ShouldEmit::ErrorsAndLints
}

fn id_is_crate_root(id: Self::Id) -> bool {
id == CRATE_HIR_ID
}
}

/// used when parsing attributes for miscellaneous things *before* ast lowering
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
};

(accept.accept_fn)(&mut cx, args);

if !matches!(self.stage.should_emit(), ShouldEmit::Nothing) {
if !matches!(cx.stage.should_emit(), ShouldEmit::Nothing) {
Self::check_type(accept.attribute_type, target, &mut cx);
self.check_target(
path.get_attribute_path(),
attr.span,
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_attr_parsing/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,19 @@ pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<L::Id>, lint_emi
attr_span: *span,
},
),

&AttributeLintKind::InvalidStyle { ref name, is_used_as_inner, target, target_span } => {
lint_emitter.emit_node_span_lint(
rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
*id,
*span,
session_diagnostics::InvalidAttrStyle {
name: name.clone(),
is_used_as_inner,
target_span: (!is_used_as_inner).then_some(target_span),
target,
},
)
}
}
}
12 changes: 11 additions & 1 deletion compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_errors::{
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
};
use rustc_feature::AttributeTemplate;
use rustc_hir::AttrPath;
use rustc_hir::{AttrPath, Target};
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_span::{Span, Symbol};

Expand Down Expand Up @@ -826,3 +826,13 @@ pub(crate) struct SuffixedLiteralInAttribute {
#[primary_span]
pub span: Span,
}

#[derive(LintDiagnostic)]
#[diag(attr_parsing_invalid_style)]
pub(crate) struct InvalidAttrStyle {
pub name: AttrPath,
pub is_used_as_inner: bool,
#[note]
pub target_span: Option<Span>,
pub target: Target,
}
33 changes: 30 additions & 3 deletions compiler/rustc_attr_parsing/src/target_checking.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use std::borrow::Cow;

use rustc_ast::AttrStyle;
use rustc_errors::DiagArgValue;
use rustc_feature::Features;
use rustc_feature::{AttributeType, Features};
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
use rustc_hir::{AttrPath, MethodKind, Target};
use rustc_span::Span;

use crate::AttributeParser;
use crate::context::Stage;
use crate::context::{AcceptContext, Stage};
use crate::session_diagnostics::InvalidTarget;

#[derive(Debug)]
Expand Down Expand Up @@ -68,7 +69,7 @@ pub(crate) enum Policy {
Error(Target),
}

impl<S: Stage> AttributeParser<'_, S> {
impl<'sess, S: Stage> AttributeParser<'sess, S> {
pub(crate) fn check_target(
&self,
attr_name: AttrPath,
Expand Down Expand Up @@ -111,6 +112,32 @@ impl<S: Stage> AttributeParser<'_, S> {
}
}
}

pub(crate) fn check_type(
attribute_type: AttributeType,
target: Target,
cx: &mut AcceptContext<'_, 'sess, S>,
) {
let is_crate_root = S::id_is_crate_root(cx.target_id);

if is_crate_root {
return;
}

if attribute_type != AttributeType::CrateLevel {
return;
}

let lint = AttributeLintKind::InvalidStyle {
name: cx.attr_path.clone(),
is_used_as_inner: cx.attr_style == AttrStyle::Inner,
target,
target_span: cx.target_span,
};
let attr_span = cx.attr_span;

cx.emit_lint(lint, attr_span);
}
}

/// Takes a list of `allowed_targets` for an attribute, and the `target` the attribute was applied to.
Expand Down
12 changes: 9 additions & 3 deletions compiler/rustc_codegen_ssa/src/back/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,12 +329,18 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
// Source: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/079772828bd10933d34121117a222b4cc0ee2200/riscv-elf.adoc
let mut e_flags: u32 = 0x0;

// Check if compressed is enabled
// `unstable_target_features` is used here because "c" is gated behind riscv_target_feature.
if sess.unstable_target_features.contains(&sym::c) {
// Check if compression is enabled
// `unstable_target_features` is used here because "zca" is gated behind riscv_target_feature.
if sess.unstable_target_features.contains(&sym::zca) {
e_flags |= elf::EF_RISCV_RVC;
}

// Check if RVTSO is enabled
// `unstable_target_features` is used here because "ztso" is gated behind riscv_target_feature.
if sess.unstable_target_features.contains(&sym::ztso) {
e_flags |= elf::EF_RISCV_TSO;
}

// Set the appropriate flag based on ABI
// This needs to match LLVM `RISCVELFStreamer.cpp`
match &*sess.target.llvm_abiname {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel
// core/std/allocators/etc. For example symbols used to hook up allocation
// are not considered for export
let codegen_fn_attrs = tcx.codegen_fn_attrs(sym_def_id);
let is_extern = codegen_fn_attrs.contains_extern_indicator(tcx, sym_def_id);
let is_extern = codegen_fn_attrs.contains_extern_indicator();
let std_internal =
codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,8 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code

// Foreign items by default use no mangling for their symbol name.
if tcx.is_foreign_item(did) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::FOREIGN_ITEM;

// There's a few exceptions to this rule though:
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
// * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ pub enum AttributeLintKind {
IllFormedAttributeInput { suggestions: Vec<String> },
EmptyAttribute { first_span: Span },
InvalidTarget { name: AttrPath, target: Target, applied: Vec<String>, only: &'static str },
InvalidStyle { name: AttrPath, is_used_as_inner: bool, target: Target, target_span: Span },
}
7 changes: 4 additions & 3 deletions compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use std::borrow::Cow;

use rustc_abi::Align;
use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, Linkage, OptimizeAttr};
use rustc_hir::def_id::DefId;
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
use rustc_span::Symbol;
use rustc_target::spec::SanitizerSet;
Expand Down Expand Up @@ -161,6 +160,8 @@ bitflags::bitflags! {
const ALLOCATOR_ZEROED = 1 << 14;
/// `#[no_builtins]`: indicates that disable implicit builtin knowledge of functions for the function.
const NO_BUILTINS = 1 << 15;
/// Marks foreign items, to make `contains_extern_indicator` cheaper.
const FOREIGN_ITEM = 1 << 16;
}
}
rustc_data_structures::external_bitflags_debug! { CodegenFnAttrFlags }
Expand Down Expand Up @@ -194,8 +195,8 @@ impl CodegenFnAttrs {
/// * `#[linkage]` is present
///
/// Keep this in sync with the logic for the unused_attributes for `#[inline]` lint.
pub fn contains_extern_indicator(&self, tcx: TyCtxt<'_>, did: DefId) -> bool {
if tcx.is_foreign_item(did) {
pub fn contains_extern_indicator(&self) -> bool {
if self.flags.contains(CodegenFnAttrFlags::FOREIGN_ITEM) {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl<'tcx> MonoItem<'tcx> {
// instantiation:
// We emit an unused_attributes lint for this case, which should be kept in sync if possible.
let codegen_fn_attrs = tcx.codegen_instance_attrs(instance.def);
if codegen_fn_attrs.contains_extern_indicator(tcx, instance.def.def_id())
if codegen_fn_attrs.contains_extern_indicator()
|| codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED)
{
return InstantiationMode::GloballyShared { may_conflict: false };
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/cross_crate_inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id);
// If this has an extern indicator, then this function is globally shared and thus will not
// generate cgu-internal copies which would make it cross-crate inlinable.
if codegen_fn_attrs.contains_extern_indicator(tcx, def_id.into()) {
if codegen_fn_attrs.contains_extern_indicator() {
return false;
}

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,10 @@ passes_object_lifetime_err =
{$repr}
passes_outer_crate_level_attr =
crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
crate-level attribute should be an inner attribute
passes_outer_crate_level_attr_suggestion =
add a `!`
passes_panic_unwind_without_std =
unwinding panics are not supported without std
Expand Down
Loading
Loading