Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d8cc575
std_detect Darwin AArch64: add new-style detection for FEAT_CRC32
pthariensflame Sep 10, 2025
edc87e3
std_detect Darwin AArch64: re-alphabetize
pthariensflame Sep 14, 2025
d49f6a7
std_detect Darwin AArch64: synchronize features
pthariensflame Sep 14, 2025
3847786
bootstrap: Don't force -static for musl targets in cc-rs
Gelbpunkt Sep 15, 2025
f4b8768
Support ctr and lr as clobber-only registers in PowerPC inline assembly
taiki-e Sep 21, 2025
2dfcd09
btree InternalNode::new safety comments
hkBst Sep 21, 2025
8886790
Add panic=immediate-abort
saethlin Sep 7, 2025
df58fd8
Change the cfg to a dash
saethlin Sep 18, 2025
aef02fb
Explain tests and setting cfgs
saethlin Sep 21, 2025
5f0a68e
regression test for https://github.com/rust-lang/rust/issues/117763
the8472 Aug 14, 2025
b3c2435
Make mips64el-unknown-linux-muslabi64 link dynamically
Gelbpunkt Sep 21, 2025
3565b06
emit attribute for readonly non-pure inline assembly
folkertdev Sep 19, 2025
c54a953
Early return in `visibility_print_with_space`
yotamofek Sep 21, 2025
cdf9661
Re-use some existing util fns
yotamofek Sep 21, 2025
2067160
Introduce "wrapper" helpers to rustdoc
yotamofek Sep 21, 2025
ce78d6f
port `#[feature]` to the new attribute parsing infrastructure
jdonszelmann Aug 24, 2025
858e26c
use feature parser throughout the compiler
jdonszelmann Sep 16, 2025
5d77369
Rollup merge of #145411 - the8472:cows-have-no-branches, r=Mark-Simul…
Zalathar Sep 22, 2025
cf662e3
Rollup merge of #146317 - saethlin:panic=immediate-abort, r=nnethercote
Zalathar Sep 22, 2025
8ff0836
Rollup merge of #146397 - pthariensflame:patch-1, r=Amanieu
Zalathar Sep 22, 2025
63a296a
Rollup merge of #146594 - Gelbpunkt:bootstrap-musl-static, r=Mark-Sim…
Zalathar Sep 22, 2025
ce358ff
Rollup merge of #146652 - jdonszelmann:convert-feature-attr-parser, r…
Zalathar Sep 22, 2025
a25ee5a
Rollup merge of #146791 - folkertdev:readonly-not-pure, r=nikic,josht…
Zalathar Sep 22, 2025
feede06
Rollup merge of #146831 - taiki-e:powerpc-clobber, r=Amanieu
Zalathar Sep 22, 2025
b2866fc
Rollup merge of #146838 - yotamofek:pr/rustdoc/wrappers, r=lolbinarycat
Zalathar Sep 22, 2025
1119d33
Rollup merge of #146846 - hkBst:btree-2, r=tgross35
Zalathar Sep 22, 2025
6335498
Rollup merge of #146858 - Gelbpunkt:mips64el-musl-dynamic, r=jieyouxu
Zalathar Sep 22, 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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3409,6 +3409,7 @@ dependencies = [
"rustc_errors",
"rustc_feature",
"rustc_fluent_macro",
"rustc_hir",
"rustc_macros",
"rustc_session",
"rustc_span",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
rustc_macros = { path = "../rustc_macros" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
Expand Down
23 changes: 18 additions & 5 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use rustc_ast as ast;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::{NodeId, PatKind, attr, token};
use rustc_attr_parsing::AttributeParser;
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features};
use rustc_hir::Attribute;
use rustc_hir::attrs::AttributeKind;
use rustc_session::Session;
use rustc_session::parse::{feature_err, feature_warn};
use rustc_span::source_map::Spanned;
use rustc_span::{Span, Symbol, sym};
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
use thin_vec::ThinVec;

use crate::errors;
Expand Down Expand Up @@ -587,17 +590,27 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
return;
}
let mut errored = false;
for attr in krate.attrs.iter().filter(|attr| attr.has_name(sym::feature)) {

if let Some(Attribute::Parsed(AttributeKind::Feature(feature_idents, first_span))) =
AttributeParser::parse_limited(
sess,
&krate.attrs,
sym::feature,
DUMMY_SP,
krate.id,
Some(&features),
)
{
// `feature(...)` used on non-nightly. This is definitely an error.
let mut err = errors::FeatureOnNonNightly {
span: attr.span,
span: first_span,
channel: option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)"),
stable_features: vec![],
sugg: None,
};

let mut all_stable = true;
for ident in attr.meta_item_list().into_iter().flatten().flat_map(|nested| nested.ident()) {
for ident in feature_idents {
let name = ident.name;
let stable_since = features
.enabled_lang_features()
Expand All @@ -612,7 +625,7 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
}
}
if all_stable {
err.sugg = Some(attr.span);
err.sugg = Some(first_span);
}
sess.dcx().emit_err(err);
errored = true;
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_attr_parsing/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,7 @@ attr_parsing_whole_archive_needs_static =
attr_parsing_limit_invalid =
`limit` must be a non-negative integer
.label = {$error_str}
attr_parsing_feature_single_word =
rust features are always a single identifier, not paths with multiple segments
.help = did you maybe mean `{$first_segment}`?
54 changes: 53 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/crate_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::num::IntErrorKind;
use rustc_hir::limit::Limit;

use super::prelude::*;
use crate::session_diagnostics::LimitInvalid;
use crate::session_diagnostics::{FeatureExpectedSingleWord, LimitInvalid};

impl<S: Stage> AcceptContext<'_, '_, S> {
fn parse_limit_int(&self, nv: &NameValueParser) -> Option<Limit> {
Expand Down Expand Up @@ -183,3 +183,55 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcCoherenceIsCoreParser {
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcCoherenceIsCore;
}

pub(crate) struct FeatureParser;

impl<S: Stage> CombineAttributeParser<S> for FeatureParser {
const PATH: &[Symbol] = &[sym::feature];
type Item = Ident;
const CONVERT: ConvertFn<Self::Item> = AttributeKind::Feature;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
const TEMPLATE: AttributeTemplate = template!(List: &["feature1, feature2, ..."]);

fn extend<'c>(
cx: &'c mut AcceptContext<'_, '_, S>,
args: &'c ArgParser<'_>,
) -> impl IntoIterator<Item = Self::Item> + 'c {
let ArgParser::List(list) = args else {
cx.expected_list(cx.attr_span);
return Vec::new();
};

if list.is_empty() {
cx.warn_empty_attribute(cx.attr_span);
}

let mut res = Vec::new();

for elem in list.mixed() {
let Some(elem) = elem.meta_item() else {
cx.expected_identifier(elem.span());
continue;
};
if let Err(arg_span) = elem.args().no_args() {
cx.expected_no_args(arg_span);
continue;
}

let path = elem.path();
let Some(ident) = path.word() else {
let first_segment = elem.path().segments().next().expect("at least one segment");
cx.emit_err(FeatureExpectedSingleWord {
span: path.span(),
first_segment_span: first_segment.span,
first_segment: first_segment.name,
});
continue;
};

res.push(ident);
}

res
}
}
6 changes: 4 additions & 2 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ use crate::attributes::codegen_attrs::{
};
use crate::attributes::confusables::ConfusablesParser;
use crate::attributes::crate_level::{
CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoStdParser, PatternComplexityLimitParser,
RecursionLimitParser, RustcCoherenceIsCoreParser, TypeLengthLimitParser,
CrateNameParser, FeatureParser, MoveSizeLimitParser, NoCoreParser, NoStdParser,
PatternComplexityLimitParser, RecursionLimitParser, RustcCoherenceIsCoreParser,
TypeLengthLimitParser,
};
use crate::attributes::deprecation::DeprecationParser;
use crate::attributes::dummy::DummyParser;
Expand Down Expand Up @@ -163,6 +164,7 @@ attribute_parsers!(
// tidy-alphabetical-start
Combine<AllowConstFnUnstableParser>,
Combine<AllowInternalUnstableParser>,
Combine<FeatureParser>,
Combine<ForceTargetFeatureParser>,
Combine<LinkParser>,
Combine<ReprParser>,
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -968,3 +968,14 @@ pub(crate) struct LimitInvalid<'a> {
pub value_span: Span,
pub error_str: &'a str,
}

#[derive(Diagnostic)]
#[diag(attr_parsing_feature_single_word)]
pub(crate) struct FeatureExpectedSingleWord {
#[primary_span]
pub span: Span,

#[help]
pub first_segment_span: Span,
pub first_segment: Symbol,
}
10 changes: 4 additions & 6 deletions compiler/rustc_builtin_macros/src/test_harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ pub fn inject(

if sess.is_test_crate() {
let panic_strategy = match (panic_strategy, sess.opts.unstable_opts.panic_abort_tests) {
(PanicStrategy::Abort, true) => PanicStrategy::Abort,
(PanicStrategy::Abort, false) => {
(PanicStrategy::Abort | PanicStrategy::ImmediateAbort, true) => panic_strategy,
(PanicStrategy::Abort | PanicStrategy::ImmediateAbort, false) => {
if panic_strategy == platform_panic_strategy {
// Silently allow compiling with panic=abort on these platforms,
// but with old behavior (abort if a test fails).
Expand Down Expand Up @@ -287,10 +287,8 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> Box<ast::Item> {
let ecx = &cx.ext_cx;
let test_ident = Ident::new(sym::test, sp);

let runner_name = match cx.panic_strategy {
PanicStrategy::Unwind => "test_main_static",
PanicStrategy::Abort => "test_main_static_abort",
};
let runner_name =
if cx.panic_strategy.unwinds() { "test_main_static" } else { "test_main_static_abort" };

// test::test_main_static(...)
let mut test_runner = cx.test_runner.clone().unwrap_or_else(|| {
Expand Down
16 changes: 12 additions & 4 deletions compiler/rustc_codegen_gcc/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -698,8 +698,12 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
InlineAsmRegClass::PowerPC(
PowerPCInlineAsmRegClass::cr
| PowerPCInlineAsmRegClass::ctr
| PowerPCInlineAsmRegClass::lr
| PowerPCInlineAsmRegClass::xer,
) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r",
Expand Down Expand Up @@ -777,8 +781,12 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => {
cx.type_vector(cx.type_i32(), 4)
}
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
InlineAsmRegClass::PowerPC(
PowerPCInlineAsmRegClass::cr
| PowerPCInlineAsmRegClass::ctr
| PowerPCInlineAsmRegClass::lr
| PowerPCInlineAsmRegClass::xer,
) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_gcc/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ use rustc_middle::mir::mono::Visibility;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::DebugInfo;
use rustc_span::Symbol;
use rustc_target::spec::RelocModel;
#[cfg(feature = "master")]
use rustc_target::spec::SymbolVisibility;
use rustc_target::spec::{PanicStrategy, RelocModel};

use crate::builder::Builder;
use crate::context::CodegenCx;
Expand Down Expand Up @@ -101,7 +101,7 @@ pub fn compile_codegen_unit(
// Instantiate monomorphizations without filling out definitions yet...
let context = new_context(tcx);

if tcx.sess.panic_strategy() == PanicStrategy::Unwind {
if tcx.sess.panic_strategy().unwinds() {
context.add_command_line_option("-fexceptions");
context.add_driver_option("-fexceptions");
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, Instance, Ty};
use rustc_span::{Span, Symbol, sym};
use rustc_target::callconv::{ArgAbi, PassMode};
use rustc_target::spec::PanicStrategy;

#[cfg(feature = "master")]
use crate::abi::FnAbiGccExt;
Expand Down Expand Up @@ -1334,7 +1333,7 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(
_catch_func: RValue<'gcc>,
dest: PlaceRef<'tcx, RValue<'gcc>>,
) {
if bx.sess().panic_strategy() == PanicStrategy::Abort {
if !bx.sess().panic_strategy().unwinds() {
bx.call(bx.type_void(), None, None, try_func, &[data], None, None);
// Return 0 unconditionally from the intrinsic call;
// we can never unwind.
Expand Down
18 changes: 14 additions & 4 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
attrs.push(llvm::AttributeKind::WillReturn.create_attr(self.cx.llcx));
} else if options.contains(InlineAsmOptions::NOMEM) {
attrs.push(llvm::MemoryEffects::InaccessibleMemOnly.create_attr(self.cx.llcx));
} else {
// LLVM doesn't have an attribute to represent ReadOnly + SideEffect
} else if options.contains(InlineAsmOptions::READONLY) {
attrs.push(llvm::MemoryEffects::ReadOnlyNotPure.create_attr(self.cx.llcx));
}
attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs });

Expand Down Expand Up @@ -662,7 +662,12 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
PowerPC(
PowerPCInlineAsmRegClass::cr
| PowerPCInlineAsmRegClass::ctr
| PowerPCInlineAsmRegClass::lr
| PowerPCInlineAsmRegClass::xer,
) => {
unreachable!("clobber-only")
}
RiscV(RiscVInlineAsmRegClass::reg) => "r",
Expand Down Expand Up @@ -830,7 +835,12 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
PowerPC(PowerPCInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i32(), 4),
PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
PowerPC(
PowerPCInlineAsmRegClass::cr
| PowerPCInlineAsmRegClass::ctr
| PowerPCInlineAsmRegClass::lr
| PowerPCInlineAsmRegClass::xer,
) => {
unreachable!("clobber-only")
}
RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use rustc_middle::{bug, span_bug};
use rustc_span::{Span, Symbol, sym};
use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate};
use rustc_target::callconv::PassMode;
use rustc_target::spec::PanicStrategy;
use tracing::debug;

use crate::abi::FnAbiLlvmExt;
Expand Down Expand Up @@ -674,7 +673,7 @@ fn catch_unwind_intrinsic<'ll, 'tcx>(
catch_func: &'ll Value,
dest: PlaceRef<'tcx, &'ll Value>,
) {
if bx.sess().panic_strategy() == PanicStrategy::Abort {
if !bx.sess().panic_strategy().unwinds() {
let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
bx.call(try_func_ty, None, None, try_func, &[data], None, None);
// Return 0 unconditionally from the intrinsic call;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ pub(crate) enum MemoryEffects {
None,
ReadOnly,
InaccessibleMemOnly,
ReadOnlyNotPure,
}

/// LLVMOpcode
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ unsafe fn configure_llvm(sess: &Session) {

if sess.target.os == "emscripten"
&& !sess.opts.unstable_opts.emscripten_wasm_eh
&& sess.panic_strategy() == PanicStrategy::Unwind
&& sess.panic_strategy().unwinds()
{
add("-enable-emscripten-cxx-exceptions", false);
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ use rustc_span::Symbol;
use rustc_target::spec::crt_objects::CrtObjects;
use rustc_target::spec::{
BinaryFormat, Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault,
LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy, RelocModel, RelroLevel,
SanitizerSet, SplitDebuginfo,
LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, RelocModel, RelroLevel, SanitizerSet,
SplitDebuginfo,
};
use tracing::{debug, info, warn};

Expand Down Expand Up @@ -2512,10 +2512,10 @@ fn add_order_independent_options(
if sess.target.os == "emscripten" {
cmd.cc_arg(if sess.opts.unstable_opts.emscripten_wasm_eh {
"-fwasm-exceptions"
} else if sess.panic_strategy() == PanicStrategy::Abort {
"-sDISABLE_EXCEPTION_CATCHING=1"
} else {
} else if sess.panic_strategy().unwinds() {
"-sDISABLE_EXCEPTION_CATCHING=0"
} else {
"-sDISABLE_EXCEPTION_CATCHING=1"
});
}

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_error_codes/src/error_codes/E0556.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#### Note: this error code is no longer emitted by the compiler.

The `feature` attribute was badly formed.

Erroneous code example:

```compile_fail,E0556
```compile_fail
#![feature(foo_bar_baz, foo(bar), foo = "baz", foo)] // error!
#![feature] // error!
#![feature = "foo"] // error!
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ E0550: 0550,
E0551: 0551,
E0552: 0552,
E0554: 0554,
E0556: 0556,
E0556: 0556, // REMOVED: merged with other attribute error codes
E0557: 0557,
E0559: 0559,
E0560: 0560,
Expand Down
Loading
Loading