diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 1272970a81be9..07a4553e76f69 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -1,13 +1,11 @@ use rustc_ast::expand::allocator::{ALLOC_ERROR_HANDLER, global_fn_name}; -use rustc_ast::{ - self as ast, Fn, FnHeader, FnSig, Generics, ItemKind, Safety, Stmt, StmtKind, TyKind, -}; +use rustc_ast::{self as ast, FnHeader, FnSig, Generics, ItemKind, Safety, Stmt, StmtKind, TyKind}; use rustc_expand::base::{Annotatable, ExtCtxt}; -use rustc_span::{Ident, Span, kw, sym}; -use thin_vec::{ThinVec, thin_vec}; +use rustc_span::{Ident, Span, sym}; +use thin_vec::thin_vec; use crate::diagnostics; -use crate::util::check_builtin_macro_attribute; +use crate::util::{check_builtin_macro_attribute, path_std}; pub(crate) fn expand( ecx: &mut ExtCtxt<'_>, @@ -42,10 +40,7 @@ pub(crate) fn expand( let stmts = thin_vec![generate_handler(ecx, ident, span, sig_span)]; // Generate anonymous constant serving as container for the allocator methods. - let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new())); - let const_body = ecx.expr_block(ecx.block(span, stmts)); - let const_item = - ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, Some(const_body)); + let const_item = ecx.item_const_underscore(span, ecx.block(span, stmts)); let const_item = if is_stmt { Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item))) } else { @@ -61,38 +56,34 @@ pub(crate) fn expand( // handler(core::alloc::Layout::from_size_align_unchecked(size, align)) // } fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt { - let usize = cx.path_ident(span, Ident::new(sym::usize, span)); - let ty_usize = cx.ty_path(usize); - let size = Ident::new(sym::size, span); - let align = Ident::new(sym::align, span); + let ty_usize = cx.ty_sym(span, sym::usize); - let layout_new = cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]); - let layout_new = cx.expr_path(cx.path(span, layout_new)); + let layout_new = path_std!(cx, span, alloc::Layout::from_size_align_unchecked); + let layout_new = cx.expr_path(layout_new); let layout = cx.expr_call( span, layout_new, - thin_vec![cx.expr_ident(span, size), cx.expr_ident(span, align)], + thin_vec![cx.expr_ident_sym(span, sym::size), cx.expr_ident_sym(span, sym::align)], ); let call = cx.expr_call_ident(sig_span, handler, thin_vec![layout]); let never = ast::FnRetTy::Ty(cx.ty(span, TyKind::Never)); - let params = thin_vec![cx.param(span, size, ty_usize.clone()), cx.param(span, align, ty_usize)]; + let params = thin_vec![ + cx.param(span, sym::size, ty_usize.clone()), + cx.param(span, sym::align, ty_usize) + ]; let decl = cx.fn_decl(params, never); let header = FnHeader { safety: Safety::Unsafe(span), ..FnHeader::default() }; let sig = FnSig { decl, header, span }; let body = Some(cx.block_expr(call)); - let kind = ItemKind::Fn(Box::new(Fn { - defaultness: ast::Defaultness::Implicit, + let kind = ItemKind::Fn(cx.item_fn( sig, - ident: Ident::from_str_and_span(&global_fn_name(ALLOC_ERROR_HANDLER), span), - generics: Generics::default(), - contract: None, + Ident::from_str_and_span(&global_fn_name(ALLOC_ERROR_HANDLER), span), + Generics::default(), body, - define_opaque: None, - eii_impl: None, - })); + )); let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)]; diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index f5a582ddffcc5..d211cb0d71263 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -13,6 +13,7 @@ use thin_vec::thin_vec; use crate::diagnostics; use crate::edition_panic::use_panic_2021; +use crate::util::path_std; pub(crate) fn expand_assert<'cx>( cx: &'cx mut ExtCtxt<'_>, @@ -34,7 +35,7 @@ pub(crate) fn expand_assert<'cx>( let panic_path = || { if use_panic_2021(span) { // On edition 2021, we always call `$crate::panic::panic_2021!()`. - cx.path(call_site_span, cx.std_path(&[sym::panic, sym::panic_2021])) + path_std!(cx, call_site_span, panic::panic_2021) } else { // Before edition 2021, we call `panic!()` unqualified, // such that it calls either `std::panic!()` or `core::panic!()`. @@ -64,7 +65,7 @@ pub(crate) fn expand_assert<'cx>( // passed literally. let then = cx.expr_call_global( call_site_span, - cx.std_path(&[sym::panicking, sym::panic]), + path_std!(cx, call_site_span, panicking::panic), thin_vec![cx.expr_str( DUMMY_SP, Symbol::intern(&format!( diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 11c97da0db5ad..0dd6152ffa86a 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -10,6 +10,8 @@ use rustc_expand::base::ExtCtxt; use rustc_span::{Ident, Span, Symbol, sym}; use thin_vec::{ThinVec, thin_vec}; +use crate::util::path_std; + pub(super) struct Context<'cx, 'a> { // An optimization. // @@ -99,7 +101,7 @@ impl<'cx, 'a> Context<'cx, 'a> { fn build_initial_imports(&self) -> Stmt { let nested_tree = |this: &Self, sym| UseTreeAndId { inner: UseTree { - prefix: this.cx.path(this.span, vec![Ident::with_dummy_span(sym)]), + prefix: this.cx.path_sym(this.span, sym), kind: UseTreeKind::Simple(None), }, id: DUMMY_NODE_ID, @@ -110,7 +112,7 @@ impl<'cx, 'a> Context<'cx, 'a> { self.span, thin_vec![self.cx.attr_nested_word(sym::allow, sym::unused_imports, self.span)], ItemKind::Use(UseTree { - prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])), + prefix: path_std!(self.cx, self.span, asserting), kind: UseTreeKind::Nested { items: thin_vec![ nested_tree(self, sym::TryCaptureGeneric), @@ -125,10 +127,9 @@ impl<'cx, 'a> Context<'cx, 'a> { /// Takes the conditional expression of `assert!` and then wraps it inside `unlikely` fn build_unlikely(&self, cond_expr: Box) -> Box { - let unlikely_path = self.cx.std_path(&[sym::intrinsics, sym::unlikely]); - self.cx.expr_call( + self.cx.expr_call_intrinsic( self.span, - self.cx.expr_path(self.cx.path(self.span, unlikely_path)), + sym::unlikely, thin_vec![self.cx.expr(self.span, ExprKind::Unary(UnOp::Not, cond_expr))], ) } @@ -342,13 +343,9 @@ impl<'cx, 'a> Context<'cx, 'a> { let curr_capture_idx = self.capture_decls.len(); let capture_string = format!("__capture{curr_capture_idx}"); let ident = Ident::new(Symbol::intern(&capture_string), self.span); - let init_std_path = self.cx.std_path(&[sym::asserting, sym::Capture, sym::new]); - let init = self.cx.expr_call( - self.span, - self.cx.expr_path(self.cx.path(self.span, init_std_path)), - ThinVec::new(), - ); - let capture = Capture { decl: self.cx.stmt_let(self.span, true, ident, init), ident }; + let init_std_path = path_std!(self.cx, self.span, asserting::Capture::new); + let init = self.cx.expr_call(self.span, self.cx.expr_path(init_std_path), ThinVec::new()); + let capture = Capture { decl: self.cx.stmt_let(self.span, true, ident.name, init), ident }; self.capture_decls.push(capture); self.manage_try_capture(ident, curr_capture_idx, expr); } @@ -366,7 +363,7 @@ impl<'cx, 'a> Context<'cx, 'a> { expr: &mut Box, ) { let local_bind_string = format!("__local_bind{curr_capture_idx}"); - let local_bind = Ident::new(Symbol::intern(&local_bind_string), self.span); + let local_bind = Symbol::intern(&local_bind_string); self.local_bind_decls.push(self.cx.stmt_let( self.span, false, @@ -375,10 +372,8 @@ impl<'cx, 'a> Context<'cx, 'a> { )); let wrapper = self.cx.expr_call( self.span, - self.cx.expr_path( - self.cx.path(self.span, self.cx.std_path(&[sym::asserting, sym::Wrapper])), - ), - thin_vec![self.cx.expr_path(Path::from_ident(local_bind))], + self.cx.expr_path(path_std!(self.cx, self.span, asserting::Wrapper)), + thin_vec![self.cx.expr_path(self.cx.path_sym(self.span, local_bind))], ); let try_capture_call = self .cx @@ -393,7 +388,7 @@ impl<'cx, 'a> Context<'cx, 'a> { )], )) .add_trailing_semicolon(); - let local_bind_path = self.cx.expr_path(Path::from_ident(local_bind)); + let local_bind_path = self.cx.expr_path(self.cx.path_sym(self.span, local_bind)); let rslt = if self.is_consumed { let ret = self.cx.stmt_expr(local_bind_path); self.cx.expr_block(self.cx.block(self.span, thin_vec![try_capture_call, ret])) diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 21f424836e476..2ea6b74d5fdaf 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -14,7 +14,7 @@ mod llvm_enzyme { use rustc_ast::tokenstream::*; use rustc_ast::visit::AssocCtxt::*; use rustc_ast::{ - self as ast, AnonConst, FnRetTy, FnSig, GenericArg, GenericParamKind, Generics, ItemKind, + self as ast, FnRetTy, FnSig, GenericArg, GenericParamKind, Generics, ItemKind, MetaItemInner, PatKind, TyKind, Visibility, }; use rustc_attr_ir::RustcAutodiff; @@ -332,16 +332,7 @@ mod llvm_enzyme { ); // The first element of it is the name of the function to be generated - let d_fn = Box::new(ast::Fn { - defaultness: ast::Defaultness::Implicit, - sig: d_sig, - ident: first_ident(&meta_item_vec[0]), - generics, - contract: None, - body: Some(d_body), - define_opaque: None, - eii_impl: None, - }); + let d_fn = ecx.item_fn(d_sig, first_ident(&meta_item_vec[0]), generics, Some(d_body)); let mut rustc_ad_attr = Box::new(ast::NormalAttr::from_ident(Ident::with_dummy_span(sym::rustc_autodiff))); @@ -502,7 +493,7 @@ mod llvm_enzyme { ) -> rustc_ast::Stmt { let primal_path_expr = gen_turbofish_expr(ecx, primal, generics, span, is_impl); - let self_ty = || ecx.ty_path(ast::Path::from_ident(Ident::with_dummy_span(kw::SelfUpper))); + let self_ty = || ecx.ty_self(DUMMY_SP); let fn_ptr_params: ThinVec = p_sig .decl .inputs @@ -562,11 +553,9 @@ mod llvm_enzyme { .collect::>(), ); - let enzyme_path_idents = ecx.std_path(&[sym::intrinsics, sym::autodiff]); - let enzyme_path = ecx.path(span, enzyme_path_idents); - let call_expr = ecx.expr_call( + let call_expr = ecx.expr_call_intrinsic( span, - ecx.expr_path(enzyme_path), + sym::autodiff, thin_vec![primal_fn_ptr, diff_path_expr, tuple_expr], ); @@ -593,17 +582,15 @@ mod llvm_enzyme { Some(GenericArg::Type(ty)) } GenericParamKind::Const { .. } => { - let expr = ecx.expr_path(ast::Path::from_ident(p.ident)); - let anon_const = AnonConst { id: ast::DUMMY_NODE_ID, value: expr }; + let anon_const = ecx.const_ident(span, p.ident); Some(GenericArg::Const(anon_const)) } GenericParamKind::Lifetime => None, }) .collect::>(); - let idents = - if is_impl { vec![Ident::new(kw::SelfUpper, span), ident] } else { vec![ident] }; - let path = ecx.path_all(span, false, idents, generic_args); + let idents = if is_impl { &[Ident::new(kw::SelfUpper, span), ident][..] } else { &[ident] }; + let path = ecx.path_all(span, idents, generic_args); ecx.expr_path(path) } @@ -707,8 +694,7 @@ mod llvm_enzyme { panic!("not an ident?"); }; let name = format!("d{}_{}", old_name, i); - let ident = Ident::from_str_and_span(&name, shadow_arg.pat.span); - *shadow_arg.pat = ecx.pat_ident(shadow_arg.pat.span, ident); + *shadow_arg.pat = ecx.pat_ident(shadow_arg.pat.span, Symbol::intern(&name)); d_inputs.push(shadow_arg); } } @@ -733,9 +719,8 @@ mod llvm_enzyme { panic!("not an ident?"); }; let name = format!("b{}_{}", old_name, i); - let ident = Ident::from_str_and_span(&name, shadow_arg.pat.span); - *shadow_arg.pat = ecx.pat_ident(shadow_arg.pat.span, ident); + *shadow_arg.pat = ecx.pat_ident(shadow_arg.pat.span, Symbol::intern(&name)); d_inputs.push(shadow_arg); } } @@ -764,9 +749,7 @@ mod llvm_enzyme { panic!("Did not expect Default ret ty: {:?}", span); } }; - let name = "dret".to_string(); - let ident = Ident::from_str_and_span(&name, ty.span); - let shadow_arg = ecx.param(ty.span, ident, ty); + let shadow_arg = ecx.param(ty.span, sym::dret, ty); d_inputs.push(shadow_arg); } _ => {} @@ -841,8 +824,7 @@ mod llvm_enzyme { if act_ret.len() == 1 { act_ret[0].clone() } else { - let kind = TyKind::Tup(act_ret); - Box::new(rustc_ast::Ty { kind, id: ast::DUMMY_NODE_ID, span }) + ecx.ty(span, TyKind::Tup(act_ret)) } } }; diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 5c2c3052d1d51..f1d9487ea741f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -1,11 +1,11 @@ use rustc_ast::{self as ast, Generics, ItemKind, Safety, VariantData}; use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::ExtCtxt; -use rustc_span::{DUMMY_SP, Ident, Span, kw, sym}; +use rustc_span::{DUMMY_SP, Span, sym}; use thin_vec::{ThinVec, thin_vec}; use crate::deriving::generic::*; -use crate::deriving::path_std; +use crate::util::path_std; pub(crate) fn expand_deriving_clone( cx: &ExtCtxt<'_>, @@ -28,7 +28,7 @@ pub(crate) fn expand_deriving_clone( // enough. Whether Clone is implemented for fields is irrelevant so we // don't assert it.) let bounds; - let substructure; + let substructure: CombineSubstructureFunc; let is_simple; match &item.kind { ItemKind::Struct(_, Generics { params, .. }, _) @@ -42,16 +42,16 @@ pub(crate) fn expand_deriving_clone( .any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. })) { is_simple = true; - substructure = combine_substructure(|c, s, sub| cs_clone_simple(c, s, sub, false)); + substructure = |c, s, sub| cs_clone_simple(c, s, sub, false); } else { is_simple = false; - substructure = combine_substructure(cs_clone); + substructure = cs_clone; } } ItemKind::Union(..) => { bounds = smallvec![path_std!(cx, span, marker::Copy)]; is_simple = true; - substructure = combine_substructure(|c, s, sub| cs_clone_simple(c, s, sub, true)); + substructure = |c, s, sub| cs_clone_simple(c, s, sub, true); } _ => cx.dcx().span_bug(span, "`derive(Clone)` on wrong item kind"), } @@ -62,7 +62,6 @@ pub(crate) fn expand_deriving_clone( let trivial_def = TraitDef { span, path: path_std!(cx, span, clone::TrivialClone), - skip_path_as_bound: false, needs_copy_as_bound_if_packed: true, additional_bounds: bounds.clone(), supports_unions: true, @@ -72,6 +71,7 @@ pub(crate) fn expand_deriving_clone( // `TrivialClone` is not part of an API guarantee, so it shouldn't // appear in rustdoc output. document: false, + .. }; trivial_def.expand(cx, item, push); @@ -80,7 +80,6 @@ pub(crate) fn expand_deriving_clone( let trait_def = TraitDef { span, path: path_std!(cx, span, clone::Clone), - skip_path_as_bound: false, needs_copy_as_bound_if_packed: true, additional_bounds: bounds, supports_unions: true, @@ -96,8 +95,7 @@ pub(crate) fn expand_deriving_clone( combine_substructure: substructure, }], is_const, - safety: Safety::Default, - document: true, + .. }; trait_def.expand_ext(cx, item, push, is_simple) @@ -138,7 +136,7 @@ fn cs_clone_simple( if is_union { // Just a single assertion for unions, that the union impls `Copy`. // let _: AssertParamIsCopy; - let self_ty = cx.ty_path(cx.path_ident(trait_span, Ident::with_dummy_span(kw::SelfUpper))); + let self_ty = cx.ty_self(DUMMY_SP); super::assert_ty_bounds( cx, &mut stmts, @@ -163,10 +161,9 @@ fn cs_clone_simple( } fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> BlockOrExpr { - let fn_path = cx.std_path(&[sym::clone, sym::Clone, sym::clone]); let subcall = |field: FieldInfo| { let args = thin_vec![field.self_expr]; - cx.expr_call_global(field.span, fn_path.clone(), args) + cx.expr_call_global(field.span, path_std!(cx, field.span, clone::Clone::clone), args) }; let ctor_path; @@ -174,12 +171,12 @@ fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> Blo let vdata; match substr.fields { Struct(vdata_, af) => { - ctor_path = cx.path(trait_span, vec![substr.type_ident]); + ctor_path = cx.path(trait_span, &[substr.type_ident]); all_fields = af; vdata = vdata_; } EnumMatching(.., variant, af) => { - ctor_path = cx.path(trait_span, vec![substr.type_ident, variant.ident]); + ctor_path = cx.path(trait_span, &[substr.type_ident, variant.ident]); all_fields = af; vdata = &variant.data; } diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 7d0db12a450d6..0c5e169008748 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -13,8 +13,8 @@ use rustc_span::{Ident, Span, Symbol, sym}; use thin_vec::{ThinVec, thin_vec}; use crate::deriving::generic::*; -use crate::deriving::{new_path, path_std}; use crate::diagnostics; +use crate::util::path_std; pub(crate) fn expand_deriving_coerce_pointee( cx: &ExtCtxt<'_>, @@ -81,7 +81,7 @@ pub(crate) fn expand_deriving_coerce_pointee( }; // Create the type of `self`. - let path = cx.path_all(span, false, vec![name_ident], self_params.clone()); + let path = cx.path_all(span, &[name_ident], self_params.clone()); let self_type = cx.ty_path(path); // Declare helper function that adds implementation blocks. @@ -102,7 +102,7 @@ pub(crate) fn expand_deriving_coerce_pointee( )); } let mut add_impl_block = |generics, trait_symbol, trait_args| { - let trait_path = new_path(cx, span, &[sym::ops, trait_symbol], trait_args); + let trait_path = cx.std_path_all(span, &[sym::ops, trait_symbol], trait_args); let trait_ref = cx.trait_ref(trait_path); let item = cx.item_trait_impl( span, @@ -119,10 +119,10 @@ pub(crate) fn expand_deriving_coerce_pointee( // Create unsized `self`, that is, one where the `#[pointee]` type arg is replaced with `__S`. For // example, instead of `MyType<'a, T>`, it will be `MyType<'a, __S>`. - let s_ty = cx.ty_ident(span, Ident::new(sym::__S, span)); + let s_ty = cx.ty_sym(span, sym::__S); let mut alt_self_params = self_params; alt_self_params[pointee_param_idx] = GenericArg::Type(s_ty.clone()); - let alt_self_type = cx.ty_path(cx.path_all(span, false, vec![name_ident], alt_self_params)); + let alt_self_type = cx.ty_path(cx.path_all(span, &[name_ident], alt_self_params)); // # Add `Unsize<__S>` bound to `#[pointee]` at the generic parameter location // @@ -146,7 +146,7 @@ pub(crate) fn expand_deriving_coerce_pointee( return; } let arg = GenericArg::Type(s_ty.clone()); - let unsize = cx.path_all(span, true, cx.std_path(&[sym::marker, sym::Unsize]), vec![arg]); + let unsize = cx.std_path_all(span, &[sym::marker, sym::Unsize], vec![arg]); pointee.bounds.push(cx.trait_bound(unsize, false)); // Drop `#[pointee]` attribute since it should not be recognized outside `derive(CoercePointee)` pointee.attrs.retain(|attr| !attr.has_name(sym::pointee)); @@ -267,7 +267,7 @@ pub(crate) fn expand_deriving_coerce_pointee( impl_generics.params.insert(pointee_param_idx + 1, extra_param); // Add the impl blocks for `DispatchFromDyn` and `CoerceUnsized`. - let gen_args = vec![alt_self_type]; + let gen_args = vec![ast::GenericArg::Type(alt_self_type)]; add_impl_block(impl_generics.clone(), sym::DispatchFromDyn, gen_args.clone()); add_impl_block(impl_generics, sym::CoerceUnsized, gen_args); } diff --git a/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs b/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs index c693cbb66fee9..d11d7f32513db 100644 --- a/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs @@ -1,9 +1,8 @@ -use rustc_ast::Safety; use rustc_expand::base::ExtCtxt; use rustc_span::Span; use crate::deriving::generic::*; -use crate::deriving::path_std; +use crate::util::path_std; pub(crate) fn expand_deriving_const_param_ty( cx: &ExtCtxt<'_>, @@ -15,14 +14,12 @@ pub(crate) fn expand_deriving_const_param_ty( let trait_def = TraitDef { span, path: path_std!(cx, span, marker::ConstParamTy_), - skip_path_as_bound: false, needs_copy_as_bound_if_packed: false, additional_bounds: smallvec![path_std!(cx, span, cmp::Eq)], supports_unions: false, methods: SmallVec::new(), is_const, - safety: Safety::Default, - document: true, + .. }; trait_def.expand(cx, item, push); diff --git a/compiler/rustc_builtin_macros/src/deriving/copy.rs b/compiler/rustc_builtin_macros/src/deriving/copy.rs index 4ce8598e96711..c01723b236e17 100644 --- a/compiler/rustc_builtin_macros/src/deriving/copy.rs +++ b/compiler/rustc_builtin_macros/src/deriving/copy.rs @@ -1,9 +1,8 @@ -use rustc_ast::Safety; use rustc_expand::base::ExtCtxt; use rustc_span::Span; use crate::deriving::generic::*; -use crate::deriving::path_std; +use crate::util::path_std; pub(crate) fn expand_deriving_copy( cx: &ExtCtxt<'_>, @@ -15,14 +14,12 @@ pub(crate) fn expand_deriving_copy( let trait_def = TraitDef { span, path: path_std!(cx, span, marker::Copy), - skip_path_as_bound: false, needs_copy_as_bound_if_packed: false, additional_bounds: SmallVec::new(), supports_unions: true, methods: SmallVec::new(), is_const, - safety: Safety::Default, - document: true, + .. }; trait_def.expand(cx, item, push); diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index d8355d733a7f3..f014ee92aa4f2 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -1,11 +1,11 @@ -use rustc_ast::{self as ast, EnumDef, Safety}; +use rustc_ast::{self as ast, EnumDef}; use rustc_expand::base::ExtCtxt; use rustc_session::config::FmtDebug; use rustc_span::{Ident, Span, Symbol, sym}; use thin_vec::{ThinVec, thin_vec}; use crate::deriving::generic::*; -use crate::deriving::path_std; +use crate::util::path_std; pub(crate) fn expand_deriving_debug( cx: &ExtCtxt<'_>, @@ -22,10 +22,16 @@ pub(crate) fn expand_deriving_debug( ast::Mutability::Mut, ); + let all_fieldless = match &item.kind { + ast::ItemKind::Enum(_, _, def) => { + def.variants.len() > 1 && def.variants.iter().all(|v| v.data.fields().is_empty()) + } + _ => false, + }; + let trait_def = TraitDef { span, path: path_std!(cx, span, fmt::Debug), - skip_path_as_bound: false, needs_copy_as_bound_if_packed: true, additional_bounds: SmallVec::new(), supports_unions: false, @@ -33,54 +39,39 @@ pub(crate) fn expand_deriving_debug( name: sym::fmt, generics: cx.empty_generics(span), explicit_self: true, - nonself_args: smallvec![(fmtr, sym::character('f'))], + nonself_args: smallvec![(fmtr, sym::f)], has_other_selflike_arg: false, ret_ty: cx.ty_path(path_std!(cx, span, fmt::Result)), attributes: thin_vec![cx.attr_word(sym::inline, span)], - fieldless_variants_strategy: - FieldlessVariantsStrategy::SpecializeIfAllVariantsFieldless, - combine_substructure: combine_substructure(|cx, span, substr| show_substructure( - cx, - span, - substr, - item.kind.ident().unwrap() - )), + fieldless_variants_strategy: FieldlessVariantsStrategy::Default, + combine_substructure: show_substructure, }], is_const, - safety: Safety::Default, - document: true, + .. }; - trait_def.expand(cx, item, push) -} - -fn formatter_ident(cx: &ExtCtxt<'_>, span: Span) -> Box { - cx.expr_ident_sym(span, sym::character('f')) + trait_def.expand_ext(cx, item, push, all_fieldless); } -fn show_substructure( - cx: &ExtCtxt<'_>, - span: Span, - substr: Substructure<'_>, - type_ident: Ident, -) -> BlockOrExpr { +fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> BlockOrExpr { let fmt_detail = cx.sess.opts.unstable_opts.fmt_debug; if fmt_detail == FmtDebug::None { return BlockOrExpr::new_expr(cx.expr_ok(span, cx.expr_tuple(span, ThinVec::new()))); } + let type_ident = substr.type_ident; let (ident, vdata, fields) = match substr.fields { Struct(vdata, fields) => (type_ident, vdata, fields), EnumMatching(v, fields) => (v.ident, &v.data, fields), - AllFieldlessEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, type_ident), + StaticEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, type_ident), _ => cx.dcx().span_bug(span, "unexpected substructure in `derive(Debug)`"), }; let name = cx.expr_str(span, ident.name); - let fmt = formatter_ident(cx, span); + let fmt = cx.expr_ident_sym(span, sym::f); // Fieldless enums have been special-cased earlier if fmt_detail == FmtDebug::Shallow { - let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]); + let fn_path_write_str = path_std!(cx, span, fmt::Formatter::write_str); let expr = cx.expr_call_global(span, fn_path_write_str, thin_vec![fmt, name]); return BlockOrExpr::new_expr(expr); } @@ -113,7 +104,7 @@ fn show_substructure( if fields.is_empty() { // Special case for no fields. - let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]); + let fn_path_write_str = path_std!(cx, span, fmt::Formatter::write_str); let expr = cx.expr_call_global(span, fn_path_write_str, thin_vec![fmt, name]); BlockOrExpr::new_expr(expr) } else if fields.len() <= CUTOFF { @@ -123,7 +114,7 @@ fn show_substructure( } else { format!("debug_tuple_field{}_finish", fields.len()) }; - let fn_path_debug = cx.std_path(&[sym::fmt, sym::Formatter, Symbol::intern(&debug)]); + let fn_path_debug = cx.std_path(span, &[sym::fmt, sym::Formatter, Symbol::intern(&debug)]); let mut args = ThinVec::with_capacity(2 + fields.len() * args_per_field); args.extend([fmt, name]); @@ -159,14 +150,14 @@ fn show_substructure( cx.stmt_let_ty( span, false, - Ident::new(sym::names, span), + sym::names, Some(ty_static_ref), cx.expr_array_ref(span, name_exprs), ) }); // `let values: &[&dyn Debug] = &[&&self.field1, &&self.field2];` - let path_debug = cx.path_global(span, cx.std_path(&[sym::fmt, sym::Debug])); + let path_debug = path_std!(cx, span, fmt::Debug); let ty_dyn_debug = cx.ty( span, ast::TyKind::TraitObject( @@ -181,7 +172,7 @@ fn show_substructure( let values_let = cx.stmt_let_ty( span, false, - Ident::new(sym::values, span), + sym::values, Some(cx.ty_ref(span, ty_slice, None, ast::Mutability::Not)), cx.expr_array_ref(span, value_exprs), ); @@ -193,7 +184,7 @@ fn show_substructure( } else { sym::debug_tuple_fields_finish }; - let fn_path_debug_internal = cx.std_path(&[sym::fmt, sym::Formatter, sym_debug]); + let fn_path_debug_internal = cx.std_path(span, &[sym::fmt, sym::Formatter, sym_debug]); let mut args = ThinVec::with_capacity(4); args.push(fmt); @@ -232,12 +223,12 @@ fn show_fieldless_enum( def: &EnumDef, type_ident: Ident, ) -> BlockOrExpr { - let fmt = formatter_ident(cx, span); + let fmt = cx.expr_ident_sym(span, sym::f); let arms = def .variants .iter() .map(|v| { - let variant_path = cx.path(span, vec![type_ident, v.ident]); + let variant_path = cx.path(span, &[type_ident, v.ident]); let pat = match &v.data { ast::VariantData::Tuple(fields, _) => { debug_assert!(fields.is_empty()); @@ -253,6 +244,6 @@ fn show_fieldless_enum( }) .collect::>(); let name = cx.expr_match(span, cx.expr_self(span), arms); - let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]); + let fn_path_write_str = path_std!(cx, span, fmt::Formatter::write_str); BlockOrExpr::new_expr(cx.expr_call_global(span, fn_path_write_str, thin_vec![fmt, name])) } diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 268153c1cbb31..1142f26b0fe64 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -1,14 +1,13 @@ use core::ops::ControlFlow; use rustc_ast::visit::{Visitor, visit_opt}; -use rustc_ast::{self as ast, EnumDef, Safety, VariantData, attr}; +use rustc_ast::{self as ast, EnumDef, VariantData, attr}; use rustc_expand::base::{DummyResult, ExtCtxt}; use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym}; use smallvec::SmallVec; use thin_vec::{ThinVec, thin_vec}; use crate::deriving::generic::*; -use crate::deriving::new_path; use crate::diagnostics; pub(crate) fn expand_deriving_default( @@ -22,7 +21,7 @@ pub(crate) fn expand_deriving_default( let trait_def = TraitDef { span, - path: new_path(cx, span, &[kw::Default, sym::Default], vec![]), + path: cx.std_path(span, &[kw::Default, sym::Default]), skip_path_as_bound: has_a_default_variant(item), needs_copy_as_bound_if_packed: false, additional_bounds: SmallVec::new(), @@ -36,30 +35,29 @@ pub(crate) fn expand_deriving_default( ret_ty: cx.ty_self(span), attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: FieldlessVariantsStrategy::Default, - combine_substructure: combine_substructure(|cx, trait_span, substr| { + combine_substructure: |cx, trait_span, substr| { match substr.fields { StaticStruct(variant_data) => { default_struct_substructure(cx, trait_span, variant_data, substr.type_ident) } StaticEnum(enum_def) => { - default_enum_substructure(cx, trait_span, enum_def, item.span) + default_enum_substructure(cx, trait_span, enum_def, substr.item.span) } _ => cx .dcx() .span_bug(trait_span, "unexpected substructure in `derive(Default)`"), } - }), + }, }], is_const, - safety: Safety::Default, - document: true, + .. }; trait_def.expand(cx, item, push) } fn default_call(cx: &ExtCtxt<'_>, span: Span) -> Box { // Note that `kw::Default` is "default" and `sym::Default` is "Default"! - let default_ident = cx.std_path(&[kw::Default, sym::Default, kw::Default]); + let default_ident = cx.std_path(span, &[kw::Default, sym::Default, kw::Default]); cx.expr_call_global(span, default_ident, ThinVec::new()) } @@ -118,7 +116,7 @@ fn default_enum_substructure( match &default_variant.data { VariantData::Unit(_) => cx.expr_path(cx.path( default_variant.span, - vec![Ident::new(kw::SelfUpper, default_variant.span), default_variant.ident], + &[Ident::new(kw::SelfUpper, default_variant.span), default_variant.ident], )), VariantData::Struct { fields, .. } => { // This only happens if `#![feature(default_field_values)]`. We have validated @@ -143,10 +141,7 @@ fn default_enum_substructure( .collect(); let path = cx.path( default_variant.span, - vec![ - Ident::new(kw::SelfUpper, default_variant.span), - default_variant.ident, - ], + &[Ident::new(kw::SelfUpper, default_variant.span), default_variant.ident], ); cx.expr_struct(default_variant.span, path, default_fields) } diff --git a/compiler/rustc_builtin_macros/src/deriving/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs index 27be8a8cb6dff..0268c74e47f05 100644 --- a/compiler/rustc_builtin_macros/src/deriving/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/eq.rs @@ -1,11 +1,11 @@ -use rustc_ast::{self as ast, Safety}; +use rustc_ast::{self as ast}; use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::ExtCtxt; use rustc_span::{Span, sym}; use thin_vec::{ThinVec, thin_vec}; use crate::deriving::generic::*; -use crate::deriving::path_std; +use crate::util::{path, path_std}; pub(crate) fn expand_deriving_eq( cx: &ExtCtxt<'_>, @@ -19,7 +19,6 @@ pub(crate) fn expand_deriving_eq( let trait_def = TraitDef { span, path: path_std!(cx, span, cmp::Eq), - skip_path_as_bound: false, needs_copy_as_bound_if_packed: true, additional_bounds: SmallVec::new(), supports_unions: true, @@ -38,11 +37,10 @@ pub(crate) fn expand_deriving_eq( cx.attr_nested_word(sym::coverage, sym::off, span), ], fieldless_variants_strategy: FieldlessVariantsStrategy::Unify, - combine_substructure: combine_substructure(cs_total_eq_assert), + combine_substructure: cs_total_eq_assert, }], is_const, - safety: Safety::Default, - document: true, + .. }; trait_def.expand_ext(cx, item, push, true) } @@ -66,7 +64,7 @@ fn cs_total_eq_assert(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<' &mut stmts, field.ty.clone(), field.span, - &[sym::cmp, sym::AssertParamIsEq], + path!(cmp::AssertParamIsEq), ); } } diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index edd1cf75488fc..4971cd3407fec 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -1,13 +1,13 @@ use rustc_ast as ast; -use rustc_ast::{ItemKind, Safety, VariantData}; +use rustc_ast::{ItemKind, VariantData}; use rustc_errors::MultiSpan; -use rustc_expand::base::{DummyResult, ExtCtxt}; +use rustc_expand::base::ExtCtxt; use rustc_span::{Ident, Span, kw, sym}; use thin_vec::thin_vec; use crate::deriving::generic::*; -use crate::deriving::{new_path, pathvec}; use crate::diagnostics; +use crate::util::path; /// Generate an implementation of the `From` trait, provided that `item` /// is a struct or a tuple struct with exactly one field. @@ -22,36 +22,31 @@ pub(crate) fn expand_deriving_from( let item_span = item.kind.ident().map(|ident| ident.span).unwrap_or(item.span); MultiSpan::from_spans(vec![span, item_span]) }; - // `#[derive(From)]` is currently usable only on structs with exactly one field. - let field = match &item.kind { + let from_type = match &item.kind { ItemKind::Struct(_, _, data) => { if let [field] = data.fields() { - Ok(field.clone()) + field.ty.clone() } else { - let guar = cx.dcx().emit_err(diagnostics::DeriveFromWrongFieldCount { + cx.dcx().emit_err(diagnostics::DeriveFromWrongFieldCount { span: err_span(), multiple_fields: data.fields().len() > 1, }); - Err(guar) + return; } } ItemKind::Enum(_, _, _) | ItemKind::Union(_, _, _) => { - let guar = cx.dcx().emit_err(diagnostics::DeriveFromWrongTarget { + cx.dcx().emit_err(diagnostics::DeriveFromWrongTarget { span: err_span(), kind: &format!("{} {}", item.kind.article(), item.kind.descr()), }); - Err(guar) + return; } _ => cx.dcx().bug("Invalid derive(From) ADT input"), }; - let from_type = match field { - Ok(ref field) => field.ty.clone(), - Err(guar) => cx.ty(span, ast::TyKind::Err(guar)), - }; - - let path = new_path(cx, span, pathvec!(convert::From), vec![from_type.clone()]); + let path = + cx.std_path_all(span, path!(convert::From), vec![ast::GenericArg::Type(from_type.clone())]); // Generate code like this: // @@ -79,46 +74,46 @@ pub(crate) fn expand_deriving_from( ret_ty: cx.ty_self(span), attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: FieldlessVariantsStrategy::Default, - combine_substructure: combine_substructure(|cx, span, substructure| { - let field = match field { - Ok(ref field) => field, - Err(guar) => { - return BlockOrExpr::new_expr(DummyResult::raw_expr(span, Some(guar))); - } - }; - - let self_kw = Ident::new(kw::SelfUpper, span); - let expr: Box = match substructure.fields { - StaticStruct(variant) => match variant { - // Self { field: value } - VariantData::Struct { .. } => cx.expr_struct_ident( - span, - self_kw, - thin_vec![cx.field_imm( - span, - field.ident.unwrap(), - cx.expr_ident_sym(span, sym::value) - )], - ), - // Self(value) - VariantData::Tuple(_, _) => cx.expr_call_ident( - span, - self_kw, - thin_vec![cx.expr_ident_sym(span, sym::value)], - ), - variant => { - cx.dcx().bug(format!("Invalid derive(From) ADT variant: {variant:?}")); - } - }, - _ => cx.dcx().bug("Invalid derive(From) ADT input"), - }; - BlockOrExpr::new_expr(expr) - }), + combine_substructure: from_body, }], is_const, - safety: Safety::Default, - document: true, + .. }; from_trait_def.expand(cx, item, push); } + +fn from_body(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> BlockOrExpr { + let field = if let ItemKind::Struct(_, _, data) = &substr.item.kind + && let [field] = data.fields() + { + field + } else { + unreachable!(); + }; + + let self_kw = Ident::new(kw::SelfUpper, span); + let expr = match substr.fields { + StaticStruct(variant) => match variant { + // Self { field: value } + VariantData::Struct { .. } => cx.expr_struct_ident( + span, + self_kw, + thin_vec![cx.field_imm( + span, + field.ident.unwrap(), + cx.expr_ident_sym(span, sym::value) + )], + ), + // Self(value) + VariantData::Tuple(_, _) => { + cx.expr_call_ident(span, self_kw, thin_vec![cx.expr_ident_sym(span, sym::value)]) + } + variant => { + cx.dcx().bug(format!("Invalid derive(From) ADT variant: {variant:?}")); + } + }, + _ => cx.dcx().bug("Invalid derive(From) ADT input"), + }; + BlockOrExpr::new_expr(expr) +} diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index fbbadce3a8816..f2a216fa6ba3d 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -175,26 +175,26 @@ //! ``` use std::ops::Not; -use std::vec; pub(crate) use SubstructureFields::*; pub(crate) use rustc_ast as ast; use rustc_ast::token::{IdentKind, LitKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenTree}; use rustc_ast::{ - AttrArgs, DelimArgs, EnumDef, Expr, GenericArg, GenericParam, GenericParamKind, Generics, - Safety, SelfKind, VariantData, + AttrArgs, DelimArgs, EnumDef, Expr, GenericArg, GenericParam, GenericParamKind, Generics, Item, + Safety, VariantData, }; use rustc_attr_ir::{Attribute, AttributeKind, ReprPacked}; use rustc_attr_parsing::AttributeParser; use rustc_expand::base::ExtCtxt; -use rustc_span::{Ident, Span, Symbol, kw, respan, sym}; +use rustc_span::{Ident, Span, Symbol, kw, sym}; pub(crate) use smallvec::{SmallVec, smallvec}; use thin_vec::{ThinVec, thin_vec}; +use crate::util::path_std; use crate::{deriving, diagnostics}; -pub(crate) struct TraitDef<'a> { +pub(crate) struct TraitDef<> { /// The span for the current #[derive(Foo)] header. pub span: Span, @@ -202,7 +202,7 @@ pub(crate) struct TraitDef<'a> { pub path: ast::Path, /// Whether to skip adding the current trait as a bound to the type parameters of the type. - pub skip_path_as_bound: bool, + pub skip_path_as_bound: bool = false, /// Whether `Copy` is needed as an additional bound on type parameters in a packed struct. pub needs_copy_as_bound_if_packed: bool, @@ -214,18 +214,18 @@ pub(crate) struct TraitDef<'a> { /// Can this trait be derived for unions? pub supports_unions: bool, - pub methods: SmallVec<[MethodDef<'a>; 1]>, + pub methods: SmallVec<[MethodDef<>; 1]>, pub is_const: bool, /// The safety of the `impl`. - pub safety: Safety, + pub safety: Safety = Safety::Default, /// Whether the added `impl` should appear in rustdoc output. - pub document: bool, + pub document: bool = true, } -pub(crate) struct MethodDef<'a> { +pub(crate) struct MethodDef { /// name of the method pub name: Symbol, /// List of generics, e.g., `R: rand::Rng` @@ -247,7 +247,7 @@ pub(crate) struct MethodDef<'a> { pub fieldless_variants_strategy: FieldlessVariantsStrategy, - pub combine_substructure: CombineSubstructureFunc<'a>, + pub combine_substructure: CombineSubstructureFunc, } /// How to handle fieldless enum variants. @@ -260,10 +260,6 @@ pub(crate) enum FieldlessVariantsStrategy { /// Don't do anything special about fieldless variants. They are /// handled like any other variant. Default, - /// If all variants of the enum are fieldless, expand the special - /// `AllFieldLessEnum` substructure, so that the entire enum can be handled - /// at once. - SpecializeIfAllVariantsFieldless, } /// Summary of the relevant parts of a struct/enum field. @@ -287,6 +283,7 @@ pub(crate) struct Substructure<'a> { // such as https://github.com/rust-lang/rust/issues/163800. // Ideally we would just use `Self` instead. pub type_ident: Ident, + pub item: &'a Item, } /// A summary of the possible sets of fields. @@ -294,11 +291,6 @@ pub(crate) enum SubstructureFields<'a> { /// A non-static method where `Self` is a struct. Struct(&'a ast::VariantData, Vec), - /// A non-static method handling the entire enum at once - /// (after it has been determined that none of the enum - /// variants has any fields). - AllFieldlessEnum(&'a ast::EnumDef), - /// Matching variants of the enum: ast::Variant, /// fields: the field name is only non-`None` in the case of a struct /// variant. @@ -317,14 +309,7 @@ pub(crate) enum SubstructureFields<'a> { /// Combine the values of all the fields together. The last argument is /// all the fields of all the structures. -pub(crate) type CombineSubstructureFunc<'a> = - Box, Span, Substructure<'_>) -> BlockOrExpr + 'a>; - -pub(crate) fn combine_substructure<'a>( - f: impl Fn(&ExtCtxt<'_>, Span, Substructure<'_>) -> BlockOrExpr + 'a, -) -> CombineSubstructureFunc<'a> { - Box::new(f) -} +pub(crate) type CombineSubstructureFunc = fn(&ExtCtxt<'_>, Span, Substructure<'_>) -> BlockOrExpr; struct TypeParameter { bound_generic_params: ThinVec, @@ -449,21 +434,16 @@ fn find_type_parameters( visitor.type_params } -impl<'a> TraitDef<'a> { - pub(crate) fn expand( - self, - cx: &ExtCtxt<'_>, - item: &'a ast::Item, - push: &mut dyn FnMut(Box), - ) { +impl<'a> TraitDef { + pub(crate) fn expand(self, cx: &ExtCtxt<'_>, item: &'a Item, push: &mut dyn FnMut(Box)) { self.expand_ext(cx, item, push, false); } pub(crate) fn expand_ext( self, cx: &ExtCtxt<'_>, - item: &'a ast::Item, - push: &mut dyn FnMut(Box), + item: &'a Item, + push: &mut dyn FnMut(Box), from_scratch: bool, ) { let span = self.span; @@ -486,11 +466,10 @@ impl<'a> TraitDef<'a> { cx, span, StaticStruct(struct_def), - *ident, + item, ) } else { - method_def - .expand_struct_method_body(cx, span, struct_def, is_packed, *ident) + method_def.expand_struct_method_body(cx, span, struct_def, is_packed, item) }; method_def.create_method(cx, span, body) @@ -508,9 +487,9 @@ impl<'a> TraitDef<'a> { let fields = enum_def.variants.iter().flat_map(|variant| variant.data.fields()); let methods = self.methods.iter().filter_map(|method_def| { let body = if from_scratch || method_def.is_static() { - method_def.call_substructure_method(cx, span, StaticEnum(enum_def), *ident) + method_def.call_substructure_method(cx, span, StaticEnum(enum_def), item) } else { - method_def.expand_enum_method_body(cx, span, enum_def, *ident) + method_def.expand_enum_method_body(cx, span, enum_def, item) }; method_def.create_method(cx, span, body) @@ -582,7 +561,7 @@ impl<'a> TraitDef<'a> { fields: impl Iterator, methods: impl Iterator>, is_packed: bool, - ) -> Box { + ) -> Box { let mut where_clause = ast::WhereClause::default(); where_clause.span = generics.where_clause.span; let ctxt = self.span.ctxt(); @@ -612,7 +591,7 @@ impl<'a> TraitDef<'a> { .chain({ // Add a `Copy` bound if required. if is_packed && self.needs_copy_as_bound_if_packed { - let p = deriving::path_std!(cx, span, marker::Copy); + let p = path_std!(cx, span, marker::Copy); Some(cx.trait_bound(p, self.is_const)) } else { None @@ -689,7 +668,7 @@ impl<'a> TraitDef<'a> { // Add a `Copy` bound if required. if is_packed && self.needs_copy_as_bound_if_packed { - let p = deriving::path_std!(cx, self.span, marker::Copy); + let p = path_std!(cx, self.span, marker::Copy); bounds.push(cx.trait_bound(p, self.is_const)); } @@ -726,8 +705,7 @@ impl<'a> TraitDef<'a> { .collect(); // Create the type of `self`. - let path = - cx.path_all(type_ident.span.with_ctxt(ctxt), false, vec![type_ident], self_params); + let path = cx.path_all(type_ident.span.with_ctxt(ctxt), &[type_ident], self_params); let self_type = cx.ty_path(path); let mut attrs = thin_vec![cx.attr_word(sym::automatically_derived, self.span),]; @@ -736,8 +714,7 @@ impl<'a> TraitDef<'a> { // Other crates don't need stability attributes, so adding them is not useful, but libcore needs them // on all const trait impls. if self.is_const && cx.ecfg.features.staged_api() { - let rustc_const_unstable = - cx.path_ident(self.span, Ident::new(sym::rustc_const_unstable, self.span)); + let rustc_const_unstable = cx.path_sym(self.span, sym::rustc_const_unstable); // #[rustc_const_unstable(feature = "derive_const", issue = "118304")] attrs.push( @@ -787,34 +764,25 @@ impl<'a> TraitDef<'a> { } } -impl<'a> MethodDef<'a> { +impl MethodDef { fn call_substructure_method( &self, cx: &ExtCtxt<'_>, span: Span, fields: SubstructureFields<'_>, - type_ident: Ident, + item: &Item, ) -> BlockOrExpr { - (self.combine_substructure)(cx, span, Substructure { fields, type_ident }) + (self.combine_substructure)( + cx, + span, + Substructure { fields, type_ident: item.kind.ident().unwrap(), item }, + ) } fn is_static(&self) -> bool { !self.explicit_self } - /// Expressions for `&self` and also any other - /// args with the same type (e.g. the `other` arg in `PartialEq::eq`). - fn get_selflike_args(&self, cx: &ExtCtxt<'_>, span: Span) -> ThinVec> { - assert!(self.explicit_self); - - let self_expr = cx.expr_self(span); - if self.has_other_selflike_arg { - thin_vec![self_expr, cx.expr_ident_sym(span, self.nonself_args[0].1)] - } else { - thin_vec![self_expr] - } - } - fn create_method( &self, cx: &ExtCtxt<'_>, @@ -825,24 +793,16 @@ impl<'a> MethodDef<'a> { if body.0.is_empty() && body.1.is_none() && self.name == sym::assert_fields_are_eq { return None; } - // Create the generics that aren't for `Self`. - let fn_generics = self.generics.clone(); let self_arg = self.explicit_self.then(|| { - let ident = Ident::new(kw::SelfLower, span); - ast::Param::from_self( - ast::AttrVec::default(), - respan(span, SelfKind::Region(None, ast::Mutability::Not)), - ident, - ) + let infer_ty = cx.ty(span, ast::TyKind::ImplicitSelf); + let ty = cx.ty_ref(span, infer_ty, None, ast::Mutability::Not); + (ty, kw::SelfLower) }); let args = self_arg .into_iter() - .chain(self.nonself_args.iter().map(|(ty, name)| { - let ast_ty = ty.clone(); - let ident = Ident::new(*name, span); - cx.param(span, ident, ast_ty) - })) + .chain(self.nonself_args.iter().cloned()) + .map(|(ty, name)| cx.param(span, name, ty)) .collect(); let ret_type = if self.ret_ty.kind.is_unit() { @@ -858,7 +818,6 @@ impl<'a> MethodDef<'a> { let trait_lo_sp = span.shrink_to_lo(); let sig = ast::FnSig { header: ast::FnHeader::default(), decl: fn_decl, span }; - let defaultness = ast::Defaultness::Implicit; // Create the method. Some(Box::new(ast::AssocItem { @@ -866,16 +825,12 @@ impl<'a> MethodDef<'a> { attrs: self.attributes.clone(), span, vis: ast::Visibility { span: trait_lo_sp, kind: ast::VisibilityKind::Inherited }, - kind: ast::AssocItemKind::Fn(Box::new(ast::Fn { - defaultness, + kind: ast::AssocItemKind::Fn(cx.item_fn( sig, - ident: method_ident, - generics: fn_generics, - contract: None, - body: Some(body_block), - define_opaque: None, - eii_impl: None, - })), + method_ident, + self.generics.clone(), + Some(body_block), + )), tokens: None, })) } @@ -921,13 +876,18 @@ impl<'a> MethodDef<'a> { span: Span, struct_def: &'b VariantData, is_packed: bool, - type_ident: Ident, + item: &Item, ) -> BlockOrExpr { - let selflike_args = self.get_selflike_args(cx, span); + let self_expr = cx.expr_self(span); + let selflike_args = if self.has_other_selflike_arg { + &[self_expr, cx.expr_ident_sym(span, self.nonself_args[0].1)][..] + } else { + &[self_expr] + }; let selflike_fields = - create_struct_field_access_fields(span, cx, &selflike_args, struct_def, is_packed); - self.call_substructure_method(cx, span, Struct(struct_def, selflike_fields), type_ident) + create_struct_field_access_fields(span, cx, selflike_args, struct_def, is_packed); + self.call_substructure_method(cx, span, Struct(struct_def, selflike_fields), item) } /// ``` @@ -970,14 +930,10 @@ impl<'a> MethodDef<'a> { cx: &ExtCtxt<'_>, span: Span, enum_def: &'b EnumDef, - type_ident: Ident, + item: &Item, ) -> BlockOrExpr { let variants = &enum_def.variants; - // Traits that unify fieldless variants always use the discriminant(s). - let unify_fieldless_variants = - self.fieldless_variants_strategy == FieldlessVariantsStrategy::Unify; - // For zero-variant enum, this function body is unreachable. Generate // `match *self {}`. This produces machine code identical to `unsafe { // core::intrinsics::unreachable() }` while being safe and stable. @@ -988,14 +944,6 @@ impl<'a> MethodDef<'a> { return BlockOrExpr(ThinVec::new(), Some(expr)); } - let selflike_args = self.get_selflike_args(cx, span); - - let prefixes: &[&str] = match selflike_args.len() { - 1 => &["__self"], - 2 => &["__self", "__arg1"], - _ => unreachable!(), - }; - // There are some special cases involving fieldless enums where no // match is necessary. let all_fieldless = variants.iter().all(|v| v.data.fields().is_empty()); @@ -1006,20 +954,7 @@ impl<'a> MethodDef<'a> { // If the type is fieldless and the trait uses the discriminant and // there are multiple variants, we need just an operation on // the discriminant(s). - return self.call_substructure_method( - cx, - span, - EnumDiscr(None), - type_ident, - ); - } - FieldlessVariantsStrategy::SpecializeIfAllVariantsFieldless => { - return self.call_substructure_method( - cx, - span, - AllFieldlessEnum(enum_def), - type_ident, - ); + return self.call_substructure_method(cx, span, EnumDiscr(None), item); } FieldlessVariantsStrategy::Default => (), } @@ -1030,11 +965,18 @@ impl<'a> MethodDef<'a> { cx, span, EnumMatching(variant, Vec::new()), - type_ident, + item, ); } } + // Traits that unify fieldless variants always use the discriminant(s). + let unify_fieldless_variants = + self.fieldless_variants_strategy == FieldlessVariantsStrategy::Unify; + + let prefixes: &[&str] = + if self.has_other_selflike_arg { &["__self", "__arg1"] } else { &["__self"] }; + // These arms are of the form: // (Variant1, Variant1, ...) => Body1 // (Variant2, Variant2, ...) => Body2 @@ -1050,8 +992,7 @@ impl<'a> MethodDef<'a> { let fields = create_struct_pattern_fields(span, cx, &variant.data, &prefixes); let sp = variant.span.with_ctxt(span.ctxt()); - let variant_path = - cx.path(sp, vec![Ident::new(kw::SelfUpper, span), variant.ident]); + let variant_path = cx.path(sp, &[Ident::new(kw::SelfUpper, span), variant.ident]); let mut subpats = create_struct_patterns(span, cx, variant_path, &variant.data, &prefixes); @@ -1070,9 +1011,8 @@ impl<'a> MethodDef<'a> { // expressions for referencing every field of every // Self arg, assuming all are instances of VariantK. // Build up code associated with such a case. - let substructure = EnumMatching(variant, fields); let arm_expr = self - .call_substructure_method(cx, span, substructure, type_ident) + .call_substructure_method(cx, span, EnumMatching(variant, fields), item) .into_expr(cx, span); cx.arm(span, single_pat, arm_expr) @@ -1085,16 +1025,11 @@ impl<'a> MethodDef<'a> { Some(v) if unify_fieldless_variants => { // We need a default case that handles all the fieldless variants. Some( - self.call_substructure_method( - cx, - span, - EnumMatching(v, Vec::new()), - type_ident, - ) - .into_expr(cx, span), + self.call_substructure_method(cx, span, EnumMatching(v, Vec::new()), item) + .into_expr(cx, span), ) } - _ if variants.len() > 1 && selflike_args.len() > 1 => { + _ if variants.len() > 1 && self.has_other_selflike_arg => { // Because we know that all the arguments will match if we reach // the match expression we add the unreachable intrinsic as the // result of the default which should help llvm in optimizing it. @@ -1109,33 +1044,31 @@ impl<'a> MethodDef<'a> { // Create a match expression with one arm per discriminant plus // possibly a default arm, e.g.: // match (self, other) { - // (Variant1, Variant1, ...) => Body1 - // (Variant2, Variant2, ...) => Body2, + // (Variant1, Variant1) => Body1 + // (Variant2, Variant2) => Body2, // ... // _ => ::core::intrinsics::unreachable(), // } - let get_match_expr = |mut selflike_args: ThinVec>| { - let match_arg = if selflike_args.len() == 1 { - selflike_args.pop().unwrap() - } else { - cx.expr_tuple(span, selflike_args) - }; - cx.expr_match(span, match_arg, match_arms) + + let self_expr = cx.expr_self(span); + let match_arg = if self.has_other_selflike_arg { + cx.expr_tuple( + span, + thin_vec![self_expr, cx.expr_ident_sym(span, self.nonself_args[0].1)], + ) + } else { + self_expr }; + let match_expr = cx.expr_match(span, match_arg, match_arms); // If the trait uses the discriminant and there are multiple variants, we need // to add a discriminant check operation before the match. Otherwise, the match // is enough. if unify_fieldless_variants && variants.len() > 1 { // Combine a discriminant check with the match. - self.call_substructure_method( - cx, - span, - EnumDiscr(Some(get_match_expr(selflike_args))), - type_ident, - ) + self.call_substructure_method(cx, span, EnumDiscr(Some(match_expr)), item) } else { - BlockOrExpr(ThinVec::new(), Some(get_match_expr(selflike_args))) + BlockOrExpr(ThinVec::new(), Some(match_expr)) } } } @@ -1152,9 +1085,8 @@ fn create_struct_patterns( .iter() .map(|prefix| { let pieces_iter = struct_def.fields().iter().enumerate().map(|(i, struct_field)| { - let ident = mk_pattern_ident(span, prefix, i); - let path = ident.with_span_pos(struct_field.span); - (struct_field.ident, cx.pat_ident(path.span, path)) + let ident = Symbol::intern(&format!("{prefix}_{i}")); + (struct_field.ident, cx.pat_ident(struct_field.span.with_ctxt(span.ctxt()), ident)) }); let struct_path = struct_path.clone(); @@ -1209,10 +1141,6 @@ where .collect() } -fn mk_pattern_ident(span: Span, prefix: &str, i: usize) -> Ident { - Ident::from_str_and_span(&format!("{prefix}_{i}"), span) -} - fn create_struct_pattern_fields( span: Span, cx: &ExtCtxt<'_>, @@ -1222,10 +1150,7 @@ fn create_struct_pattern_fields( create_fields(span, struct_def, |i, _struct_field, sp| { prefixes .iter() - .map(|prefix| { - let ident = mk_pattern_ident(span, prefix, i); - cx.expr_path(cx.path_ident(sp, ident)) - }) + .map(|prefix| cx.expr_ident_sym(sp, Symbol::intern(&format!("{prefix}_{i}")))) .collect() }) } @@ -1249,9 +1174,9 @@ fn create_struct_field_access_fields( sp, ast::ExprKind::Field( selflike_arg.clone(), - struct_field.ident.unwrap_or_else(|| { - Ident::from_str_and_span(&i.to_string(), struct_field.span) - }), + struct_field + .ident + .unwrap_or_else(|| Ident::new(sym::integer(i), struct_field.span)), ), ); if is_packed { diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index db0e8efc99f3c..57b2dda4387b2 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -1,10 +1,11 @@ -use rustc_ast::{Mutability, Safety}; +use rustc_ast::Mutability; use rustc_expand::base::ExtCtxt; use rustc_span::{Ident, Span, kw, sym}; use thin_vec::{ThinVec, thin_vec}; +use crate::deriving::call_discriminant_value; use crate::deriving::generic::*; -use crate::deriving::{call_discriminant_value, path_std}; +use crate::util::path_std; pub(crate) fn expand_deriving_hash( cx: &ExtCtxt<'_>, @@ -15,13 +16,11 @@ pub(crate) fn expand_deriving_hash( ) { let path = path_std!(cx, span, hash::Hash); - let typaram = Ident::new(sym::__H, span); - - let arg = cx.ty_path(cx.path_ident(span, typaram)); + let arg = cx.ty_sym(span, sym::__H); let param = { let path = path_std!(cx, span, hash::Hasher); - cx.typaram(typaram, thin_vec![cx.trait_bound(path, false)], None) + cx.typaram(Ident::new(sym::__H, span), thin_vec![cx.trait_bound(path, false)], None) }; let generics = ast::Generics { @@ -33,7 +32,6 @@ pub(crate) fn expand_deriving_hash( let hash_trait_def = TraitDef { span, path, - skip_path_as_bound: false, needs_copy_as_bound_if_packed: true, additional_bounds: SmallVec::new(), supports_unions: false, @@ -46,11 +44,10 @@ pub(crate) fn expand_deriving_hash( ret_ty: cx.ty_unit(span), attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: FieldlessVariantsStrategy::Unify, - combine_substructure: combine_substructure(hash_substructure), + combine_substructure: hash_substructure, }], is_const, - safety: Safety::Default, - document: true, + .. }; hash_trait_def.expand(cx, item, push); @@ -58,8 +55,8 @@ pub(crate) fn expand_deriving_hash( fn hash_substructure(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> BlockOrExpr { let call_hash = |span, expr| { - let strs = cx.std_path(&[sym::hash, sym::Hash, sym::hash]); - let hash_path = cx.expr_path(cx.path_global(span, strs)); + let strs = path_std!(cx, span, hash::Hash::hash); + let hash_path = cx.expr_path(strs); let expr = cx.expr_call(span, hash_path, thin_vec![expr, cx.expr_ident_sym(span, sym::state)]); cx.stmt_expr(expr) diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index c4af6ac16bdc6..ecea219338d10 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -1,21 +1,11 @@ //! The compiler code necessary to implement the `#[derive]` extensions. -use std::iter::once; - use rustc_ast as ast; use rustc_ast::{GenericArg, MetaItem}; use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier}; -use rustc_span::{Ident, Span, Symbol, kw, sym}; +use rustc_span::{Span, Symbol, sym}; use thin_vec::{ThinVec, thin_vec}; -macro pathvec($($rest:ident)::+) {{ - &[ $( sym::$rest ),+ ] -}} - -macro path_std($cx: expr, $span: expr, $($x:tt)*) { - new_path($cx, $span, pathvec!( $($x)* ), vec![] ) -} - pub(crate) mod clone; pub(crate) mod coerce_pointee; pub(crate) mod const_param_ty; @@ -77,26 +67,14 @@ impl MultiItemModifier for BuiltinDerive { } } -/// Constructs an expression that calls an intrinsic -fn call_intrinsic( - cx: &ExtCtxt<'_>, - span: Span, - intrinsic: Symbol, - args: ThinVec>, -) -> Box { - let span = cx.with_def_site_ctxt(span); - let path = cx.std_path(&[sym::intrinsics, intrinsic]); - cx.expr_call_global(span, path, args) -} - /// Constructs an expression that calls the `discriminant_value` intrinsic. fn call_discriminant_value(cx: &ExtCtxt<'_>, span: Span, arg: Symbol) -> Box { - call_intrinsic(cx, span, sym::discriminant_value, thin_vec![cx.expr_ident_sym(span, arg)]) + cx.expr_call_intrinsic(span, sym::discriminant_value, thin_vec![cx.expr_ident_sym(span, arg)]) } /// Constructs an expression that calls the `unreachable` intrinsic. fn call_unreachable(cx: &ExtCtxt<'_>, span: Span) -> Box { - let call = call_intrinsic(cx, span, sym::unreachable, ThinVec::new()); + let call = cx.expr_call_intrinsic(span, sym::unreachable, ThinVec::new()); cx.expr_block(Box::new(ast::Block { stmts: thin_vec![cx.stmt_expr(call)], id: ast::DUMMY_NODE_ID, @@ -114,14 +92,6 @@ fn assert_ty_bounds( ) { // Generate statement `let _: assert_path;`. let span = cx.with_def_site_ctxt(span); - let assert_path = cx.path_all(span, true, cx.std_path(assert_path), vec![GenericArg::Type(ty)]); + let assert_path = cx.std_path_all(span, assert_path, vec![GenericArg::Type(ty)]); stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path))); } - -fn new_path(cx: &ExtCtxt<'_>, span: Span, path: &[Symbol], params: Vec>) -> ast::Path { - let idents = path.iter().map(|s| Ident::new(*s, span)); - let params = params.into_iter().map(GenericArg::Type).collect(); - - let idents = once(Ident::new(kw::DollarCrate, span)).chain(idents).collect(); - cx.path_all(span, false, idents, params) -} diff --git a/compiler/rustc_builtin_macros/src/deriving/ord.rs b/compiler/rustc_builtin_macros/src/deriving/ord.rs index c20bfc81bd409..2daab160a80a0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/ord.rs @@ -1,11 +1,10 @@ -use rustc_ast::Safety; use rustc_expand::base::ExtCtxt; use rustc_span::{Span, sym}; use thin_vec::thin_vec; use crate::deriving::generic::*; -use crate::deriving::partial_ord::{OrdlikeDerive, cmp_body, discr_data_order}; -use crate::deriving::path_std; +use crate::deriving::partial_ord::{OrdlikeDerive, cmp_body}; +use crate::util::path_std; pub(crate) fn expand_deriving_ord( cx: &ExtCtxt<'_>, @@ -14,12 +13,9 @@ pub(crate) fn expand_deriving_ord( push: &mut dyn FnMut(Box), is_const: bool, ) { - let discr_then_data = discr_data_order(item); - let trait_def = TraitDef { span, path: path_std!(cx, span, cmp::Ord), - skip_path_as_bound: false, needs_copy_as_bound_if_packed: true, additional_bounds: SmallVec::new(), supports_unions: false, @@ -32,27 +28,16 @@ pub(crate) fn expand_deriving_ord( ret_ty: cx.ty_path(path_std!(cx, span, cmp::Ordering)), attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: FieldlessVariantsStrategy::Unify, - combine_substructure: combine_substructure(|cx, span, substr| cs_cmp( - cx, - span, - substr, - discr_then_data - )), + combine_substructure: cs_cmp, }], is_const, - safety: Safety::Default, - document: true, + .. }; trait_def.expand(cx, item, push) } -pub(crate) fn cs_cmp( - cx: &ExtCtxt<'_>, - span: Span, - substr: Substructure<'_>, - discr_then_data: bool, -) -> BlockOrExpr { +pub(crate) fn cs_cmp(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> BlockOrExpr { // Builds: // // match ::core::cmp::Ord::cmp(&self.x, &other.x) { @@ -60,6 +45,6 @@ pub(crate) fn cs_cmp( // ::core::cmp::Ord::cmp(&self.y, &other.y), // cmp => cmp, // } - let expr = cmp_body(cx, span, substr, discr_then_data, OrdlikeDerive::Ord); + let expr = cmp_body(cx, span, substr, OrdlikeDerive::Ord); BlockOrExpr::new_expr(expr) } diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index 180800aa72025..9eb239be12afe 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -1,10 +1,11 @@ -use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, Mutability, Safety}; +use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, Mutability}; use rustc_expand::base::ExtCtxt; -use rustc_span::{Ident, Span, kw, sym}; +use rustc_span::{Span, kw, sym}; use thin_vec::thin_vec; +use crate::deriving::call_discriminant_value; use crate::deriving::generic::*; -use crate::deriving::{call_discriminant_value, path_std}; +use crate::util::path_std; /// Expands a `#[derive(PartialEq)]` attribute into an implementation for the /// target item. @@ -29,8 +30,7 @@ pub(crate) fn expand_deriving_partial_eq( supports_unions: true, methods: SmallVec::new(), is_const: false, - safety: Safety::Default, - document: true, + .. }; structural_trait_def.expand(cx, item, push); @@ -42,23 +42,21 @@ pub(crate) fn expand_deriving_partial_eq( explicit_self: true, nonself_args: smallvec![(cx.ty_self_ref(span), sym::other)], has_other_selflike_arg: true, - ret_ty: cx.ty_path(cx.path_ident(span, Ident::new(sym::bool, span))), + ret_ty: cx.ty_sym(span, sym::bool), attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: FieldlessVariantsStrategy::Unify, - combine_substructure: combine_substructure(get_substructure_equality_expr), + combine_substructure: get_substructure_equality_expr, }]; let trait_def = TraitDef { span, path: path_std!(cx, span, cmp::PartialEq), - skip_path_as_bound: false, needs_copy_as_bound_if_packed: true, additional_bounds: SmallVec::new(), supports_unions: false, methods, is_const, - safety: Safety::Default, - document: true, + .. }; trait_def.expand(cx, item, push) } diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index 4ce695a16200f..a44bc77735570 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -1,10 +1,11 @@ -use rustc_ast::{Expr, ItemKind, Safety, ast}; +use rustc_ast::{Expr, ItemKind, ast}; use rustc_expand::base::ExtCtxt; -use rustc_span::{Ident, Span, kw, sym}; +use rustc_span::{Span, kw, sym}; use thin_vec::thin_vec; +use crate::deriving::call_discriminant_value; use crate::deriving::generic::*; -use crate::deriving::{call_discriminant_value, new_path, path_std, pathvec}; +use crate::util::{path, path_std}; pub(crate) fn expand_deriving_partial_ord( cx: &ExtCtxt<'_>, @@ -14,18 +15,15 @@ pub(crate) fn expand_deriving_partial_ord( is_const: bool, ) { let ordering_ty = cx.ty_path(path_std!(cx, span, cmp::Ordering)); - let ret_ty = cx.ty_path(new_path(cx, span, pathvec!(option::Option), vec![ordering_ty])); - - // Order in which to perform matching - let discr_then_data = discr_data_order(item); + let ret_ty = cx.ty_path(cx.std_path_all( + span, + path!(option::Option), + vec![ast::GenericArg::Type(ordering_ty)], + )); let container_id = cx.current_expansion.id.expn_data().parent.expect_local(); let has_derive_ord = cx.resolver.has_derive_ord(container_id); - let default_substructure = - combine_substructure(|cx, span, substr| cs_partial_cmp(cx, span, substr, discr_then_data)); - let simple_substructure = combine_substructure(|cx, span, _| { - cs_partial_cmp_simple(cx, span, cx.expr_ident_sym(span, sym::other)) - }); + let default_substructure = cs_partial_cmp; let is_simple = match &item.kind { // For unit structs/zero-variant enums, the default generated code is better. ItemKind::Struct(.., ast::VariantData::Unit(..)) => false, @@ -58,20 +56,22 @@ pub(crate) fn expand_deriving_partial_ord( ret_ty, attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: FieldlessVariantsStrategy::Unify, - combine_substructure: if is_simple { simple_substructure } else { default_substructure }, + combine_substructure: if is_simple { + |cx, span, _| cs_partial_cmp_simple(cx, span, cx.expr_ident_sym(span, sym::other)) + } else { + default_substructure + }, }; let trait_def = TraitDef { span, path: path_std!(cx, span, cmp::PartialOrd), - skip_path_as_bound: false, needs_copy_as_bound_if_packed: true, additional_bounds: smallvec![], supports_unions: false, methods: smallvec![partial_cmp_def], is_const, - safety: Safety::Default, - document: true, + .. }; trait_def.expand_ext(cx, item, push, is_simple) } @@ -103,18 +103,13 @@ pub(crate) fn discr_data_order(item: &ast::Item) -> bool { // Some(::core::cmp::Ord::cmp(self, other)) // ``` fn cs_partial_cmp_simple(cx: &ExtCtxt<'_>, span: Span, other_expr: Box) -> BlockOrExpr { - let ord_cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]); + let ord_cmp_path = path_std!(cx, span, cmp::Ord::cmp); let cmp_expr = cx.expr_call_global(span, ord_cmp_path, thin_vec![cx.expr_self(span), other_expr]); BlockOrExpr::new_expr(cx.expr_some(span, cmp_expr)) } -fn cs_partial_cmp( - cx: &ExtCtxt<'_>, - span: Span, - substr: Substructure<'_>, - discr_then_data: bool, -) -> BlockOrExpr { +fn cs_partial_cmp(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> BlockOrExpr { // Builds: // // match ::core::cmp::PartialOrd::partial_cmp(&self.x, &other.x) { @@ -122,7 +117,7 @@ fn cs_partial_cmp( // ::core::cmp::PartialOrd::partial_cmp(&self.y, &other.y), // cmp => cmp, // } - let expr = cmp_body(cx, span, substr, discr_then_data, OrdlikeDerive::PartialOrd); + let expr = cmp_body(cx, span, substr, OrdlikeDerive::PartialOrd); BlockOrExpr::new_expr(expr) } @@ -136,16 +131,17 @@ pub(crate) fn cmp_body( cx: &ExtCtxt<'_>, span: Span, substructure: Substructure<'_>, - discr_then_data: bool, derive: OrdlikeDerive, ) -> Box { + // Order in which to perform matching + let discr_then_data = discr_data_order(substructure.item); let is_partial_ord = derive == OrdlikeDerive::PartialOrd; let method_path = if is_partial_ord { - cx.std_path(&[sym::cmp, sym::PartialOrd, sym::partial_cmp]) + [sym::cmp, sym::PartialOrd, sym::partial_cmp] } else { - cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]) + [sym::cmp, sym::Ord, sym::cmp] }; - let equal_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal])); + let equal_path = path_std!(cx, span, cmp::Ordering::Equal); // The combination of two field expressions. E.g. for `Ord::cmp` this // is something like ` && `. @@ -195,9 +191,8 @@ pub(crate) fn cmp_body( if is_partial_ord { cx.pat_some(span, eq_pat) } else { eq_pat }, expr1, ); - let cmp_ident = Ident::new(sym::cmp, span); - let neq_arm = - cx.arm(span, cx.pat_ident(span, cmp_ident), cx.expr_ident(span, cmp_ident)); + let cmp = sym::cmp; + let neq_arm = cx.arm(span, cx.pat_ident(span, cmp), cx.expr_ident_sym(span, cmp)); cx.expr_match(span, expr2, thin_vec![eq_arm, neq_arm]) } }; @@ -210,7 +205,8 @@ pub(crate) fn cmp_body( let other_expr = field.other_selflike_expr.expect("not exactly 2 arguments in `derive`"); let args = thin_vec![field.self_expr, other_expr]; - let new = cx.expr_call_global(field.span, method_path.clone(), args); + let new = + cx.expr_call_global(field.span, cx.std_path(field.span, &method_path), args); match old { Some(old) => Some(combine(field.span, old, new)), None => Some(new), @@ -230,7 +226,7 @@ pub(crate) fn cmp_body( let self_expr = cx.expr_addr_of(span, call_discriminant_value(cx, span, kw::SelfLower)); let other_expr = cx.expr_addr_of(span, call_discriminant_value(cx, span, sym::other)); let args = thin_vec![self_expr, other_expr]; - let discr_check_expr = cx.expr_call_global(span, method_path, args); + let discr_check_expr = cx.expr_call_global(span, cx.std_path(span, &method_path), args); if let Some(match_expr) = match_expr { combine(span, match_expr, discr_check_expr) } else { diff --git a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs index 05ad76dbd1ff9..5380d1eae3ace 100644 --- a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs +++ b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs @@ -6,7 +6,6 @@ use rustc_span::{Ident, Span, Symbol, sym}; use thin_vec::ThinVec; use crate::deriving::generic::*; -use crate::deriving::new_path; pub(crate) fn expand_deriving_reborrow( cx: &ExtCtxt<'_>, @@ -36,7 +35,15 @@ pub(crate) fn expand_deriving_coerce_shared( return; }; - push_marker_impl(cx, span, ident, generics, sym::CoerceShared, vec![target], push); + push_marker_impl( + cx, + span, + ident, + generics, + sym::CoerceShared, + vec![ast::GenericArg::Type(target)], + push, + ); } fn struct_def<'a>( @@ -105,15 +112,15 @@ fn push_marker_impl( ident: Ident, generics: &Generics, trait_name: Symbol, - trait_args: Vec>, + trait_args: Vec, push: &mut dyn FnMut(Box), ) { - let trait_path = new_path(cx, span, &[sym::core, sym::marker, trait_name], trait_args); + let trait_path = cx.std_path_all(span, &[sym::marker, trait_name], trait_args); let trait_ref = cx.trait_ref(trait_path); let self_params: Vec<_> = generics.params.iter().map(|p| generic_param_to_arg(cx, p, p.span())).collect(); - let self_ty = cx.ty_path(cx.path_all(span, false, vec![ident], self_params)); + let self_ty = cx.ty_path(cx.path_all(span, &[ident], self_params)); push(cx.item_trait_impl( span, diff --git a/compiler/rustc_builtin_macros/src/edition_panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs index 4c99ef9a9da26..d38fcc503bc20 100644 --- a/compiler/rustc_builtin_macros/src/edition_panic.rs +++ b/compiler/rustc_builtin_macros/src/edition_panic.rs @@ -45,12 +45,7 @@ fn expand<'cx>( ExpandResult::Ready(MacEager::expr(cx.expr_macro_call( sp, - cx.macro_call( - sp, - cx.path(sp, cx.std_path(&[sym::panic, mac])), - Delimiter::Parenthesis, - tts, - ), + cx.macro_call(sp, cx.std_path(sp, &[sym::panic, mac]), Delimiter::Parenthesis, tts), ))) } diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index ed37599c9e85a..4cd7a77a8e219 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -331,7 +331,7 @@ fn generate_default_impl( foreign_item_name.span, // prefix self to explicitly escape the const block generated below // NOTE: this is why EIIs can't be used on statements - vec![Ident::new(kw::SelfLower, foreign_item_name.span), foreign_item_name], + &[Ident::new(kw::SelfLower, foreign_item_name.span), foreign_item_name], )), }); @@ -349,9 +349,7 @@ fn generate_default_impl( }; let anon_mod = |span: Span, stmts: ThinVec| { - let unit = ecx.ty(item_span, ast::TyKind::Tup(ThinVec::new())); - let underscore = Ident::new(kw::Underscore, item_span); - ecx.item_const(span, underscore, unit, Some(ecx.expr_block(ecx.block(span, stmts)))) + ecx.item_const_underscore(span, ecx.block(span, stmts)) }; // const _: () = { diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index cced54e3cb534..19894cc1eb3d9 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -12,7 +12,6 @@ use rustc_ast_pretty::pprust; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; use rustc_span::edit_distance::edit_distance; use rustc_span::{Ident, Span, Symbol, kw, sym}; -use thin_vec::thin_vec; use crate::diagnostics; use crate::util::{expr_to_string, get_exprs_from_tts, get_single_expr_from_tts}; @@ -51,13 +50,12 @@ pub(crate) fn expand_option_env<'cx>( let e = match value { Err(VarError::NotPresent) => { let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp)); - cx.expr_path(cx.path_all( + cx.expr_path(cx.std_path_all( sp, - true, - cx.std_path(&[sym::option, sym::Option, sym::None]), + &[sym::option, sym::Option, sym::None], vec![GenericArg::Type(cx.ty_ref( sp, - cx.ty_ident(sp, Ident::new(sym::str, sp)), + cx.ty_sym(sp, sym::str), Some(lt), Mutability::Not, ))], @@ -68,11 +66,7 @@ pub(crate) fn expand_option_env<'cx>( let guar = cx.dcx().emit_err(diagnostics::EnvNotUnicode { span: sp, var: escaped_var }); return ExpandResult::Ready(DummyResult::any(sp, guar)); } - Ok(value) => cx.expr_call_global( - sp, - cx.std_path(&[sym::option, sym::Option, sym::Some]), - thin_vec![cx.expr_str(sp, value)], - ), + Ok(value) => cx.expr_some(sp, cx.expr_str(sp, value)), }; ExpandResult::Ready(MacEager::expr(e)) } diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index fada1c477ac88..c5da0026c2460 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -2,15 +2,15 @@ use rustc_ast::expand::allocator::{ ALLOCATOR_METHODS, AllocatorMethod, AllocatorMethodInput, AllocatorTy, global_fn_name, }; use rustc_ast::{ - self as ast, AttrVec, Expr, Fn, FnHeader, FnSig, Generics, ItemKind, Mutability, Param, Safety, - Stmt, StmtKind, Ty, TyKind, + self as ast, AttrVec, Expr, FnHeader, FnSig, Generics, ItemKind, Mutability, Param, Safety, + Stmt, StmtKind, Ty, }; use rustc_expand::base::{Annotatable, ExtCtxt}; -use rustc_span::{Ident, Span, Symbol, kw, sym}; +use rustc_span::{Ident, Span, Symbol, sym}; use thin_vec::{ThinVec, thin_vec}; use crate::diagnostics; -use crate::util::check_builtin_macro_attribute; +use crate::util::{check_builtin_macro_attribute, path_std}; pub(crate) fn expand( ecx: &mut ExtCtxt<'_>, @@ -53,10 +53,7 @@ pub(crate) fn expand( let stmts = ALLOCATOR_METHODS.iter().map(|method| f.allocator_fn(method)).collect(); // Generate anonymous constant serving as container for the allocator methods. - let const_ty = ecx.ty(ty_span, TyKind::Tup(ThinVec::new())); - let const_body = ecx.expr_block(ecx.block(span, stmts)); - let const_item = - ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, Some(const_body)); + let const_item = ecx.item_const_underscore(span, ecx.block(span, stmts)); let const_item = if is_stmt { Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item))) } else { @@ -84,23 +81,19 @@ impl AllocFnFactory<'_, '_> { let header = FnHeader { safety: Safety::Unsafe(self.span), ..FnHeader::default() }; let sig = FnSig { decl, header, span: self.span }; let body = Some(self.cx.block_expr(result)); - let kind = ItemKind::Fn(Box::new(Fn { - defaultness: ast::Defaultness::Implicit, + let kind = ItemKind::Fn(self.cx.item_fn( sig, - ident: Ident::from_str_and_span(&global_fn_name(method.name), self.span), - generics: Generics::default(), - contract: None, + Ident::from_str_and_span(&global_fn_name(method.name), self.span), + Generics::default(), body, - define_opaque: None, - eii_impl: None, - })); + )); let item = self.cx.item(self.span, self.attrs(method), kind); self.cx.stmt_item(self.ty_span, item) } fn call_allocator(&self, method: Symbol, mut args: ThinVec>) -> Box { - let method = self.cx.std_path(&[sym::alloc, sym::GlobalAlloc, method]); - let method = self.cx.expr_path(self.cx.path(self.ty_span, method)); + let method = self.cx.std_path(self.ty_span, &[sym::alloc, sym::GlobalAlloc, method]); + let method = self.cx.expr_path(method); let allocator = self.cx.path_ident(self.ty_span, self.global); let allocator = self.cx.expr_path(allocator); let allocator = self.cx.expr_addr_of(self.ty_span, allocator); @@ -131,37 +124,31 @@ impl AllocFnFactory<'_, '_> { // disambiguated somehow. Currently the generated code would // fail to compile with "identifier is bound more than once in // this parameter list". - let size = Ident::new(sym::size, self.span); - let align = Ident::new(sym::align, self.span); - let usize = self.cx.path_ident(self.span, Ident::new(sym::usize, self.span)); - let ty_usize = self.cx.ty_path(usize); - args.push(self.cx.param(self.span, size, ty_usize)); + let ty_usize = self.usize(); + args.push(self.cx.param(self.span, sym::size, ty_usize)); let ty_align = self.ptr_alignment(); - args.push(self.cx.param(self.span, align, ty_align)); - - let layout_new = self.cx.std_path(&[ - sym::alloc, - sym::Layout, - sym::from_size_alignment_unchecked, - ]); - let layout_new = self.cx.expr_path(self.cx.path(self.span, layout_new)); - let size = self.cx.expr_ident(self.span, size); - let align = self.cx.expr_ident(self.span, align); + args.push(self.cx.param(self.span, sym::align, ty_align)); + + let layout_new = + path_std!(self.cx, self.span, alloc::Layout::from_size_alignment_unchecked); + let layout_new = self.cx.expr_path(layout_new); + let size = self.cx.expr_ident_sym(self.span, sym::size); + let align = self.cx.expr_ident_sym(self.span, sym::align); let layout = self.cx.expr_call(self.span, layout_new, thin_vec![size, align]); layout } AllocatorTy::Ptr => { - let ident = Ident::from_str_and_span(input.name, self.span); - args.push(self.cx.param(self.span, ident, self.ptr_u8())); - self.cx.expr_ident(self.span, ident) + let name = Symbol::intern(input.name); + args.push(self.cx.param(self.span, name, self.ptr_u8())); + self.cx.expr_ident_sym(self.span, name) } AllocatorTy::Usize => { - let ident = Ident::from_str_and_span(input.name, self.span); - args.push(self.cx.param(self.span, ident, self.usize())); - self.cx.expr_ident(self.span, ident) + let name = Symbol::intern(input.name); + args.push(self.cx.param(self.span, name, self.usize())); + self.cx.expr_ident_sym(self.span, name) } AllocatorTy::Never | AllocatorTy::ResultPtr | AllocatorTy::Unit => { @@ -174,7 +161,7 @@ impl AllocFnFactory<'_, '_> { match *ty { AllocatorTy::ResultPtr => self.ptr_u8(), - AllocatorTy::Unit => self.cx.ty(self.span, TyKind::Tup(ThinVec::new())), + AllocatorTy::Unit => self.cx.ty_unit(self.span), AllocatorTy::Layout | AllocatorTy::Never | AllocatorTy::Usize | AllocatorTy::Ptr => { panic!("can't convert `AllocatorTy` to an output") @@ -183,19 +170,16 @@ impl AllocFnFactory<'_, '_> { } fn usize(&self) -> Box { - let usize = self.cx.path_ident(self.span, Ident::new(sym::usize, self.span)); - self.cx.ty_path(usize) + self.cx.ty_sym(self.span, sym::usize) } fn ptr_alignment(&self) -> Box { - let path = self.cx.std_path(&[sym::mem, sym::Alignment]); - let path = self.cx.path(self.span, path); + let path = path_std!(self.cx, self.span, mem::Alignment); self.cx.ty_path(path) } fn ptr_u8(&self) -> Box { - let u8 = self.cx.path_ident(self.span, Ident::new(sym::u8, self.span)); - let ty_u8 = self.cx.ty_path(u8); + let ty_u8 = self.cx.ty_sym(self.span, sym::u8); self.cx.ty_ptr(self.span, ty_u8, Mutability::Mut) } } diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index c564e14776c91..4c3b42eaa0b22 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -4,6 +4,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![feature(decl_macro)] +#![feature(default_field_values)] #![feature(deref_patterns)] #![feature(iter_order_by)] #![feature(proc_macro_internals)] @@ -62,13 +63,13 @@ pub mod util; pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { let mut register = |name, kind| resolver.register_builtin_macro(name, kind); macro register_bang($($name:ident: $f:expr,)*) { - $(register(sym::$name, SyntaxExtensionKind::LegacyBang(Arc::new($f as MacroExpanderFn)));)* + $(register(sym::$name, SyntaxExtensionKind::AstBang(Arc::new($f as MacroExpanderFn)));)* } macro register_attr($($name:ident: $f:expr,)*) { - $(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Arc::new($f)));)* + $(register(sym::$name, SyntaxExtensionKind::AstAttr(Arc::new($f)));)* } macro register_derive($($name:ident: $f:expr,)*) { - $(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Arc::new(BuiltinDerive($f))));)* + $(register(sym::$name, SyntaxExtensionKind::AstDerive(Arc::new(BuiltinDerive($f))));)* } register_bang! { diff --git a/compiler/rustc_builtin_macros/src/offload.rs b/compiler/rustc_builtin_macros/src/offload.rs index 4da4ce4e4a505..ef38382c48319 100644 --- a/compiler/rustc_builtin_macros/src/offload.rs +++ b/compiler/rustc_builtin_macros/src/offload.rs @@ -75,16 +75,7 @@ pub(crate) fn expand_kernel( let span = ecx.with_def_site_ctxt(expand_span); // device function - let mut device_fn = Box::new(ast::Fn { - defaultness: ast::Defaultness::Implicit, - sig: sig.clone(), - ident, - generics: generics.clone(), - contract: None, - body, - define_opaque: None, - eii_impl: None, - }); + let mut device_fn = ecx.item_fn(sig.clone(), ident, generics.clone(), body); let extern_gpu_kernel = ast::Extern::from_abi( Some(ast::StrLit { @@ -120,10 +111,7 @@ pub(crate) fn expand_kernel( span, ecx.macro_call( span, - ecx.path_global( - span, - [sym::core, sym::unimplemented].map(|s| Ident::new(s, span)).to_vec(), - ), + ecx.std_path(span, &[sym::unimplemented]), Delimiter::Parenthesis, TokenStream::default(), ), @@ -132,16 +120,7 @@ pub(crate) fn expand_kernel( let body = ecx.block(span, thin_vec![stmt]); // host function - let mut host_fn = Box::new(ast::Fn { - defaultness: ast::Defaultness::Implicit, - sig, - ident, - generics, - contract: None, - body: Some(body), - define_opaque: None, - eii_impl: None, - }); + let mut host_fn = ecx.item_fn(sig, ident, generics, Some(body)); for param in host_fn.sig.decl.inputs.iter_mut() { *param.pat = ecx.pat_wild(param.pat.span); diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index ecf4f7e7fb1af..5f40231c7f67c 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -12,9 +12,9 @@ use rustc_feature::Features; use rustc_session::Session; use rustc_span::hygiene::AstPass; use rustc_span::source_map::SourceMap; -use rustc_span::{DUMMY_SP, Ident, Span, kw, sym}; +use rustc_span::{DUMMY_SP, Ident, Span, sym}; use smallvec::smallvec; -use thin_vec::{ThinVec, thin_vec}; +use thin_vec::thin_vec; use crate::diagnostics; @@ -299,11 +299,11 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> Box { ProcMacro::Derive(m) => m.span, ProcMacro::Attr(m) | ProcMacro::Bang(m) => m.span, }; - let local_path = |cx: &ExtCtxt<'_>, ident| cx.expr_path(cx.path(span, vec![ident])); + let local_path = |cx: &ExtCtxt<'_>, ident| cx.expr_ident(span, ident); let proc_macro_ty_method_path = |cx: &ExtCtxt<'_>, method| { cx.expr_path(cx.path( span.with_ctxt(harness_span.ctxt()), - vec![proc_macro, bridge, client, client_ty, method], + &[proc_macro, bridge, client, client_ty, method], )) }; match m { @@ -346,7 +346,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> Box { cx.ty( span, ast::TyKind::Slice( - cx.ty_path(cx.path(span, vec![proc_macro, bridge, client, client_ty])), + cx.ty_path(cx.path(span, &[proc_macro, bridge, client, client_ty])), ), ), None, @@ -361,16 +361,10 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> Box { cx.attr_nested_word(sym::allow, sym::deprecated, span), ]); - let block = cx.expr_block( - cx.block(span, thin_vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]), - ); + let block = + cx.block(span, thin_vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]); - let anon_constant = cx.item_const( - span, - Ident::new(kw::Underscore, span), - cx.ty(span, ast::TyKind::Tup(ThinVec::new())), - Some(block), - ); + let anon_constant = cx.item_const_underscore(span, block); // Integrate the new item into existing module structures. let items = AstFragment::Items(smallvec![anon_constant]); diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs index 674793937c1a9..ceada06a08010 100644 --- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs +++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs @@ -60,14 +60,14 @@ pub fn inject( EditionFuture => sym::rust_future, }]) .map(|&symbol| Ident::new(symbol, span)) - .collect(); + .collect::>(); // Inject the relevant crate's prelude. let use_item = cx.item( span, thin_vec![cx.attr_word(sym::prelude_import, span)], ast::ItemKind::Use(ast::UseTree { - prefix: cx.path(span, import_path), + prefix: cx.path(span, &import_path), kind: ast::UseTreeKind::Glob(span), }), ); diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 8e99d532029db..cc7d25de6ff1a 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -161,13 +161,13 @@ pub(crate) fn expand_test_or_bench( let test_ident = Ident::new(sym::test, attr_sp); // creates test::$name - let test_path = |name| cx.path(ret_ty_sp, vec![test_ident, Ident::from_str_and_span(name, sp)]); + let test_path = |name| cx.path(ret_ty_sp, &[test_ident, Ident::from_str_and_span(name, sp)]); // creates test::ShouldPanic::$name let should_panic_path = |name| { cx.path( sp, - vec![test_ident, Ident::new(sym::ShouldPanic, sp), Ident::from_str_and_span(name, sp)], + &[test_ident, Ident::new(sym::ShouldPanic, sp), Ident::from_str_and_span(name, sp)], ) }; @@ -175,7 +175,7 @@ pub(crate) fn expand_test_or_bench( let test_type_path = |name| { cx.path( sp, - vec![test_ident, Ident::new(sym::TestType, sp), Ident::from_str_and_span(name, sp)], + &[test_ident, Ident::new(sym::TestType, sp), Ident::from_str_and_span(name, sp)], ) }; @@ -194,8 +194,7 @@ pub(crate) fn expand_test_or_bench( let test_fn = if is_bench { // avoid name collisions by using the function name within the identifier, see bug #148275 - let bencher_param = - Ident::from_str_and_span(&format!("__bench_{}", fn_.ident.name), attr_sp); + let bencher_param = Symbol::intern(&format!("__bench_{}", fn_.ident.name)); cx.expr_call( sp, cx.expr_path(test_path("StaticBenchFn")), @@ -212,8 +211,8 @@ pub(crate) fn expand_test_or_bench( // super::$test_fn(__bench_fn_name) cx.expr_call( ret_ty_sp, - cx.expr_path(cx.path(sp, vec![fn_.ident])), - thin_vec![cx.expr_ident(sp, bencher_param)], + cx.expr_path(cx.path_ident(sp, fn_.ident)), + thin_vec![cx.expr_ident_sym(sp, bencher_param)], ), ], ), @@ -238,7 +237,7 @@ pub(crate) fn expand_test_or_bench( // $test_fn() cx.expr_call( ret_ty_sp, - cx.expr_path(cx.path(sp, vec![fn_.ident])), + cx.expr_path(cx.path(sp, &[fn_.ident])), ThinVec::new(), ), // ) ], @@ -272,7 +271,7 @@ pub(crate) fn expand_test_or_bench( cx.attr_nested_word(sym::doc, sym::hidden, attr_sp), ], Ident::new(fn_.ident.name, sp), - cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))), + cx.ty_path(test_path("TestDescAndFn")), Mutability::Not, // test::TestDescAndFn { cx.expr_struct( diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index d6167d30558a3..7c19ffc331364 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -301,7 +301,7 @@ fn add_main(cx: &mut TestCtxt<'_>, c: &mut ast::Crate) { } else { "test_main_env_args_abort" }; - ecx.path(sp, vec![test_ident, Ident::from_str_and_span(runner_name, sp)]) + ecx.path(sp, &[test_ident, Ident::from_str_and_span(runner_name, sp)]) }); test_runner.span = sp; @@ -324,35 +324,25 @@ fn add_main(cx: &mut TestCtxt<'_>, c: &mut ast::Crate) { // pub fn main() -> ExitCode { ... } let main_ret_ty = if cx.test_runner.is_none() { // Built-in runner has return type `ExitCode`. - let exit_code_path = vec![test_ident, Ident::new(sym::ExitCode, sp)]; - ecx.ty(sp, ast::TyKind::Path(None, ecx.path(sp, exit_code_path))) + let exit_code_path = &[test_ident, Ident::new(sym::ExitCode, sp)]; + ecx.ty_path(ecx.path(sp, exit_code_path)) } else { // User-defined runners have return type `()`. - ecx.ty(sp, ast::TyKind::Tup(ThinVec::new())) + ecx.ty_unit(sp) }; let main_body = ecx.block(sp, thin_vec![call_test_main]); let decl = ecx.fn_decl(ThinVec::new(), ast::FnRetTy::Ty(main_ret_ty)); let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp }; - let defaultness = ast::Defaultness::Implicit; - // Honor the reexport_test_harness_main attribute let main_ident = match cx.reexport_test_harness_main { Some(sym) => Ident::new(sym, sp.with_ctxt(SyntaxContext::root())), None => Ident::new(sym::main, sp), }; - let main = ast::ItemKind::Fn(Box::new(ast::Fn { - defaultness, - sig, - ident: main_ident, - generics: ast::Generics::default(), - contract: None, - body: Some(main_body), - define_opaque: None, - eii_impl: None, - })); + let main = + ast::ItemKind::Fn(ecx.item_fn(sig, main_ident, ast::Generics::default(), Some(main_body))); let main = Box::new(ast::Item { attrs: thin_vec![main_attr, coverage_attr, doc_hidden_attr], @@ -389,7 +379,7 @@ fn mk_tests_slice(cx: &TestCtxt<'_>, sp: Span) -> Box { tests .iter() .map(|test| { - ecx.expr_addr_of(test.span, ecx.expr_path(ecx.path(test.span, vec![test.ident]))) + ecx.expr_addr_of(test.span, ecx.expr_path(ecx.path(test.span, &[test.ident]))) }) .collect(), ) diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs index 7b990c5af080f..11041a14d9584 100644 --- a/compiler/rustc_builtin_macros/src/util.rs +++ b/compiler/rustc_builtin_macros/src/util.rs @@ -7,10 +7,18 @@ use rustc_expand::expand::AstFragment; use rustc_lint_defs::builtin::DUPLICATE_MACRO_ATTRIBUTES; use rustc_parse::{exp, parser}; use rustc_session::diagnostics::report_lit_error; -use rustc_span::{BytePos, Span, Symbol}; +use rustc_span::{BytePos, Span, Symbol, sym}; use crate::diagnostics; +pub macro path($($rest:ident)::+) {{ + &[ $( sym::$rest ),+ ] +}} + +pub macro path_std($cx: expr, $span: expr, $($x:tt)*) { + $cx.std_path($span, path!( $($x)* ) ) +} + pub(crate) fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) { // All the built-in macro attributes are "words" at the moment. let template = AttributeTemplate { word: true, ..Default::default() }; diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 01e8cef49e445..501bb21c1eea9 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -689,7 +689,7 @@ pub enum SyntaxExtensionKind { ), /// An AST-based function-like macro. - LegacyBang( + AstBang( /// An expander with signature TokenStream -> AST. Arc, ), @@ -703,7 +703,7 @@ pub enum SyntaxExtensionKind { ), /// An AST-based attribute macro. - LegacyAttr( + AstAttr( /// An expander with signature (AST, AST) -> AST. /// The first AST fragment is the attribute itself, the second is the annotated item. /// The produced AST fragment replaces the input AST fragment. @@ -722,14 +722,14 @@ pub enum SyntaxExtensionKind { /// The produced TokenStream is appended to the input TokenStream. /// /// FIXME: The text above describes how this should work. Currently it - /// is handled identically to `LegacyDerive`. It should be migrated to + /// is handled identically to `AstDerive`. It should be migrated to /// a token-based representation like `Bang` and `Attr`, instead of /// using `MultiItemModifier`. Arc, ), /// An AST-based derive macro. - LegacyDerive( + AstDerive( /// An expander with signature AST -> AST. /// The produced AST fragment is appended to the input AST fragment. Arc, @@ -742,12 +742,12 @@ pub enum SyntaxExtensionKind { } impl SyntaxExtensionKind { - /// Returns `Some(expander)` for a macro usable as a `LegacyBang`; otherwise returns `None` + /// Returns `Some(expander)` for a macro usable as a `AstBang`; otherwise returns `None` /// /// This includes a `MacroRules` with function-like rules. - pub fn as_legacy_bang(&self) -> Option<&(dyn TTMacroExpander + sync::DynSync + sync::DynSend)> { + pub fn as_ast_bang(&self) -> Option<&(dyn TTMacroExpander + sync::DynSync + sync::DynSend)> { match self { - SyntaxExtensionKind::LegacyBang(exp) => Some(exp.as_ref()), + SyntaxExtensionKind::AstBang(exp) => Some(exp.as_ref()), SyntaxExtensionKind::MacroRules(exp) if exp.kinds().contains(MacroKinds::BANG) => { Some(exp.as_ref()) } @@ -805,12 +805,12 @@ impl SyntaxExtension { pub fn macro_kinds(&self) -> MacroKinds { match self.kind { SyntaxExtensionKind::Bang(..) - | SyntaxExtensionKind::LegacyBang(..) + | SyntaxExtensionKind::AstBang(..) | SyntaxExtensionKind::GlobDelegation(..) => MacroKinds::BANG, SyntaxExtensionKind::Attr(..) - | SyntaxExtensionKind::LegacyAttr(..) + | SyntaxExtensionKind::AstAttr(..) | SyntaxExtensionKind::NonMacroAttr => MacroKinds::ATTR, - SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::LegacyDerive(..) => { + SyntaxExtensionKind::Derive(..) | SyntaxExtensionKind::AstDerive(..) => { MacroKinds::DERIVE } SyntaxExtensionKind::MacroRules(ref m) => m.kinds(), diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 2a4089b1213ab..efed0e83e8e6a 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -5,7 +5,7 @@ use rustc_ast::tokenstream::TokenStream; use rustc_ast::util::literal; use rustc_ast::{ self as ast, AnonConst, AttrItem, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, PatKind, - UnOp, attr, token, tokenstream, + Path, UnOp, attr, token, tokenstream, }; use rustc_span::{DUMMY_SP, Ident, Span, Spanned, Symbol, kw, sym}; use thin_vec::{ThinVec, thin_vec}; @@ -13,57 +13,68 @@ use thin_vec::{ThinVec, thin_vec}; use crate::base::ExtCtxt; impl<'a> ExtCtxt<'a> { - pub fn std_path(&self, components: &[Symbol]) -> Vec { - let def_site = self.with_def_site_ctxt(DUMMY_SP); - iter::once(Ident::new(kw::DollarCrate, def_site)) - .chain(components.iter().map(|&s| Ident::new(s, def_site))) - .collect() + pub fn std_path(&self, span: Span, components: &[Symbol]) -> Path { + self.std_path_all(span, components, vec![]) + } + pub fn std_path_all( + &self, + span: Span, + components: &[Symbol], + args: Vec, + ) -> Path { + let mut segments = ThinVec::with_capacity(components.len() + 1); + let (last, rest) = components.split_last().expect("cannot construct empty path"); + segments.extend( + iter::once(Ident::new(kw::DollarCrate, self.with_def_site_ctxt(DUMMY_SP))) + .chain(rest.iter().copied().map(|name| Ident::new(name, span))) + .map(|name| ast::PathSegment::from_ident(name)), + ); + self.build_path(span, segments, Ident::new(*last, span), args) } - pub fn path(&self, span: Span, strs: Vec) -> ast::Path { - self.path_all(span, false, strs, vec![]) + pub fn path(&self, span: Span, strs: &[Ident]) -> Path { + self.path_all(span, strs, vec![]) } - pub fn path_ident(&self, span: Span, id: Ident) -> ast::Path { - self.path(span, vec![id]) + + pub fn path_ident(&self, span: Span, id: Ident) -> Path { + let segments = thin_vec![ast::PathSegment::from_ident(id.with_span_pos(span))]; + Path { span, segments } } - pub fn path_global(&self, span: Span, strs: Vec) -> ast::Path { - self.path_all(span, true, strs, vec![]) + + pub fn path_sym(&self, span: Span, name: Symbol) -> Path { + Path::from_ident(Ident::new(name, span)) } - pub fn path_all( + + pub fn path_all(&self, span: Span, idents: &[Ident], args: Vec) -> Path { + let mut segments = ThinVec::with_capacity(idents.len()); + let (last, rest) = idents.split_last().expect("cannot construct empty path"); + segments.extend( + rest.iter().map(|ident| ast::PathSegment::from_ident(ident.with_span_pos(span))), + ); + self.build_path(span, segments, last.with_span_pos(span), args) + } + + fn build_path( &self, span: Span, - global: bool, - mut idents: Vec, + mut segments: ThinVec, + last: Ident, args: Vec, - ) -> ast::Path { - assert!(!idents.is_empty()); - let add_root = global && !idents[0].is_path_segment_keyword(); - let mut segments = ThinVec::with_capacity(idents.len() + add_root as usize); - if add_root { - segments.push(ast::PathSegment::path_root(span)); - } - let last_ident = idents.pop().unwrap(); - segments.extend( - idents.into_iter().map(|ident| ast::PathSegment::from_ident(ident.with_span_pos(span))), - ); + ) -> Path { let args = if !args.is_empty() { let args = args.into_iter().map(ast::AngleBracketedArg::Arg).collect(); Some(ast::AngleBracketedArgs { args, span }.into()) } else { None }; - segments.push(ast::PathSegment { - ident: last_ident.with_span_pos(span), - id: ast::DUMMY_NODE_ID, - args, - }); - ast::Path { span, segments } + segments.push(ast::PathSegment { ident: last, id: ast::DUMMY_NODE_ID, args }); + Path { span, segments } } pub fn macro_call( &self, span: Span, - path: ast::Path, + path: Path, delim: Delimiter, tokens: TokenStream, ) -> Box { @@ -85,16 +96,18 @@ impl<'a> ExtCtxt<'a> { self.ty(span, ast::TyKind::Infer) } - pub fn ty_path(&self, path: ast::Path) -> Box { + pub fn ty_path(&self, path: Path) -> Box { self.ty(path.span, ast::TyKind::Path(None, path)) } - // Might need to take bounds as an argument in the future, if you ever want - // to generate a bounded existential trait type. pub fn ty_ident(&self, span: Span, ident: Ident) -> Box { self.ty_path(self.path_ident(span, ident)) } + pub fn ty_sym(&self, span: Span, name: Symbol) -> Box { + self.ty_path(self.path_sym(span, name)) + } + pub fn anon_const(&self, span: Span, kind: ast::ExprKind) -> ast::AnonConst { ast::AnonConst { id: ast::DUMMY_NODE_ID, @@ -135,7 +148,7 @@ impl<'a> ExtCtxt<'a> { } pub fn ty_self(&self, span: Span) -> Box { - self.ty_path(self.path_ident(span, Ident::new(kw::SelfUpper, span))) + self.ty_path(self.path_sym(span, kw::SelfUpper)) } pub fn ty_self_ref(&self, span: Span) -> Box { self.ty_ref(span, self.ty_self(span), None, ast::Mutability::Not) @@ -188,11 +201,11 @@ impl<'a> ExtCtxt<'a> { } } - pub fn trait_ref(&self, path: ast::Path) -> ast::TraitRef { + pub fn trait_ref(&self, path: Path) -> ast::TraitRef { ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID } } - pub fn poly_trait_ref(&self, span: Span, path: ast::Path, is_const: bool) -> ast::PolyTraitRef { + pub fn poly_trait_ref(&self, span: Span, path: Path, is_const: bool) -> ast::PolyTraitRef { ast::PolyTraitRef { bound_generic_params: ThinVec::new(), modifiers: ast::TraitBoundModifiers { @@ -210,7 +223,7 @@ impl<'a> ExtCtxt<'a> { } } - pub fn trait_bound(&self, path: ast::Path, is_const: bool) -> ast::GenericBound { + pub fn trait_bound(&self, path: Path, is_const: bool) -> ast::GenericBound { ast::GenericBound::Trait(self.poly_trait_ref(path.span, path, is_const)) } @@ -226,22 +239,22 @@ impl<'a> ExtCtxt<'a> { ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) } } - pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: Box) -> ast::Stmt { - self.stmt_let_ty(sp, mutbl, ident, None, ex) + pub fn stmt_let(&self, sp: Span, mutbl: bool, name: Symbol, ex: Box) -> ast::Stmt { + self.stmt_let_ty(sp, mutbl, name, None, ex) } pub fn stmt_let_ty( &self, sp: Span, mutbl: bool, - ident: Ident, + name: Symbol, ty: Option>, ex: Box, ) -> ast::Stmt { let pat = if mutbl { - self.pat_ident_binding_mode(sp, ident, ast::BindingMode::MUT) + self.pat_ident_binding_mode(sp, name, ast::BindingMode::MUT) } else { - self.pat_ident(sp, ident) + self.pat_ident(sp, name) }; let local = Box::new(ast::Local { super_: None, @@ -305,7 +318,7 @@ impl<'a> ExtCtxt<'a> { }) } - pub fn expr_path(&self, path: ast::Path) -> Box { + pub fn expr_path(&self, path: Path) -> Box { self.expr(path.span, ast::ExprKind::Path(None, path)) } @@ -383,10 +396,10 @@ impl<'a> ExtCtxt<'a> { pub fn expr_call_global( &self, sp: Span, - fn_path: Vec, + fn_path: Path, args: ThinVec>, ) -> Box { - let pathexpr = self.expr_path(self.path_global(sp, fn_path)); + let pathexpr = self.expr_path(fn_path); self.expr_call(sp, pathexpr, args) } pub fn expr_block(&self, b: Box) -> Box { @@ -406,7 +419,7 @@ impl<'a> ExtCtxt<'a> { pub fn expr_struct( &self, span: Span, - path: ast::Path, + path: Path, fields: ThinVec, ) -> Box { self.expr( @@ -466,57 +479,61 @@ impl<'a> ExtCtxt<'a> { } pub fn expr_some(&self, sp: Span, expr: Box) -> Box { - let some = self.std_path(&[sym::option, sym::Option, sym::Some]); + let some = self.std_path(sp, &[sym::option, sym::Option, sym::Some]); self.expr_call_global(sp, some, thin_vec![expr]) } pub fn expr_none(&self, sp: Span) -> Box { - let none = self.std_path(&[sym::option, sym::Option, sym::None]); - self.expr_path(self.path_global(sp, none)) + let none = self.std_path(sp, &[sym::option, sym::Option, sym::None]); + self.expr_path(none) } pub fn expr_tuple(&self, sp: Span, exprs: ThinVec>) -> Box { self.expr(sp, ast::ExprKind::Tup(exprs)) } pub fn expr_ok(&self, sp: Span, expr: Box) -> Box { - let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); + let ok = self.std_path(sp, &[sym::result, sym::Result, sym::Ok]); self.expr_call_global(sp, ok, thin_vec![expr]) } + pub fn expr_call_intrinsic( + &self, + span: Span, + intrinsic: Symbol, + args: ThinVec>, + ) -> Box { + self.expr_call_global(span, self.std_path(span, &[sym::intrinsics, intrinsic]), args) + } + pub fn pat(&self, span: Span, kind: PatKind) -> ast::Pat { ast::Pat { id: ast::DUMMY_NODE_ID, kind, span } } pub fn pat_wild(&self, span: Span) -> ast::Pat { self.pat(span, PatKind::Wild) } - pub fn pat_ident(&self, span: Span, ident: Ident) -> ast::Pat { - self.pat_ident_binding_mode(span, ident, ast::BindingMode::NONE) + pub fn pat_ident(&self, span: Span, name: Symbol) -> ast::Pat { + self.pat_ident_binding_mode(span, name, ast::BindingMode::NONE) } pub fn pat_ident_binding_mode( &self, span: Span, - ident: Ident, + name: Symbol, ann: ast::BindingMode, ) -> ast::Pat { - let pat = PatKind::Ident(ann, ident.with_span_pos(span), None); + let pat = PatKind::Ident(ann, Ident::new(name, span), None); self.pat(span, pat) } - pub fn pat_path(&self, span: Span, path: ast::Path) -> ast::Pat { + pub fn pat_path(&self, span: Span, path: Path) -> ast::Pat { self.pat(span, PatKind::Path(None, path)) } - pub fn pat_tuple_struct( - &self, - span: Span, - path: ast::Path, - subpats: ThinVec, - ) -> ast::Pat { + pub fn pat_tuple_struct(&self, span: Span, path: Path, subpats: ThinVec) -> ast::Pat { self.pat(span, PatKind::TupleStruct(None, path, subpats)) } pub fn pat_struct( &self, span: Span, - path: ast::Path, + path: Path, field_pats: ThinVec, ) -> ast::Pat { self.pat(span, PatKind::Struct(None, path, field_pats, ast::PatFieldsRest::None)) @@ -526,9 +543,8 @@ impl<'a> ExtCtxt<'a> { } pub fn pat_some(&self, span: Span, pat: ast::Pat) -> 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, thin_vec![pat]) + let some = self.std_path(span, &[sym::option, sym::Option, sym::Some]); + self.pat_tuple_struct(span, some, thin_vec![pat]) } pub fn arm(&self, span: Span, pat: ast::Pat, expr: Box) -> ast::Arm { @@ -563,9 +579,9 @@ impl<'a> ExtCtxt<'a> { self.expr(span, ast::ExprKind::If(cond, self.block_expr(then), els)) } - pub fn closure(&self, span: Span, ids: Vec, body: Box) -> Box { + pub fn closure(&self, span: Span, ids: Vec, body: Box) -> Box { let fn_decl = self.fn_decl( - ids.iter().map(|id| self.param(span, *id, self.ty(span, ast::TyKind::Infer))).collect(), + ids.iter().map(|id| self.param(span, *id, self.ty_infer(span))).collect(), ast::FnRetTy::Default(span), ); @@ -591,8 +607,8 @@ impl<'a> ExtCtxt<'a> { ) } - pub fn param(&self, span: Span, ident: Ident, ty: Box) -> ast::Param { - let pat = Box::new(self.pat_ident(span, ident)); + pub fn param(&self, span: Span, name: Symbol, ty: Box) -> ast::Param { + let pat = Box::new(self.pat_ident(span, name)); ast::Param { attrs: AttrVec::default(), id: ast::DUMMY_NODE_ID, @@ -704,6 +720,34 @@ impl<'a> ExtCtxt<'a> { ) } + pub fn item_const_underscore(&self, span: Span, body: Box) -> Box { + self.item_const( + span, + Ident::new(kw::Underscore, span), + self.ty_unit(span), + Some(self.expr_block(body)), + ) + } + + pub fn item_fn( + &self, + sig: ast::FnSig, + ident: Ident, + generics: ast::Generics, + body: Option>, + ) -> Box { + Box::new(ast::Fn { + defaultness: ast::Defaultness::Implicit, + sig, + ident, + generics, + contract: None, + body, + define_opaque: None, + eii_impl: None, + }) + } + // Builds `#[name]`. pub fn attr_word(&self, name: Symbol, span: Span) -> ast::Attribute { let g = &self.sess.psess.attr_id_generator; diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 5a2442fbccf35..09335b42958c7 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -742,7 +742,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } Err(guar) => return ExpandResult::Ready(fragment_kind.dummy(span, guar)), } - } else if let Some(expander) = ext.as_legacy_bang() { + } else if let Some(expander) = ext.as_ast_bang() { let tok_result = match expander.expand(self.cx, span, mac.args.tokens.clone()) { ExpandResult::Ready(tok_result) => tok_result, ExpandResult::Retry(_) => { @@ -856,7 +856,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } Err(guar) => return ExpandResult::Ready(fragment_kind.dummy(span, guar)), } - } else if let SyntaxExtensionKind::LegacyAttr(expander) = ext { + } else if let SyntaxExtensionKind::AstAttr(expander) = ext { self.gate_proc_macro_attr_item(span, &item); // `LegacyAttr` is only used for builtin attribute macros, which have their // safety checked by `check_builtin_meta_item`, so we don't need to check @@ -913,7 +913,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } InvocationKind::Derive { path, item, is_const } => match ext { SyntaxExtensionKind::Derive(expander) - | SyntaxExtensionKind::LegacyDerive(expander) => { + | SyntaxExtensionKind::AstDerive(expander) => { // The `MetaItem` representing the trait to derive can't // have an unsafe around it (as of now). let meta = ast::MetaItem { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b9e7a9f5f94cb..51e4d293854bd 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -881,6 +881,7 @@ symbols! { dreg, dreg_low8, dreg_low16, + dret, drop, drop_glue, drop_in_place, diff --git a/tests/ui/derives/deriving-from-wrong-target.rs b/tests/ui/derives/deriving-from-wrong-target.rs index d0cab937b5d49..37c9300e28b3c 100644 --- a/tests/ui/derives/deriving-from-wrong-target.rs +++ b/tests/ui/derives/deriving-from-wrong-target.rs @@ -29,6 +29,8 @@ struct S4 { enum E1 {} #[derive(From)] +//~^ ERROR the size for values of type `T` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `T` cannot be known at compilation time [E0277] struct SUnsizedField { last: T, //~^ ERROR the size for values of type `T` cannot be known at compilation time [E0277] diff --git a/tests/ui/derives/deriving-from-wrong-target.stderr b/tests/ui/derives/deriving-from-wrong-target.stderr index 4547cea5ba6a1..dd18c5dcb5b28 100644 --- a/tests/ui/derives/deriving-from-wrong-target.stderr +++ b/tests/ui/derives/deriving-from-wrong-target.stderr @@ -54,7 +54,46 @@ LL | enum E1 {} = note: `#[derive(From)]` can only be used on structs with exactly one field error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/deriving-from-wrong-target.rs:33:11 + --> $DIR/deriving-from-wrong-target.rs:31:10 + | +LL | #[derive(From)] + | ^^^^ doesn't have a size known at compile-time +... +LL | struct SUnsizedField { + | - this type parameter needs to be `Sized` + | +note: required by an implicit `Sized` bound in `From` + --> $SRC_DIR/core/src/convert/mod.rs:LL:COL +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - struct SUnsizedField { +LL + struct SUnsizedField { + | + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/deriving-from-wrong-target.rs:31:10 + | +LL | #[derive(From)] + | ^^^^ doesn't have a size known at compile-time +... +LL | struct SUnsizedField { + | - this type parameter needs to be `Sized` + | +note: required because it appears within the type `SUnsizedField` + --> $DIR/deriving-from-wrong-target.rs:35:5 + | +LL | struct SUnsizedField { +LL | last: T, + | ^^^^^^^ required by this field + = note: the return type of a function must have a statically known size +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - struct SUnsizedField { +LL + struct SUnsizedField { + | + +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/deriving-from-wrong-target.rs:35:11 | LL | struct SUnsizedField { | - this type parameter needs to be `Sized` @@ -72,6 +111,6 @@ help: function arguments must have a statically known size, borrowed types alway LL | last: &T, | + -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0277`.