Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6c4c438
destabilise target-spec-json
davidtwco Dec 19, 2025
9c4ead6
Remove legacy homu `try` and `auto` branch mentions
Kobzol Jan 7, 2026
6f12b86
s390x: support `f16` and `f16x8` in inline assembly
folkertdev Jan 8, 2026
ef1e4e6
Move checks from `check_doc_attrs` directly into `rustc_attr_parsing`
GuillaumeGomez Jan 10, 2026
b327e30
core: ptr: split_at_mut: fix typo in safety doc
lschuermann Jan 12, 2026
284d136
Dogfood `-Zno-embed-metadata` for the standard library
Kobzol Aug 25, 2025
e03cb1f
run-make-support: resolve .rmeta companion for .rlib stubs
akshitgaur2005 Jan 2, 2026
6ca9501
Relax test expectation for @__llvm_profile_runtime_user
zmodem Jan 12, 2026
c451e9b
Remove a workaround for a bug
bjorn3 Sep 19, 2021
a2cc9ef
std: move `errno` and related functions into `sys::io`
joboet Jan 6, 2026
210c157
update import in UI test
joboet Jan 6, 2026
90b32e7
Fix typo in `MaybeUninit` docs
tbu- Jan 12, 2026
50b60aa
std: sys: net: uefi: Make TcpStream Send
Ayush1325 Jan 12, 2026
439da07
Update books
rustbot Jan 12, 2026
418cff3
Port `#[must_not_suspend]` to attribute parser
Bryntet Jan 10, 2026
b5d8fcf
Rollup merge of #145343 - dogfood-z-no-embed-metadata, r=bjorn3
JonathanBrouwer Jan 12, 2026
d35b381
Rollup merge of #150151 - destabilise-target-spec-json, r=Kivooeo
JonathanBrouwer Jan 12, 2026
6f28ef9
Rollup merge of #150723 - move_pal_error, r=@tgross35
JonathanBrouwer Jan 12, 2026
873728f
Rollup merge of #150771 - remove-homu-branches, r=marcoieni
JonathanBrouwer Jan 12, 2026
586d65a
Rollup merge of #150826 - s390x-asm-f16-vector, r=uweigand,tgross35
JonathanBrouwer Jan 12, 2026
7992d18
Rollup merge of #150934 - move-doc-attr-checks, r=JonathanBrouwer
JonathanBrouwer Jan 12, 2026
2139df2
Rollup merge of #150943 - port_must_not_suspend, r=jdonszelmann,Jonat…
JonathanBrouwer Jan 12, 2026
03aafbc
Rollup merge of #150990 - uefi-run-test, r=joboet
JonathanBrouwer Jan 12, 2026
df24ff4
Rollup merge of #150995 - dev/core-ptr-split-at-mut-docs-fix, r=joboet
JonathanBrouwer Jan 12, 2026
b47c4d5
Rollup merge of #150998 - win___llvm_profile_runtime_user, r=durin42
JonathanBrouwer Jan 12, 2026
a39c974
Rollup merge of #151002 - remove_bug_workaround, r=lqd
JonathanBrouwer Jan 12, 2026
b499e51
Rollup merge of #151005 - pr_doc_maybeuninit_typo, r=joboet
JonathanBrouwer Jan 12, 2026
bdf341b
Rollup merge of #151011 - docs-update, r=ehuss
JonathanBrouwer Jan 12, 2026
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
19 changes: 9 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@ name: CI
on:
push:
branches:
- auto
- try
- try-perf
- automation/bors/try
- automation/bors/auto
- automation/bors/try
- try-perf
pull_request:
branches:
- "**"
Expand All @@ -33,9 +31,10 @@ defaults:

