diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:43 +0000 |
commit | 3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245 (patch) | |
tree | daf049b282ab10e8c3d03e409b3cd84ff3f7690c /compiler/rustc_expand | |
parent | Adding debian version 1.68.2+dfsg1-1. (diff) | |
download | rustc-3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245.tar.xz rustc-3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245.zip |
Merging upstream version 1.69.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_expand')
-rw-r--r-- | compiler/rustc_expand/Cargo.toml | 2 | ||||
-rw-r--r-- | compiler/rustc_expand/locales/en-US.ftl | 138 | ||||
-rw-r--r-- | compiler/rustc_expand/src/base.rs | 62 | ||||
-rw-r--r-- | compiler/rustc_expand/src/build.rs | 74 | ||||
-rw-r--r-- | compiler/rustc_expand/src/config.rs | 13 | ||||
-rw-r--r-- | compiler/rustc_expand/src/errors.rs | 43 | ||||
-rw-r--r-- | compiler/rustc_expand/src/lib.rs | 5 | ||||
-rw-r--r-- | compiler/rustc_expand/src/mbe/macro_parser.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_expand/src/mbe/macro_rules.rs | 30 | ||||
-rw-r--r-- | compiler/rustc_expand/src/mbe/metavar_expr.rs | 12 | ||||
-rw-r--r-- | compiler/rustc_expand/src/mbe/transcribe.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_expand/src/module.rs | 4 | ||||
-rw-r--r-- | compiler/rustc_expand/src/parse/tests.rs | 5 | ||||
-rw-r--r-- | compiler/rustc_expand/src/proc_macro.rs | 14 | ||||
-rw-r--r-- | compiler/rustc_expand/src/tests.rs | 20 |
15 files changed, 323 insertions, 103 deletions
diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index 192f54171..c971714e0 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -24,5 +24,5 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.12" tracing = "0.1" diff --git a/compiler/rustc_expand/locales/en-US.ftl b/compiler/rustc_expand/locales/en-US.ftl new file mode 100644 index 000000000..cfae781bd --- /dev/null +++ b/compiler/rustc_expand/locales/en-US.ftl @@ -0,0 +1,138 @@ +expand_explain_doc_comment_outer = + outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match + +expand_explain_doc_comment_inner = + inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match + +expand_expr_repeat_no_syntax_vars = + attempted to repeat an expression containing no syntax variables matched as repeating at this depth + +expand_must_repeat_once = + this must repeat at least once + +expand_count_repetition_misplaced = + `count` can not be placed inside the inner-most repetition + +expand_meta_var_expr_unrecognized_var = + variable `{$key}` is not recognized in meta-variable expression + +expand_var_still_repeating = + variable '{$ident}' is still repeating at this depth + +expand_meta_var_dif_seq_matchers = {$msg} + +expand_macro_const_stability = + macros cannot have const stability attributes + .label = invalid const stability attribute + .label2 = const stability attribute affects this macro + +expand_macro_body_stability = + macros cannot have body stability attributes + .label = invalid body stability attribute + .label2 = body stability attribute affects this macro + +expand_resolve_relative_path = + cannot resolve relative path in non-file source `{$path}` + +expand_attr_no_arguments = + attribute must have either one or two arguments + +expand_not_a_meta_item = + not a meta item + +expand_only_one_word = + must only be one word + +expand_cannot_be_name_of_macro = + `{$trait_ident}` cannot be a name of {$macro_type} macro + +expand_arg_not_attributes = + second argument must be `attributes` + +expand_attributes_wrong_form = + attribute must be of form: `attributes(foo, bar)` + +expand_attribute_meta_item = + attribute must be a meta item, not a literal + +expand_attribute_single_word = + attribute must only be a single word + +expand_helper_attribute_name_invalid = + `{$name}` cannot be a name of derive helper attribute + +expand_expected_comma_in_list = + expected token: `,` + +expand_only_one_argument = + {$name} takes 1 argument + +expand_takes_no_arguments = + {$name} takes no arguments + +expand_feature_included_in_edition = + the feature `{$feature}` is included in the Rust {$edition} edition + +expand_feature_removed = + feature has been removed + .label = feature has been removed + .reason = {$reason} + +expand_feature_not_allowed = + the feature `{$name}` is not in the list of allowed features + +expand_recursion_limit_reached = + recursion limit reached while expanding `{$descr}` + .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`) + +expand_malformed_feature_attribute = + malformed `feature` attribute input + .expected = expected just one word + +expand_remove_expr_not_supported = + removing an expression is not supported in this position + +expand_invalid_cfg_no_parens = `cfg` is not followed by parentheses +expand_invalid_cfg_no_predicate = `cfg` predicate is not specified +expand_invalid_cfg_multiple_predicates = multiple `cfg` predicates are specified +expand_invalid_cfg_predicate_literal = `cfg` predicate key cannot be a literal +expand_invalid_cfg_expected_syntax = expected syntax is + +expand_wrong_fragment_kind = + non-{$kind} macro in {$kind} position: {$name} + +expand_unsupported_key_value = + key-value macro attributes are not supported + +expand_incomplete_parse = + macro expansion ignores token `{$token}` and any following + .label = caused by the macro expansion here + .note = the usage of `{$macro_path}!` is likely invalid in {$kind_name} context + .suggestion_add_semi = you might be missing a semicolon here + +expand_remove_node_not_supported = + removing {$descr} is not supported in this position + +expand_module_circular = + circular modules: {$modules} + +expand_module_in_block = + cannot declare a non-inline module inside a block unless it has a path attribute + .note = maybe `use` the module `{$name}` instead of redeclaring it + +expand_module_file_not_found = + file not found for module `{$name}` + .help = to create the module `{$name}`, create file "{$default_path}" or "{$secondary_path}" + +expand_module_multiple_candidates = + file for module `{$name}` found at both "{$default_path}" and "{$secondary_path}" + .help = delete or rename one of them to remove the ambiguity + +expand_trace_macro = trace_macro + +expand_proc_macro_panicked = + proc macro panicked + .help = message: {$message} + +expand_proc_macro_derive_tokens = + proc-macro derive produced unparseable tokens diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 951d59246..22bc90f5c 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1,15 +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::errors; use crate::expand::{self, AstFragment, Invocation}; use crate::module::DirOwnership; use rustc_ast::attr::MarkedAttrs; +use rustc_ast::mut_visit::DummyAstNode; use rustc_ast::ptr::P; use rustc_ast::token::{self, Nonterminal}; use rustc_ast::tokenstream::TokenStream; @@ -33,10 +29,11 @@ use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, FileName, Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; - +use std::default::Default; use std::iter; use std::path::{Path, PathBuf}; use std::rc::Rc; +use thin_vec::ThinVec; pub(crate) use rustc_span::hygiene::MacroKind; @@ -558,7 +555,7 @@ impl DummyResult { pub fn raw_expr(sp: Span, is_error: bool) -> P<ast::Expr> { P(ast::Expr { id: ast::DUMMY_NODE_ID, - kind: if is_error { ast::ExprKind::Err } else { ast::ExprKind::Tup(Vec::new()) }, + kind: if is_error { ast::ExprKind::Err } else { ast::ExprKind::Tup(ThinVec::new()) }, span: sp, attrs: ast::AttrVec::new(), tokens: None, @@ -574,7 +571,7 @@ impl DummyResult { pub fn raw_ty(sp: Span, is_error: bool) -> P<ast::Ty> { P(ast::Ty { id: ast::DUMMY_NODE_ID, - kind: if is_error { ast::TyKind::Err } else { ast::TyKind::Tup(Vec::new()) }, + kind: if is_error { ast::TyKind::Err } else { ast::TyKind::Tup(ThinVec::new()) }, span: sp, tokens: None, }) @@ -645,6 +642,10 @@ impl MacResult for DummyResult { fn make_variants(self: Box<DummyResult>) -> Option<SmallVec<[ast::Variant; 1]>> { Some(SmallVec::new()) } + + fn make_crate(self: Box<DummyResult>) -> Option<ast::Crate> { + Some(DummyAstNode::dummy()) + } } /// A syntax extension kind. @@ -796,13 +797,13 @@ impl SyntaxExtension { .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.emit_err(MacroConstStability { + sess.emit_err(errors::MacroConstStability { span: sp, head_span: sess.source_map().guess_head_span(span), }); } if let Some((_, sp)) = body_stability { - sess.emit_err(MacroBodyStability { + sess.emit_err(errors::MacroBodyStability { span: sp, head_span: sess.source_map().guess_head_span(span), }); @@ -1142,8 +1143,8 @@ impl<'a> ExtCtxt<'a> { self.sess.parse_sess.span_diagnostic.span_bug(sp, msg); } pub fn trace_macros_diag(&mut self) { - for (sp, notes) in self.expansions.iter() { - let mut db = self.sess.parse_sess.span_diagnostic.span_note_diag(*sp, "trace_macro"); + for (span, notes) in self.expansions.iter() { + let mut db = self.sess.parse_sess.create_note(errors::TraceMacro { span: *span }); for note in notes { db.note(note); } @@ -1197,7 +1198,7 @@ pub fn resolve_path( .expect("attempting to resolve a file path in an external file"), FileName::DocTest(path, _) => path, other => { - return Err(ResolveRelativePath { + return Err(errors::ResolveRelativePath { span, path: parse_sess.source_map().filename_for_diagnostics(&other).to_string(), } @@ -1279,7 +1280,7 @@ pub fn expr_to_string( /// done as rarely as possible). pub fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, name: &str) { if !tts.is_empty() { - cx.emit_err(TakesNoArguments { span, name }); + cx.emit_err(errors::TakesNoArguments { span, name }); } } @@ -1307,14 +1308,14 @@ pub fn get_single_str_from_tts( ) -> Option<Symbol> { let mut p = cx.new_parser_from_tts(tts); if p.token == token::Eof { - cx.emit_err(OnlyOneArgument { span, name }); + cx.emit_err(errors::OnlyOneArgument { span, name }); return None; } let ret = parse_expr(&mut p)?; let _ = p.eat(&token::Comma); if p.token != token::Eof { - cx.emit_err(OnlyOneArgument { span, name }); + cx.emit_err(errors::OnlyOneArgument { span, name }); } expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| s) } @@ -1336,7 +1337,7 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt<'_>, tts: TokenStream) -> Option<Vec< continue; } if p.token != token::Eof { - cx.emit_err(ExpectedCommaInList { span: p.token.span }); + cx.emit_err(errors::ExpectedCommaInList { span: p.token.span }); return None; } } @@ -1353,51 +1354,58 @@ pub fn parse_macro_name_and_helper_attrs( // `#[proc_macro_derive(Foo, attributes(A, ..))]` let list = attr.meta_item_list()?; if list.len() != 1 && list.len() != 2 { - diag.emit_err(AttrNoArguments { span: attr.span }); + diag.emit_err(errors::AttrNoArguments { span: attr.span }); return None; } let Some(trait_attr) = list[0].meta_item() else { - diag.emit_err(NotAMetaItem {span: list[0].span()}); + diag.emit_err(errors::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.emit_err(OnlyOneWord { span: trait_attr.span }); + diag.emit_err(errors::OnlyOneWord { span: trait_attr.span }); return None; } }; if !trait_ident.name.can_be_raw() { - diag.emit_err(CannotBeNameOfMacro { span: trait_attr.span, trait_ident, macro_type }); + diag.emit_err(errors::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.emit_err(ArgumentNotAttributes { span: attr.span() }); + diag.emit_err(errors::ArgumentNotAttributes { span: attr.span() }); } attr.meta_item_list() .unwrap_or_else(|| { - diag.emit_err(AttributesWrongForm { span: attr.span() }); + diag.emit_err(errors::AttributesWrongForm { span: attr.span() }); &[] }) .iter() .filter_map(|attr| { let Some(attr) = attr.meta_item() else { - diag.emit_err(AttributeMetaItem { span: attr.span() }); + diag.emit_err(errors::AttributeMetaItem { span: attr.span() }); return None; }; let ident = match attr.ident() { Some(ident) if attr.is_word() => ident, _ => { - diag.emit_err(AttributeSingleWord { span: attr.span }); + diag.emit_err(errors::AttributeSingleWord { span: attr.span }); return None; } }; if !ident.name.can_be_raw() { - diag.emit_err(HelperAttributeNameInvalid { span: attr.span, name: ident }); + diag.emit_err(errors::HelperAttributeNameInvalid { + span: attr.span, + name: ident, + }); } Some(ident.name) diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 9b16e79d4..8a78c3296 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -5,7 +5,7 @@ use rustc_ast::{attr, token, util::literal}; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; -use thin_vec::ThinVec; +use thin_vec::{thin_vec, ThinVec}; impl<'a> ExtCtxt<'a> { pub fn path(&self, span: Span, strs: Vec<Ident>) -> ast::Path { @@ -125,16 +125,20 @@ impl<'a> ExtCtxt<'a> { pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { ast::PolyTraitRef { - bound_generic_params: Vec::new(), + bound_generic_params: ThinVec::new(), trait_ref: self.trait_ref(path), span, } } - pub fn trait_bound(&self, path: ast::Path) -> ast::GenericBound { + pub fn trait_bound(&self, path: ast::Path, is_const: bool) -> ast::GenericBound { ast::GenericBound::Trait( self.poly_trait_ref(path.span, path), - ast::TraitBoundModifier::None, + if is_const { + ast::TraitBoundModifier::MaybeConst + } else { + ast::TraitBoundModifier::None + }, ) } @@ -217,14 +221,14 @@ impl<'a> ExtCtxt<'a> { pub fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> { self.block( expr.span, - vec![ast::Stmt { + thin_vec![ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr), }], ) } - pub fn block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block> { + pub fn block(&self, span: Span, stmts: ThinVec<ast::Stmt>) -> P<ast::Block> { P(ast::Block { stmts, id: ast::DUMMY_NODE_ID, @@ -272,22 +276,31 @@ impl<'a> ExtCtxt<'a> { self.expr(sp, ast::ExprKind::AddrOf(ast::BorrowKind::Ref, ast::Mutability::Not, e)) } + pub fn expr_paren(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> { + self.expr(sp, ast::ExprKind::Paren(e)) + } + pub fn expr_call( &self, span: Span, expr: P<ast::Expr>, - args: Vec<P<ast::Expr>>, + args: ThinVec<P<ast::Expr>>, ) -> P<ast::Expr> { self.expr(span, ast::ExprKind::Call(expr, args)) } - pub fn expr_call_ident(&self, span: Span, id: Ident, args: Vec<P<ast::Expr>>) -> P<ast::Expr> { + pub fn expr_call_ident( + &self, + span: Span, + id: Ident, + args: ThinVec<P<ast::Expr>>, + ) -> P<ast::Expr> { self.expr(span, ast::ExprKind::Call(self.expr_ident(span, id), args)) } pub fn expr_call_global( &self, sp: Span, fn_path: Vec<Ident>, - args: Vec<P<ast::Expr>>, + args: ThinVec<P<ast::Expr>>, ) -> P<ast::Expr> { let pathexpr = self.expr_path(self.path_global(sp, fn_path)); self.expr_call(sp, pathexpr, args) @@ -310,7 +323,7 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, path: ast::Path, - fields: Vec<ast::ExprField>, + fields: ThinVec<ast::ExprField>, ) -> P<ast::Expr> { self.expr( span, @@ -326,7 +339,7 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, id: Ident, - fields: Vec<ast::ExprField>, + fields: ThinVec<ast::ExprField>, ) -> P<ast::Expr> { self.expr_struct(span, self.path_ident(span, id), fields) } @@ -364,12 +377,12 @@ impl<'a> ExtCtxt<'a> { } /// `[expr1, expr2, ...]` - pub fn expr_array(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { + pub fn expr_array(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> { self.expr(sp, ast::ExprKind::Array(exprs)) } /// `&[expr1, expr2, ...]` - pub fn expr_array_ref(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { + pub fn expr_array_ref(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> { self.expr_addr_of(sp, self.expr_array(sp, exprs)) } @@ -379,14 +392,14 @@ impl<'a> ExtCtxt<'a> { pub fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { let some = self.std_path(&[sym::option, sym::Option, sym::Some]); - self.expr_call_global(sp, some, vec![expr]) + self.expr_call_global(sp, some, thin_vec![expr]) } pub fn expr_none(&self, sp: Span) -> P<ast::Expr> { let none = self.std_path(&[sym::option, sym::Option, sym::None]); self.expr_path(self.path_global(sp, none)) } - pub fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { + pub fn expr_tuple(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> { self.expr(sp, ast::ExprKind::Tup(exprs)) } @@ -394,7 +407,7 @@ impl<'a> ExtCtxt<'a> { self.expr_call_global( span, [sym::std, sym::rt, sym::begin_panic].iter().map(|s| Ident::new(*s, span)).collect(), - vec![self.expr_str(span, msg)], + thin_vec![self.expr_str(span, msg)], ) } @@ -404,7 +417,7 @@ impl<'a> ExtCtxt<'a> { pub fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); - self.expr_call_global(sp, ok, vec![expr]) + self.expr_call_global(sp, ok, thin_vec![expr]) } pub fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> { @@ -418,12 +431,12 @@ impl<'a> ExtCtxt<'a> { let binding_expr = self.expr_ident(sp, binding_variable); // `Ok(__try_var)` pattern - let ok_pat = self.pat_tuple_struct(sp, ok_path, vec![binding_pat.clone()]); + let ok_pat = self.pat_tuple_struct(sp, ok_path, thin_vec![binding_pat.clone()]); // `Err(__try_var)` (pattern and expression respectively) - let err_pat = self.pat_tuple_struct(sp, err_path.clone(), vec![binding_pat]); + let err_pat = self.pat_tuple_struct(sp, err_path.clone(), thin_vec![binding_pat]); let err_inner_expr = - self.expr_call(sp, self.expr_path(err_path), vec![binding_expr.clone()]); + self.expr_call(sp, self.expr_path(err_path), thin_vec![binding_expr.clone()]); // `return Err(__try_var)` let err_expr = self.expr(sp, ast::ExprKind::Ret(Some(err_inner_expr))); @@ -433,7 +446,7 @@ impl<'a> ExtCtxt<'a> { let err_arm = self.arm(sp, err_pat, err_expr); // `match head { Ok() => ..., Err() => ... }` - self.expr_match(sp, head, vec![ok_arm, err_arm]) + self.expr_match(sp, head, thin_vec![ok_arm, err_arm]) } pub fn pat(&self, span: Span, kind: PatKind) -> P<ast::Pat> { @@ -465,7 +478,7 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, path: ast::Path, - subpats: Vec<P<ast::Pat>>, + subpats: ThinVec<P<ast::Pat>>, ) -> P<ast::Pat> { self.pat(span, PatKind::TupleStruct(None, path, subpats)) } @@ -473,18 +486,18 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, path: ast::Path, - field_pats: Vec<ast::PatField>, + field_pats: ThinVec<ast::PatField>, ) -> P<ast::Pat> { self.pat(span, PatKind::Struct(None, path, field_pats, false)) } - pub fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> { + pub fn pat_tuple(&self, span: Span, pats: ThinVec<P<ast::Pat>>) -> P<ast::Pat> { self.pat(span, PatKind::Tuple(pats)) } pub fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> { let some = self.std_path(&[sym::option, sym::Option, sym::Some]); let path = self.path_global(span, some); - self.pat_tuple_struct(span, path, vec![pat]) + self.pat_tuple_struct(span, path, thin_vec![pat]) } pub fn arm(&self, span: Span, pat: P<ast::Pat>, expr: P<ast::Expr>) -> ast::Arm { @@ -503,7 +516,7 @@ impl<'a> ExtCtxt<'a> { self.arm(span, self.pat_wild(span), self.expr_unreachable(span)) } - pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm>) -> P<Expr> { + pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: ThinVec<ast::Arm>) -> P<Expr> { self.expr(span, ast::ExprKind::Match(arg, arms)) } @@ -554,7 +567,12 @@ impl<'a> ExtCtxt<'a> { self.lambda(span, vec![ident], body) } - pub fn lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>, ident: Ident) -> P<ast::Expr> { + pub fn lambda_stmts_1( + &self, + span: Span, + stmts: ThinVec<ast::Stmt>, + ident: Ident, + ) -> P<ast::Expr> { self.lambda1(span, self.expr_block(self.block(span, stmts)), ident) } @@ -571,7 +589,7 @@ impl<'a> ExtCtxt<'a> { } // `self` is unused but keep it as method for the convenience use. - pub fn fn_decl(&self, inputs: Vec<ast::Param>, output: ast::FnRetTy) -> P<ast::FnDecl> { + pub fn fn_decl(&self, inputs: ThinVec<ast::Param>, output: ast::FnRetTy) -> P<ast::FnDecl> { P(ast::FnDecl { inputs, output }) } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 1fcbdfd9b..01500c2c7 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -24,6 +24,7 @@ use rustc_session::Session; use rustc_span::edition::{Edition, ALL_EDITIONS}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; +use thin_vec::ThinVec; /// A folder that strips out items that do not belong in the current configuration. pub struct StripUnconfigured<'a> { @@ -206,7 +207,7 @@ pub fn features( None => { // The entire crate is unconfigured. krate.attrs = ast::AttrVec::new(); - krate.items = Vec::new(); + krate.items = ThinVec::new(); Features::default() } Some(attrs) => { @@ -238,12 +239,10 @@ macro_rules! configure { impl<'a> StripUnconfigured<'a> { pub fn configure<T: HasAttrs + HasTokens>(&self, mut node: T) -> Option<T> { self.process_cfg_attrs(&mut node); - if self.in_cfg(node.attrs()) { + self.in_cfg(node.attrs()).then(|| { self.try_configure_tokens(&mut node); - Some(node) - } else { - None - } + node + }) } fn try_configure_tokens<T: HasTokens>(&self, node: &mut T) { @@ -257,7 +256,7 @@ impl<'a> StripUnconfigured<'a> { fn configure_krate_attrs(&self, mut attrs: ast::AttrVec) -> Option<ast::AttrVec> { attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr)); - if self.in_cfg(&attrs) { Some(attrs) } else { None } + self.in_cfg(&attrs).then_some(attrs) } /// Performs cfg-expansion on `stream`, producing a new `AttrTokenStream`. diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index afe5169d3..e5102a952 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -65,7 +65,7 @@ pub(crate) struct MacroConstStability { #[primary_span] #[label] pub span: Span, - #[label(label2)] + #[label(expand_label2)] pub head_span: Span, } @@ -75,7 +75,7 @@ pub(crate) struct MacroBodyStability { #[primary_span] #[label] pub span: Span, - #[label(label2)] + #[label(expand_label2)] pub head_span: Span, } @@ -188,7 +188,7 @@ pub(crate) struct FeatureRemoved<'a> { } #[derive(Subdiagnostic)] -#[note(reason)] +#[note(expand_reason)] pub(crate) struct FeatureRemovedReason<'a> { pub reason: &'a str, } @@ -223,12 +223,12 @@ pub(crate) struct MalformedFeatureAttribute { #[derive(Subdiagnostic)] pub(crate) enum MalformedFeatureAttributeHelp { - #[label(expected)] + #[label(expand_expected)] Label { #[primary_span] span: Span, }, - #[suggestion(expected, code = "{suggestion}", applicability = "maybe-incorrect")] + #[suggestion(expand_expected, code = "{suggestion}", applicability = "maybe-incorrect")] Suggestion { #[primary_span] span: Span, @@ -306,7 +306,7 @@ pub(crate) struct IncompleteParse<'a> { pub kind_name: &'a str, #[suggestion( - suggestion_add_semi, + expand_suggestion_add_semi, style = "verbose", code = ";", applicability = "maybe-incorrect" @@ -340,7 +340,7 @@ pub(crate) struct ModuleInBlock { } #[derive(Subdiagnostic)] -#[note(note)] +#[note(expand_note)] pub(crate) struct ModuleInBlockName { #[primary_span] pub span: Span, @@ -368,3 +368,32 @@ pub(crate) struct ModuleMultipleCandidates { pub default_path: String, pub secondary_path: String, } + +#[derive(Diagnostic)] +#[diag(expand_trace_macro)] +pub struct TraceMacro { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(expand_proc_macro_panicked)] +pub(crate) struct ProcMacroPanicked { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub message: Option<ProcMacroPanickedHelp>, +} + +#[derive(Subdiagnostic)] +#[help(expand_help)] +pub(crate) struct ProcMacroPanickedHelp { + pub message: String, +} + +#[derive(Diagnostic)] +#[diag(expand_proc_macro_derive_tokens)] +pub struct ProcMacroDeriveTokens { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 897268566..634e206e5 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -20,6 +20,9 @@ extern crate tracing; extern crate proc_macro as pm; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; + mod placeholders; mod proc_macro_server; @@ -60,3 +63,5 @@ mod tokenstream { mod mut_visit { mod tests; } + +fluent_messages! { "../locales/en-US.ftl" } diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index 2e199541b..283e68a68 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -503,7 +503,7 @@ impl TtParser { mp.push_match(metavar_idx, seq_depth, MatchedSeq(vec![])); } - if op == KleeneOp::ZeroOrMore || op == KleeneOp::ZeroOrOne { + if matches!(op, KleeneOp::ZeroOrMore | KleeneOp::ZeroOrOne) { // Try zero matches of this sequence, by skipping over it. self.cur_mps.push(MatcherPos { idx: idx_first_after, diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 4ebd75f01..5679cdcbb 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -10,13 +10,12 @@ use crate::mbe::transcribe::transcribe; use rustc_ast as ast; use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind, TokenKind::*}; -use rustc_ast::tokenstream::{DelimSpan, TokenStream}; +use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree}; use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, TransparencyError}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::{Applicability, ErrorGuaranteed}; -use rustc_feature::Features; use rustc_lint_defs::builtin::{ RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, }; @@ -212,7 +211,6 @@ fn expand_macro<'cx>( }; let arm_span = rhses[i].span(); - let rhs_spans = rhs.tts.iter().map(|t| t.span()).collect::<Vec<_>>(); // rhs has holes ( `$id` and `$(...)` that need filled) let mut tts = match transcribe(cx, &named_matches, &rhs, rhs_span, transparency) { Ok(tts) => tts, @@ -224,12 +222,25 @@ fn expand_macro<'cx>( // Replace all the tokens for the corresponding positions in the macro, to maintain // proper positions in error reporting, while maintaining the macro_backtrace. - if rhs_spans.len() == tts.len() { + if tts.len() == rhs.tts.len() { tts = tts.map_enumerated(|i, tt| { let mut tt = tt.clone(); - let mut sp = rhs_spans[i]; - sp = sp.with_ctxt(tt.span().ctxt()); - tt.set_span(sp); + let rhs_tt = &rhs.tts[i]; + let ctxt = tt.span().ctxt(); + match (&mut tt, rhs_tt) { + // preserve the delim spans if able + ( + TokenTree::Delimited(target_sp, ..), + mbe::TokenTree::Delimited(source_sp, ..), + ) => { + target_sp.open = source_sp.open.with_ctxt(ctxt); + target_sp.close = source_sp.close.with_ctxt(ctxt); + } + _ => { + let sp = rhs_tt.span().with_ctxt(ctxt); + tt.set_span(sp); + } + } tt }); } @@ -367,7 +378,6 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>( /// Converts a macro item into a syntax extension. pub fn compile_declarative_macro( sess: &Session, - features: &Features, def: &ast::Item, edition: Edition, ) -> (SyntaxExtension, Vec<(usize, Span)>) { @@ -496,7 +506,7 @@ pub fn compile_declarative_macro( true, &sess.parse_sess, def.id, - features, + sess.features_untracked(), edition, ) .pop() @@ -520,7 +530,7 @@ pub fn compile_declarative_macro( false, &sess.parse_sess, def.id, - features, + sess.features_untracked(), edition, ) .pop() diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index 99fe47454..de34df011 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -1,5 +1,5 @@ use rustc_ast::token::{self, Delimiter}; -use rustc_ast::tokenstream::{CursorRef, TokenStream, TokenTree}; +use rustc_ast::tokenstream::{RefTokenTreeCursor, TokenStream, TokenTree}; use rustc_ast::{LitIntType, LitKind}; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, PResult}; @@ -72,7 +72,7 @@ impl MetaVarExpr { // Checks if there are any remaining tokens. For example, `${ignore(ident ... a b c ...)}` fn check_trailing_token<'sess>( - iter: &mut CursorRef<'_>, + iter: &mut RefTokenTreeCursor<'_>, sess: &'sess ParseSess, ) -> PResult<'sess, ()> { if let Some(tt) = iter.next() { @@ -88,7 +88,7 @@ fn check_trailing_token<'sess>( /// Parse a meta-variable `count` expression: `count(ident[, depth])` fn parse_count<'sess>( - iter: &mut CursorRef<'_>, + iter: &mut RefTokenTreeCursor<'_>, sess: &'sess ParseSess, span: Span, ) -> PResult<'sess, MetaVarExpr> { @@ -99,7 +99,7 @@ fn parse_count<'sess>( /// Parses the depth used by index(depth) and length(depth). fn parse_depth<'sess>( - iter: &mut CursorRef<'_>, + iter: &mut RefTokenTreeCursor<'_>, sess: &'sess ParseSess, span: Span, ) -> PResult<'sess, usize> { @@ -126,7 +126,7 @@ fn parse_depth<'sess>( /// Parses an generic ident fn parse_ident<'sess>( - iter: &mut CursorRef<'_>, + iter: &mut RefTokenTreeCursor<'_>, sess: &'sess ParseSess, span: Span, ) -> PResult<'sess, Ident> { @@ -152,7 +152,7 @@ fn parse_ident<'sess>( /// Tries to move the iterator forward returning `true` if there is a comma. If not, then the /// iterator is not modified and the result is `false`. -fn try_eat_comma(iter: &mut CursorRef<'_>) -> bool { +fn try_eat_comma(iter: &mut RefTokenTreeCursor<'_>) -> bool { if let Some(TokenTree::Token(token::Token { kind: token::Comma, .. }, _)) = iter.look_ahead(0) { let _ = iter.next(); return true; diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index b79835be7..47a8b4bc4 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -282,7 +282,7 @@ pub(super) fn transcribe<'a>( } // There should be no meta-var declarations in the invocation of a macro. - mbe::TokenTree::MetaVarDecl(..) => panic!("unexpected `TokenTree::MetaVarDecl"), + mbe::TokenTree::MetaVarDecl(..) => panic!("unexpected `TokenTree::MetaVarDecl`"), } } } diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index 07f47a9c3..3779af19e 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -12,8 +12,8 @@ use rustc_session::Session; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use std::iter::once; - use std::path::{self, Path, PathBuf}; +use thin_vec::ThinVec; #[derive(Copy, Clone)] pub enum DirOwnership { @@ -31,7 +31,7 @@ pub struct ModulePathSuccess { } pub(crate) struct ParsedExternalMod { - pub items: Vec<P<Item>>, + pub items: ThinVec<P<Item>>, pub spans: ModSpans, pub file_path: PathBuf, pub dir_path: PathBuf, diff --git a/compiler/rustc_expand/src/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs index 0726d922c..8b37728b6 100644 --- a/compiler/rustc_expand/src/parse/tests.rs +++ b/compiler/rustc_expand/src/parse/tests.rs @@ -18,7 +18,10 @@ use rustc_span::{BytePos, FileName, Pos, Span}; use std::path::PathBuf; fn sess() -> ParseSess { - ParseSess::new(FilePathMapping::empty()) + ParseSess::new( + vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + FilePathMapping::empty(), + ) } /// Parses an item. diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index e9a691920..ddba14417 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -1,4 +1,5 @@ use crate::base::{self, *}; +use crate::errors; use crate::proc_macro_server; use rustc_ast as ast; @@ -60,11 +61,12 @@ impl base::BangProcMacro for BangProcMacro { let strategy = exec_strategy(ecx); let server = proc_macro_server::Rustc::new(ecx); self.client.run(&strategy, server, input, proc_macro_backtrace).map_err(|e| { - let mut err = ecx.struct_span_err(span, "proc macro panicked"); - if let Some(s) = e.as_str() { - err.help(&format!("message: {}", s)); - } - err.emit() + ecx.sess.emit_err(errors::ProcMacroPanicked { + span, + message: e + .as_str() + .map(|message| errors::ProcMacroPanickedHelp { message: message.into() }), + }) }) } } @@ -174,7 +176,7 @@ impl MultiItemModifier for DeriveProcMacro { // fail if there have been errors emitted if ecx.sess.parse_sess.span_diagnostic.err_count() > error_count_before { - ecx.struct_span_err(span, "proc-macro derive produced unparseable tokens").emit(); + ecx.sess.emit_err(errors::ProcMacroDeriveTokens { span }); } ExpandResult::Ready(items) diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index 8f3bea29f..480d95b77 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -8,7 +8,7 @@ use rustc_span::{BytePos, Span}; use rustc_data_structures::sync::Lrc; use rustc_errors::emitter::EmitterWriter; -use rustc_errors::{Handler, MultiSpan, PResult}; +use rustc_errors::{Handler, MultiSpan, PResult, TerminalUrl}; use std::io; use std::io::prelude::*; @@ -34,18 +34,23 @@ where /// Maps a string to tts, using a made-up filename. pub(crate) fn string_to_stream(source_str: String) -> TokenStream { - let ps = ParseSess::new(FilePathMapping::empty()); + let ps = ParseSess::new( + vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + FilePathMapping::empty(), + ); source_file_to_stream( &ps, ps.source_map().new_source_file(PathBuf::from("bogofile").into(), source_str), None, ) - .0 } /// Parses a string, returns a crate. pub(crate) fn string_to_crate(source_str: String) -> ast::Crate { - let ps = ParseSess::new(FilePathMapping::empty()); + let ps = ParseSess::new( + vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + FilePathMapping::empty(), + ); with_error_checking_parse(source_str, &ps, |p| p.parse_crate_mod()) } @@ -127,8 +132,10 @@ fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: & create_default_session_if_not_set_then(|_| { let output = Arc::new(Mutex::new(Vec::new())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + false, + ); let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); source_map.new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned()); @@ -152,6 +159,7 @@ fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: & None, false, false, + TerminalUrl::No, ); let handler = Handler::with_emitter(true, None, Box::new(emitter)); #[allow(rustc::untranslatable_diagnostic)] |