Skip to content

Commit a84c790

Browse files
committed
Auto merge of #128268 - matthiaskrgr:rollup-tck33df, r=matthiaskrgr
Rollup of 3 pull requests Successful merges: - #128006 (Make `missing_fragment_specifier` an error in edition 2024) - #128207 (improve error message when `global_asm!` uses `asm!` options) - #128266 (update `rust.channel` default value documentation) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3942254 + 3f0fb36 commit a84c790

22 files changed

+295
-95
lines changed

compiler/rustc_ast/src/ast.rs

+5
Original file line numberDiff line numberDiff line change
@@ -2266,6 +2266,11 @@ bitflags::bitflags! {
22662266
}
22672267

22682268
impl InlineAsmOptions {
2269+
pub const COUNT: usize = Self::all().bits().count_ones() as usize;
2270+
2271+
pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
2272+
pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW).union(Self::NORETURN);
2273+
22692274
pub fn human_readable_names(&self) -> Vec<&'static str> {
22702275
let mut options = vec![];
22712276

compiler/rustc_builtin_macros/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ builtin_macros_format_use_positional = consider using a positional formatting ar
199199
200200
builtin_macros_global_asm_clobber_abi = `clobber_abi` cannot be used with `global_asm!`
201201
202+
builtin_macros_global_asm_unsupported_option = the `{$symbol}` option cannot be used with `global_asm!`
203+
.label = the `{$symbol}` option is not meaningful for global-scoped inline assembly
204+
.suggestion = remove this option
205+
202206
builtin_macros_invalid_crate_attribute = invalid crate attribute
203207
204208
builtin_macros_multiple_default_attrs = multiple `#[default]` attributes

compiler/rustc_builtin_macros/src/asm.rs

+43-22
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,16 @@ fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
310310
p.dcx().emit_err(errors::AsmOptAlreadyprovided { span, symbol, full_span });
311311
}
312312