concurrency:
# For a given workflow, if we push to the same branch, cancel all previous builds on that branch.
# We add an exception for try builds (try branch) and unrolled rollup builds (try-perf), which
# are all triggered on the same branch, but which should be able to run concurrently.
group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try') && github.sha) || github.ref }}
# We add an exception for try builds (automation/bors/try branch) and unrolled rollup builds
# (try-perf), which are all triggered on the same branch, but which should be able to run
# concurrently.
group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try') && github.sha) || github.ref }}
cancel-in-progress: true
env:
TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
Expand All @@ -57,7 +56,7 @@ jobs:
- name: Test citool
# Only test citool on the auto branch, to reduce latency of the calculate matrix job
# on PR/try builds.
if: ${{ github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto' }}
if: ${{ github.ref == 'refs/heads/automation/bors/auto' }}
run: |
cd src/ci/citool
CARGO_INCREMENTAL=0 cargo test
Expand All @@ -80,7 +79,7 @@ jobs:
# access the environment.
#
# We only enable the environment for the rust-lang/rust repository, so that CI works on forks.
environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }}
environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }}
env:
CI_JOB_NAME: ${{ matrix.name }}
CI_JOB_DOC_URL: ${{ matrix.doc_url }}
Expand Down Expand Up @@ -314,7 +313,7 @@ jobs:
needs: [ calculate_matrix, job ]
# !cancelled() executes the job regardless of whether the previous jobs passed or failed
if: ${{ !cancelled() && contains(fromJSON('["auto", "try"]'), needs.calculate_matrix.outputs.run_type) }}
environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }}
environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }}
steps:
- name: checkout the source code
uses: actions/checkout@v5
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_attr_parsing/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ attr_parsing_doc_alias_malformed =
attr_parsing_doc_alias_start_end =
{$attr_str} cannot start or end with ' '
attr_parsing_doc_attr_not_crate_level =
`#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute
attr_parsing_doc_attribute_not_attribute =
nonexistent builtin attribute `{$attribute}` used in `#[doc(attribute = "...")]`
.help = only existing builtin attributes are allowed in core/std
Expand Down
119 changes: 96 additions & 23 deletions compiler/rustc_attr_parsing/src/attributes/doc.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_ast::ast::{AttrStyle, LitKind, MetaItemLit};
use rustc_feature::template;
use rustc_hir::Target;
use rustc_hir::attrs::{
AttributeKind, CfgEntry, CfgHideShow, CfgInfo, DocAttribute, DocInline, HideOrShow,
};
Expand All @@ -12,8 +13,8 @@ use super::{AcceptMapping, AttributeParser};
use crate::context::{AcceptContext, FinalizeContext, Stage};
use crate::parser::{ArgParser, MetaItemOrLitParser, MetaItemParser, OwnedPathParser};
use crate::session_diagnostics::{
DocAliasBadChar, DocAliasEmpty, DocAliasMalformed, DocAliasStartEnd, DocAttributeNotAttribute,
DocKeywordNotKeyword,
DocAliasBadChar, DocAliasEmpty, DocAliasMalformed, DocAliasStartEnd, DocAttrNotCrateLevel,
DocAttributeNotAttribute, DocKeywordNotKeyword,
};

