Skip to content

Commit

Permalink
Auto merge of rust-lang#110092 - clubby789:builtin-macros-translatabl…
Browse files Browse the repository at this point in the history
…e, r=compiler-errors

Migrate most of `rustc_builtin_macros` to diagnostic impls

cc rust-lang#100717

This is a couple of days work, but I decided to stop for now before the PR becomes too big. There's around 50 unresolved failures when `rustc::untranslatable_diagnostic` is denied, which I'll finish addressing once this PR goes thtough

A couple of outputs have changed, but in all instances I think the changes are an improvement/are more consistent with other diagnostics (although I'm happy to revert any which seem worse)
  • Loading branch information
bors committed Apr 11, 2023
2 parents dfe024e + 64f7597 commit 45749b2
Show file tree
Hide file tree
Showing 31 changed files with 978 additions and 349 deletions.
146 changes: 146 additions & 0 deletions compiler/rustc_builtin_macros/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,149 @@ builtin_macros_requires_cfg_pattern =
.label = cfg-pattern required
builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
builtin_macros_alloc_error_must_be_fn = alloc_error_handler must be a function
builtin_macros_assert_requires_boolean = macro requires a boolean expression as an argument
.label = boolean expression required
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_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_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_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_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_bad_repeat = repeat count is not a positive number
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_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_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_path_args_list = traits in `#[derive(...)]` don't accept arguments
.suggestion = remove the arguments
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_format_duplicate_arg = duplicate argument named `{$ident}`
.label1 = previously here
.label2 = duplicate argument
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_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
- `?`, which uses the `Debug` trait
- `e`, which uses the `LowerExp` trait
- `E`, which uses the `UpperExp` trait
- `o`, which uses the `Octal` trait
- `p`, which uses the `Pointer` trait
- `b`, which uses the `Binary` trait
- `x`, which uses the `LowerHex` trait
- `X`, which uses the `UpperHex` trait
.suggestion = use the `{$trait_name}` trait
builtin_macros_format_unused_arg = {$named ->
[true] named argument
*[false] argument
} never used
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}
3 changes: 2 additions & 1 deletion compiler/rustc_builtin_macros/src/alloc_error_handler.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::errors;
use crate::util::check_builtin_macro_attribute;

use rustc_ast::ptr::P;
Expand Down Expand Up @@ -31,7 +32,7 @@ pub fn expand(
{
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
} else {
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "alloc_error_handler must be a function");
ecx.sess.parse_sess.span_diagnostic.emit_err(errors::AllocErrorMustBeFn {span: item.span() });
return vec![orig_item];
};

Expand Down
28 changes: 6 additions & 22 deletions compiler/rustc_builtin_macros/src/assert.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
mod context;

use crate::edition_panic::use_panic_2021;
use crate::errors;
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
use rustc_ast::{DelimArgs, Expr, ExprKind, MacCall, MacDelimiter, Path, PathSegment, UnOp};
use rustc_ast_pretty::pprust;
use rustc_errors::{Applicability, PResult};
use rustc_errors::PResult;
use rustc_expand::base::{DummyResult, ExtCtxt, MacEager, MacResult};
use rustc_parse::parser::Parser;
use rustc_span::symbol::{sym, Ident, Symbol};
Expand Down Expand Up @@ -114,9 +115,7 @@ fn parse_assert<'a>(cx: &mut ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PRes
let mut parser = cx.new_parser_from_tts(stream);

if parser.token == token::Eof {
let mut err = cx.struct_span_err(sp, "macro requires a boolean expression as an argument");
err.span_label(sp, "boolean expression required");
return Err(err);
return Err(cx.create_err(errors::AssertRequiresBoolean { span: sp }));
}

let cond_expr = parser.parse_expr()?;
Expand All @@ -129,15 +128,7 @@ fn parse_assert<'a>(cx: &mut ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PRes
//
// Emit an error about semicolon and suggest removing it.
if parser.token == token::Semi {
let mut err = cx.struct_span_err(sp, "macro requires an expression as an argument");
err.span_suggestion(
parser.token.span,
"try removing semicolon",
"",
Applicability::MaybeIncorrect,
);
err.emit();

cx.emit_err(errors::AssertRequiresExpression { span: sp, token: parser.token.span });
parser.bump();
}

Expand All @@ -149,15 +140,8 @@ fn parse_assert<'a>(cx: &mut ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PRes
// Emit an error and suggest inserting a comma.
let custom_message =
if let token::Literal(token::Lit { kind: token::Str, .. }) = parser.token.kind {
let mut err = cx.struct_span_err(parser.token.span, "unexpected string literal");
let comma_span = parser.prev_token.span.shrink_to_hi();
err.span_suggestion_short(
comma_span,
"try adding a comma",
", ",
Applicability::MaybeIncorrect,
);
err.emit();
let comma = parser.prev_token.span.shrink_to_hi();
cx.emit_err(errors::AssertMissingComma { span: parser.token.span, comma });

parse_custom_message(&mut parser)
} else if parser.eat(&token::Comma) {
Expand Down
21 changes: 3 additions & 18 deletions compiler/rustc_builtin_macros/src/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
//! a literal `true` or `false` based on whether the given cfg matches the
//! current compilation environment.

use crate::errors;
use rustc_ast as ast;
use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_attr as attr;
use rustc_errors::PResult;
use rustc_expand::base::{self, *};
use rustc_macros::Diagnostic;
use rustc_span::Span;

pub fn expand_cfg(
Expand All @@ -35,34 +35,19 @@ pub fn expand_cfg(
}
}

#[derive(Diagnostic)]
#[diag(builtin_macros_requires_cfg_pattern)]
struct RequiresCfgPattern {
#[primary_span]
#[label]
span: Span,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_expected_one_cfg_pattern)]
struct OneCfgPattern {
#[primary_span]
span: Span,
}

