X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_expand%2Fsrc%2Fbase.rs;h=00453f78287efb8ab9067dbbf1fae3a27e43984e;hb=309c469eece74cd9b83328d18302f1a177d0df7f;hp=13e2d1ebbe7869530fc7e514d3884e3f6dd55926;hpb=4b6010cbb70bb903c0d69cddaa27e262cef15761;p=rust.git diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 13e2d1ebbe7..00453f78287 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1,3 +1,11 @@ +#![deny(rustc::untranslatable_diagnostic)] + +use crate::errors::{ + ArgumentNotAttributes, AttrNoArguments, AttributeMetaItem, AttributeSingleWord, + AttributesWrongForm, CannotBeNameOfMacro, ExpectedCommaInList, HelperAttributeNameInvalid, + MacroBodyStability, MacroConstStability, NotAMetaItem, OnlyOneArgument, OnlyOneWord, + ResolveRelativePath, TakesNoArguments, +}; use crate::expand::{self, AstFragment, Invocation}; use crate::module::DirOwnership; @@ -26,7 +34,6 @@ use rustc_span::{BytePos, FileName, RealFileName, Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; -use std::default::Default; use std::iter; use std::path::PathBuf; use std::rc::Rc; @@ -789,26 +796,16 @@ pub fn new( .unwrap_or_else(|| (None, helper_attrs)); let (stability, const_stability, body_stability) = attr::find_stability(&sess, attrs, span); if let Some((_, sp)) = const_stability { - sess.parse_sess - .span_diagnostic - .struct_span_err(sp, "macros cannot have const stability attributes") - .span_label(sp, "invalid const stability attribute") - .span_label( - sess.source_map().guess_head_span(span), - "const stability attribute affects this macro", - ) - .emit(); + sess.emit_err(MacroConstStability { + span: sp, + head_span: sess.source_map().guess_head_span(span), + }); } if let Some((_, sp)) = body_stability { - sess.parse_sess - .span_diagnostic - .struct_span_err(sp, "macros cannot have body stability attributes") - .span_label(sp, "invalid body stability attribute") - .span_label( - sess.source_map().guess_head_span(span), - "body stability attribute affects this macro", - ) - .emit(); + sess.emit_err(MacroBodyStability { + span: sp, + head_span: sess.source_map().guess_head_span(span), + }); } SyntaxExtension { @@ -960,7 +957,7 @@ fn pre_expansion_lint( node_id: NodeId, attrs: &[Attribute], items: &[P], - name: &str, + name: Symbol, ); } @@ -1200,13 +1197,11 @@ pub fn resolve_path( .expect("attempting to resolve a file path in an external file"), FileName::DocTest(path, _) => path, other => { - return Err(parse_sess.span_diagnostic.struct_span_err( + return Err(ResolveRelativePath { span, - &format!( - "cannot resolve relative path in non-file source `{}`", - parse_sess.source_map().filename_for_diagnostics(&other) - ), - )); + path: parse_sess.source_map().filename_for_diagnostics(&other).to_string(), + } + .into_diagnostic(&parse_sess.span_diagnostic)); } }; result.pop(); @@ -1222,6 +1217,8 @@ pub fn resolve_path( /// The returned bool indicates whether an applicable suggestion has already been /// added to the diagnostic to avoid emitting multiple suggestions. `Err(None)` /// indicates that an ast error was encountered. +// FIXME(Nilstrieb) Make this function setup translatable +#[allow(rustc::untranslatable_diagnostic)] pub fn expr_to_spanned_string<'a>( cx: &'a mut ExtCtxt<'_>, expr: P, @@ -1234,7 +1231,7 @@ pub fn expr_to_spanned_string<'a>( Err(match expr.kind { ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) { Ok(ast::LitKind::Str(s, style)) => return Ok((s, style, expr.span)), - Ok(ast::LitKind::ByteStr(_)) => { + Ok(ast::LitKind::ByteStr(..)) => { let mut err = cx.struct_span_err(expr.span, err_msg); let span = expr.span.shrink_to_lo(); err.span_suggestion( @@ -1280,9 +1277,9 @@ pub fn expr_to_string( /// compilation should call /// `cx.parse_sess.span_diagnostic.abort_if_errors()` (this should be /// done as rarely as possible). -pub fn check_zero_tts(cx: &ExtCtxt<'_>, sp: Span, tts: TokenStream, name: &str) { +pub fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, name: &str) { if !tts.is_empty() { - cx.span_err(sp, &format!("{} takes no arguments", name)); + cx.emit_err(TakesNoArguments { span, name }); } } @@ -1304,31 +1301,27 @@ pub fn parse_expr(p: &mut parser::Parser<'_>) -> Option> { /// expect exactly one string literal, or emit an error and return `None`. pub fn get_single_str_from_tts( cx: &mut ExtCtxt<'_>, - sp: Span, + span: Span, tts: TokenStream, name: &str, ) -> Option { let mut p = cx.new_parser_from_tts(tts); if p.token == token::Eof { - cx.span_err(sp, &format!("{} takes 1 argument", name)); + cx.emit_err(OnlyOneArgument { span, name }); return None; } let ret = parse_expr(&mut p)?; let _ = p.eat(&token::Comma); if p.token != token::Eof { - cx.span_err(sp, &format!("{} takes 1 argument", name)); + cx.emit_err(OnlyOneArgument { span, name }); } expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| s) } /// Extracts comma-separated expressions from `tts`. /// On error, emit it, and return `None`. -pub fn get_exprs_from_tts( - cx: &mut ExtCtxt<'_>, - sp: Span, - tts: TokenStream, -) -> Option>> { +pub fn get_exprs_from_tts(cx: &mut ExtCtxt<'_>, tts: TokenStream) -> Option>> { let mut p = cx.new_parser_from_tts(tts); let mut es = Vec::new(); while p.token != token::Eof { @@ -1343,7 +1336,7 @@ pub fn get_exprs_from_tts( continue; } if p.token != token::Eof { - cx.span_err(sp, "expected token: `,`"); + cx.emit_err(ExpectedCommaInList { span: p.token.span }); return None; } } @@ -1353,64 +1346,58 @@ pub fn get_exprs_from_tts( pub fn parse_macro_name_and_helper_attrs( diag: &rustc_errors::Handler, attr: &Attribute, - descr: &str, + macro_type: &str, ) -> Option<(Symbol, Vec)> { // Once we've located the `#[proc_macro_derive]` attribute, verify // that it's of the form `#[proc_macro_derive(Foo)]` or // `#[proc_macro_derive(Foo, attributes(A, ..))]` let list = attr.meta_item_list()?; if list.len() != 1 && list.len() != 2 { - diag.span_err(attr.span, "attribute must have either one or two arguments"); + diag.emit_err(AttrNoArguments { span: attr.span }); return None; } let Some(trait_attr) = list[0].meta_item() else { - diag.span_err(list[0].span(), "not a meta item"); + diag.emit_err(NotAMetaItem {span: list[0].span()}); return None; }; let trait_ident = match trait_attr.ident() { Some(trait_ident) if trait_attr.is_word() => trait_ident, _ => { - diag.span_err(trait_attr.span, "must only be one word"); + diag.emit_err(OnlyOneWord { span: trait_attr.span }); return None; } }; if !trait_ident.name.can_be_raw() { - diag.span_err( - trait_attr.span, - &format!("`{}` cannot be a name of {} macro", trait_ident, descr), - ); + diag.emit_err(CannotBeNameOfMacro { span: trait_attr.span, trait_ident, macro_type }); } let attributes_attr = list.get(1); let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr { if !attr.has_name(sym::attributes) { - diag.span_err(attr.span(), "second argument must be `attributes`"); + diag.emit_err(ArgumentNotAttributes { span: attr.span() }); } attr.meta_item_list() .unwrap_or_else(|| { - diag.span_err(attr.span(), "attribute must be of form: `attributes(foo, bar)`"); + diag.emit_err(AttributesWrongForm { span: attr.span() }); &[] }) .iter() .filter_map(|attr| { let Some(attr) = attr.meta_item() else { - diag.span_err(attr.span(), "not a meta item"); + diag.emit_err(AttributeMetaItem { span: attr.span() }); return None; }; let ident = match attr.ident() { Some(ident) if attr.is_word() => ident, _ => { - diag.span_err(attr.span, "must only be one word"); + diag.emit_err(AttributeSingleWord { span: attr.span }); return None; } }; if !ident.name.can_be_raw() { - diag.span_err( - attr.span, - &format!("`{}` cannot be a name of derive helper attribute", ident), - ); + diag.emit_err(HelperAttributeNameInvalid { span: attr.span, name: ident }); } Some(ident.name)