fn check_keyword<S: Stage>(cx: &mut AcceptContext<'_, '_, S>, keyword: Symbol, span: Span) -> bool {
Expand Down Expand Up @@ -43,16 +44,39 @@ fn check_attribute<S: Stage>(
false
}

fn parse_keyword_and_attribute<S, F>(
/// Checks that an attribute is *not* used at the crate level. Returns `true` if valid.
fn check_attr_not_crate_level<S: Stage>(
cx: &mut AcceptContext<'_, '_, S>,
span: Span,
attr_name: Symbol,
) -> bool {
if cx.shared.target.is_some_and(|target| target == Target::Crate) {
cx.emit_err(DocAttrNotCrateLevel { span, attr_name });
return false;
}
true
}

/// Checks that an attribute is used at the crate level. Returns `true` if valid.
fn check_attr_crate_level<S: Stage>(cx: &mut AcceptContext<'_, '_, S>, span: Span) -> bool {
if cx.shared.target.is_some_and(|target| target != Target::Crate) {
cx.emit_lint(
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
AttributeLintKind::AttrCrateLevelOnly,
span,
);
return false;
}
true
}

fn parse_keyword_and_attribute<S: Stage>(
cx: &mut AcceptContext<'_, '_, S>,
path: &OwnedPathParser,
args: &ArgParser,
attr_value: &mut Option<(Symbol, Span)>,
callback: F,
) where
S: Stage,
F: FnOnce(&mut AcceptContext<'_, '_, S>, Symbol, Span) -> bool,
{
attr_name: Symbol,
) {
let Some(nv) = args.name_value() else {
cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym());
return;
Expand All @@ -63,16 +87,26 @@ fn parse_keyword_and_attribute<S, F>(
return;
};

if !callback(cx, value, nv.value_span) {
let ret = if attr_name == sym::keyword {
check_keyword(cx, value, nv.value_span)
} else {
check_attribute(cx, value, nv.value_span)
};
if !ret {
return;
}

let span = path.span();
if attr_value.is_some() {
cx.duplicate_key(path.span(), path.word_sym().unwrap());
cx.duplicate_key(span, path.word_sym().unwrap());
return;
}

*attr_value = Some((value, path.span()));
if !check_attr_not_crate_level(cx, span, attr_name) {
return;
}

*attr_value = Some((value, span));
}

#[derive(Default, Debug)]
Expand Down Expand Up @@ -102,6 +136,10 @@ impl DocParser {
return;
}

if !check_attr_crate_level(cx, path.span()) {
return;
}

self.attribute.no_crate_inject = Some(path.span())
}
Some(sym::attr) => {
Expand Down Expand Up @@ -155,6 +193,9 @@ impl DocParser {
cx.emit_err(DocAliasStartEnd { span, attr_str });
return;
}
if !check_attr_not_crate_level(cx, span, sym::alias) {
return;
}

if let Some(first_definition) = self.attribute.aliases.get(&alias).copied() {
cx.emit_lint(
Expand Down Expand Up @@ -366,7 +407,33 @@ impl DocParser {
self.attribute.$ident = Some(path.span());
}};
}
macro_rules! string_arg {
macro_rules! no_args_and_not_crate_level {
($ident: ident) => {{
if let Err(span) = args.no_args() {
cx.expected_no_args(span);
return;
}
let span = path.span();
if !check_attr_not_crate_level(cx, span, sym::$ident) {
return;
}
self.attribute.$ident = Some(span);
}};
}
macro_rules! no_args_and_crate_level {
($ident: ident) => {{
if let Err(span) = args.no_args() {
cx.expected_no_args(span);
return;
}
let span = path.span();
if !check_attr_crate_level(cx, span) {
return;
}
self.attribute.$ident = Some(span);
}};
}
macro_rules! string_arg_and_crate_level {
($ident: ident) => {{
let Some(nv) = args.name_value() else {
cx.expected_name_value(args.span().unwrap_or(path.span()), path.word_sym());
Expand All @@ -378,6 +445,10 @@ impl DocParser {
return;
};

if !check_attr_crate_level(cx, path.span()) {
return;
}

// FIXME: It's errorring when the attribute is passed multiple times on the command
// line.
// The right fix for this would be to only check this rule if the attribute is
Expand All @@ -394,12 +465,14 @@ impl DocParser {
match path.word_sym() {
Some(sym::alias) => self.parse_alias(cx, path, args),
Some(sym::hidden) => no_args!(hidden),
Some(sym::html_favicon_url) => string_arg!(html_favicon_url),
Some(sym::html_logo_url) => string_arg!(html_logo_url),
Some(sym::html_no_source) => no_args!(html_no_source),
Some(sym::html_playground_url) => string_arg!(html_playground_url),
Some(sym::html_root_url) => string_arg!(html_root_url),
Some(sym::issue_tracker_base_url) => string_arg!(issue_tracker_base_url),
Some(sym::html_favicon_url) => string_arg_and_crate_level!(html_favicon_url),
Some(sym::html_logo_url) => string_arg_and_crate_level!(html_logo_url),
Some(sym::html_no_source) => no_args_and_crate_level!(html_no_source),
Some(sym::html_playground_url) => string_arg_and_crate_level!(html_playground_url),
Some(sym::html_root_url) => string_arg_and_crate_level!(html_root_url),
Some(sym::issue_tracker_base_url) => {
string_arg_and_crate_level!(issue_tracker_base_url)
}
Some(sym::inline) => self.parse_inline(cx, path, args, DocInline::Inline),
Some(sym::no_inline) => self.parse_inline(cx, path, args, DocInline::NoInline),
Some(sym::masked) => no_args!(masked),
Expand All @@ -410,18 +483,18 @@ impl DocParser {
path,
args,
&mut self.attribute.keyword,
check_keyword,
sym::keyword,
),
Some(sym::attribute) => parse_keyword_and_attribute(
cx,
path,
args,
&mut self.attribute.attribute,
check_attribute,
sym::attribute,
),
Some(sym::fake_variadic) => no_args!(fake_variadic),
Some(sym::search_unbox) => no_args!(search_unbox),
Some(sym::rust_logo) => no_args!(rust_logo),
Some(sym::fake_variadic) => no_args_and_not_crate_level!(fake_variadic),
Some(sym::search_unbox) => no_args_and_not_crate_level!(search_unbox),
Some(sym::rust_logo) => no_args_and_crate_level!(rust_logo),
Some(sym::auto_cfg) => self.parse_auto_cfg(cx, path, args),
Some(sym::test) => {
let Some(list) = args.list() else {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_attr_parsing/src/attributes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub(crate) mod link_attrs;
pub(crate) mod lint_helpers;
pub(crate) mod loop_match;
pub(crate) mod macro_attrs;
pub(crate) mod must_not_suspend;
pub(crate) mod must_use;
pub(crate) mod no_implicit_prelude;
pub(crate) mod no_link;
Expand Down
35 changes: 35 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use super::prelude::*;

pub(crate) struct MustNotSuspendParser;

impl<S: Stage> SingleAttributeParser<S> for MustNotSuspendParser {
const PATH: &[rustc_span::Symbol] = &[sym::must_not_suspend];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Struct),
Allow(Target::Enum),
Allow(Target::Union),
Allow(Target::Trait),
]);
const TEMPLATE: AttributeTemplate = template!(Word, List: &["count"]);

fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
let reason = match args {
ArgParser::NameValue(reason) => match reason.value_as_str() {
Some(val) => Some(val),
None => {
cx.expected_nv_or_no_args(reason.value_span);
return None;
}
},
ArgParser::NoArgs => None,
ArgParser::List(list) => {
cx.expected_nv_or_no_args(list.span);
return None;
}
};

Some(AttributeKind::MustNotSupend { reason })
}
}
4 changes: 3 additions & 1 deletion compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ use crate::attributes::macro_attrs::{
AllowInternalUnsafeParser, CollapseDebugInfoParser, MacroEscapeParser, MacroExportParser,
MacroUseParser,
};
use crate::attributes::must_not_suspend::MustNotSuspendParser;
use crate::attributes::must_use::MustUseParser;
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
use crate::attributes::no_link::NoLinkParser;
Expand Down Expand Up @@ -89,7 +90,6 @@ use crate::session_diagnostics::{
AttributeParseError, AttributeParseErrorReason, ParsedDescription,
};
use crate::target_checking::AllowedTargets;

type GroupType<S> = LazyLock<GroupTypeInner<S>>;

pub(super) struct GroupTypeInner<S: Stage> {
Expand Down Expand Up @@ -208,6 +208,7 @@ attribute_parsers!(
Single<LinkageParser>,
Single<MacroExportParser>,
Single<MoveSizeLimitParser>,
Single<MustNotSuspendParser>,
Single<MustUseParser>,
Single<ObjcClassParser>,
Single<ObjcSelectorParser>,
Expand Down Expand Up @@ -655,6 +656,7 @@ pub struct SharedContext<'p, 'sess, S: Stage> {
pub(crate) target_span: Span,
/// The id ([`NodeId`] if `S` is `Early`, [`HirId`] if `S` is `Late`) of the syntactical component this attribute was applied to
pub(crate) target_id: S::Id,
pub(crate) target: Option<rustc_hir::Target>,

pub(crate) emit_lint: &'p mut dyn FnMut(AttributeLint<S::Id>),
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_attr_parsing/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ impl<'sess> AttributeParser<'sess, Early> {
cx: &mut parser,
target_span,
target_id: target_node_id,
target: None,
emit_lint: &mut emit_lint,
},
attr_span,
Expand Down Expand Up @@ -378,6 +379,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
cx: self,
target_span,
target_id,
target: Some(target),
emit_lint: &mut emit_lint,
},
attr_span,
Expand Down Expand Up @@ -429,6 +431,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
cx: self,
target_span,
target_id,
target: Some(target),
emit_lint: &mut emit_lint,
},
all_attrs: &attr_paths,
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ pub(crate) struct DocAliasStartEnd<'a> {
pub attr_str: &'a str,
}

#[derive(Diagnostic)]
#[diag(attr_parsing_doc_attr_not_crate_level)]
pub(crate) struct DocAttrNotCrateLevel {
#[primary_span]
pub span: Span,
pub attr_name: Symbol,
}

#[derive(Diagnostic)]
#[diag(attr_parsing_doc_keyword_not_keyword)]
#[help]
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1124,9 +1124,10 @@ fn get_backend_from_raw_matches(
let backend_name = debug_flags
.iter()
.find_map(|x| x.strip_prefix("codegen-backend=").or(x.strip_prefix("codegen_backend=")));
let unstable_options = debug_flags.iter().find(|x| *x == "unstable-options").is_some();
let target = parse_target_triple(early_dcx, matches);
let sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from));
let target = config::build_target_config(early_dcx, &target, sysroot.path());
let target = config::build_target_config(early_dcx, &target, sysroot.path(), unstable_options);

get_codegen_backend(early_dcx, &sysroot, backend_name, &target)
}
Expand Down
Loading
Loading