fn parse_cfg<'a>(cx: &mut ExtCtxt<'a>, span: Span, tts: TokenStream) -> PResult<'a, ast::MetaItem> {
let mut p = cx.new_parser_from_tts(tts);

if p.token == token::Eof {
return Err(cx.create_err(RequiresCfgPattern { span }));
return Err(cx.create_err(errors::RequiresCfgPattern { span }));
}

let cfg = p.parse_meta_item()?;

let _ = p.eat(&token::Comma);

if !p.eat(&token::Eof) {
return Err(cx.create_err(OneCfgPattern { span }));
return Err(cx.create_err(errors::OneCfgPattern { span }));
}

Ok(cfg)
Expand Down
18 changes: 13 additions & 5 deletions compiler/rustc_builtin_macros/src/cfg_accessible.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Implementation of the `#[cfg_accessible(path)]` attribute macro.

use crate::errors;
use rustc_ast as ast;
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
use rustc_feature::AttributeTemplate;
Expand All @@ -10,15 +11,22 @@ use rustc_span::Span;
pub(crate) struct Expander;

fn validate_input<'a>(ecx: &mut ExtCtxt<'_>, mi: &'a ast::MetaItem) -> Option<&'a ast::Path> {
use errors::CfgAccessibleInvalid::*;
match mi.meta_item_list() {
None => {}
Some([]) => ecx.span_err(mi.span, "`cfg_accessible` path is not specified"),
Some([_, .., l]) => ecx.span_err(l.span(), "multiple `cfg_accessible` paths are specified"),
Some([]) => {
ecx.emit_err(UnspecifiedPath(mi.span));
}
Some([_, .., l]) => {
ecx.emit_err(MultiplePaths(l.span()));
}
Some([nmi]) => match nmi.meta_item() {
None => ecx.span_err(nmi.span(), "`cfg_accessible` path cannot be a literal"),
None => {
ecx.emit_err(LiteralPath(nmi.span()));
}
Some(mi) => {
if !mi.is_word() {
ecx.span_err(mi.span, "`cfg_accessible` path cannot accept arguments");
ecx.emit_err(HasArguments(mi.span));
}
return Some(&mi.path);
}
Expand Down Expand Up @@ -53,7 +61,7 @@ impl MultiItemModifier for Expander {
Ok(true) => ExpandResult::Ready(vec![item]),
Ok(false) => ExpandResult::Ready(Vec::new()),
Err(Indeterminate) if ecx.force_mode => {
ecx.span_err(span, "cannot determine whether the path is accessible or not");
ecx.emit_err(errors::CfgAccessibleIndeterminate { span });
ExpandResult::Ready(vec![item])
}
Err(Indeterminate) => ExpandResult::Retry(item),
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_builtin_macros/src/compile_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ pub fn expand_compile_error<'cx>(
return DummyResult::any(sp);
};

#[expect(
rustc::diagnostic_outside_of_impl,
reason = "diagnostic message is specified by user"
)]
#[expect(rustc::untranslatable_diagnostic, reason = "diagnostic message is specified by user")]
cx.span_err(sp, var.as_str());

DummyResult::any(sp)
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_builtin_macros/src/concat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use rustc_expand::base::{self, DummyResult};
use rustc_session::errors::report_lit_error;
use rustc_span::symbol::Symbol;

use crate::errors;

pub fn expand_concat(
cx: &mut base::ExtCtxt<'_>,
sp: rustc_span::Span,
Expand Down Expand Up @@ -31,7 +33,7 @@ pub fn expand_concat(
accumulator.push_str(&b.to_string());
}
Ok(ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..)) => {
cx.span_err(e.span, "cannot concatenate a byte string literal");
cx.emit_err(errors::ConcatBytestr { span: e.span });
has_errors = true;
}
Ok(ast::LitKind::Err) => {
Expand All @@ -55,7 +57,7 @@ pub fn expand_concat(
}
}
ast::ExprKind::IncludedBytes(..) => {
cx.span_err(e.span, "cannot concatenate a byte string literal")
cx.emit_err(errors::ConcatBytestr { span: e.span });
}
ast::ExprKind::Err => {
has_errors = true;
Expand All @@ -67,9 +69,7 @@ pub fn expand_concat(
}

if !missing_literal.is_empty() {
let mut err = cx.struct_span_err(missing_literal, "expected a literal");
err.note("only literals (like `\"foo\"`, `-42` and `3.14`) can be passed to `concat!()`");
err.emit();
cx.emit_err(errors::ConcatMissingLiteral { spans: missing_literal });
return DummyResult::any(sp);
} else if has_errors {
return DummyResult::any(sp);
Expand Down
Loading

0 comments on commit 45749b2

Please sign in to comment.