313+
/// Report an invalid option error.
314+
///
315+
/// This function must be called immediately after the option token is parsed.
316+
/// Otherwise, the suggestion will be incorrect.
317+
fn err_unsupported_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
318+
// Tool-only output
319+
let full_span = if p.token.kind == token::Comma { span.to(p.token.span) } else { span };
320+
p.dcx().emit_err(errors::GlobalAsmUnsupportedOption { span, symbol, full_span });
321+
}
322+
313323
/// Try to set the provided option in the provided `AsmArgs`.
314324
/// If it is already set, report a duplicate option error.
315325
///
@@ -318,13 +328,16 @@ fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
318328
fn try_set_option<'a>(
319329
p: &Parser<'a>,
320330
args: &mut AsmArgs,
331+
is_global_asm: bool,
321332
symbol: Symbol,
322333
option: ast::InlineAsmOptions,
323334
) {
324-
if !args.options.contains(option) {
325-
args.options |= option;
326-
} else {
335+
if is_global_asm && !ast::InlineAsmOptions::GLOBAL_OPTIONS.contains(option) {
336+
err_unsupported_option(p, symbol, p.prev_token.span);
337+
} else if args.options.contains(option) {
327338
err_duplicate_option(p, symbol, p.prev_token.span);
339+
} else {
340+
args.options |= option;
328341
}
329342
}
330343

@@ -338,25 +351,33 @@ fn parse_options<'a>(
338351
p.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
339352

340353
while !p.eat(&token::CloseDelim(Delimiter::Parenthesis)) {
341-
if !is_global_asm && p.eat_keyword(sym::pure) {
342-
try_set_option(p, args, sym::pure, ast::InlineAsmOptions::PURE);
343-
} else if !is_global_asm && p.eat_keyword(sym::nomem) {
344-
try_set_option(p, args, sym::nomem, ast::InlineAsmOptions::NOMEM);
345-
} else if !is_global_asm && p.eat_keyword(sym::readonly) {
346-
try_set_option(p, args, sym::readonly, ast::InlineAsmOptions::READONLY);
347-
} else if !is_global_asm && p.eat_keyword(sym::preserves_flags) {
348-
try_set_option(p, args, sym::preserves_flags, ast::InlineAsmOptions::PRESERVES_FLAGS);
349-
} else if !is_global_asm && p.eat_keyword(sym::noreturn) {
350-
try_set_option(p, args, sym::noreturn, ast::InlineAsmOptions::NORETURN);
351-
} else if !is_global_asm && p.eat_keyword(sym::nostack) {
352-
try_set_option(p, args, sym::nostack, ast::InlineAsmOptions::NOSTACK);
353-
} else if !is_global_asm && p.eat_keyword(sym::may_unwind) {
354-
try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::MAY_UNWIND);
355-
} else if p.eat_keyword(sym::att_syntax) {
356-
try_set_option(p, args, sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX);
357-
} else if p.eat_keyword(kw::Raw) {
358-
try_set_option(p, args, kw::Raw, ast::InlineAsmOptions::RAW);
359-
} else {
354+
const OPTIONS: [(Symbol, ast::InlineAsmOptions); ast::InlineAsmOptions::COUNT] = [
355+
(sym::pure, ast::InlineAsmOptions::PURE),
356+
(sym::nomem, ast::InlineAsmOptions::NOMEM),
357+
(sym::readonly, ast::InlineAsmOptions::READONLY),
358+
(sym::preserves_flags, ast::InlineAsmOptions::PRESERVES_FLAGS),
359+
(sym::noreturn, ast::InlineAsmOptions::NORETURN),
360+
(sym::nostack, ast::InlineAsmOptions::NOSTACK),
361+
(sym::may_unwind, ast::InlineAsmOptions::MAY_UNWIND),
362+
(sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX),
363+
(kw::Raw, ast::InlineAsmOptions::RAW),
364+
];
365+
366+
'blk: {
367+
for (symbol, option) in OPTIONS {
368+
let kw_matched =
369+
if !is_global_asm || ast::InlineAsmOptions::GLOBAL_OPTIONS.contains(option) {
370+
p.eat_keyword(symbol)
371+
} else {
372+
p.eat_keyword_noexpect(symbol)
373+
};
374+
375+
if kw_matched {
376+
try_set_option(p, args, is_global_asm, symbol, option);
377+
break 'blk;
378+
}
379+
}
380+
360381
return p.unexpected();
361382
}
362383

compiler/rustc_builtin_macros/src/errors.rs

+11
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,17 @@ pub(crate) struct AsmOptAlreadyprovided {
845845
pub(crate) full_span: Span,
846846
}
847847

848+
#[derive(Diagnostic)]
849+
#[diag(builtin_macros_global_asm_unsupported_option)]
850+
pub(crate) struct GlobalAsmUnsupportedOption {
851+
#[primary_span]
852+
#[label]
853+
pub(crate) span: Span,
854+
pub(crate) symbol: Symbol,
855+
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
856+
pub(crate) full_span: Span,
857+
}
858+
848859
#[derive(Diagnostic)]
849860
#[diag(builtin_macros_test_runner_invalid)]
850861
pub(crate) struct TestRunnerInvalid {

compiler/rustc_expand/messages.ftl

+5
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ expand_meta_var_dif_seq_matchers = {$msg}
105105
expand_meta_var_expr_unrecognized_var =
106106
variable `{$key}` is not recognized in meta-variable expression
107107
108+
expand_missing_fragment_specifier = missing fragment specifier
109+
.note = fragment specifiers must be specified in the 2024 edition
110+
.suggestion_add_fragspec = try adding a specifier here
111+
.valid = {$valid}
112+
108113
expand_module_circular =
109114
circular modules: {$modules}
110115

compiler/rustc_expand/src/errors.rs

+17
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,23 @@ pub struct DuplicateMatcherBinding {
416416
pub prev: Span,
417417
}
418418

419+
#[derive(Diagnostic)]
420+
#[diag(expand_missing_fragment_specifier)]
421+
#[note]
422+
#[help(expand_valid)]
423+
pub struct MissingFragmentSpecifier {
424+
#[primary_span]
425+
pub span: Span,
426+
#[suggestion(
427+
expand_suggestion_add_fragspec,
428+
style = "verbose",
429+
code = ":spec",
430+
applicability = "maybe-incorrect"
431+
)]
432+
pub add_span: Span,
433+
pub valid: &'static str,
434+
}
435+
419436
#[derive(Diagnostic)]
420437
#[diag(expand_invalid_fragment_specifier)]
421438
#[help]

compiler/rustc_expand/src/mbe/macro_check.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,16 @@ use rustc_errors::MultiSpan;
115115
use rustc_lint_defs::BuiltinLintDiag;
116116
use rustc_session::lint::builtin::{META_VARIABLE_MISUSE, MISSING_FRAGMENT_SPECIFIER};
117117
use rustc_session::parse::ParseSess;
118+
use rustc_span::edition::Edition;
118119
use rustc_span::symbol::kw;
119120
use rustc_span::{symbol::MacroRulesNormalizedIdent, ErrorGuaranteed, Span};
120121

121122
use smallvec::SmallVec;
122123

123124
use std::iter;
124125

