summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_builtin_macros
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /compiler/rustc_builtin_macros
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_builtin_macros')
-rw-r--r--compiler/rustc_builtin_macros/Cargo.toml2
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl203
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs156
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs18
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_eval.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/concat.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/concat_idents.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/bounds.rs23
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/edition_panic.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/env.rs12
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs191
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs18
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/global_allocator.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs16
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs12
-rw-r--r--compiler/rustc_builtin_macros/src/trace_macros.rs2
24 files changed, 463 insertions, 251 deletions
diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml
index 336e14ef9..44012e802 100644
--- a/compiler/rustc_builtin_macros/Cargo.toml
+++ b/compiler/rustc_builtin_macros/Cargo.toml
@@ -14,9 +14,11 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_expand = { path = "../rustc_expand" }
rustc_feature = { path = "../rustc_feature" }
+rustc_index = { path = "../rustc_index" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_lint_defs = { path = "../rustc_lint_defs" }
rustc_macros = { path = "../rustc_macros" }
+rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_parse_format = { path = "../rustc_parse_format" }
rustc_parse = { path = "../rustc_parse" }
rustc_session = { path = "../rustc_session" }
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index 83dc1ac50..f00cd39cb 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -1,10 +1,50 @@
-builtin_macros_requires_cfg_pattern =
- macro requires a cfg-pattern as an argument
- .label = cfg-pattern required
+builtin_macros_alloc_error_must_be_fn = alloc_error_handler must be a function
-builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
+builtin_macros_asm_clobber_abi = clobber_abi
+builtin_macros_asm_clobber_no_reg = asm with `clobber_abi` must specify explicit registers for outputs
+builtin_macros_asm_clobber_outputs = generic outputs
-builtin_macros_alloc_error_must_be_fn = alloc_error_handler must be a function
+builtin_macros_asm_duplicate_arg = duplicate argument named `{$name}`
+ .label = previously here
+ .arg = duplicate argument
+
+builtin_macros_asm_expected_comma = expected token: `,`
+ .label = expected `,`
+
+builtin_macros_asm_expected_other = expected operand, {$is_global_asm ->
+ [true] options
+ *[false] clobber_abi, options
+ }, or additional template string
+
+builtin_macros_asm_explicit_register_name = explicit register arguments cannot have names
+
+builtin_macros_asm_modifier_invalid = asm template modifier must be a single character
+
+builtin_macros_asm_mutually_exclusive = the `{$opt1}` and `{$opt2}` options are mutually exclusive
+
+builtin_macros_asm_noreturn = asm outputs are not allowed with the `noreturn` option
+
+builtin_macros_asm_opt_already_provided = the `{$symbol}` option was already provided
+ .label = this option was already provided
+ .suggestion = remove this option
+
+builtin_macros_asm_pos_after = positional arguments cannot follow named arguments or explicit register arguments
+ .pos = positional argument
+ .named = named argument
+ .explicit = explicit register argument
+
+builtin_macros_asm_pure_combine = the `pure` option must be combined with either `nomem` or `readonly`
+
+builtin_macros_asm_pure_no_output = asm with the `pure` option must have at least one output
+
+builtin_macros_asm_requires_template = requires at least a template string argument
+
+builtin_macros_asm_sym_no_path = expected a path for argument to `sym`
+
+builtin_macros_asm_underscore_input = _ cannot be used for input operands
+
+builtin_macros_assert_missing_comma = unexpected string literal
+ .suggestion = try adding a comma
builtin_macros_assert_requires_boolean = macro requires a boolean expression as an argument
.label = boolean expression required
@@ -12,51 +52,50 @@ builtin_macros_assert_requires_boolean = macro requires a boolean expression as
builtin_macros_assert_requires_expression = macro requires an expression as an argument
.suggestion = try removing semicolon
-builtin_macros_assert_missing_comma = unexpected string literal
- .suggestion = try adding a comma
+builtin_macros_bad_derive_target = `derive` may only be applied to `struct`s, `enum`s and `union`s
+ .label = not applicable here
+ .label2 = not a `struct`, `enum` or `union`
+
+builtin_macros_cannot_derive_union = this trait cannot be derived for unions
-builtin_macros_cfg_accessible_unspecified_path = `cfg_accessible` path is not specified
-builtin_macros_cfg_accessible_multiple_paths = multiple `cfg_accessible` paths are specified
-builtin_macros_cfg_accessible_literal_path = `cfg_accessible` path cannot be a literal
builtin_macros_cfg_accessible_has_args = `cfg_accessible` path cannot accept arguments
builtin_macros_cfg_accessible_indeterminate = cannot determine whether the path is accessible or not
-builtin_macros_concat_bytestr = cannot concatenate a byte string literal
-
-builtin_macros_concat_missing_literal = expected a literal
- .note = only literals (like `"foo"`, `-42` and `3.14`) can be passed to `concat!()`
+builtin_macros_cfg_accessible_literal_path = `cfg_accessible` path cannot be a literal
+builtin_macros_cfg_accessible_multiple_paths = multiple `cfg_accessible` paths are specified
+builtin_macros_cfg_accessible_unspecified_path = `cfg_accessible` path is not specified
+builtin_macros_concat_bytes_array = cannot concatenate doubly nested array
+ .note = byte strings are treated as arrays of bytes
+ .help = try flattening the array
-builtin_macros_concat_bytes_missing_literal = expected a byte literal
- .note = only byte literals (like `b"foo"`, `b's'` and `[3, 4, 5]`) can be passed to `concat_bytes!()`
+builtin_macros_concat_bytes_bad_repeat = repeat count is not a positive number
builtin_macros_concat_bytes_invalid = cannot concatenate {$lit_kind} literals
.byte_char = try using a byte character
.byte_str = try using a byte string
.number_array = try wrapping the number in an array
-builtin_macros_concat_bytes_oob = numeric literal is out of bounds
+builtin_macros_concat_bytes_missing_literal = expected a byte literal
+ .note = only byte literals (like `b"foo"`, `b's'` and `[3, 4, 5]`) can be passed to `concat_bytes!()`
builtin_macros_concat_bytes_non_u8 = numeric literal is not a `u8`
-builtin_macros_concat_bytes_array = cannot concatenate doubly nested array
- .note = byte strings are treated as arrays of bytes
- .help = try flattening the array
+builtin_macros_concat_bytes_oob = numeric literal is out of bounds
-builtin_macros_concat_bytes_bad_repeat = repeat count is not a positive number
+builtin_macros_concat_bytestr = cannot concatenate a byte string literal
+
+builtin_macros_concat_idents_ident_args = `concat_idents!()` requires ident args
builtin_macros_concat_idents_missing_args = `concat_idents!()` takes 1 or more arguments
builtin_macros_concat_idents_missing_comma = `concat_idents!()` expecting comma
-builtin_macros_concat_idents_ident_args = `concat_idents!()` requires ident args
+builtin_macros_concat_missing_literal = expected a literal
+ .note = only literals (like `"foo"`, `-42` and `3.14`) can be passed to `concat!()`
-builtin_macros_bad_derive_target = `derive` may only be applied to `struct`s, `enum`s and `union`s
- .label = not applicable here
- .label2 = not a `struct`, `enum` or `union`
+builtin_macros_default_arg = `#[default]` attribute does not accept a value
+ .suggestion = try using `#[default]`
-builtin_macros_unexpected_lit = expected path to a trait, found literal
- .label = not a trait
- .str_lit = try using `#[derive({$sym})]`
- .other = for example, write `#[derive(Debug)]` for `Debug`
+builtin_macros_derive_macro_call = `derive` cannot be used on items with type macros
builtin_macros_derive_path_args_list = traits in `#[derive(...)]` don't accept arguments
.suggestion = remove the arguments
@@ -64,66 +103,38 @@ builtin_macros_derive_path_args_list = traits in `#[derive(...)]` don't accept a
builtin_macros_derive_path_args_value = traits in `#[derive(...)]` don't accept values
.suggestion = remove the value
-builtin_macros_derive_macro_call = `derive` cannot be used on items with type macros
-
-builtin_macros_cannot_derive_union = this trait cannot be derived for unions
-
-builtin_macros_no_default_variant = no default declared
- .help = make a unit variant default by placing `#[default]` above it
- .suggestion = make `{$ident}` default
-
-builtin_macros_multiple_defaults = multiple declared defaults
- .label = first default
- .additional = additional default
- .note = only one variant can be default
- .suggestion = make `{$ident}` default
-
-builtin_macros_non_unit_default = the `#[default]` attribute may only be used on unit enum variants
- .help = consider a manual implementation of `Default`
-
-builtin_macros_non_exhaustive_default = default variant must be exhaustive
- .label = declared `#[non_exhaustive]` here
- .help = consider a manual implementation of `Default`
-
-builtin_macros_multiple_default_attrs = multiple `#[default]` attributes
- .note = only one `#[default]` attribute is needed
- .label = `#[default]` used here
- .label_again = `#[default]` used again here
- .help = try removing {$only_one ->
- [true] this
- *[false] these
- }
-
-builtin_macros_default_arg = `#[default]` attribute does not accept a value
- .suggestion = try using `#[default]`
-
-builtin_macros_env_takes_args = `env!()` takes 1 or 2 arguments
-
builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time
.cargo = Cargo sets build script variables at run time. Use `std::env::var("{$var}")` instead
.other = use `std::env::var("{$var}")` to read the variable at run time
-builtin_macros_format_requires_string = requires at least a format string argument
+builtin_macros_env_takes_args = `env!()` takes 1 or 2 arguments
+
+builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
builtin_macros_format_duplicate_arg = duplicate argument named `{$ident}`
.label1 = previously here
.label2 = duplicate argument
+builtin_macros_format_no_arg_named = there is no argument named `{$name}`
+ .note = did you intend to capture a variable `{$name}` from the surrounding scope?
+ .note2 = to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
+
+builtin_macros_format_pos_mismatch = {$n} positional {$n ->
+ [one] argument
+ *[more] arguments
+ } in format string, but {$desc}
+
builtin_macros_format_positional_after_named = positional arguments cannot follow named arguments
.label = positional arguments must be before named arguments
.named_args = named argument
+builtin_macros_format_requires_string = requires at least a format string argument
+
builtin_macros_format_string_invalid = invalid format string: {$desc}
.label = {$label1} in format string
.note = {$note}
.second_label = {$label}
-builtin_macros_sugg = consider using a positional formatting argument instead
-
-builtin_macros_format_no_arg_named = there is no argument named `{$name}`
- .note = did you intend to capture a variable `{$name}` from the surrounding scope?
- .note2 = to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
-
builtin_macros_format_unknown_trait = unknown format trait `{$ty}`
.note = the only appropriate formatting traits are:
- ``, which uses the `Display` trait
@@ -145,7 +156,49 @@ builtin_macros_format_unused_arg = {$named ->
builtin_macros_format_unused_args = multiple unused formatting arguments
.label = multiple missing formatting specifiers
-builtin_macros_format_pos_mismatch = {$n} positional {$n ->
- [one] argument
- *[more] arguments
- } in format string, but {$desc}
+builtin_macros_global_asm_clobber_abi = `clobber_abi` cannot be used with `global_asm!`
+
+builtin_macros_multiple_default_attrs = multiple `#[default]` attributes
+ .note = only one `#[default]` attribute is needed
+ .label = `#[default]` used here
+ .label_again = `#[default]` used again here
+ .help = try removing {$only_one ->
+ [true] this
+ *[false] these
+ }
+
+builtin_macros_multiple_defaults = multiple declared defaults
+ .label = first default
+ .additional = additional default
+ .note = only one variant can be default
+ .suggestion = make `{$ident}` default
+
+builtin_macros_no_default_variant = no default declared
+ .help = make a unit variant default by placing `#[default]` above it
+ .suggestion = make `{$ident}` default
+
+builtin_macros_non_exhaustive_default = default variant must be exhaustive
+ .label = declared `#[non_exhaustive]` here
+ .help = consider a manual implementation of `Default`
+
+builtin_macros_non_unit_default = the `#[default]` attribute may only be used on unit enum variants
+ .help = consider a manual implementation of `Default`
+
+builtin_macros_requires_cfg_pattern =
+ macro requires a cfg-pattern as an argument
+ .label = cfg-pattern required
+
+builtin_macros_sugg = consider using a positional formatting argument instead
+
+builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests
+ .label = `{$kind}` because of this
+
+builtin_macros_test_case_non_item = `#[test_case]` attribute is only allowed on items
+
+builtin_macros_test_runner_invalid = `test_runner` argument must be a path
+builtin_macros_test_runner_nargs = `#![test_runner(..)]` accepts exactly 1 argument
+
+builtin_macros_unexpected_lit = expected path to a trait, found literal
+ .label = not a trait
+ .str_lit = try using `#[derive({$sym})]`
+ .other = for example, write `#[derive(Debug)]` for `Debug`
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 8c1579baa..5217e317a 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -2,9 +2,10 @@ use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter};
use rustc_ast::tokenstream::TokenStream;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_errors::{Applicability, PResult};
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
+use rustc_errors::PResult;
use rustc_expand::base::{self, *};
+use rustc_index::bit_set::GrowableBitSet;
use rustc_parse::parser::Parser;
use rustc_parse_format as parse;
use rustc_session::lint;
@@ -15,11 +16,13 @@ use rustc_span::{InnerSpan, Span};
use rustc_target::asm::InlineAsmArch;
use smallvec::smallvec;
+use crate::errors;
+
pub struct AsmArgs {
pub templates: Vec<P<ast::Expr>>,
pub operands: Vec<(ast::InlineAsmOperand, Span)>,
- named_args: FxHashMap<Symbol, usize>,
- reg_args: FxHashSet<usize>,
+ named_args: FxIndexMap<Symbol, usize>,
+ reg_args: GrowableBitSet<usize>,
pub clobber_abis: Vec<(Symbol, Span)>,
options: ast::InlineAsmOptions,
pub options_spans: Vec<Span>,
@@ -47,15 +50,15 @@ pub fn parse_asm_args<'a>(
let diag = &sess.span_diagnostic;
if p.token == token::Eof {
- return Err(diag.struct_span_err(sp, "requires at least a template string argument"));
+ return Err(diag.create_err(errors::AsmRequiresTemplate { span: sp }));
}
let first_template = p.parse_expr()?;
let mut args = AsmArgs {
templates: vec![first_template],
operands: vec![],
- named_args: FxHashMap::default(),
- reg_args: FxHashSet::default(),
+ named_args: Default::default(),
+ reg_args: Default::default(),
clobber_abis: Vec::new(),
options: ast::InlineAsmOptions::empty(),
options_spans: vec![],
@@ -66,10 +69,7 @@ pub fn parse_asm_args<'a>(
if !p.eat(&token::Comma) {
if allow_templates {
// After a template string, we always expect *only* a comma...
- let mut err = diag.struct_span_err(p.token.span, "expected token: `,`");
- err.span_label(p.token.span, "expected `,`");
- p.maybe_annotate_with_ascription(&mut err, false);
- return Err(err);
+ return Err(diag.create_err(errors::AsmExpectedComma { span: p.token.span }));
} else {
// ...after that delegate to `expect` to also include the other expected tokens.
return Err(p.expect(&token::Comma).err().unwrap());
@@ -110,7 +110,7 @@ pub fn parse_asm_args<'a>(
let op = if !is_global_asm && p.eat_keyword(kw::In) {
let reg = parse_reg(p, &mut explicit_reg)?;
if p.eat_keyword(kw::Underscore) {
- let err = diag.struct_span_err(p.token.span, "_ cannot be used for input operands");
+ let err = diag.create_err(errors::AsmUnderscoreInput { span: p.token.span });
return Err(err);
}
let expr = p.parse_expr()?;
@@ -126,7 +126,7 @@ pub fn parse_asm_args<'a>(
} else if !is_global_asm && p.eat_keyword(sym::inout) {
let reg = parse_reg(p, &mut explicit_reg)?;
if p.eat_keyword(kw::Underscore) {
- let err = diag.struct_span_err(p.token.span, "_ cannot be used for input operands");
+ let err = diag.create_err(errors::AsmUnderscoreInput { span: p.token.span });
return Err(err);
}
let expr = p.parse_expr()?;
@@ -140,7 +140,7 @@ pub fn parse_asm_args<'a>(
} else if !is_global_asm && p.eat_keyword(sym::inlateout) {
let reg = parse_reg(p, &mut explicit_reg)?;
if p.eat_keyword(kw::Underscore) {
- let err = diag.struct_span_err(p.token.span, "_ cannot be used for input operands");
+ let err = diag.create_err(errors::AsmUnderscoreInput { span: p.token.span });
return Err(err);
}
let expr = p.parse_expr()?;
@@ -158,7 +158,7 @@ pub fn parse_asm_args<'a>(
let expr = p.parse_expr()?;
let ast::ExprKind::Path(qself, path) = &expr.kind else {
let err = diag
- .struct_span_err(expr.span, "expected a path for argument to `sym`");
+ .create_err(errors::AsmSymNoPath { span: expr.span });
return Err(err);
};
let sym = ast::InlineAsmSym {
@@ -179,13 +179,10 @@ pub fn parse_asm_args<'a>(
) => {}
ast::ExprKind::MacCall(..) => {}
_ => {
- let errstr = if is_global_asm {
- "expected operand, options, or additional template string"
- } else {
- "expected operand, clobber_abi, options, or additional template string"
- };
- let mut err = diag.struct_span_err(template.span, errstr);
- err.span_label(template.span, errstr);
+ let err = diag.create_err(errors::AsmExpectedOther {
+ span: template.span,
+ is_global_asm,
+ });
return Err(err);
}
}
@@ -205,33 +202,21 @@ pub fn parse_asm_args<'a>(
// of the argument available.
if explicit_reg {
if name.is_some() {
- diag.struct_span_err(span, "explicit register arguments cannot have names").emit();
+ diag.emit_err(errors::AsmExplicitRegisterName { span });
}
args.reg_args.insert(slot);
} else if let Some(name) = name {
if let Some(&prev) = args.named_args.get(&name) {
- diag.struct_span_err(span, &format!("duplicate argument named `{}`", name))
- .span_label(args.operands[prev].1, "previously here")
- .span_label(span, "duplicate argument")
- .emit();
+ diag.emit_err(errors::AsmDuplicateArg { span, name, prev: args.operands[prev].1 });
continue;
}
args.named_args.insert(name, slot);
} else {
if !args.named_args.is_empty() || !args.reg_args.is_empty() {
- let mut err = diag.struct_span_err(
- span,
- "positional arguments cannot follow named arguments \
- or explicit register arguments",
- );
- err.span_label(span, "positional argument");
- for pos in args.named_args.values() {
- err.span_label(args.operands[*pos].1, "named argument");
- }
- for pos in &args.reg_args {
- err.span_label(args.operands[*pos].1, "explicit register argument");
- }
- err.emit();
+ let named = args.named_args.values().map(|p| args.operands[*p].1).collect();
+ let explicit = args.reg_args.iter().map(|p| args.operands[p].1).collect();
+
+ diag.emit_err(errors::AsmPositionalAfter { span, named, explicit });
}
}
}
@@ -240,25 +225,19 @@ pub fn parse_asm_args<'a>(
&& args.options.contains(ast::InlineAsmOptions::READONLY)
{
let spans = args.options_spans.clone();
- diag.struct_span_err(spans, "the `nomem` and `readonly` options are mutually exclusive")
- .emit();
+ diag.emit_err(errors::AsmMutuallyExclusive { spans, opt1: "nomem", opt2: "readonly" });
}
if args.options.contains(ast::InlineAsmOptions::PURE)
&& args.options.contains(ast::InlineAsmOptions::NORETURN)
{
let spans = args.options_spans.clone();
- diag.struct_span_err(spans, "the `pure` and `noreturn` options are mutually exclusive")
- .emit();
+ diag.emit_err(errors::AsmMutuallyExclusive { spans, opt1: "pure", opt2: "noreturn" });
}
if args.options.contains(ast::InlineAsmOptions::PURE)
&& !args.options.intersects(ast::InlineAsmOptions::NOMEM | ast::InlineAsmOptions::READONLY)
{
let spans = args.options_spans.clone();
- diag.struct_span_err(
- spans,
- "the `pure` option must be combined with either `nomem` or `readonly`",
- )
- .emit();
+ diag.emit_err(errors::AsmPureCombine { spans });
}
let mut have_real_output = false;
@@ -285,41 +264,28 @@ pub fn parse_asm_args<'a>(
}
}
if args.options.contains(ast::InlineAsmOptions::PURE) && !have_real_output {
- diag.struct_span_err(
- args.options_spans.clone(),
- "asm with the `pure` option must have at least one output",
- )
- .emit();
+ diag.emit_err(errors::AsmPureNoOutput { spans: args.options_spans.clone() });
}
if args.options.contains(ast::InlineAsmOptions::NORETURN) && !outputs_sp.is_empty() {
- let err = diag
- .struct_span_err(outputs_sp, "asm outputs are not allowed with the `noreturn` option");
-
+ let err = diag.create_err(errors::AsmNoReturn { outputs_sp });
// Bail out now since this is likely to confuse MIR
return Err(err);
}
if args.clobber_abis.len() > 0 {
if is_global_asm {
- let err = diag.struct_span_err(
- args.clobber_abis.iter().map(|(_, span)| *span).collect::<Vec<Span>>(),
- "`clobber_abi` cannot be used with `global_asm!`",
- );
+ let err = diag.create_err(errors::GlobalAsmClobberAbi {
+ spans: args.clobber_abis.iter().map(|(_, span)| *span).collect(),
+ });
// Bail out now since this is likely to confuse later stages
return Err(err);
}
if !regclass_outputs.is_empty() {
- diag.struct_span_err(
- regclass_outputs.clone(),
- "asm with `clobber_abi` must specify explicit registers for outputs",
- )
- .span_labels(
- args.clobber_abis.iter().map(|(_, span)| *span).collect::<Vec<Span>>(),
- "clobber_abi",
- )
- .span_labels(regclass_outputs, "generic outputs")
- .emit();
+ diag.emit_err(errors::AsmClobberNoReg {
+ spans: regclass_outputs,
+ clobbers: args.clobber_abis.iter().map(|(_, span)| *span).collect(),
+ });
}
}
@@ -331,25 +297,9 @@ pub fn parse_asm_args<'a>(
/// This function must be called immediately after the option token is parsed.
/// Otherwise, the suggestion will be incorrect.
fn err_duplicate_option(p: &mut Parser<'_>, symbol: Symbol, span: Span) {
- let mut err = p
- .sess
- .span_diagnostic
- .struct_span_err(span, &format!("the `{}` option was already provided", symbol));
- err.span_label(span, "this option was already provided");
-
// Tool-only output
- let mut full_span = span;
- if p.token.kind == token::Comma {
- full_span = full_span.to(p.token.span);
- }
- err.tool_only_span_suggestion(
- full_span,
- "remove this option",
- "",
- Applicability::MachineApplicable,
- );
-
- err.emit();
+ let full_span = if p.token.kind == token::Comma { span.to(p.token.span) } else { span };
+ p.sess.span_diagnostic.emit_err(errors::AsmOptAlreadyprovided { span, symbol, full_span });
}
/// Try to set the provided option in the provided `AsmArgs`.
@@ -497,8 +447,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
// Register operands are implicitly used since they are not allowed to be
// referenced in the template string.
let mut used = vec![false; args.operands.len()];
- for pos in &args.reg_args {
- used[*pos] = true;
+ for pos in args.reg_args.iter() {
+ used[pos] = true;
}
let named_pos: FxHashMap<usize, Symbol> =
args.named_args.iter().map(|(&sym, &idx)| (idx, sym)).collect();
@@ -600,11 +550,11 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
if !parser.errors.is_empty() {
let err = parser.errors.remove(0);
let err_sp = template_span.from_inner(InnerSpan::new(err.span.start, err.span.end));
- let msg = &format!("invalid asm template string: {}", err.description);
+ let msg = format!("invalid asm template string: {}", err.description);
let mut e = ecx.struct_span_err(err_sp, msg);
e.span_label(err_sp, err.label + " in asm template string");
if let Some(note) = err.note {
- e.note(&note);
+ e.note(note);
}
if let Some((label, span)) = err.secondary_label {
let err_sp = template_span.from_inner(InnerSpan::new(span.start, span.end));
@@ -632,10 +582,10 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
parse::ArgumentIs(idx) | parse::ArgumentImplicitlyIs(idx) => {
if idx >= args.operands.len()
|| named_pos.contains_key(&idx)
- || args.reg_args.contains(&idx)
+ || args.reg_args.contains(idx)
{
let msg = format!("invalid reference to argument at index {}", idx);
- let mut err = ecx.struct_span_err(span, &msg);
+ let mut err = ecx.struct_span_err(span, msg);
err.span_label(span, "from here");
let positional_args = args.operands.len()
@@ -651,7 +601,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
1 => format!("there is 1 {}argument", positional),
x => format!("there are {} {}arguments", x, positional),
};
- err.note(&msg);
+ err.note(msg);
if named_pos.contains_key(&idx) {
err.span_label(args.operands[idx].1, "named argument");
@@ -659,7 +609,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
args.operands[idx].1,
"named arguments cannot be referenced by position",
);
- } else if args.reg_args.contains(&idx) {
+ } else if args.reg_args.contains(idx) {
err.span_label(
args.operands[idx].1,
"explicit register argument",
@@ -688,7 +638,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
ecx.struct_span_err(
template_span
.from_inner(InnerSpan::new(span.start, span.end)),
- &msg,
+ msg,
)
.emit();
None
@@ -705,11 +655,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
.ty_span
.map(|sp| template_sp.from_inner(InnerSpan::new(sp.start, sp.end)))
.unwrap_or(template_sp);
- ecx.struct_span_err(
- span,
- "asm template modifier must be a single character",
- )
- .emit();
+ ecx.emit_err(errors::AsmModifierInvalid { span });
modifier = None;
}
@@ -758,7 +704,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
let (sp, msg) = unused_operands.into_iter().next().unwrap();
let mut err = ecx.struct_span_err(sp, msg);
err.span_label(sp, msg);
- err.help(&format!(
+ err.help(format!(
"if this argument is intentionally unused, \
consider using it in an asm comment: `\"/*{} */\"`",
help_str
@@ -773,7 +719,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
for (sp, msg) in unused_operands {
err.span_label(sp, msg);
}
- err.help(&format!(
+ err.help(format!(
"if these arguments are intentionally unused, \
consider using them in an asm comment: `\"/*{} */\"`",
help_str
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index 0de424be2..ab4ea9c8c 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -61,7 +61,6 @@ pub fn expand_assert<'cx>(
delim: MacDelimiter::Parenthesis,
tokens,
}),
- prior_type_ascription: None,
})),
);
expr_if_not(cx, call_site_span, cond_expr, then, None)
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index c9e3cd486..b619e80e1 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -182,7 +182,6 @@ impl<'cx, 'a> Context<'cx, 'a> {
delim: MacDelimiter::Parenthesis,
tokens: initial.into_iter().chain(captures).collect::<TokenStream>(),
}),
- prior_type_ascription: None,
})),
)
}
@@ -234,10 +233,19 @@ impl<'cx, 'a> Context<'cx, 'a> {
ExprKind::Cast(local_expr, _) => {
self.manage_cond_expr(local_expr);
}
+ ExprKind::If(local_expr, _, _) => {
+ self.manage_cond_expr(local_expr);
+ }
ExprKind::Index(prefix, suffix) => {
self.manage_cond_expr(prefix);
self.manage_cond_expr(suffix);
}
+ ExprKind::Let(_, local_expr, _) => {
+ self.manage_cond_expr(local_expr);
+ }
+ ExprKind::Match(local_expr, _) => {
+ self.manage_cond_expr(local_expr);
+ }
ExprKind::MethodCall(call) => {
for arg in &mut call.args {
self.manage_cond_expr(arg);
@@ -288,7 +296,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
ExprKind::Assign(_, _, _)
| ExprKind::AssignOp(_, _, _)
| ExprKind::Async(_, _)
- | ExprKind::Await(_)
+ | ExprKind::Await(_, _)
| ExprKind::Block(_, _)
| ExprKind::Break(_, _)
| ExprKind::Closure(_)
@@ -296,16 +304,14 @@ impl<'cx, 'a> Context<'cx, 'a> {
| ExprKind::Continue(_)
| ExprKind::Err
| ExprKind::Field(_, _)
- | ExprKind::FormatArgs(_)
| ExprKind::ForLoop(_, _, _, _)
- | ExprKind::If(_, _, _)
+ | ExprKind::FormatArgs(_)
| ExprKind::IncludedBytes(..)
| ExprKind::InlineAsm(_)
- | ExprKind::Let(_, _, _)
| ExprKind::Lit(_)
| ExprKind::Loop(_, _, _)
| ExprKind::MacCall(_)
- | ExprKind::Match(_, _)
+ | ExprKind::OffsetOf(_, _)
| ExprKind::Path(_, _)
| ExprKind::Ret(_)
| ExprKind::Try(_)
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index 750f1fe12..49401e9ca 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -119,7 +119,7 @@ impl<'ast> visit::Visitor<'ast> for CfgFinder {
self.has_cfg_or_cfg_attr = self.has_cfg_or_cfg_attr
|| attr
.ident()
- .map_or(false, |ident| ident.name == sym::cfg || ident.name == sym::cfg_attr);
+ .is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr);
}
}
@@ -166,7 +166,9 @@ impl CfgEval<'_, '_> {
))
},
Annotatable::Stmt(_) => |parser| {
- Ok(Annotatable::Stmt(P(parser.parse_stmt(ForceCollect::Yes)?.unwrap())))
+ Ok(Annotatable::Stmt(P(parser
+ .parse_stmt_without_recovery(false, ForceCollect::Yes)?
+ .unwrap())))
},
Annotatable::Expr(_) => {
|parser| Ok(Annotatable::Expr(parser.parse_expr_force_collect()?))
diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs
index b92964d03..50e88ae2e 100644
--- a/compiler/rustc_builtin_macros/src/concat.rs
+++ b/compiler/rustc_builtin_macros/src/concat.rs
@@ -32,6 +32,10 @@ pub fn expand_concat(
Ok(ast::LitKind::Bool(b)) => {
accumulator.push_str(&b.to_string());
}
+ Ok(ast::LitKind::CStr(..)) => {
+ cx.span_err(e.span, "cannot concatenate a C string literal");
+ has_errors = true;
+ }
Ok(ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..)) => {
cx.emit_err(errors::ConcatBytestr { span: e.span });
has_errors = true;
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index ba639c0a9..5ef35af0a 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -18,6 +18,11 @@ fn invalid_type_err(
};
let snippet = cx.sess.source_map().span_to_snippet(span).ok();
match ast::LitKind::from_token_lit(token_lit) {
+ Ok(ast::LitKind::CStr(_, _)) => {
+ // FIXME(c_str_literals): should concatenation of C string literals
+ // include the null bytes in the end?
+ cx.span_err(span, "cannot concatenate C string literals");
+ }
Ok(ast::LitKind::Char(_)) => {
let sugg =
snippet.map(|snippet| ConcatBytesInvalidSuggestion::CharLit { span, snippet });
diff --git a/compiler/rustc_builtin_macros/src/concat_idents.rs b/compiler/rustc_builtin_macros/src/concat_idents.rs
index 8c737f043..ee56d45c9 100644
--- a/compiler/rustc_builtin_macros/src/concat_idents.rs
+++ b/compiler/rustc_builtin_macros/src/concat_idents.rs
@@ -19,7 +19,7 @@ pub fn expand_concat_idents<'cx>(
}
let mut res_str = String::new();
- for (i, e) in tts.into_trees().enumerate() {
+ for (i, e) in tts.trees().enumerate() {
if i & 1 == 1 {
match e {
TokenTree::Token(Token { kind: token::Comma, .. }, _) => {}
diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
index 0481a1189..2c8e6f99c 100644
--- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
@@ -27,3 +27,26 @@ pub fn expand_deriving_copy(
trait_def.expand(cx, mitem, item, push);
}
+
+pub fn expand_deriving_const_param_ty(
+ cx: &mut ExtCtxt<'_>,
+ span: Span,
+ mitem: &MetaItem,
+ item: &Annotatable,
+ push: &mut dyn FnMut(Annotatable),
+ is_const: bool,
+) {
+ let trait_def = TraitDef {
+ span,
+ path: path_std!(marker::ConstParamTy),
+ skip_path_as_bound: false,
+ needs_copy_as_bound_if_packed: false,
+ additional_bounds: Vec::new(),
+ supports_unions: false,
+ methods: Vec::new(),
+ associated_types: Vec::new(),
+ is_const,
+ };
+
+ trait_def.expand(cx, mitem, item, push);
+}
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index dfee2d3ce..988356374 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -145,7 +145,7 @@ fn cs_clone_simple(
}
_ => cx.span_bug(
trait_span,
- &format!("unexpected substructure in simple `derive({})`", name),
+ format!("unexpected substructure in simple `derive({})`", name),
),
}
}
@@ -179,10 +179,10 @@ fn cs_clone(
vdata = &variant.data;
}
EnumTag(..) | AllFieldlessEnum(..) => {
- cx.span_bug(trait_span, &format!("enum tags in `derive({})`", name,))
+ cx.span_bug(trait_span, format!("enum tags in `derive({})`", name,))
}
StaticEnum(..) | StaticStruct(..) => {
- cx.span_bug(trait_span, &format!("associated function in `derive({})`", name))
+ cx.span_bug(trait_span, format!("associated function in `derive({})`", name))
}
}
@@ -194,7 +194,7 @@ fn cs_clone(
let Some(ident) = field.name else {
cx.span_bug(
trait_span,
- &format!("unnamed field in normal struct in `derive({})`", name,),
+ format!("unnamed field in normal struct in `derive({})`", name,),
);
};
let call = subcall(cx, field);
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index e5a003315..4ba09335c 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -1038,7 +1038,7 @@ impl<'a> MethodDef<'a> {
/// `&self.x` because that might cause an unaligned ref. So for any trait
/// method that takes a reference, we use a local block to force a copy.
/// This requires that the field impl `Copy`.
- /// ```
+ /// ```rust,ignore (example)
/// # struct A { x: u8, y: u8 }
/// impl PartialEq for A {
/// fn eq(&self, other: &A) -> bool {
@@ -1591,7 +1591,7 @@ impl<'a> TraitDef<'a> {
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
sp,
ast::CRATE_NODE_ID,
- &format!(
+ format!(
"{} slice in a packed struct that derives a built-in trait",
ty
),
diff --git a/compiler/rustc_builtin_macros/src/edition_panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs
index b2a21611d..ef0db23ff 100644
--- a/compiler/rustc_builtin_macros/src/edition_panic.rs
+++ b/compiler/rustc_builtin_macros/src/edition_panic.rs
@@ -63,7 +63,6 @@ fn expand<'cx>(
delim: MacDelimiter::Parenthesis,
tokens: tts,
}),
- prior_type_ascription: None,
})),
),
)
diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs
index 58c972738..8f64e3328 100644
--- a/compiler/rustc_builtin_macros/src/env.rs
+++ b/compiler/rustc_builtin_macros/src/env.rs
@@ -63,7 +63,8 @@ pub fn expand_env<'cx>(
Some(exprs) => exprs.into_iter(),
};
- let Some((var, _style)) = expr_to_string(cx, exprs.next().unwrap(), "expected string literal") else {
+ let var_expr = exprs.next().unwrap();
+ let Some((var, _)) = expr_to_string(cx, var_expr.clone(), "expected string literal") else {
return DummyResult::any(sp);
};
@@ -71,7 +72,7 @@ pub fn expand_env<'cx>(
None => None,
Some(second) => match expr_to_string(cx, second, "expected string literal") {
None => return DummyResult::any(sp),
- Some((s, _style)) => Some(s),
+ Some((s, _)) => Some(s),
},
};
@@ -80,10 +81,15 @@ pub fn expand_env<'cx>(
cx.sess.parse_sess.env_depinfo.borrow_mut().insert((var, value));
let e = match value {
None => {
+ // Use the string literal in the code in the diagnostic to avoid confusing diagnostics,
+ // e.g. when the literal contains escape sequences.
+ let ast::ExprKind::Lit(ast::token::Lit { kind: ast::token::LitKind::Str, symbol: original_var, ..}) = &var_expr.kind else {
+ unreachable!("`expr_to_string` ensures this is a string lit")
+ };
cx.emit_err(errors::EnvNotDefined {
span: sp,
msg: custom_msg,
- var,
+ var: *original_var,
help: custom_msg.is_none().then(|| help_for_missing_env_var(var.as_str())),
});
return DummyResult::any(sp);
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index 630f9b87b..d0d786460 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -1,5 +1,6 @@
use rustc_errors::{
- AddToDiagnostic, EmissionGuarantee, IntoDiagnostic, MultiSpan, SingleLabelManySpans,
+ AddToDiagnostic, DiagnosticBuilder, EmissionGuarantee, Handler, IntoDiagnostic, MultiSpan,
+ SingleLabelManySpans,
};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{symbol::Ident, Span, Symbol};
@@ -370,11 +371,12 @@ pub(crate) struct EnvNotDefined {
// Hand-written implementation to support custom user messages
impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for EnvNotDefined {
#[track_caller]
- fn into_diagnostic(
- self,
- handler: &'a rustc_errors::Handler,
- ) -> rustc_errors::DiagnosticBuilder<'a, G> {
+ fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, G> {
let mut diag = if let Some(msg) = self.msg {
+ #[expect(
+ rustc::untranslatable_diagnostic,
+ reason = "cannot translate user-provided messages"
+ )]
handler.struct_diagnostic(msg.as_str())
} else {
handler.struct_diagnostic(crate::fluent_generated::builtin_macros_env_not_defined)
@@ -551,3 +553,182 @@ pub(crate) struct FormatPositionalMismatch {
#[subdiagnostic]
pub(crate) highlight: SingleLabelManySpans,
}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_test_case_non_item)]
+pub(crate) struct TestCaseNonItem {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_test_bad_fn)]
+pub(crate) struct TestBadFn {
+ #[primary_span]
+ pub(crate) span: Span,
+ #[label]
+ pub(crate) cause: Span,
+ pub(crate) kind: &'static str,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_explicit_register_name)]
+pub(crate) struct AsmExplicitRegisterName {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_mutually_exclusive)]
+pub(crate) struct AsmMutuallyExclusive {
+ #[primary_span]
+ pub(crate) spans: Vec<Span>,
+ pub(crate) opt1: &'static str,
+ pub(crate) opt2: &'static str,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_pure_combine)]
+pub(crate) struct AsmPureCombine {
+ #[primary_span]
+ pub(crate) spans: Vec<Span>,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_pure_no_output)]
+pub(crate) struct AsmPureNoOutput {
+ #[primary_span]
+ pub(crate) spans: Vec<Span>,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_modifier_invalid)]
+pub(crate) struct AsmModifierInvalid {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_requires_template)]
+pub(crate) struct AsmRequiresTemplate {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_expected_comma)]
+pub(crate) struct AsmExpectedComma {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_underscore_input)]
+pub(crate) struct AsmUnderscoreInput {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_sym_no_path)]
+pub(crate) struct AsmSymNoPath {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_expected_other)]
+pub(crate) struct AsmExpectedOther {
+ #[primary_span]
+ #[label(builtin_macros_asm_expected_other)]
+ pub(crate) span: Span,
+ pub(crate) is_global_asm: bool,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_duplicate_arg)]
+pub(crate) struct AsmDuplicateArg {
+ #[primary_span]
+ #[label(builtin_macros_arg)]
+ pub(crate) span: Span,
+ #[label]
+ pub(crate) prev: Span,
+ pub(crate) name: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_pos_after)]
+pub(crate) struct AsmPositionalAfter {
+ #[primary_span]
+ #[label(builtin_macros_pos)]
+ pub(crate) span: Span,
+ #[label(builtin_macros_named)]
+ pub(crate) named: Vec<Span>,
+ #[label(builtin_macros_explicit)]
+ pub(crate) explicit: Vec<Span>,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_noreturn)]
+pub(crate) struct AsmNoReturn {
+ #[primary_span]
+ pub(crate) outputs_sp: Vec<Span>,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_global_asm_clobber_abi)]
+pub(crate) struct GlobalAsmClobberAbi {
+ #[primary_span]
+ pub(crate) spans: Vec<Span>,
+}
+
+pub(crate) struct AsmClobberNoReg {
+ pub(crate) spans: Vec<Span>,
+ pub(crate) clobbers: Vec<Span>,
+}
+
+impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for AsmClobberNoReg {
+ fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, G> {
+ let mut diag =
+ handler.struct_diagnostic(crate::fluent_generated::builtin_macros_asm_clobber_no_reg);
+ diag.set_span(self.spans.clone());
+ // eager translation as `span_labels` takes `AsRef<str>`
+ let lbl1 = handler.eagerly_translate_to_string(
+ crate::fluent_generated::builtin_macros_asm_clobber_abi,
+ [].into_iter(),
+ );
+ diag.span_labels(self.clobbers, &lbl1);
+ let lbl2 = handler.eagerly_translate_to_string(
+ crate::fluent_generated::builtin_macros_asm_clobber_outputs,
+ [].into_iter(),
+ );
+ diag.span_labels(self.spans, &lbl2);
+ diag
+ }
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_opt_already_provided)]
+pub(crate) struct AsmOptAlreadyprovided {
+ #[primary_span]
+ #[label]
+ pub(crate) span: Span,
+ pub(crate) symbol: Symbol,
+ #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
+ pub(crate) full_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_test_runner_invalid)]
+pub(crate) struct TestRunnerInvalid {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_test_runner_nargs)]
+pub(crate) struct TestRunnerNargs {
+ #[primary_span]
+ pub(crate) span: Span,
+}
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index f0fc61d7c..c59a733c0 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -141,13 +141,7 @@ fn parse_args<'a>(ecx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<
args: args
.named_args()
.iter()
- .filter_map(|a| {
- if let Some(ident) = a.kind.ident() {
- Some((a, ident))
- } else {
- None
- }
- })
+ .filter_map(|a| a.kind.ident().map(|ident| (a, ident)))
.map(|(arg, n)| n.span.to(arg.expr.span))
.collect(),
});
@@ -622,14 +616,14 @@ fn report_missing_placeholders(
} else {
diag.span_note(
sp,
- &format!("format specifiers use curly braces, and {}", trn),
+ format!("format specifiers use curly braces, and {}", trn),
);
}
} else {
if success {
- diag.help(&format!("`{}` should be written as `{}`", sub, trn));
+ diag.help(format!("`{}` should be written as `{}`", sub, trn));
} else {
- diag.note(&format!("`{}` should use curly braces, and {}", sub, trn));
+ diag.note(format!("`{}` should use curly braces, and {}", sub, trn));
}
}
}
@@ -783,7 +777,7 @@ fn report_invalid_references(
has_precision_star = true;
e.span_label(
*span,
- &format!(
+ format!(
"this precision flag adds an extra required argument at position {}, which is why there {} expected",
index,
if num_placeholders == 1 {
@@ -820,7 +814,7 @@ fn report_invalid_references(
};
e = ecx.struct_span_err(
span,
- &format!("invalid reference to positional {} ({})", arg_list, num_args_desc),
+ format!("invalid reference to positional {} ({})", arg_list, num_args_desc),
);
e.note("positional arguments are zero-based");
}
diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs
index bd9e903b6..bd5356575 100644
--- a/compiler/rustc_builtin_macros/src/format_foreign.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign.rs
@@ -562,15 +562,13 @@ pub(crate) mod printf {
}
if let Type = state {
- drop(c);
type_ = at.slice_between(next).unwrap();
// Don't use `move_to!` here, as we *can* be at the end of the input.
at = next;
}
- drop(c);
- drop(next);
+ let _ = c; // to avoid never used value
end = at;
let position = InnerSpan::new(start.at, end.at);
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 866cc5adb..f0d378d12 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -1,7 +1,7 @@
use crate::util::check_builtin_macro_attribute;
use rustc_ast::expand::allocator::{
- AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS,
+ global_fn_name, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS,
};
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, AttrVec, Expr, FnHeader, FnSig, Generics, Param, StmtKind};
@@ -40,8 +40,7 @@ pub fn expand(
// Generate a bunch of new items using the AllocFnFactory
let span = ecx.with_def_site_ctxt(item.span);
- let f =
- AllocFnFactory { span, ty_span, kind: AllocatorKind::Global, global: item.ident, cx: ecx };
+ let f = AllocFnFactory { span, ty_span, global: item.ident, cx: ecx };
// Generate item statements for the allocator methods.
let stmts = ALLOCATOR_METHODS.iter().map(|method| f.allocator_fn(method)).collect();
@@ -63,7 +62,6 @@ pub fn expand(
struct AllocFnFactory<'a, 'b> {
span: Span,
ty_span: Span,
- kind: AllocatorKind,
global: Ident,
cx: &'b ExtCtxt<'a>,
}
@@ -92,7 +90,7 @@ impl AllocFnFactory<'_, '_> {
}));
let item = self.cx.item(
self.span,
- Ident::from_str_and_span(&self.kind.fn_name(method.name), self.span),
+ Ident::from_str_and_span(&global_fn_name(method.name), self.span),
self.attrs(),
kind,
);
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 37fbd03a6..ebf1448f5 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -1,7 +1,6 @@
//! This crate contains implementations of built-in macros and other code generating facilities
//! injecting code into the crate before it is lowered to HIR.
-#![allow(rustc::potential_query_instability)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(array_windows)]
#![feature(box_patterns)]
@@ -24,7 +23,7 @@ use crate::deriving::*;
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
use rustc_expand::proc_macro::BangProcMacro;
-use rustc_macros::fluent_messages;
+use rustc_fluent_macro::fluent_messages;
use rustc_span::symbol::sym;
mod alloc_error_handler;
@@ -116,6 +115,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
register_derive! {
Clone: clone::expand_deriving_clone,
Copy: bounds::expand_deriving_copy,
+ ConstParamTy: bounds::expand_deriving_const_param_ty,
Debug: debug::expand_deriving_debug,
Default: default::expand_deriving_default,
Eq: eq::expand_deriving_eq,
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index 378d5f39f..52b5601bb 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -194,7 +194,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
};
self.handler
- .struct_span_err(attr.span, &msg)
+ .struct_span_err(attr.span, msg)
.span_label(prev_attr.span, "previous attribute here")
.emit();
@@ -219,7 +219,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
pprust::path_to_string(&attr.get_normal_item().path),
);
- self.handler.span_err(attr.span, &msg);
+ self.handler.span_err(attr.span, msg);
return;
}
@@ -233,7 +233,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
pprust::path_to_string(&attr.get_normal_item().path),
);
- self.handler.span_err(attr.span, &msg);
+ self.handler.span_err(attr.span, msg);
return;
}
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index 0b17e92ef..e613b904d 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -150,7 +150,7 @@ pub fn expand_include<'cx>(
if self.p.token != token::Eof {
let token = pprust::token_to_string(&self.p.token);
let msg = format!("expected item, found `{}`", token);
- self.p.struct_span_err(self.p.token.span, &msg).emit();
+ self.p.struct_span_err(self.p.token.span, msg).emit();
}
break;
@@ -188,12 +188,12 @@ pub fn expand_include_str(
base::MacEager::expr(cx.expr_str(sp, interned_src))
}
Err(_) => {
- cx.span_err(sp, &format!("{} wasn't a utf-8 file", file.display()));
+ cx.span_err(sp, format!("{} wasn't a utf-8 file", file.display()));
DummyResult::any(sp)
}
},
Err(e) => {
- cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
+ cx.span_err(sp, format!("couldn't read {}: {}", file.display(), e));
DummyResult::any(sp)
}
}
@@ -221,7 +221,7 @@ pub fn expand_include_bytes(
base::MacEager::expr(expr)
}
Err(e) => {
- cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
+ cx.span_err(sp, format!("couldn't read {}: {}", file.display(), e));
DummyResult::any(sp)
}
}
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index 79d8be248..49ee276af 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -1,3 +1,4 @@
+use crate::errors;
/// The expansion from a test function to the appropriate test struct for libtest
/// Ideally, this code would be in libtest but for efficiency and error messages it lives here.
use crate::util::{check_builtin_macro_attribute, warn_on_duplicate_attribute};
@@ -40,12 +41,7 @@ pub fn expand_test_case(
unreachable!()
},
_ => {
- ecx.struct_span_err(
- anno_item.span(),
- "`#[test_case]` attribute is only allowed on items",
- )
- .emit();
-
+ ecx.emit_err(errors::TestCaseNonItem { span: anno_item.span() });
return vec![];
}
};
@@ -533,15 +529,11 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
match &i.kind {
ast::ItemKind::Fn(box ast::Fn { sig, generics, .. }) => {
if let ast::Unsafe::Yes(span) = sig.header.unsafety {
- sd.struct_span_err(i.span, "unsafe functions cannot be used for tests")
- .span_label(span, "`unsafe` because of this")
- .emit();
+ sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" });
return false;
}
if let ast::Async::Yes { span, .. } = sig.header.asyncness {
- sd.struct_span_err(i.span, "async functions cannot be used for tests")
- .span_label(span, "`async` because of this")
- .emit();
+ sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "async" });
return false;
}
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 80f497333..9bc1e27b4 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -19,6 +19,8 @@ use tracing::debug;
use std::{iter, mem};
+use crate::errors;
+
#[derive(Clone)]
struct Test {
span: Span,
@@ -230,7 +232,7 @@ fn generate_test_harness(
let expn_id = ext_cx.resolver.expansion_for_ast_pass(
DUMMY_SP,
AstPass::TestHarness,
- &[sym::test, sym::rustc_attrs],
+ &[sym::test, sym::rustc_attrs, sym::no_coverage],
None,
);
let def_site = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
@@ -311,6 +313,8 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
// #[rustc_main]
let main_attr = ecx.attr_word(sym::rustc_main, sp);
+ // #[no_coverage]
+ let no_coverage_attr = ecx.attr_word(sym::no_coverage, sp);
// pub fn main() { ... }
let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(ThinVec::new()));
@@ -340,7 +344,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
let main = P(ast::Item {
ident: main_id,
- attrs: thin_vec![main_attr],
+ attrs: thin_vec![main_attr, no_coverage_attr],
id: ast::DUMMY_NODE_ID,
kind: main,
vis: ast::Visibility { span: sp, kind: ast::VisibilityKind::Public, tokens: None },
@@ -385,11 +389,11 @@ fn get_test_runner(sd: &rustc_errors::Handler, krate: &ast::Crate) -> Option<ast
[single] => match single.meta_item() {
Some(meta_item) if meta_item.is_word() => return Some(meta_item.path.clone()),
_ => {
- sd.struct_span_err(span, "`test_runner` argument must be a path").emit();
+ sd.emit_err(errors::TestRunnerInvalid { span });
}
},
_ => {
- sd.struct_span_err(span, "`#![test_runner(..)]` accepts exactly 1 argument").emit();
+ sd.emit_err(errors::TestRunnerNargs { span });
}
}
None
diff --git a/compiler/rustc_builtin_macros/src/trace_macros.rs b/compiler/rustc_builtin_macros/src/trace_macros.rs
index cc5ae6894..9c98723e1 100644
--- a/compiler/rustc_builtin_macros/src/trace_macros.rs
+++ b/compiler/rustc_builtin_macros/src/trace_macros.rs
@@ -8,7 +8,7 @@ pub fn expand_trace_macros(
sp: Span,
tt: TokenStream,
) -> Box<dyn base::MacResult + 'static> {
- let mut cursor = tt.into_trees();
+ let mut cursor = tt.trees();
let mut err = false;
let value = match &cursor.next() {
Some(TokenTree::Token(token, _)) if token.is_keyword(kw::True) => true,