diff options
Diffstat (limited to 'compiler/rustc_builtin_macros/src')
32 files changed, 221 insertions, 288 deletions
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 1a0ea8f41..a1051d990 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -852,7 +852,7 @@ pub(super) fn expand_global_asm<'cx>( if let Some(inline_asm) = expand_preparsed_asm(ecx, args) { MacEager::items(smallvec![P(ast::Item { ident: Ident::empty(), - attrs: Vec::new(), + attrs: ast::AttrVec::new(), id: ast::DUMMY_NODE_ID, kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)), vis: ast::Visibility { diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index 925c36edb..119724b50 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -52,7 +52,7 @@ pub fn expand_assert<'cx>( let expr = if let Some(tokens) = custom_message { let then = cx.expr( call_site_span, - ExprKind::MacCall(MacCall { + ExprKind::MacCall(P(MacCall { path: panic_path(), args: P(MacArgs::Delimited( DelimSpan::from_single(call_site_span), @@ -60,7 +60,7 @@ pub fn expand_assert<'cx>( 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 dcea883a5..f80215a3c 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -13,6 +13,7 @@ use rustc_span::{ symbol::{sym, Ident, Symbol}, Span, }; +use thin_vec::thin_vec; pub(super) struct Context<'cx, 'a> { // An optimization. @@ -116,7 +117,7 @@ impl<'cx, 'a> Context<'cx, 'a> { self.cx.item( self.span, Ident::empty(), - vec![self.cx.attribute(attr::mk_list_item( + thin_vec![self.cx.attribute(attr::mk_list_item( Ident::new(sym::allow, self.span), vec![attr::mk_nested_word_item(Ident::new(sym::unused_imports, self.span))], ))], @@ -177,7 +178,7 @@ impl<'cx, 'a> Context<'cx, 'a> { }); self.cx.expr( self.span, - ExprKind::MacCall(MacCall { + ExprKind::MacCall(P(MacCall { path: panic_path, args: P(MacArgs::Delimited( DelimSpan::from_single(self.span), @@ -185,7 +186,7 @@ impl<'cx, 'a> Context<'cx, 'a> { initial.into_iter().chain(captures).collect::<TokenStream>(), )), prior_type_ascription: None, - }), + })), ) } diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index aa355150b..9046bf130 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -36,7 +36,7 @@ pub fn expand_cfg( } #[derive(SessionDiagnostic)] -#[error(builtin_macros::requires_cfg_pattern)] +#[diag(builtin_macros::requires_cfg_pattern)] struct RequiresCfgPattern { #[primary_span] #[label] @@ -44,7 +44,7 @@ struct RequiresCfgPattern { } #[derive(SessionDiagnostic)] -#[error(builtin_macros::expected_one_cfg_pattern)] +#[diag(builtin_macros::expected_one_cfg_pattern)] struct OneCfgPattern { #[primary_span] span: Span, diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 89b2c3292..e673dff0d 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -188,14 +188,14 @@ impl CfgEval<'_, '_> { let orig_tokens = annotatable.to_tokens().flattened(); // Re-parse the tokens, setting the `capture_cfg` flag to save extra information - // to the captured `AttrAnnotatedTokenStream` (specifically, we capture - // `AttrAnnotatedTokenTree::AttributesData` for all occurrences of `#[cfg]` and `#[cfg_attr]`) + // to the captured `AttrTokenStream` (specifically, we capture + // `AttrTokenTree::AttributesData` for all occurrences of `#[cfg]` and `#[cfg_attr]`) let mut parser = rustc_parse::stream_to_parser(&self.cfg.sess.parse_sess, orig_tokens, None); parser.capture_cfg = true; annotatable = parse_annotatable_with(&mut parser); - // Now that we have our re-parsed `AttrAnnotatedTokenStream`, recursively configuring + // Now that we have our re-parsed `AttrTokenStream`, recursively configuring // our attribute target will correctly the tokens as well. flat_map_annotatable(self, annotatable) } diff --git a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs index 747e48ece..db05c00d2 100644 --- a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs +++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs @@ -28,7 +28,13 @@ pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) - continue; } - krate.attrs.push(mk_attr(AttrStyle::Inner, path, args, start_span.to(end_span))); + krate.attrs.push(mk_attr( + &parse_sess.attr_id_generator, + AttrStyle::Inner, + path, + args, + start_span.to(end_span), + )); } krate diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs index a23dd1d12..41f4e8c23 100644 --- a/compiler/rustc_builtin_macros/src/concat.rs +++ b/compiler/rustc_builtin_macros/src/concat.rs @@ -39,7 +39,7 @@ pub fn expand_concat( ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..) => { cx.span_err(e.span, "cannot concatenate a byte string literal"); } - ast::LitKind::Err(_) => { + ast::LitKind::Err => { has_errors = true; } }, diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index a1afec410..66e86bf21 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -1,6 +1,5 @@ use rustc_ast as ast; use rustc_ast::{ptr::P, tokenstream::TokenStream}; -use rustc_data_structures::sync::Lrc; use rustc_errors::Applicability; use rustc_expand::base::{self, DummyResult}; @@ -43,7 +42,7 @@ fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_ne ast::LitKind::Bool(_) => { cx.span_err(expr.span, "cannot concatenate boolean literals"); } - ast::LitKind::Err(_) => {} + ast::LitKind::Err => {} ast::LitKind::Int(_, _) if !is_nested => { let mut err = cx.struct_span_err(expr.span, "cannot concatenate numeric literals"); if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) { @@ -185,5 +184,5 @@ pub fn expand_concat_bytes( return base::MacEager::expr(DummyResult::raw_expr(sp, true)); } let sp = cx.with_def_site_ctxt(sp); - base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(accumulator)))) + base::MacEager::expr(cx.expr_byte_str(sp, accumulator)) } diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index d3de10ca4..e0fb7affb 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -32,7 +32,8 @@ impl MultiItemModifier for Expander { ecx.resolver.resolve_derives(ecx.current_expansion.id, ecx.force_mode, &|| { let template = AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() }; - let attr = attr::mk_attr_outer(meta_item.clone()); + let attr = + attr::mk_attr_outer(&sess.parse_sess.attr_id_generator, meta_item.clone()); validate_attr::check_builtin_attribute( &sess.parse_sess, &attr, @@ -126,9 +127,9 @@ fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool { } fn report_unexpected_literal(sess: &Session, lit: &ast::Lit) { - let help_msg = match lit.token.kind { - token::Str if rustc_lexer::is_ident(lit.token.symbol.as_str()) => { - format!("try using `#[derive({})]`", lit.token.symbol) + let help_msg = match lit.token_lit.kind { + token::Str if rustc_lexer::is_ident(lit.token_lit.symbol.as_str()) => { + format!("try using `#[derive({})]`", lit.token_lit.symbol) } _ => "for example, write `#[derive(Debug)]` for `Debug`".to_string(), }; diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 5ef68c6ae..77e0b6c55 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -15,7 +15,6 @@ pub fn expand_deriving_copy( ) { let trait_def = TraitDef { span, - attributes: Vec::new(), path: path_std!(marker::Copy), additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 7755ff779..c7f2d95e7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -1,12 +1,12 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::path_std; - use rustc_ast::{self as ast, Generics, ItemKind, MetaItem, VariantData}; use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; +use thin_vec::thin_vec; pub fn expand_deriving_clone( cx: &mut ExtCtxt<'_>, @@ -68,10 +68,9 @@ pub fn expand_deriving_clone( } let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(inline)]; + let attrs = thin_vec![cx.attribute(inline)]; let trait_def = TraitDef { span, - attributes: Vec::new(), path: path_std!(clone::Clone), additional_bounds: bounds, generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index 4e798bf6a..5b556c5c9 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; +use thin_vec::thin_vec; pub fn expand_deriving_eq( cx: &mut ExtCtxt<'_>, @@ -20,10 +21,9 @@ pub fn expand_deriving_eq( let hidden = rustc_ast::attr::mk_nested_word_item(Ident::new(sym::hidden, span)); let doc = rustc_ast::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]); let no_coverage = cx.meta_word(span, sym::no_coverage); - let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)]; + let attrs = thin_vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)]; let trait_def = TraitDef { span, - attributes: Vec::new(), path: path_std!(cmp::Eq), additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs index 1612be862..726258695 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs @@ -1,11 +1,11 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::path_std; - use rustc_ast::MetaItem; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; +use thin_vec::thin_vec; pub fn expand_deriving_ord( cx: &mut ExtCtxt<'_>, @@ -15,10 +15,9 @@ pub fn expand_deriving_ord( push: &mut dyn FnMut(Annotatable), ) { let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(inline)]; + let attrs = thin_vec![cx.attribute(inline)]; let trait_def = TraitDef { span, - attributes: Vec::new(), path: path_std!(cmp::Ord), additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs index 0141b3377..42ee65b57 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs @@ -1,12 +1,12 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::{path_local, path_std}; - use rustc_ast::ptr::P; use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; +use thin_vec::thin_vec; pub fn expand_deriving_partial_eq( cx: &mut ExtCtxt<'_>, @@ -15,14 +15,8 @@ pub fn expand_deriving_partial_eq( item: &Annotatable, push: &mut dyn FnMut(Annotatable), ) { - fn cs_op( - cx: &mut ExtCtxt<'_>, - span: Span, - substr: &Substructure<'_>, - op: BinOpKind, - combiner: BinOpKind, - base: bool, - ) -> BlockOrExpr { + fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr { + let base = true; let expr = cs_fold( true, // use foldl cx, @@ -47,39 +41,22 @@ pub fn expand_deriving_partial_eq( cx.expr_deref(field.span, expr.clone()) } }; - cx.expr_binary(field.span, op, convert(&field.self_expr), convert(other_expr)) + cx.expr_binary( + field.span, + BinOpKind::Eq, + convert(&field.self_expr), + convert(other_expr), + ) + } + CsFold::Combine(span, expr1, expr2) => { + cx.expr_binary(span, BinOpKind::And, expr1, expr2) } - CsFold::Combine(span, expr1, expr2) => cx.expr_binary(span, combiner, expr1, expr2), CsFold::Fieldless => cx.expr_bool(span, base), }, ); BlockOrExpr::new_expr(expr) } - fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr { - cs_op(cx, span, substr, BinOpKind::Eq, BinOpKind::And, true) - } - fn cs_ne(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr { - cs_op(cx, span, substr, BinOpKind::Ne, BinOpKind::Or, false) - } - - macro_rules! md { - ($name:expr, $f:ident) => {{ - let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(inline)]; - MethodDef { - name: $name, - generics: Bounds::empty(), - explicit_self: true, - nonself_args: vec![(self_ref(), sym::other)], - ret_ty: Path(path_local!(bool)), - attributes: attrs, - unify_fieldless_variants: true, - combine_substructure: combine_substructure(Box::new(|a, b, c| $f(a, b, c))), - } - }}; - } - super::inject_impl_of_structural_trait( cx, span, @@ -88,17 +65,23 @@ pub fn expand_deriving_partial_eq( push, ); - // avoid defining `ne` if we can - // c-like enums, enums without any fields and structs without fields - // can safely define only `eq`. - let mut methods = vec![md!(sym::eq, cs_eq)]; - if !is_type_without_fields(item) { - methods.push(md!(sym::ne, cs_ne)); - } + // No need to generate `ne`, the default suffices, and not generating it is + // faster. + let inline = cx.meta_word(span, sym::inline); + let attrs = thin_vec![cx.attribute(inline)]; + let methods = vec![MethodDef { + name: sym::eq, + generics: Bounds::empty(), + explicit_self: true, + nonself_args: vec![(self_ref(), sym::other)], + ret_ty: Path(path_local!(bool)), + attributes: attrs, + unify_fieldless_variants: true, + combine_substructure: combine_substructure(Box::new(|a, b, c| cs_eq(a, b, c))), + }]; let trait_def = TraitDef { span, - attributes: Vec::new(), path: path_std!(cmp::PartialEq), additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs index 2ebb01cc8..516892aed 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -1,11 +1,11 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::{path_std, pathvec_std}; - use rustc_ast::MetaItem; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; +use thin_vec::thin_vec; pub fn expand_deriving_partial_ord( cx: &mut ExtCtxt<'_>, @@ -19,7 +19,7 @@ pub fn expand_deriving_partial_ord( Path(Path::new_(pathvec_std!(option::Option), vec![Box::new(ordering_ty)], PathKind::Std)); let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(inline)]; + let attrs = thin_vec![cx.attribute(inline)]; let partial_cmp_def = MethodDef { name: sym::partial_cmp, @@ -36,7 +36,6 @@ pub fn expand_deriving_partial_ord( let trait_def = TraitDef { span, - attributes: vec![], path: path_std!(cmp::PartialOrd), additional_bounds: vec![], generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index ceef893e8..4af7fd816 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -19,7 +19,6 @@ pub fn expand_deriving_debug( let trait_def = TraitDef { span, - attributes: Vec::new(), path: path_std!(fmt::Debug), additional_bounds: Vec::new(), generics: Bounds::empty(), @@ -30,7 +29,7 @@ pub fn expand_deriving_debug( explicit_self: true, nonself_args: vec![(fmtr, sym::f)], ret_ty: Path(path_std!(fmt::Result)), - attributes: Vec::new(), + attributes: ast::AttrVec::new(), unify_fieldless_variants: false, combine_substructure: combine_substructure(Box::new(|a, b, c| { show_substructure(a, b, c) @@ -52,7 +51,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> // We want to make sure we have the ctxt set so that we can use unstable methods let span = cx.with_def_site_ctxt(span); - let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked)); + let name = cx.expr_str(span, ident.name); let fmt = substr.nonselflike_args[0].clone(); // Struct and tuples are similar enough that we use the same code for both, @@ -89,10 +88,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> for i in 0..fields.len() { let field = &fields[i]; if is_struct { - let name = cx.expr_lit( - field.span, - ast::LitKind::Str(field.name.unwrap().name, ast::StrStyle::Cooked), - ); + let name = cx.expr_str(field.span, field.name.unwrap().name); args.push(name); } // Use an extra indirection to make sure this works for unsized types. @@ -108,10 +104,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> for field in fields { if is_struct { - name_exprs.push(cx.expr_lit( - field.span, - ast::LitKind::Str(field.name.unwrap().name, ast::StrStyle::Cooked), - )); + name_exprs.push(cx.expr_str(field.span, field.name.unwrap().name)); } // Use an extra indirection to make sure this works for unsized types. diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs index d688143a2..7174dbbe7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs @@ -22,7 +22,6 @@ pub fn expand_deriving_rustc_decodable( let trait_def = TraitDef { span, - attributes: Vec::new(), path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global), additional_bounds: Vec::new(), generics: Bounds::empty(), @@ -48,7 +47,7 @@ pub fn expand_deriving_rustc_decodable( ], PathKind::Std, )), - attributes: Vec::new(), + attributes: ast::AttrVec::new(), unify_fieldless_variants: false, combine_substructure: combine_substructure(Box::new(|a, b, c| { decodable_substructure(a, b, c, krate) diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 517769091..a94c8a996 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -1,16 +1,14 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; - use rustc_ast as ast; -use rustc_ast::walk_list; -use rustc_ast::EnumDef; -use rustc_ast::VariantData; +use rustc_ast::{walk_list, EnumDef, VariantData}; use rustc_errors::Applicability; use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt}; use rustc_span::symbol::Ident; use rustc_span::symbol::{kw, sym}; use rustc_span::Span; use smallvec::SmallVec; +use thin_vec::thin_vec; pub fn expand_deriving_default( cx: &mut ExtCtxt<'_>, @@ -22,10 +20,9 @@ pub fn expand_deriving_default( item.visit_with(&mut DetectNonVariantDefaultAttr { cx }); let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(inline)]; + let attrs = thin_vec![cx.attribute(inline)]; let trait_def = TraitDef { span, - attributes: Vec::new(), path: Path::new(vec![kw::Default, sym::Default]), additional_bounds: Vec::new(), generics: Bounds::empty(), diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs index 70167cac6..b220e5423 100644 --- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs @@ -89,7 +89,7 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::pathvec_std; -use rustc_ast::{ExprKind, MetaItem, Mutability}; +use rustc_ast::{AttrVec, ExprKind, MetaItem, Mutability}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; @@ -106,7 +106,6 @@ pub fn expand_deriving_rustc_encodable( let trait_def = TraitDef { span, - attributes: Vec::new(), path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global), additional_bounds: Vec::new(), generics: Bounds::empty(), @@ -132,7 +131,7 @@ pub fn expand_deriving_rustc_encodable( ], PathKind::Std, )), - attributes: Vec::new(), + attributes: AttrVec::new(), unify_fieldless_variants: false, combine_substructure: combine_substructure(Box::new(|a, b, c| { encodable_substructure(a, b, c, krate) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 735017aa5..3cc160adb 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -162,30 +162,28 @@ pub use StaticFields::*; pub use SubstructureFields::*; -use std::cell::RefCell; -use std::iter; -use std::vec; - +use crate::deriving; use rustc_ast::ptr::P; -use rustc_ast::{self as ast, EnumDef, Expr, Generics, PatKind}; +use rustc_ast::{ + self as ast, BindingAnnotation, ByRef, EnumDef, Expr, Generics, Mutability, PatKind, +}; use rustc_ast::{GenericArg, GenericParamKind, VariantData}; use rustc_attr as attr; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; - +use std::cell::RefCell; +use std::iter; +use std::vec; +use thin_vec::thin_vec; use ty::{Bounds, Path, Ref, Self_, Ty}; -use crate::deriving; - pub mod ty; pub struct TraitDef<'a> { /// The span for the current #[derive(Foo)] header. pub span: Span, - pub attributes: Vec<ast::Attribute>, - /// Path of the trait, including any type parameters pub path: Path, @@ -219,7 +217,7 @@ pub struct MethodDef<'a> { /// Returns type pub ret_ty: Ty, - pub attributes: Vec<ast::Attribute>, + pub attributes: ast::AttrVec, /// Can we combine fieldless variants for enums into a single match arm? /// If true, indicates that the trait operation uses the enum tag in some @@ -383,16 +381,11 @@ fn find_type_parameters( } // Place bound generic params on a stack, to extract them when a type is encountered. - fn visit_poly_trait_ref( - &mut self, - trait_ref: &'a ast::PolyTraitRef, - modifier: &'a ast::TraitBoundModifier, - ) { + fn visit_poly_trait_ref(&mut self, trait_ref: &'a ast::PolyTraitRef) { let stack_len = self.bound_generic_params_stack.len(); - self.bound_generic_params_stack - .extend(trait_ref.bound_generic_params.clone().into_iter()); + self.bound_generic_params_stack.extend(trait_ref.bound_generic_params.iter().cloned()); - visit::walk_poly_trait_ref(self, trait_ref, modifier); + visit::walk_poly_trait_ref(self, trait_ref); self.bound_generic_params_stack.truncate(stack_len); } @@ -568,7 +561,7 @@ impl<'a> TraitDef<'a> { kind: ast::VisibilityKind::Inherited, tokens: None, }, - attrs: Vec::new(), + attrs: ast::AttrVec::new(), kind: ast::AssocItemKind::TyAlias(Box::new(ast::TyAlias { defaultness: ast::Defaultness::Final, generics: Generics::default(), @@ -609,7 +602,7 @@ impl<'a> TraitDef<'a> { param.bounds.iter().cloned() ).collect(); - cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, vec![], bounds, None) + cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, bounds, None) } GenericParamKind::Const { ty, kw_span, .. } => { let const_nodefault_kind = GenericParamKind::Const { @@ -644,11 +637,7 @@ impl<'a> TraitDef<'a> { } ast::WherePredicate::EqPredicate(we) => { let span = we.span.with_ctxt(ctxt); - ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { - id: ast::DUMMY_NODE_ID, - span, - ..we.clone() - }) + ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { span, ..we.clone() }) } } })); @@ -726,15 +715,13 @@ impl<'a> TraitDef<'a> { let self_type = cx.ty_path(path); let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived)); + let attrs = thin_vec![attr]; let opt_trait_ref = Some(trait_ref); - let mut a = vec![attr]; - a.extend(self.attributes.iter().cloned()); - cx.item( self.span, Ident::empty(), - a, + attrs, ast::ItemKind::Impl(Box::new(ast::Impl { unsafety: ast::Unsafe::No, polarity: ast::ImplPolarity::Positive, @@ -1078,9 +1065,9 @@ impl<'a> MethodDef<'a> { let mut body = mk_body(cx, selflike_fields); let struct_path = cx.path(span, vec![Ident::new(kw::SelfUpper, type_ident.span)]); - let use_ref_pat = is_packed && !always_copy; + let by_ref = ByRef::from(is_packed && !always_copy); let patterns = - trait_.create_struct_patterns(cx, struct_path, struct_def, &prefixes, use_ref_pat); + trait_.create_struct_patterns(cx, struct_path, struct_def, &prefixes, by_ref); // Do the let-destructuring. let mut stmts: Vec<_> = iter::zip(selflike_args, patterns) @@ -1262,13 +1249,13 @@ impl<'a> MethodDef<'a> { let sp = variant.span.with_ctxt(trait_.span.ctxt()); let variant_path = cx.path(sp, vec![type_ident, variant.ident]); - let use_ref_pat = false; // because enums can't be repr(packed) + let by_ref = ByRef::No; // because enums can't be repr(packed) let mut subpats: Vec<_> = trait_.create_struct_patterns( cx, variant_path, &variant.data, &prefixes, - use_ref_pat, + by_ref, ); // `(VariantK, VariantK, ...)` or just `VariantK`. @@ -1429,7 +1416,7 @@ impl<'a> TraitDef<'a> { struct_path: ast::Path, struct_def: &'a VariantData, prefixes: &[String], - use_ref_pat: bool, + by_ref: ByRef, ) -> Vec<P<ast::Pat>> { prefixes .iter() @@ -1437,17 +1424,19 @@ impl<'a> TraitDef<'a> { let pieces_iter = struct_def.fields().iter().enumerate().map(|(i, struct_field)| { let sp = struct_field.span.with_ctxt(self.span.ctxt()); - let binding_mode = if use_ref_pat { - ast::BindingMode::ByRef(ast::Mutability::Not) - } else { - ast::BindingMode::ByValue(ast::Mutability::Not) - }; let ident = self.mk_pattern_ident(prefix, i); let path = ident.with_span_pos(sp); ( sp, struct_field.ident, - cx.pat(path.span, PatKind::Ident(binding_mode, path, None)), + cx.pat( + path.span, + PatKind::Ident( + BindingAnnotation(by_ref, Mutability::Not), + path, + None, + ), + ), ) }); @@ -1637,19 +1626,3 @@ where StaticEnum(..) | StaticStruct(..) => cx.span_bug(trait_span, "static function in `derive`"), } } - -/// Returns `true` if the type has no value fields -/// (for an enum, no variant has any fields) -pub fn is_type_without_fields(item: &Annotatable) -> bool { - if let Annotatable::Item(ref item) = *item { - match item.kind { - ast::ItemKind::Enum(ref enum_def, _) => { - enum_def.variants.iter().all(|v| v.data.fields().is_empty()) - } - ast::ItemKind::Struct(ref variant_data, _) => variant_data.fields().is_empty(), - _ => false, - } - } else { - false - } -} diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs index 4d46f7cd4..36e2e2930 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs @@ -146,7 +146,6 @@ fn mk_ty_param( cx: &ExtCtxt<'_>, span: Span, name: Symbol, - attrs: &[ast::Attribute], bounds: &[Path], self_ident: Ident, self_generics: &Generics, @@ -158,7 +157,7 @@ fn mk_ty_param( cx.trait_bound(path) }) .collect(); - cx.typaram(span, Ident::new(name, span), attrs.to_owned(), bounds, None) + cx.typaram(span, Ident::new(name, span), bounds, None) } /// Bounds on type parameters. @@ -183,7 +182,7 @@ impl Bounds { .iter() .map(|t| { let (name, ref bounds) = *t; - mk_ty_param(cx, span, name, &[], &bounds, self_ty, self_generics) + mk_ty_param(cx, span, name, &bounds, self_ty, self_generics) }) .collect(); diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 32ae3d344..f1f02e7ce 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -2,7 +2,7 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::{path_std, pathvec_std}; -use rustc_ast::{MetaItem, Mutability}; +use rustc_ast::{AttrVec, MetaItem, Mutability}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -21,7 +21,6 @@ pub fn expand_deriving_hash( let arg = Path::new_local(typaram); let hash_trait_def = TraitDef { span, - attributes: Vec::new(), path, additional_bounds: Vec::new(), generics: Bounds::empty(), @@ -32,7 +31,7 @@ pub fn expand_deriving_hash( explicit_self: true, nonself_args: vec![(Ref(Box::new(Path(arg)), Mutability::Mut), sym::state)], ret_ty: Unit, - attributes: vec![], + attributes: AttrVec::new(), unify_fieldless_variants: true, combine_substructure: combine_substructure(Box::new(|a, b, c| { hash_substructure(a, b, c) diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index c1ca089da..a65d0bad6 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -164,7 +164,7 @@ fn inject_impl_of_structural_trait( // Keep the lint and stability attributes of the original item, to control // how the generated implementation is linted. - let mut attrs = Vec::new(); + let mut attrs = ast::AttrVec::new(); attrs.extend( item.attrs .iter() diff --git a/compiler/rustc_builtin_macros/src/edition_panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs index ea0e768a5..3f1a8b3bc 100644 --- a/compiler/rustc_builtin_macros/src/edition_panic.rs +++ b/compiler/rustc_builtin_macros/src/edition_panic.rs @@ -48,7 +48,7 @@ fn expand<'cx>( MacEager::expr( cx.expr( sp, - ExprKind::MacCall(MacCall { + ExprKind::MacCall(P(MacCall { path: Path { span: sp, segments: cx @@ -64,7 +64,7 @@ fn expand<'cx>( tts, )), prior_type_ascription: None, - }), + })), ), ) } diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 9eb96ec76..210048710 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -130,64 +130,46 @@ impl PositionalNamedArgsLint { /// CountIsParam, which contains an index into the arguments. fn maybe_add_positional_named_arg( &mut self, - current_positional_arg: usize, - total_args_length: usize, - format_argument_index: usize, + arg: Option<&FormatArg>, ty: PositionalNamedArgType, cur_piece: usize, inner_span_to_replace: Option<rustc_parse_format::InnerSpan>, - names: &FxHashMap<Symbol, (usize, Span)>, has_formatting: bool, ) { - let start_of_named_args = total_args_length - names.len(); - if current_positional_arg >= start_of_named_args { - self.maybe_push( - format_argument_index, - ty, - cur_piece, - inner_span_to_replace, - names, - has_formatting, - ) + if let Some(arg) = arg { + if let Some(name) = arg.name { + self.push(name, ty, cur_piece, inner_span_to_replace, has_formatting) + } } } - /// Try constructing a PositionalNamedArg struct and pushing it into the vec of positional - /// named arguments. If a named arg associated with `format_argument_index` cannot be found, - /// a new item will not be added as the lint cannot be emitted in this case. - fn maybe_push( + /// Construct a PositionalNamedArg struct and push it into the vec of positional + /// named arguments. + fn push( &mut self, - format_argument_index: usize, + arg_name: Ident, ty: PositionalNamedArgType, cur_piece: usize, inner_span_to_replace: Option<rustc_parse_format::InnerSpan>, - names: &FxHashMap<Symbol, (usize, Span)>, has_formatting: bool, ) { - let named_arg = names - .iter() - .find(|&(_, &(index, _))| index == format_argument_index) - .map(|found| found.clone()); - - if let Some((&replacement, &(_, positional_named_arg_span))) = named_arg { - // In FormatSpec, `precision_span` starts at the leading `.`, which we want to keep in - // the lint suggestion, so increment `start` by 1 when `PositionalArgumentType` is - // `Precision`. - let inner_span_to_replace = if ty == PositionalNamedArgType::Precision { - inner_span_to_replace - .map(|is| rustc_parse_format::InnerSpan { start: is.start + 1, end: is.end }) - } else { - inner_span_to_replace - }; - self.positional_named_args.push(PositionalNamedArg { - ty, - cur_piece, - inner_span_to_replace, - replacement, - positional_named_arg_span, - has_formatting, - }); - } + // In FormatSpec, `precision_span` starts at the leading `.`, which we want to keep in + // the lint suggestion, so increment `start` by 1 when `PositionalArgumentType` is + // `Precision`. + let inner_span_to_replace = if ty == PositionalNamedArgType::Precision { + inner_span_to_replace + .map(|is| rustc_parse_format::InnerSpan { start: is.start + 1, end: is.end }) + } else { + inner_span_to_replace + }; + self.positional_named_args.push(PositionalNamedArg { + ty, + cur_piece, + inner_span_to_replace, + replacement: arg_name.name, + positional_named_arg_span: arg_name.span, + has_formatting, + }); } } @@ -211,7 +193,7 @@ struct Context<'a, 'b> { /// * `arg_types` (in JSON): `[[0, 1, 0], [0, 1, 1], [0, 1]]` /// * `arg_unique_types` (in simplified JSON): `[["o", "x"], ["o", "x"], ["o", "x"]]` /// * `names` (in JSON): `{"foo": 2}` - args: Vec<P<ast::Expr>>, + args: Vec<FormatArg>, /// The number of arguments that were added by implicit capturing. num_captured_args: usize, /// Placeholder slot numbers indexed by argument. @@ -219,7 +201,7 @@ struct Context<'a, 'b> { /// Unique format specs seen for each argument. arg_unique_types: Vec<Vec<ArgumentType>>, /// Map from named arguments to their resolved indices. - names: FxHashMap<Symbol, (usize, Span)>, + names: FxHashMap<Symbol, usize>, /// The latest consecutive literal strings, or empty if there weren't any. literal: String, @@ -282,7 +264,7 @@ struct Context<'a, 'b> { pub struct FormatArg { expr: P<ast::Expr>, - named: bool, + name: Option<Ident>, } /// Parses the arguments from the given list of tokens, returning the diagnostic @@ -298,9 +280,9 @@ fn parse_args<'a>( ecx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream, -) -> PResult<'a, (P<ast::Expr>, Vec<FormatArg>, FxHashMap<Symbol, (usize, Span)>)> { +) -> PResult<'a, (P<ast::Expr>, Vec<FormatArg>, FxHashMap<Symbol, usize>)> { let mut args = Vec::<FormatArg>::new(); - let mut names = FxHashMap::<Symbol, (usize, Span)>::default(); + let mut names = FxHashMap::<Symbol, usize>::default(); let mut p = ecx.new_parser_from_tts(tts); @@ -365,9 +347,9 @@ fn parse_args<'a>( p.bump(); p.expect(&token::Eq)?; let e = p.parse_expr()?; - if let Some((prev, _)) = names.get(&ident.name) { + if let Some(&prev) = names.get(&ident.name) { ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", ident)) - .span_label(args[*prev].expr.span, "previously here") + .span_label(args[prev].expr.span, "previously here") .span_label(e.span, "duplicate argument") .emit(); continue; @@ -378,8 +360,8 @@ fn parse_args<'a>( // if the input is valid, we can simply append to the positional // args. And remember the names. let slot = args.len(); - names.insert(ident.name, (slot, ident.span)); - args.push(FormatArg { expr: e, named: true }); + names.insert(ident.name, slot); + args.push(FormatArg { expr: e, name: Some(ident) }); } _ => { let e = p.parse_expr()?; @@ -389,12 +371,12 @@ fn parse_args<'a>( "positional arguments cannot follow named arguments", ); err.span_label(e.span, "positional arguments must be before named arguments"); - for pos in names.values() { - err.span_label(args[pos.0].expr.span, "named argument"); + for &pos in names.values() { + err.span_label(args[pos].expr.span, "named argument"); } err.emit(); } - args.push(FormatArg { expr: e, named: false }); + args.push(FormatArg { expr: e, name: None }); } } } @@ -410,8 +392,7 @@ impl<'a, 'b> Context<'a, 'b> { fn resolve_name_inplace(&mut self, p: &mut parse::Piece<'_>) { // NOTE: the `unwrap_or` branch is needed in case of invalid format // arguments, e.g., `format_args!("{foo}")`. - let lookup = - |s: &str| self.names.get(&Symbol::intern(s)).unwrap_or(&(0, Span::default())).0; + let lookup = |s: &str| self.names.get(&Symbol::intern(s)).copied().unwrap_or(0); match *p { parse::String(_) => {} @@ -432,7 +413,7 @@ impl<'a, 'b> Context<'a, 'b> { /// Verifies one piece of a parse string, and remembers it if valid. /// All errors are not emitted as fatal so we can continue giving errors /// about this and possibly other format strings. - fn verify_piece(&mut self, p: &parse::Piece<'_>) { + fn verify_piece(&mut self, p: &parse::Piece<'a>) { match *p { parse::String(..) => {} parse::NextArgument(ref arg) => { @@ -452,18 +433,20 @@ impl<'a, 'b> Context<'a, 'b> { let has_precision = arg.format.precision != Count::CountImplied; let has_width = arg.format.width != Count::CountImplied; + if has_precision || has_width { + // push before named params are resolved to aid diagnostics + self.arg_with_formatting.push(arg.format); + } + // argument second, if it's an implicit positional parameter // it's written second, so it should come after width/precision. let pos = match arg.position { parse::ArgumentIs(i) => { self.unused_names_lint.maybe_add_positional_named_arg( - i, - self.args.len(), - i, + self.args.get(i), PositionalNamedArgType::Arg, self.curpiece, Some(arg.position_span), - &self.names, has_precision || has_width, ); @@ -471,13 +454,10 @@ impl<'a, 'b> Context<'a, 'b> { } parse::ArgumentImplicitlyIs(i) => { self.unused_names_lint.maybe_add_positional_named_arg( - i, - self.args.len(), - i, + self.args.get(i), PositionalNamedArgType::Arg, self.curpiece, None, - &self.names, has_precision || has_width, ); Exact(i) @@ -561,15 +541,12 @@ impl<'a, 'b> Context<'a, 'b> { ) { match c { parse::CountImplied | parse::CountIs(..) => {} - parse::CountIsParam(i) => { + parse::CountIsParam(i) | parse::CountIsStar(i) => { self.unused_names_lint.maybe_add_positional_named_arg( - i, - self.args.len(), - i, + self.args.get(i), named_arg_type, self.curpiece, *inner_span, - &self.names, true, ); self.verify_arg_type(Exact(i), Count); @@ -609,7 +586,11 @@ impl<'a, 'b> Context<'a, 'b> { let mut zero_based_note = false; let count = self.pieces.len() - + self.arg_with_formatting.iter().filter(|fmt| fmt.precision_span.is_some()).count(); + + self + .arg_with_formatting + .iter() + .filter(|fmt| matches!(fmt.precision, parse::CountIsStar(_))) + .count(); if self.names.is_empty() && !numbered_position_args && count != self.num_args() { e = self.ecx.struct_span_err( sp, @@ -622,7 +603,7 @@ impl<'a, 'b> Context<'a, 'b> { ); for arg in &self.args { // Point at the arguments that will be formatted. - e.span_label(arg.span, ""); + e.span_label(arg.expr.span, ""); } } else { let (mut refs, spans): (Vec<_>, Vec<_>) = refs.unzip(); @@ -658,7 +639,7 @@ impl<'a, 'b> Context<'a, 'b> { if let Some(span) = fmt.precision_span { let span = self.fmtsp.from_inner(InnerSpan::new(span.start, span.end)); match fmt.precision { - parse::CountIsParam(pos) if pos > self.num_args() => { + parse::CountIsParam(pos) if pos >= self.num_args() => { e.span_label( span, &format!( @@ -670,12 +651,12 @@ impl<'a, 'b> Context<'a, 'b> { ); zero_based_note = true; } - parse::CountIsParam(pos) => { + parse::CountIsStar(pos) => { let count = self.pieces.len() + self .arg_with_formatting .iter() - .filter(|fmt| fmt.precision_span.is_some()) + .filter(|fmt| matches!(fmt.precision, parse::CountIsStar(_))) .count(); e.span_label( span, @@ -692,7 +673,7 @@ impl<'a, 'b> Context<'a, 'b> { ); if let Some(arg) = self.args.get(pos) { e.span_label( - arg.span, + arg.expr.span, "this parameter corresponds to the precision flag", ); } @@ -771,7 +752,7 @@ impl<'a, 'b> Context<'a, 'b> { match self.names.get(&name) { Some(&idx) => { // Treat as positional arg. - self.verify_arg_type(Capture(idx.0), ty) + self.verify_arg_type(Capture(idx), ty) } None => { // For the moment capturing variables from format strings expanded from macros is @@ -787,8 +768,11 @@ impl<'a, 'b> Context<'a, 'b> { self.fmtsp }; self.num_captured_args += 1; - self.args.push(self.ecx.expr_ident(span, Ident::new(name, span))); - self.names.insert(name, (idx, span)); + self.args.push(FormatArg { + expr: self.ecx.expr_ident(span, Ident::new(name, span)), + name: Some(Ident::new(name, span)), + }); + self.names.insert(name, idx); self.verify_arg_type(Capture(idx), ty) } else { let msg = format!("there is no argument named `{}`", name); @@ -853,7 +837,7 @@ impl<'a, 'b> Context<'a, 'b> { }; match c { parse::CountIs(i) => count(sym::Is, Some(self.ecx.expr_usize(sp, i))), - parse::CountIsParam(i) => { + parse::CountIsParam(i) | parse::CountIsStar(i) => { // This needs mapping too, as `i` is referring to a macro // argument. If `i` is not found in `count_positions` then // the error had already been emitted elsewhere. @@ -924,31 +908,27 @@ impl<'a, 'b> Context<'a, 'b> { }, position_span: arg.position_span, format: parse::FormatSpec { - fill: arg.format.fill, + fill: None, align: parse::AlignUnknown, flags: 0, precision: parse::CountImplied, - precision_span: None, + precision_span: arg.format.precision_span, width: parse::CountImplied, - width_span: None, + width_span: arg.format.width_span, ty: arg.format.ty, ty_span: arg.format.ty_span, }, }; let fill = arg.format.fill.unwrap_or(' '); - let pos_simple = arg.position.index() == simple_arg.position.index(); - if arg.format.precision_span.is_some() || arg.format.width_span.is_some() { - self.arg_with_formatting.push(arg.format); - } - if !pos_simple || arg.format != simple_arg.format || fill != ' ' { + if !pos_simple || arg.format != simple_arg.format { self.all_pieces_simple = false; } // Build the format - let fill = self.ecx.expr_lit(sp, ast::LitKind::Char(fill)); + let fill = self.ecx.expr_char(sp, fill); let align = |name| { let mut p = Context::rtpath(self.ecx, sym::Alignment); p.push(Ident::new(name, sp)); @@ -1054,11 +1034,11 @@ impl<'a, 'b> Context<'a, 'b> { // evaluated a single time each, in the order written by the programmer, // and that the surrounding future/generator (if any) is Send whenever // possible. - let no_need_for_match = - nicely_ordered && !original_args.iter().skip(1).any(|e| may_contain_yield_point(e)); + let no_need_for_match = nicely_ordered + && !original_args.iter().skip(1).any(|arg| may_contain_yield_point(&arg.expr)); for (arg_index, arg_ty) in fmt_arg_index_and_ty { - let e = &mut original_args[arg_index]; + let e = &mut original_args[arg_index].expr; let span = e.span; let arg = if no_need_for_match { let expansion_span = e.span.with_ctxt(self.macsp.ctxt()); @@ -1087,7 +1067,9 @@ impl<'a, 'b> Context<'a, 'b> { // span is otherwise unavailable in the MIR used by borrowck). let heads = original_args .into_iter() - .map(|e| self.ecx.expr_addr_of(e.span.with_ctxt(self.macsp.ctxt()), e)) + .map(|arg| { + self.ecx.expr_addr_of(arg.expr.span.with_ctxt(self.macsp.ctxt()), arg.expr) + }) .collect(); let pat = self.ecx.pat_ident(self.macsp, Ident::new(sym::args, self.macsp)); @@ -1199,7 +1181,7 @@ fn create_lints_for_named_arguments_used_positionally(cx: &mut Context<'_, '_>) cx.ecx.buffered_early_lint.push(BufferedEarlyLint { span: MultiSpan::from_span(named_arg.positional_named_arg_span), - msg: msg.clone(), + msg: msg.into(), node_id: ast::CRATE_NODE_ID, lint_id: LintId::of(&NAMED_ARGUMENTS_USED_POSITIONALLY), diagnostic: BuiltinLintDiagnostics::NamedArgumentUsedPositionally { @@ -1220,7 +1202,7 @@ pub fn expand_preparsed_format_args( sp: Span, efmt: P<ast::Expr>, args: Vec<FormatArg>, - names: FxHashMap<Symbol, (usize, Span)>, + names: FxHashMap<Symbol, usize>, append_newline: bool, ) -> P<ast::Expr> { // NOTE: this verbose way of initializing `Vec<Vec<ArgumentType>>` is because @@ -1312,16 +1294,17 @@ pub fn expand_preparsed_format_args( if err.should_be_replaced_with_positional_argument { let captured_arg_span = fmt_span.from_inner(InnerSpan::new(err.span.start, err.span.end)); - let positional_args = args.iter().filter(|arg| !arg.named).collect::<Vec<_>>(); + let n_positional_args = + args.iter().rposition(|arg| arg.name.is_none()).map_or(0, |i| i + 1); if let Ok(arg) = ecx.source_map().span_to_snippet(captured_arg_span) { - let span = match positional_args.last() { + let span = match args[..n_positional_args].last() { Some(arg) => arg.expr.span, None => fmt_sp, }; e.multipart_suggestion_verbose( "consider using a positional formatting argument instead", vec![ - (captured_arg_span, positional_args.len().to_string()), + (captured_arg_span, n_positional_args.to_string()), (span.shrink_to_hi(), format!(", {}", arg)), ], Applicability::MachineApplicable, @@ -1338,11 +1321,9 @@ pub fn expand_preparsed_format_args( .map(|span| fmt_span.from_inner(InnerSpan::new(span.start, span.end))) .collect(); - let named_pos: FxHashSet<usize> = names.values().cloned().map(|(i, _)| i).collect(); - let mut cx = Context { ecx, - args: args.into_iter().map(|arg| arg.expr).collect(), + args, num_captured_args: 0, arg_types, arg_unique_types, @@ -1410,14 +1391,12 @@ pub fn expand_preparsed_format_args( .enumerate() .filter(|(i, ty)| ty.is_empty() && !cx.count_positions.contains_key(&i)) .map(|(i, _)| { - let msg = if named_pos.contains(&i) { - // named argument + let msg = if cx.args[i].name.is_some() { "named argument never used" } else { - // positional argument "argument never used" }; - (cx.args[i].span, msg) + (cx.args[i].expr.span, msg) }) .collect::<Vec<_>>(); diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 36cfbba45..45b9b8ab6 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -4,11 +4,12 @@ use rustc_ast::expand::allocator::{ AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS, }; use rustc_ast::ptr::P; -use rustc_ast::{self as ast, Attribute, Expr, FnHeader, FnSig, Generics, Param, StmtKind}; +use rustc_ast::{self as ast, AttrVec, Expr, FnHeader, FnSig, Generics, Param, StmtKind}; use rustc_ast::{Fn, ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; +use thin_vec::thin_vec; pub fn expand( ecx: &mut ExtCtxt<'_>, @@ -113,10 +114,10 @@ impl AllocFnFactory<'_, '_> { self.cx.expr_call(self.ty_span, method, args) } - fn attrs(&self) -> Vec<Attribute> { + fn attrs(&self) -> AttrVec { let special = sym::rustc_std_internal_symbol; let special = self.cx.meta_word(self.span, special); - vec![self.cx.attribute(special)] + thin_vec![self.cx.attribute(special)] } fn arg_ty( diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 11565ba72..8aeb3b82a 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -9,13 +9,16 @@ #![feature(if_let_guard)] #![feature(is_sorted)] #![feature(let_chains)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] #![recursion_limit = "256"] extern crate proc_macro; +#[macro_use] +extern crate tracing; + use crate::deriving::*; use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind}; diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 5cfda3349..ebe1c3663 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -281,7 +281,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> { let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id()); let proc_macro = Ident::new(sym::proc_macro, span); - let krate = cx.item(span, proc_macro, Vec::new(), ast::ItemKind::ExternCrate(None)); + let krate = cx.item(span, proc_macro, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)); let bridge = Ident::new(sym::bridge, span); let client = Ident::new(sym::client, span); diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 8bf3a0799..d78bbc3c9 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -216,7 +216,7 @@ pub fn expand_include_bytes( } }; match cx.source_map().load_binary_file(&file) { - Ok(bytes) => base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(bytes.into()))), + Ok(bytes) => base::MacEager::expr(cx.expr_byte_str(sp, bytes)), Err(e) => { cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e)); DummyResult::any(sp) diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs index 09ad5f9b3..49ef538f0 100644 --- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs +++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs @@ -6,6 +6,7 @@ use rustc_span::edition::Edition::*; use rustc_span::hygiene::AstPass; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::DUMMY_SP; +use thin_vec::thin_vec; pub fn inject( mut krate: ast::Crate, @@ -51,7 +52,7 @@ pub fn inject( cx.item( span, ident, - vec![cx.attribute(cx.meta_word(span, sym::macro_use))], + thin_vec![cx.attribute(cx.meta_word(span, sym::macro_use))], ast::ItemKind::ExternCrate(None), ), ); @@ -78,7 +79,7 @@ pub fn inject( let use_item = cx.item( span, Ident::empty(), - vec![cx.attribute(cx.meta_word(span, sym::prelude_import))], + thin_vec![cx.attribute(cx.meta_word(span, sym::prelude_import))], ast::ItemKind::Use(ast::UseTree { prefix: cx.path(span, import_path), kind: ast::UseTreeKind::Glob, diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index e20375689..7efb6cc61 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -1,7 +1,6 @@ /// 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}; - use rustc_ast as ast; use rustc_ast::attr; use rustc_ast::ptr::P; @@ -11,8 +10,8 @@ use rustc_expand::base::*; use rustc_session::Session; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; - use std::iter; +use thin_vec::thin_vec; // #[test_case] is used by custom test authors to mark tests // When building for test, it needs to make the item public and gensym the name @@ -219,7 +218,7 @@ pub fn expand_test_or_bench( let mut test_const = cx.item( sp, Ident::new(item.ident.name, sp), - vec![ + thin_vec![ // #[cfg(test)] cx.attribute(attr::mk_list_item( Ident::new(sym::cfg, attr_sp), @@ -334,9 +333,9 @@ pub fn expand_test_or_bench( }); // extern crate test - let test_extern = cx.item(sp, test_id, vec![], ast::ItemKind::ExternCrate(None)); + let test_extern = cx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)); - tracing::debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const)); + debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const)); if is_stmt { vec![ diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 0ebe29df9..561ca00c7 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -14,7 +14,7 @@ use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::PanicStrategy; use smallvec::{smallvec, SmallVec}; -use tracing::debug; +use thin_vec::thin_vec; use std::{iter, mem}; @@ -187,7 +187,10 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> { let dc_nested = attr::mk_nested_word_item(Ident::new(sym::dead_code, self.def_site)); let allow_dead_code_item = attr::mk_list_item(allow_ident, vec![dc_nested]); - let allow_dead_code = attr::mk_attr_outer(allow_dead_code_item); + let allow_dead_code = attr::mk_attr_outer( + &self.sess.parse_sess.attr_id_generator, + allow_dead_code_item, + ); let attrs = attrs .into_iter() .filter(|attr| { @@ -298,8 +301,10 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> { let call_test_main = ecx.stmt_expr(call_test_main); // extern crate test - let test_extern_stmt = - ecx.stmt_item(sp, ecx.item(sp, test_id, vec![], ast::ItemKind::ExternCrate(None))); + let test_extern_stmt = ecx.stmt_item( + sp, + ecx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)), + ); // #[rustc_main] let main_meta = ecx.meta_word(sp, sym::rustc_main); @@ -333,7 +338,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> { let main = P(ast::Item { ident: main_id, - attrs: vec![main_attr], + attrs: thin_vec![main_attr], id: ast::DUMMY_NODE_ID, kind: main, vis: ast::Visibility { span: sp, kind: ast::VisibilityKind::Public, tokens: None }, |