126+
use super::quoted::VALID_FRAGMENT_NAMES_MSG_2021;
127+
125128
/// Stack represented as linked list.
126129
///
127130
/// Those are used for environments because they grow incrementally and are not mutable.
@@ -269,12 +272,20 @@ fn check_binders(
269272
// FIXME: Report this as a hard error eventually and remove equivalent errors from
270273
// `parse_tt_inner` and `nameize`. Until then the error may be reported twice, once
271274
// as a hard error and then once as a buffered lint.
272-
psess.buffer_lint(
273-
MISSING_FRAGMENT_SPECIFIER,
274-
span,
275-
node_id,
276-
BuiltinLintDiag::MissingFragmentSpecifier,
277-
);
275+
if span.edition() >= Edition::Edition2024 {
276+
psess.dcx().emit_err(errors::MissingFragmentSpecifier {
277+
span,
278+
add_span: span.shrink_to_hi(),
279+
valid: VALID_FRAGMENT_NAMES_MSG_2021,
280+
});
281+
} else {
282+
psess.buffer_lint(
283+
MISSING_FRAGMENT_SPECIFIER,
284+
span,
285+
node_id,
286+
BuiltinLintDiag::MissingFragmentSpecifier,
287+
);
288+
}
278289
}
279290
if !macros.is_empty() {
280291
psess.dcx().span_bug(span, "unexpected MetaVarDecl in nested lhs");

compiler/rustc_expand/src/mbe/quoted.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_span::Span;
1616
const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
1717
`ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
1818
`literal`, `path`, `meta`, `tt`, `item` and `vis`";
19-
const VALID_FRAGMENT_NAMES_MSG_2021: &str = "valid fragment specifiers are \
19+
pub const VALID_FRAGMENT_NAMES_MSG_2021: &str = "valid fragment specifiers are \
2020
`ident`, `block`, `stmt`, `expr`, `expr_2021`, `pat`, \
2121
`ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, \
2222
`item` and `vis`";

compiler/rustc_parse/src/parser/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ impl<'a> Parser<'a> {
599599

600600
/// If the next token is the given keyword, eats it and returns `true`.
601601
/// Otherwise, returns `false`. An expectation is also added for diagnostics purposes.
602-
// Public for rustfmt usage.
602+
// Public for rustc_builtin_macros and rustfmt usage.
603603
#[inline]
604604
pub fn eat_keyword(&mut self, kw: Symbol) -> bool {
605605
if self.check_keyword(kw) {
@@ -631,8 +631,11 @@ impl<'a> Parser<'a> {
631631
false
632632
}
633633

634+
/// If the next token is the given keyword, eats it and returns `true`.
635+
/// Otherwise, returns `false`. No expectation is added.
636+
// Public for rustc_builtin_macros usage.
634637
#[inline]
635-
fn eat_keyword_noexpect(&mut self, kw: Symbol) -> bool {
638+
pub fn eat_keyword_noexpect(&mut self, kw: Symbol) -> bool {
636639
if self.token.is_keyword(kw) {
637640
self.bump();
638641
true

compiler/rustc_passes/src/naked_functions.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
244244
self.tcx.dcx().emit_err(NakedFunctionsOperands { unsupported_operands });
245245
}
246246

247-
let supported_options =
248-
InlineAsmOptions::RAW | InlineAsmOptions::NORETURN | InlineAsmOptions::ATT_SYNTAX;
249-
let unsupported_options = asm.options.difference(supported_options);
250-
247+
let unsupported_options = asm.options.difference(InlineAsmOptions::NAKED_OPTIONS);
251248
if !unsupported_options.is_empty() {
252249
self.tcx.dcx().emit_err(NakedFunctionsAsmOptions {
253250
span,

config.example.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,10 @@
578578
# The "channel" for the Rust build to produce. The stable/beta channels only
579579
# allow using stable features, whereas the nightly and dev channels allow using
580580
# nightly features
581-
#channel = "dev"
581+
#
582+
# If using tarball sources, default value for `channel` is taken from the `src/ci/channel` file;
583+
# otherwise, it's "dev".
584+
#channel = if "is a tarball source" { content of `src/ci/channel` file } else { "dev" }
582585

583586
# A descriptive string to be appended to `rustc --version` output, which is
584587
# also used in places like debuginfo `DW_AT_producer`. This may be useful for

src/bootstrap/src/utils/change_tracker.rs

+5
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
215215
severity: ChangeSeverity::Info,
216216
summary: "Removed android-ndk r25b support in favor of android-ndk r26d.",
217217
},
218+
ChangeInfo {
219+
change_id: 125181,
220+
severity: ChangeSeverity::Warning,
221+
summary: "For tarball sources, default value for `rust.channel` will be taken from `src/ci/channel` file.",
222+
},
218223
];

tests/ui/asm/parse-error.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,15 @@ global_asm!("{}", const);
111111
global_asm!("{}", const(reg) FOO);
112112
//~^ ERROR expected one of
113113
global_asm!("", options(FOO));
114-
//~^ ERROR expected one of
114+
//~^ ERROR expected one of `)`, `att_syntax`, or `raw`, found `FOO`
115+
global_asm!("", options(FOO,));
116+
//~^ ERROR expected one of `)`, `att_syntax`, or `raw`, found `FOO`
115117
global_asm!("", options(nomem FOO));
116-
//~^ ERROR expected one of
118+
//~^ ERROR the `nomem` option cannot be used with `global_asm!`
119+
//~| ERROR expected one of `)` or `,`, found `FOO`
117120
global_asm!("", options(nomem, FOO));
118-
//~^ ERROR expected one of
121+
//~^ ERROR the `nomem` option cannot be used with `global_asm!`
122+
//~| ERROR expected one of `)`, `att_syntax`, or `raw`, found `FOO`
119123
global_asm!("{}", options(), const FOO);
120124
global_asm!("", clobber_abi(FOO));
121125
//~^ ERROR expected string literal

0 commit comments

Comments
 (0)