From 2ca37278b2488b6677f8d24c2658a5066e75595b Mon Sep 17 00:00:00 2001 From: cyrgani Date: Tue, 29 Sep 2026 18:34:52 +0000 Subject: [PATCH 01/18] rename `Legacy*` macro kinds to `Ast*` --- compiler/rustc_builtin_macros/src/lib.rs | 6 +++--- compiler/rustc_expand/src/base.rs | 20 ++++++++++---------- compiler/rustc_expand/src/expand.rs | 6 +++--- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index c564e14776c91..03c1653458aa1 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -62,13 +62,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_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/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 { From 023608f5d911d85220064ccb5f8a781dcdc5baa5 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sun, 4 Oct 2026 21:23:23 +0000 Subject: [PATCH 02/18] add `cx.ty_sym` and `cx.path_sym` These are especially useful for constructing types and paths referring to primitives. --- .../rustc_builtin_macros/src/alloc_error_handler.rs | 3 +-- compiler/rustc_builtin_macros/src/assert/context.rs | 2 +- .../src/deriving/coerce_pointee.rs | 2 +- .../rustc_builtin_macros/src/deriving/generic/mod.rs | 3 +-- compiler/rustc_builtin_macros/src/deriving/hash.rs | 6 ++---- .../rustc_builtin_macros/src/deriving/partial_eq.rs | 4 ++-- compiler/rustc_builtin_macros/src/env.rs | 2 +- compiler/rustc_builtin_macros/src/global_allocator.rs | 9 +++------ compiler/rustc_expand/src/build.rs | 11 ++++++++--- 9 files changed, 20 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 1272970a81be9..42d297bbd45c4 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -61,8 +61,7 @@ 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 ty_usize = cx.ty_sym(span, sym::usize); let size = Ident::new(sym::size, span); let align = Ident::new(sym::align, span); diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 11c97da0db5ad..a81f9b0c96b2c 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -99,7 +99,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, diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 7d0db12a450d6..510c8c04acfc7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -119,7 +119,7 @@ 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)); diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index fbbadce3a8816..ac11153dde178 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -736,8 +736,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( diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index db0e8efc99f3c..2ddf007bb8b97 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -15,13 +15,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 { diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index 180800aa72025..f0a123ec93e85 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -1,6 +1,6 @@ use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, Mutability, Safety}; 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::generic::*; @@ -42,7 +42,7 @@ 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), diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index cced54e3cb534..e96159ee96442 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -57,7 +57,7 @@ pub(crate) fn expand_option_env<'cx>( cx.std_path(&[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, ))], diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index fada1c477ac88..557fe3a6c12eb 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -134,8 +134,7 @@ impl AllocFnFactory<'_, '_> { 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); + let ty_usize = self.usize(); args.push(self.cx.param(self.span, size, ty_usize)); let ty_align = self.ptr_alignment(); args.push(self.cx.param(self.span, align, ty_align)); @@ -183,8 +182,7 @@ 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 { @@ -194,8 +192,7 @@ impl AllocFnFactory<'_, '_> { } 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_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 2a4089b1213ab..e3f1a4bbc35d7 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -26,6 +26,9 @@ impl<'a> ExtCtxt<'a> { pub fn path_ident(&self, span: Span, id: Ident) -> ast::Path { self.path(span, vec![id]) } + pub fn path_sym(&self, span: Span, name: Symbol) -> ast::Path { + ast::Path::from_ident(Ident::new(name, span)) + } pub fn path_global(&self, span: Span, strs: Vec) -> ast::Path { self.path_all(span, true, strs, vec![]) } @@ -89,12 +92,14 @@ impl<'a> ExtCtxt<'a> { 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 +140,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) From 79f6e3b45a7d996ab5b9a87d0ceed15975fab110 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sun, 4 Oct 2026 09:55:14 +0000 Subject: [PATCH 03/18] `cx.param` only needs a `Symbol` --- .../src/alloc_error_handler.rs | 9 ++++---- compiler/rustc_builtin_macros/src/autodiff.rs | 4 +--- .../src/deriving/generic/mod.rs | 3 +-- .../src/global_allocator.rs | 22 +++++++++---------- compiler/rustc_builtin_macros/src/test.rs | 5 ++--- compiler/rustc_expand/src/build.rs | 6 ++--- compiler/rustc_span/src/symbol.rs | 1 + 7 files changed, 23 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 42d297bbd45c4..2ec7d09f25399 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -62,21 +62,22 @@ pub(crate) fn expand( // } fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt { let ty_usize = cx.ty_sym(span, sym::usize); - let size = Ident::new(sym::size, span); - let align = Ident::new(sym::align, span); 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 = 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 }; diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 21f424836e476..1c5d4fea1961d 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -764,9 +764,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); } _ => {} diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index ac11153dde178..b9d4d35baf190 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -839,8 +839,7 @@ impl<'a> MethodDef<'a> { .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) + cx.param(span, *name, ast_ty) })) .collect(); diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 557fe3a6c12eb..7f45b5a906b1c 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -131,13 +131,11 @@ 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 ty_usize = self.usize(); - args.push(self.cx.param(self.span, size, ty_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)); + args.push(self.cx.param(self.span, sym::align, ty_align)); let layout_new = self.cx.std_path(&[ sym::alloc, @@ -145,22 +143,22 @@ impl AllocFnFactory<'_, '_> { 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); + 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 => { diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 8e99d532029db..0a9112821da09 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -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")), @@ -213,7 +212,7 @@ pub(crate) fn expand_test_or_bench( cx.expr_call( ret_ty_sp, cx.expr_path(cx.path(sp, vec![fn_.ident])), - thin_vec![cx.expr_ident(sp, bencher_param)], + thin_vec![cx.expr_ident_sym(sp, bencher_param)], ), ], ), diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index e3f1a4bbc35d7..0ac83b82dbac9 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -568,7 +568,7 @@ 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(), ast::FnRetTy::Default(span), @@ -596,8 +596,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_sym(span, name)); ast::Param { attrs: AttrVec::default(), id: ast::DUMMY_NODE_ID, 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, From 928f03eff621167cbbcf3e306cf126189ba39d34 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sun, 4 Oct 2026 15:03:21 +0000 Subject: [PATCH 04/18] `cx.pat_ident` only needs a `Symbol` --- .../src/assert/context.rs | 8 ++++---- compiler/rustc_builtin_macros/src/autodiff.rs | 8 ++++---- .../src/deriving/debug.rs | 4 ++-- .../src/deriving/generic/mod.rs | 5 ++--- .../src/deriving/partial_ord.rs | 7 +++---- compiler/rustc_expand/src/build.rs | 20 +++++++++---------- 6 files changed, 25 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index a81f9b0c96b2c..25068bee62641 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -348,7 +348,7 @@ impl<'cx, 'a> Context<'cx, 'a> { 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 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 +366,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, @@ -378,7 +378,7 @@ impl<'cx, 'a> Context<'cx, 'a> { 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))], + thin_vec![self.cx.expr_path(self.cx.path_sym(self.span, local_bind))], ); let try_capture_call = self .cx @@ -393,7 +393,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 1c5d4fea1961d..5da9daa1737cc 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -707,8 +707,8 @@ 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 +733,9 @@ 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); } } diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index d8355d733a7f3..d2dc3091f00e1 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -159,7 +159,7 @@ 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), ) @@ -181,7 +181,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), ); diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index b9d4d35baf190..b18d50bb17757 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -1150,9 +1150,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 = mk_pattern_ident(span, prefix, i).name; + (struct_field.ident, cx.pat_ident(struct_field.span.with_ctxt(span.ctxt()), ident)) }); let struct_path = struct_path.clone(); diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index 4ce695a16200f..49ee80fdaba63 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -1,6 +1,6 @@ use rustc_ast::{Expr, ItemKind, Safety, 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::generic::*; @@ -195,9 +195,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]) } }; diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 0ac83b82dbac9..a4f357325bc65 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -231,22 +231,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, @@ -494,17 +494,17 @@ impl<'a> ExtCtxt<'a> { 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 { @@ -597,7 +597,7 @@ impl<'a> ExtCtxt<'a> { } pub fn param(&self, span: Span, name: Symbol, ty: Box) -> ast::Param { - let pat = Box::new(self.pat_ident_sym(span, name)); + let pat = Box::new(self.pat_ident(span, name)); ast::Param { attrs: AttrVec::default(), id: ast::DUMMY_NODE_ID, From 6f7d1027d9d8fd73854701ad1a81c98814ba6a3b Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 28 Sep 2026 11:55:51 +0000 Subject: [PATCH 05/18] uplift `call_intrinsic` to `cx.expr_call_intrinsic` --- .../rustc_builtin_macros/src/assert/context.rs | 5 ++--- compiler/rustc_builtin_macros/src/autodiff.rs | 6 ++---- .../rustc_builtin_macros/src/deriving/mod.rs | 16 ++-------------- compiler/rustc_expand/src/build.rs | 9 +++++++++ 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 25068bee62641..7805f0a1f4ada 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -125,10 +125,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))], ) } diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 5da9daa1737cc..bc6537abc472f 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -562,11 +562,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], ); diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index c4af6ac16bdc6..5c9b5c1ee67a4 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -77,26 +77,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, diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index a4f357325bc65..04f429e3bd345 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -488,6 +488,15 @@ impl<'a> ExtCtxt<'a> { 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(&[sym::intrinsics, intrinsic]), args) + } + pub fn pat(&self, span: Span, kind: PatKind) -> ast::Pat { ast::Pat { id: ast::DUMMY_NODE_ID, kind, span } } From ec8ae84f26458b86734963c77565b41ab6b91784 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 28 Sep 2026 12:46:56 +0000 Subject: [PATCH 06/18] add `cx.item_fn` --- .../src/alloc_error_handler.rs | 16 +++++--------- compiler/rustc_builtin_macros/src/autodiff.rs | 11 +--------- .../src/deriving/generic/mod.rs | 15 +++++-------- .../src/global_allocator.rs | 14 +++++------- compiler/rustc_builtin_macros/src/offload.rs | 22 ++----------------- .../rustc_builtin_macros/src/test_harness.rs | 14 ++---------- compiler/rustc_expand/src/build.rs | 19 ++++++++++++++++ 7 files changed, 39 insertions(+), 72 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 2ec7d09f25399..4690300d8376a 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -1,7 +1,5 @@ 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}; @@ -83,16 +81,12 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span 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/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index bc6537abc472f..e13acdac616d2 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -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))); diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index b18d50bb17757..1bb92676a8b63 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -856,7 +856,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 { @@ -864,16 +863,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, + fn_generics, + Some(body_block), + )), tokens: None, })) } diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 7f45b5a906b1c..2593fe16dd2ac 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -2,7 +2,7 @@ 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, + self as ast, AttrVec, Expr, FnHeader, FnSig, Generics, ItemKind, Mutability, Param, Safety, Stmt, StmtKind, Ty, TyKind, }; use rustc_expand::base::{Annotatable, ExtCtxt}; @@ -84,16 +84,12 @@ 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) } diff --git a/compiler/rustc_builtin_macros/src/offload.rs b/compiler/rustc_builtin_macros/src/offload.rs index 4da4ce4e4a505..c1bc37c986051 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 { @@ -132,16 +123,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/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index d6167d30558a3..9038e69502a99 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -335,24 +335,14 @@ fn add_main(cx: &mut TestCtxt<'_>, c: &mut ast::Crate) { 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], diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 04f429e3bd345..87ea8a3421fb5 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -718,6 +718,25 @@ impl<'a> ExtCtxt<'a> { ) } + 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; From aa58eeb6b0c9a5a4b5c986a9b084e1ca1ed6aeff Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sun, 4 Oct 2026 09:24:24 +0000 Subject: [PATCH 07/18] add `cx.item_const_underscore` --- .../src/alloc_error_handler.rs | 9 +++------ compiler/rustc_builtin_macros/src/eii.rs | 4 +--- .../rustc_builtin_macros/src/global_allocator.rs | 7 ++----- .../src/proc_macro_harness.rs | 16 +++++----------- compiler/rustc_expand/src/build.rs | 9 +++++++++ 5 files changed, 20 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 4690300d8376a..d6af6a682f520 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -1,8 +1,8 @@ use rustc_ast::expand::allocator::{ALLOC_ERROR_HANDLER, global_fn_name}; 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; @@ -40,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 { diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs index ed37599c9e85a..8bce763a953ed 100644 --- a/compiler/rustc_builtin_macros/src/eii.rs +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -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/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 2593fe16dd2ac..ed75dd79141f1 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -6,7 +6,7 @@ use rustc_ast::{ Stmt, StmtKind, Ty, TyKind, }; 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; @@ -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 { diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index ecf4f7e7fb1af..7ceb69201d987 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; @@ -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_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 87ea8a3421fb5..f2492bc9983e6 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -718,6 +718,15 @@ 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, From 67aa421b9aabbe78fe8599ed0c74c57a2c58407d Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sun, 4 Oct 2026 09:49:42 +0000 Subject: [PATCH 08/18] use even more helpers --- compiler/rustc_builtin_macros/src/autodiff.rs | 16 ++++++---------- .../rustc_builtin_macros/src/deriving/clone.rs | 4 ++-- .../rustc_builtin_macros/src/deriving/debug.rs | 10 +++------- .../rustc_builtin_macros/src/global_allocator.rs | 4 ++-- .../src/proc_macro_harness.rs | 2 +- compiler/rustc_builtin_macros/src/test.rs | 2 +- .../rustc_builtin_macros/src/test_harness.rs | 4 ++-- compiler/rustc_expand/src/build.rs | 2 +- 8 files changed, 18 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index e13acdac616d2..843d26be0660e 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; @@ -493,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 @@ -582,8 +582,7 @@ 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, @@ -696,8 +695,7 @@ mod llvm_enzyme { panic!("not an ident?"); }; let name = format!("d{}_{}", old_name, i); - *shadow_arg.pat = - ecx.pat_ident(shadow_arg.pat.span, Symbol::intern(&name)); + *shadow_arg.pat = ecx.pat_ident(shadow_arg.pat.span, Symbol::intern(&name)); d_inputs.push(shadow_arg); } } @@ -723,8 +721,7 @@ mod llvm_enzyme { }; let name = format!("b{}_{}", old_name, i); - *shadow_arg.pat = - ecx.pat_ident(shadow_arg.pat.span, Symbol::intern(&name)); + *shadow_arg.pat = ecx.pat_ident(shadow_arg.pat.span, Symbol::intern(&name)); d_inputs.push(shadow_arg); } } @@ -828,8 +825,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..add8390fa4ae4 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -1,7 +1,7 @@ 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::*; @@ -138,7 +138,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, diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index d2dc3091f00e1..23eaac1ad8537 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -33,7 +33,7 @@ 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)], @@ -53,10 +53,6 @@ pub(crate) fn expand_deriving_debug( trait_def.expand(cx, item, push) } -fn formatter_ident(cx: &ExtCtxt<'_>, span: Span) -> Box { - cx.expr_ident_sym(span, sym::character('f')) -} - fn show_substructure( cx: &ExtCtxt<'_>, span: Span, @@ -76,7 +72,7 @@ fn show_substructure( }; 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 { @@ -232,7 +228,7 @@ 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() diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index ed75dd79141f1..398c984b9a095 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -3,7 +3,7 @@ use rustc_ast::expand::allocator::{ }; use rustc_ast::{ self as ast, AttrVec, Expr, FnHeader, FnSig, Generics, ItemKind, Mutability, Param, Safety, - Stmt, StmtKind, Ty, TyKind, + Stmt, StmtKind, Ty, }; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::{Ident, Span, Symbol, sym}; @@ -164,7 +164,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") diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 7ceb69201d987..0f3e89df87c1b 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -299,7 +299,7 @@ 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()), diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 0a9112821da09..ddc8651042e3d 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -271,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 9038e69502a99..068ce86387d5a 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -325,10 +325,10 @@ fn add_main(cx: &mut TestCtxt<'_>, c: &mut ast::Crate) { 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))) + 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]); diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index f2492bc9983e6..3e00a6a9f78b1 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -579,7 +579,7 @@ impl<'a> ExtCtxt<'a> { 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), ); From a12ceed199a0cfb579041fa60d8b64ff1a4cc640 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 1 Oct 2026 09:12:53 +0000 Subject: [PATCH 09/18] use `feature(default_field_values)` for `TraitDef` --- compiler/rustc_builtin_macros/src/deriving/clone.rs | 6 ++---- .../rustc_builtin_macros/src/deriving/const_param_ty.rs | 5 +---- compiler/rustc_builtin_macros/src/deriving/copy.rs | 5 +---- compiler/rustc_builtin_macros/src/deriving/debug.rs | 6 ++---- compiler/rustc_builtin_macros/src/deriving/default.rs | 5 ++--- compiler/rustc_builtin_macros/src/deriving/eq.rs | 6 ++---- compiler/rustc_builtin_macros/src/deriving/from.rs | 5 ++--- .../rustc_builtin_macros/src/deriving/generic/mod.rs | 6 +++--- compiler/rustc_builtin_macros/src/deriving/hash.rs | 6 ++---- compiler/rustc_builtin_macros/src/deriving/ord.rs | 5 +---- compiler/rustc_builtin_macros/src/deriving/partial_eq.rs | 9 +++------ .../rustc_builtin_macros/src/deriving/partial_ord.rs | 6 ++---- compiler/rustc_builtin_macros/src/lib.rs | 1 + 13 files changed, 24 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index add8390fa4ae4..b33615d32335a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -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) 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..7b03dd5e63e50 100644 --- a/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs @@ -1,4 +1,3 @@ -use rustc_ast::Safety; use rustc_expand::base::ExtCtxt; use rustc_span::Span; @@ -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..604ece8713291 100644 --- a/compiler/rustc_builtin_macros/src/deriving/copy.rs +++ b/compiler/rustc_builtin_macros/src/deriving/copy.rs @@ -1,4 +1,3 @@ -use rustc_ast::Safety; use rustc_expand::base::ExtCtxt; use rustc_span::Span; @@ -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 23eaac1ad8537..23f9b0e0b7ece 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -1,4 +1,4 @@ -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}; @@ -25,7 +25,6 @@ pub(crate) fn expand_deriving_debug( 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, @@ -47,8 +46,7 @@ pub(crate) fn expand_deriving_debug( )), }], is_const, - safety: Safety::Default, - document: true, + .. }; trait_def.expand(cx, item, push) } diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 268153c1cbb31..d102fe3ab326c 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -1,7 +1,7 @@ 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; @@ -51,8 +51,7 @@ pub(crate) fn expand_deriving_default( }), }], is_const, - safety: Safety::Default, - document: true, + .. }; trait_def.expand(cx, item, push) } diff --git a/compiler/rustc_builtin_macros/src/deriving/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs index 27be8a8cb6dff..fde40c723176f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/eq.rs @@ -1,4 +1,4 @@ -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}; @@ -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, @@ -41,8 +40,7 @@ pub(crate) fn expand_deriving_eq( combine_substructure: combine_substructure(cs_total_eq_assert), }], is_const, - safety: Safety::Default, - document: true, + .. }; trait_def.expand_ext(cx, item, push, true) } diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index edd1cf75488fc..d1bd32dd3bfc3 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -1,5 +1,5 @@ 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_span::{Ident, Span, kw, sym}; @@ -116,8 +116,7 @@ pub(crate) fn expand_deriving_from( }), }], is_const, - safety: Safety::Default, - document: true, + .. }; from_trait_def.expand(cx, item, push); diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 1bb92676a8b63..d8923095c899e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -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, @@ -219,10 +219,10 @@ pub(crate) struct TraitDef<'a> { 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> { diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 2ddf007bb8b97..b0363d9181f96 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -1,4 +1,4 @@ -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}; @@ -31,7 +31,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, @@ -47,8 +46,7 @@ pub(crate) fn expand_deriving_hash( combine_substructure: combine_substructure(hash_substructure), }], is_const, - safety: Safety::Default, - document: true, + .. }; hash_trait_def.expand(cx, item, push); diff --git a/compiler/rustc_builtin_macros/src/deriving/ord.rs b/compiler/rustc_builtin_macros/src/deriving/ord.rs index c20bfc81bd409..6f86216daa80f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/ord.rs @@ -1,4 +1,3 @@ -use rustc_ast::Safety; use rustc_expand::base::ExtCtxt; use rustc_span::{Span, sym}; use thin_vec::thin_vec; @@ -19,7 +18,6 @@ pub(crate) fn expand_deriving_ord( 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, @@ -40,8 +38,7 @@ pub(crate) fn expand_deriving_ord( )), }], is_const, - safety: Safety::Default, - document: true, + .. }; trait_def.expand(cx, item, push) diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index f0a123ec93e85..67db876a65e6c 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -1,4 +1,4 @@ -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::{Span, kw, sym}; use thin_vec::thin_vec; @@ -29,8 +29,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); @@ -51,14 +50,12 @@ pub(crate) fn expand_deriving_partial_eq( 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 49ee80fdaba63..978fc9aa04344 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -1,4 +1,4 @@ -use rustc_ast::{Expr, ItemKind, Safety, ast}; +use rustc_ast::{Expr, ItemKind, ast}; use rustc_expand::base::ExtCtxt; use rustc_span::{Span, kw, sym}; use thin_vec::thin_vec; @@ -64,14 +64,12 @@ pub(crate) fn expand_deriving_partial_ord( 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) } diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 03c1653458aa1..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)] From 2022888564a954f36310d7339f9f2628566f4f49 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 24 Sep 2026 18:26:40 +0000 Subject: [PATCH 10/18] remove `AllFieldlessEnum` It is only used in one place and it's easier to do the check directly in `debug.rs`. --- .../rustc_builtin_macros/src/deriving/debug.rs | 14 ++++++++++---- .../src/deriving/generic/mod.rs | 17 ----------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 23f9b0e0b7ece..a95b80b504ea3 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -22,6 +22,13 @@ 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), @@ -36,8 +43,7 @@ pub(crate) fn expand_deriving_debug( 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, + fieldless_variants_strategy: FieldlessVariantsStrategy::Default, combine_substructure: combine_substructure(|cx, span, substr| show_substructure( cx, span, @@ -48,7 +54,7 @@ pub(crate) fn expand_deriving_debug( is_const, .. }; - trait_def.expand(cx, item, push) + trait_def.expand_ext(cx, item, push, all_fieldless); } fn show_substructure( @@ -65,7 +71,7 @@ fn show_substructure( 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)`"), }; diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index d8923095c899e..dd93f099f11fd 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -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. @@ -294,11 +290,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. @@ -1006,14 +997,6 @@ impl<'a> MethodDef<'a> { type_ident, ); } - FieldlessVariantsStrategy::SpecializeIfAllVariantsFieldless => { - return self.call_substructure_method( - cx, - span, - AllFieldlessEnum(enum_def), - type_ident, - ); - } FieldlessVariantsStrategy::Default => (), } } else if let [variant] = variants.as_slice() { From d5726d36d96d6b31a211c406e86fa18373cb4004 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 24 Sep 2026 18:27:04 +0000 Subject: [PATCH 11/18] inline some code Several small changes to remove some unhelpful helpers. --- .../src/deriving/generic/mod.rs | 116 +++++++----------- 1 file changed, 43 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index dd93f099f11fd..ba1a6b6e67ba3 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -183,12 +183,12 @@ 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, + 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}; @@ -792,19 +792,6 @@ impl<'a> MethodDef<'a> { !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<'_>, @@ -815,23 +802,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(); - cx.param(span, *name, 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() { @@ -857,7 +837,7 @@ impl<'a> MethodDef<'a> { kind: ast::AssocItemKind::Fn(cx.item_fn( sig, method_ident, - fn_generics, + self.generics.clone(), Some(body_block), )), tokens: None, @@ -907,10 +887,15 @@ impl<'a> MethodDef<'a> { is_packed: bool, type_ident: Ident, ) -> 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); + 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) } @@ -958,10 +943,6 @@ impl<'a> MethodDef<'a> { ) -> 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. @@ -972,14 +953,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()); @@ -1011,6 +984,13 @@ impl<'a> MethodDef<'a> { } } + // 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 @@ -1046,9 +1026,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), type_ident) .into_expr(cx, span); cx.arm(span, single_pat, arm_expr) @@ -1070,7 +1049,7 @@ impl<'a> MethodDef<'a> { .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. @@ -1085,33 +1064,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)), type_ident) } else { - BlockOrExpr(ThinVec::new(), Some(get_match_expr(selflike_args))) + BlockOrExpr(ThinVec::new(), Some(match_expr)) } } } @@ -1128,7 +1105,7 @@ 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).name; + let ident = Symbol::intern(&format!("{prefix}_{i}")); (struct_field.ident, cx.pat_ident(struct_field.span.with_ctxt(span.ctxt()), ident)) }); @@ -1184,10 +1161,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<'_>, @@ -1197,10 +1170,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() }) } @@ -1224,9 +1194,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 { From 1cd10d973a3d10b07f40fa1dbe9ec9c96e840b23 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 28 Sep 2026 14:05:03 +0000 Subject: [PATCH 12/18] remove distinction between global and local paths As I understand it, this would only be needed if the crate defining the derive macros (which is `core`) was using edition 2015. Since `core` uses edition 2024, there is in this case no difference between global and local and we can skip the leading `::`. --- compiler/rustc_builtin_macros/src/autodiff.rs | 2 +- .../src/deriving/coerce_pointee.rs | 6 +++--- .../rustc_builtin_macros/src/deriving/debug.rs | 2 +- .../src/deriving/generic/mod.rs | 3 +-- .../rustc_builtin_macros/src/deriving/hash.rs | 2 +- .../rustc_builtin_macros/src/deriving/mod.rs | 4 ++-- .../src/deriving/partial_ord.rs | 2 +- .../src/deriving/reborrow.rs | 2 +- compiler/rustc_builtin_macros/src/env.rs | 1 - compiler/rustc_builtin_macros/src/offload.rs | 5 +---- compiler/rustc_expand/src/build.rs | 18 +++++------------- 11 files changed, 17 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 843d26be0660e..770c8c9ddfcf8 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -591,7 +591,7 @@ mod llvm_enzyme { 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 path = ecx.path_all(span, idents, generic_args); ecx.expr_path(path) } diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 510c8c04acfc7..ef265b50cf1a7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -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, vec![name_ident], self_params.clone()); let self_type = cx.ty_path(path); // Declare helper function that adds implementation blocks. @@ -122,7 +122,7 @@ pub(crate) fn expand_deriving_coerce_pointee( 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, vec![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.path_all(span, cx.std_path(&[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)); diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index a95b80b504ea3..df936f7bb47bf 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -166,7 +166,7 @@ fn show_substructure( }); // `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 = cx.path(span, cx.std_path(&[sym::fmt, sym::Debug])); let ty_dyn_debug = cx.ty( span, ast::TyKind::TraitObject( diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index ba1a6b6e67ba3..211599d20f5db 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -717,8 +717,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), vec![type_ident], self_params); let self_type = cx.ty_path(path); let mut attrs = thin_vec![cx.attr_word(sym::automatically_derived, self.span),]; diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index b0363d9181f96..2a51a0de56fc1 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -55,7 +55,7 @@ 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 hash_path = cx.expr_path(cx.path(span, 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 5c9b5c1ee67a4..0e2c2dd4e312e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -102,7 +102,7 @@ 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.path_all(span, cx.std_path(assert_path), vec![GenericArg::Type(ty)]); stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path))); } @@ -111,5 +111,5 @@ fn new_path(cx: &ExtCtxt<'_>, span: Span, path: &[Symbol], params: Vec && `. diff --git a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs index 05ad76dbd1ff9..36e22fbe652da 100644 --- a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs +++ b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs @@ -113,7 +113,7 @@ fn push_marker_impl( 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, vec![ident], self_params)); push(cx.item_trait_impl( span, diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index e96159ee96442..96ed08a68cf4f 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -53,7 +53,6 @@ pub(crate) fn expand_option_env<'cx>( let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp)); cx.expr_path(cx.path_all( sp, - true, cx.std_path(&[sym::option, sym::Option, sym::None]), vec![GenericArg::Type(cx.ty_ref( sp, diff --git a/compiler/rustc_builtin_macros/src/offload.rs b/compiler/rustc_builtin_macros/src/offload.rs index c1bc37c986051..5e26cb1182cd7 100644 --- a/compiler/rustc_builtin_macros/src/offload.rs +++ b/compiler/rustc_builtin_macros/src/offload.rs @@ -111,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.path(span, [sym::core, sym::unimplemented].map(|s| Ident::new(s, span)).to_vec()), Delimiter::Parenthesis, TokenStream::default(), ), diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 3e00a6a9f78b1..e863e40c2cdc3 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -21,7 +21,7 @@ impl<'a> ExtCtxt<'a> { } pub fn path(&self, span: Span, strs: Vec) -> ast::Path { - self.path_all(span, false, strs, vec![]) + self.path_all(span, strs, vec![]) } pub fn path_ident(&self, span: Span, id: Ident) -> ast::Path { self.path(span, vec![id]) @@ -29,22 +29,14 @@ impl<'a> ExtCtxt<'a> { pub fn path_sym(&self, span: Span, name: Symbol) -> ast::Path { ast::Path::from_ident(Ident::new(name, span)) } - pub fn path_global(&self, span: Span, strs: Vec) -> ast::Path { - self.path_all(span, true, strs, vec![]) - } pub fn path_all( &self, span: Span, - global: bool, mut idents: Vec, 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 mut segments = ThinVec::with_capacity(idents.len()); let last_ident = idents.pop().unwrap(); segments.extend( idents.into_iter().map(|ident| ast::PathSegment::from_ident(ident.with_span_pos(span))), @@ -391,7 +383,7 @@ impl<'a> ExtCtxt<'a> { fn_path: Vec, args: ThinVec>, ) -> Box { - let pathexpr = self.expr_path(self.path_global(sp, fn_path)); + let pathexpr = self.expr_path(self.path(sp, fn_path)); self.expr_call(sp, pathexpr, args) } pub fn expr_block(&self, b: Box) -> Box { @@ -477,7 +469,7 @@ impl<'a> ExtCtxt<'a> { 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)) + self.expr_path(self.path(sp, none)) } pub fn expr_tuple(&self, sp: Span, exprs: ThinVec>) -> Box { self.expr(sp, ast::ExprKind::Tup(exprs)) @@ -541,7 +533,7 @@ 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); + let path = self.path(span, some); self.pat_tuple_struct(span, path, thin_vec![pat]) } From 214fd615bb6241d98e3622cd7951e38a10ab64d8 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 2 Oct 2026 09:30:32 +0000 Subject: [PATCH 13/18] remove the intermediate `Vec` in `Path` construction Previously, `std_path` converted the given `&[Symbol]` to a `Vec` by prepending a `$crate::` and mapping each `Symbol` to an `Ident`. This commit changes the functions that previously took `Vec` to directly take `Path` instead, and updates `std_path` to also directly return a `Path`. This allows directly prepending the `$crate::` to the resulting `segments`. It also allows constructing a `Path` from `&[Ident]` instead of `Vec`. --- .../src/alloc_error_handler.rs | 4 +- compiler/rustc_builtin_macros/src/assert.rs | 4 +- .../src/assert/context.rs | 14 +-- compiler/rustc_builtin_macros/src/autodiff.rs | 3 +- .../src/deriving/clone.rs | 11 +- .../src/deriving/coerce_pointee.rs | 6 +- .../src/deriving/debug.rs | 14 +-- .../src/deriving/default.rs | 9 +- .../src/deriving/generic/mod.rs | 6 +- .../rustc_builtin_macros/src/deriving/hash.rs | 4 +- .../rustc_builtin_macros/src/deriving/mod.rs | 11 +- .../src/deriving/partial_ord.rs | 13 +- .../src/deriving/reborrow.rs | 2 +- .../rustc_builtin_macros/src/edition_panic.rs | 7 +- compiler/rustc_builtin_macros/src/eii.rs | 2 +- compiler/rustc_builtin_macros/src/env.rs | 6 +- .../src/global_allocator.rs | 18 ++- compiler/rustc_builtin_macros/src/offload.rs | 2 +- .../src/proc_macro_harness.rs | 4 +- .../src/standard_library_imports.rs | 4 +- compiler/rustc_builtin_macros/src/test.rs | 10 +- .../rustc_builtin_macros/src/test_harness.rs | 6 +- compiler/rustc_expand/src/build.rs | 112 ++++++++++-------- 23 files changed, 131 insertions(+), 141 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index d6af6a682f520..42fcb73fba0ba 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -58,8 +58,8 @@ pub(crate) fn expand( fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt { 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 = cx.std_path(span, &[sym::alloc, sym::Layout, sym::from_size_align_unchecked]); + let layout_new = cx.expr_path(layout_new); let layout = cx.expr_call( span, layout_new, diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index f5a582ddffcc5..0935153f9fae3 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -34,7 +34,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])) + cx.std_path(call_site_span, &[sym::panic, sym::panic_2021]) } else { // Before edition 2021, we call `panic!()` unqualified, // such that it calls either `std::panic!()` or `core::panic!()`. @@ -64,7 +64,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]), + cx.std_path(call_site_span, &[sym::panicking, sym::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 7805f0a1f4ada..4d65b7852a25d 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -110,7 +110,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: self.cx.std_path(self.span, &[sym::asserting]), kind: UseTreeKind::Nested { items: thin_vec![ nested_tree(self, sym::TryCaptureGeneric), @@ -341,12 +341,8 @@ 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 init_std_path = self.cx.std_path(self.span, &[sym::asserting, sym::Capture, sym::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); @@ -374,9 +370,7 @@ 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])), - ), + self.cx.expr_path(self.cx.std_path(self.span, &[sym::asserting, sym::Wrapper])), thin_vec![self.cx.expr_path(self.cx.path_sym(self.span, local_bind))], ); let try_capture_call = self diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 770c8c9ddfcf8..2ea6b74d5fdaf 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -589,8 +589,7 @@ mod llvm_enzyme { }) .collect::>(); - let idents = - if is_impl { vec![Ident::new(kw::SelfUpper, span), ident] } else { vec![ident] }; + 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) diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index b33615d32335a..854f56d86bdf0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -161,10 +161,13 @@ 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, + cx.std_path(field.span, &[sym::clone, sym::Clone, sym::clone]), + args, + ) }; let ctor_path; @@ -172,12 +175,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 ef265b50cf1a7..56187859db6ec 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -81,7 +81,7 @@ pub(crate) fn expand_deriving_coerce_pointee( }; // Create the type of `self`. - let path = cx.path_all(span, 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. @@ -122,7 +122,7 @@ pub(crate) fn expand_deriving_coerce_pointee( 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, 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, 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)); diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index df936f7bb47bf..137aa5f5f531e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -80,7 +80,7 @@ fn show_substructure( // 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 = cx.std_path(span, &[sym::fmt, sym::Formatter, sym::write_str]); let expr = cx.expr_call_global(span, fn_path_write_str, thin_vec![fmt, name]); return BlockOrExpr::new_expr(expr); } @@ -113,7 +113,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 = cx.std_path(span, &[sym::fmt, sym::Formatter, sym::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 +123,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]); @@ -166,7 +166,7 @@ fn show_substructure( }); // `let values: &[&dyn Debug] = &[&&self.field1, &&self.field2];` - let path_debug = cx.path(span, cx.std_path(&[sym::fmt, sym::Debug])); + let path_debug = cx.std_path(span, &[sym::fmt, sym::Debug]); let ty_dyn_debug = cx.ty( span, ast::TyKind::TraitObject( @@ -193,7 +193,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); @@ -237,7 +237,7 @@ fn show_fieldless_enum( .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 +253,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 = cx.std_path(span, &[sym::fmt, sym::Formatter, sym::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 d102fe3ab326c..cea92276ea178 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -58,7 +58,7 @@ pub(crate) fn expand_deriving_default( 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()) } @@ -117,7 +117,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 @@ -142,10 +142,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/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 211599d20f5db..42fb2a89489fe 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -175,7 +175,6 @@ //! ``` use std::ops::Not; -use std::vec; pub(crate) use SubstructureFields::*; pub(crate) use rustc_ast as ast; @@ -717,7 +716,7 @@ impl<'a> TraitDef<'a> { .collect(); // Create the type of `self`. - let path = cx.path_all(type_ident.span.with_ctxt(ctxt), 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),]; @@ -1005,8 +1004,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); diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 2a51a0de56fc1..552bd205c9e59 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -54,8 +54,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(span, strs)); + let strs = cx.std_path(span, &[sym::hash, sym::Hash, sym::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 0e2c2dd4e312e..8188577c3bee9 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -1,11 +1,9 @@ //! 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)::+) {{ @@ -102,14 +100,11 @@ fn assert_ty_bounds( ) { // Generate statement `let _: assert_path;`. let span = cx.with_def_site_ctxt(span); - let assert_path = cx.path_all(span, 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, idents, params) + cx.std_path_all(span, path, params) } diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index ae0f92ed32f29..e091a116f3462 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -101,7 +101,7 @@ 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 = cx.std_path(span, &[sym::cmp, sym::Ord, sym::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)) @@ -139,11 +139,11 @@ pub(crate) fn cmp_body( ) -> Box { 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(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal])); + let equal_path = cx.std_path(span, &[sym::cmp, sym::Ordering, sym::Equal]); // The combination of two field expressions. E.g. for `Ord::cmp` this // is something like ` && `. @@ -207,7 +207,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), @@ -227,7 +228,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 36e22fbe652da..ed5d9c2dbd09b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs +++ b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs @@ -113,7 +113,7 @@ fn push_marker_impl( 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, 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 8bce763a953ed..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], )), }); diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index 96ed08a68cf4f..ccdebaa88a843 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -51,9 +51,9 @@ 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, - cx.std_path(&[sym::option, sym::Option, sym::None]), + &[sym::option, sym::Option, sym::None], vec![GenericArg::Type(cx.ty_ref( sp, cx.ty_sym(sp, sym::str), @@ -69,7 +69,7 @@ pub(crate) fn expand_option_env<'cx>( } Ok(value) => cx.expr_call_global( sp, - cx.std_path(&[sym::option, sym::Option, sym::Some]), + cx.std_path(sp, &[sym::option, sym::Option, sym::Some]), thin_vec![cx.expr_str(sp, value)], ), }; diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index 398c984b9a095..4428cf8dddd76 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -92,8 +92,8 @@ impl AllocFnFactory<'_, '_> { } 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); @@ -130,12 +130,11 @@ impl AllocFnFactory<'_, '_> { let ty_align = self.ptr_alignment(); args.push(self.cx.param(self.span, sym::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 layout_new = self.cx.std_path( + self.span, + &[sym::alloc, sym::Layout, sym::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]); @@ -177,8 +176,7 @@ impl AllocFnFactory<'_, '_> { } 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 = self.cx.std_path(self.span, &[sym::mem, sym::Alignment]); self.cx.ty_path(path) } diff --git a/compiler/rustc_builtin_macros/src/offload.rs b/compiler/rustc_builtin_macros/src/offload.rs index 5e26cb1182cd7..67eb690725a69 100644 --- a/compiler/rustc_builtin_macros/src/offload.rs +++ b/compiler/rustc_builtin_macros/src/offload.rs @@ -111,7 +111,7 @@ pub(crate) fn expand_kernel( span, ecx.macro_call( span, - ecx.path(span, [sym::core, sym::unimplemented].map(|s| Ident::new(s, span)).to_vec()), + ecx.path(span, &[Ident::new(sym::core, span), Ident::new(sym::unimplemented, span)]), Delimiter::Parenthesis, TokenStream::default(), ), diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 0f3e89df87c1b..5f40231c7f67c 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -303,7 +303,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> Box { 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, 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 ddc8651042e3d..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)], ) }; @@ -211,7 +211,7 @@ 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])), + cx.expr_path(cx.path_ident(sp, fn_.ident)), thin_vec![cx.expr_ident_sym(sp, bencher_param)], ), ], @@ -237,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(), ), // ) ], diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 068ce86387d5a..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,7 +324,7 @@ 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)]; + 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 `()`. @@ -379,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_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index e863e40c2cdc3..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,52 +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 { + 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_sym(&self, span: Span, name: Symbol) -> ast::Path { - ast::Path::from_ident(Ident::new(name, span)) + + pub fn path_sym(&self, span: Span, name: Symbol) -> Path { + Path::from_ident(Ident::new(name, span)) } - pub fn path_all( - &self, - span: Span, - mut idents: Vec, - args: Vec, - ) -> ast::Path { - assert!(!idents.is_empty()); + + pub fn path_all(&self, span: Span, idents: &[Ident], args: Vec) -> Path { let mut segments = ThinVec::with_capacity(idents.len()); - let last_ident = idents.pop().unwrap(); + let (last, rest) = idents.split_last().expect("cannot construct empty path"); segments.extend( - idents.into_iter().map(|ident| ast::PathSegment::from_ident(ident.with_span_pos(span))), + 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, + mut segments: ThinVec, + last: Ident, + args: Vec, + ) -> 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 { @@ -80,7 +96,7 @@ 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)) } @@ -185,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 { @@ -207,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)) } @@ -302,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)) } @@ -380,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(sp, fn_path)); + let pathexpr = self.expr_path(fn_path); self.expr_call(sp, pathexpr, args) } pub fn expr_block(&self, b: Box) -> Box { @@ -403,7 +419,7 @@ impl<'a> ExtCtxt<'a> { pub fn expr_struct( &self, span: Span, - path: ast::Path, + path: Path, fields: ThinVec, ) -> Box { self.expr( @@ -463,20 +479,20 @@ 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(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]) } @@ -486,7 +502,7 @@ impl<'a> ExtCtxt<'a> { intrinsic: Symbol, args: ThinVec>, ) -> Box { - self.expr_call_global(span, self.std_path(&[sym::intrinsics, intrinsic]), args) + self.expr_call_global(span, self.std_path(span, &[sym::intrinsics, intrinsic]), args) } pub fn pat(&self, span: Span, kind: PatKind) -> ast::Pat { @@ -508,21 +524,16 @@ impl<'a> ExtCtxt<'a> { 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)) @@ -532,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(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 { From 6c946d30328ff9e7ca44972ad07b84f7064c125d Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 2 Oct 2026 09:49:23 +0000 Subject: [PATCH 14/18] remove `new_path` `new_path` is just a obsolete trivial wrapper around `cx.std_path_all` now. --- .../src/deriving/coerce_pointee.rs | 6 +++--- .../rustc_builtin_macros/src/deriving/default.rs | 3 +-- .../rustc_builtin_macros/src/deriving/from.rs | 8 ++++++-- compiler/rustc_builtin_macros/src/deriving/mod.rs | 7 +------ .../src/deriving/partial_ord.rs | 8 ++++++-- .../rustc_builtin_macros/src/deriving/reborrow.rs | 15 +++++++++++---- compiler/rustc_builtin_macros/src/offload.rs | 2 +- 7 files changed, 29 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 56187859db6ec..8c20dd9627d15 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -13,7 +13,7 @@ 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::deriving::path_std; use crate::diagnostics; pub(crate) fn expand_deriving_coerce_pointee( @@ -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, @@ -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/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index cea92276ea178..0c5de106f000a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -8,7 +8,6 @@ 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(), diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index d1bd32dd3bfc3..3836c950dbafc 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -6,7 +6,7 @@ use rustc_span::{Ident, Span, kw, sym}; use thin_vec::thin_vec; use crate::deriving::generic::*; -use crate::deriving::{new_path, pathvec}; +use crate::deriving::pathvec; use crate::diagnostics; /// Generate an implementation of the `From` trait, provided that `item` @@ -51,7 +51,11 @@ pub(crate) fn expand_deriving_from( 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, + pathvec!(convert::From), + vec![ast::GenericArg::Type(from_type.clone())], + ); // Generate code like this: // diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 8188577c3bee9..80df66e409016 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -11,7 +11,7 @@ macro pathvec($($rest:ident)::+) {{ }} macro path_std($cx: expr, $span: expr, $($x:tt)*) { - new_path($cx, $span, pathvec!( $($x)* ), vec![] ) + $cx.std_path($span, pathvec!( $($x)* ) ) } pub(crate) mod clone; @@ -103,8 +103,3 @@ fn assert_ty_bounds( 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 params = params.into_iter().map(GenericArg::Type).collect(); - cx.std_path_all(span, path, params) -} diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index e091a116f3462..b1e2bf3e732cf 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -4,7 +4,7 @@ use rustc_span::{Span, kw, sym}; use thin_vec::thin_vec; use crate::deriving::generic::*; -use crate::deriving::{call_discriminant_value, new_path, path_std, pathvec}; +use crate::deriving::{call_discriminant_value, path_std, pathvec}; pub(crate) fn expand_deriving_partial_ord( cx: &ExtCtxt<'_>, @@ -14,7 +14,11 @@ 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])); + let ret_ty = cx.ty_path(cx.std_path_all( + span, + pathvec!(option::Option), + vec![ast::GenericArg::Type(ordering_ty)], + )); // Order in which to perform matching let discr_then_data = discr_data_order(item); diff --git a/compiler/rustc_builtin_macros/src/deriving/reborrow.rs b/compiler/rustc_builtin_macros/src/deriving/reborrow.rs index ed5d9c2dbd09b..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,10 +112,10 @@ 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<_> = diff --git a/compiler/rustc_builtin_macros/src/offload.rs b/compiler/rustc_builtin_macros/src/offload.rs index 67eb690725a69..ef38382c48319 100644 --- a/compiler/rustc_builtin_macros/src/offload.rs +++ b/compiler/rustc_builtin_macros/src/offload.rs @@ -111,7 +111,7 @@ pub(crate) fn expand_kernel( span, ecx.macro_call( span, - ecx.path(span, &[Ident::new(sym::core, span), Ident::new(sym::unimplemented, span)]), + ecx.std_path(span, &[sym::unimplemented]), Delimiter::Parenthesis, TokenStream::default(), ), From 785039a4b8184fc0c7a81a7695a3b76144db6dea Mon Sep 17 00:00:00 2001 From: cyrgani Date: Sat, 3 Oct 2026 17:35:36 +0000 Subject: [PATCH 15/18] utilize `pathvec!` and `path_std!` in the entire crate TODO: is this actually worth it? maybe we should remove the macros entirely instead? --- .../rustc_builtin_macros/src/alloc_error_handler.rs | 4 ++-- compiler/rustc_builtin_macros/src/assert.rs | 5 +++-- compiler/rustc_builtin_macros/src/assert/context.rs | 8 +++++--- compiler/rustc_builtin_macros/src/deriving/clone.rs | 8 ++------ .../src/deriving/coerce_pointee.rs | 2 +- .../src/deriving/const_param_ty.rs | 2 +- compiler/rustc_builtin_macros/src/deriving/copy.rs | 2 +- compiler/rustc_builtin_macros/src/deriving/debug.rs | 10 +++++----- compiler/rustc_builtin_macros/src/deriving/eq.rs | 4 ++-- compiler/rustc_builtin_macros/src/deriving/from.rs | 9 +++------ .../rustc_builtin_macros/src/deriving/generic/mod.rs | 5 +++-- compiler/rustc_builtin_macros/src/deriving/hash.rs | 5 +++-- compiler/rustc_builtin_macros/src/deriving/mod.rs | 8 -------- compiler/rustc_builtin_macros/src/deriving/ord.rs | 2 +- .../rustc_builtin_macros/src/deriving/partial_eq.rs | 3 ++- .../rustc_builtin_macros/src/deriving/partial_ord.rs | 9 +++++---- compiler/rustc_builtin_macros/src/env.rs | 7 +------ compiler/rustc_builtin_macros/src/global_allocator.rs | 10 ++++------ compiler/rustc_builtin_macros/src/util.rs | 10 +++++++++- 19 files changed, 53 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 42fcb73fba0ba..07a4553e76f69 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -5,7 +5,7 @@ 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<'_>, @@ -58,7 +58,7 @@ pub(crate) fn expand( fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt { let ty_usize = cx.ty_sym(span, sym::usize); - let layout_new = cx.std_path(span, &[sym::alloc, sym::Layout, sym::from_size_align_unchecked]); + 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, diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index 0935153f9fae3..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.std_path(call_site_span, &[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(call_site_span, &[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 4d65b7852a25d..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. // @@ -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.std_path(self.span, &[sym::asserting]), + prefix: path_std!(self.cx, self.span, asserting), kind: UseTreeKind::Nested { items: thin_vec![ nested_tree(self, sym::TryCaptureGeneric), @@ -341,7 +343,7 @@ 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(self.span, &[sym::asserting, sym::Capture, sym::new]); + 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); @@ -370,7 +372,7 @@ impl<'cx, 'a> Context<'cx, 'a> { )); let wrapper = self.cx.expr_call( self.span, - self.cx.expr_path(self.cx.std_path(self.span, &[sym::asserting, sym::Wrapper])), + 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 diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 854f56d86bdf0..da23ce9b2da9e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -5,7 +5,7 @@ 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<'_>, @@ -163,11 +163,7 @@ fn cs_clone_simple( fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> BlockOrExpr { let subcall = |field: FieldInfo| { let args = thin_vec![field.self_expr]; - cx.expr_call_global( - field.span, - cx.std_path(field.span, &[sym::clone, sym::Clone, sym::clone]), - args, - ) + cx.expr_call_global(field.span, path_std!(cx, field.span, clone::Clone::clone), args) }; let ctor_path; diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 8c20dd9627d15..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::path_std; use crate::diagnostics; +use crate::util::path_std; pub(crate) fn expand_deriving_coerce_pointee( cx: &ExtCtxt<'_>, 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 7b03dd5e63e50..d11d7f32513db 100644 --- a/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/const_param_ty.rs @@ -2,7 +2,7 @@ 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<'_>, diff --git a/compiler/rustc_builtin_macros/src/deriving/copy.rs b/compiler/rustc_builtin_macros/src/deriving/copy.rs index 604ece8713291..c01723b236e17 100644 --- a/compiler/rustc_builtin_macros/src/deriving/copy.rs +++ b/compiler/rustc_builtin_macros/src/deriving/copy.rs @@ -2,7 +2,7 @@ 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<'_>, diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 137aa5f5f531e..f0c18f5cb687a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -5,7 +5,7 @@ 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<'_>, @@ -80,7 +80,7 @@ fn show_substructure( // Fieldless enums have been special-cased earlier if fmt_detail == FmtDebug::Shallow { - let fn_path_write_str = cx.std_path(span, &[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 +113,7 @@ fn show_substructure( if fields.is_empty() { // Special case for no fields. - let fn_path_write_str = cx.std_path(span, &[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 { @@ -166,7 +166,7 @@ fn show_substructure( }); // `let values: &[&dyn Debug] = &[&&self.field1, &&self.field2];` - let path_debug = cx.std_path(span, &[sym::fmt, sym::Debug]); + let path_debug = path_std!(cx, span, fmt::Debug); let ty_dyn_debug = cx.ty( span, ast::TyKind::TraitObject( @@ -253,6 +253,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(span, &[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/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs index fde40c723176f..cebd187139463 100644 --- a/compiler/rustc_builtin_macros/src/deriving/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/eq.rs @@ -5,7 +5,7 @@ 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<'_>, @@ -64,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 3836c950dbafc..5d975fbb7b984 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -6,8 +6,8 @@ use rustc_span::{Ident, Span, kw, sym}; use thin_vec::thin_vec; use crate::deriving::generic::*; -use crate::deriving::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. @@ -51,11 +51,8 @@ pub(crate) fn expand_deriving_from( Err(guar) => cx.ty(span, ast::TyKind::Err(guar)), }; - let path = cx.std_path_all( - span, - pathvec!(convert::From), - vec![ast::GenericArg::Type(from_type.clone())], - ); + let path = + cx.std_path_all(span, path!(convert::From), vec![ast::GenericArg::Type(from_type.clone())]); // Generate code like this: // diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 42fb2a89489fe..9aca677cef178 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -191,6 +191,7 @@ 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> { @@ -602,7 +603,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 @@ -679,7 +680,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)); } diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 552bd205c9e59..5ef92723dbaa7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -3,8 +3,9 @@ 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<'_>, @@ -54,7 +55,7 @@ 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(span, &[sym::hash, sym::Hash, sym::hash]); + 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)]); diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index 80df66e409016..ecea219338d10 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -6,14 +6,6 @@ use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier}; 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)*) { - $cx.std_path($span, pathvec!( $($x)* ) ) -} - pub(crate) mod clone; pub(crate) mod coerce_pointee; pub(crate) mod const_param_ty; diff --git a/compiler/rustc_builtin_macros/src/deriving/ord.rs b/compiler/rustc_builtin_macros/src/deriving/ord.rs index 6f86216daa80f..36046e9d931ab 100644 --- a/compiler/rustc_builtin_macros/src/deriving/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/ord.rs @@ -4,7 +4,7 @@ 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::util::path_std; pub(crate) fn expand_deriving_ord( cx: &ExtCtxt<'_>, diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index 67db876a65e6c..34e4bf6bf4cd0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -3,8 +3,9 @@ use rustc_expand::base::ExtCtxt; 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. diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index b1e2bf3e732cf..2a3417fb7eb96 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -3,8 +3,9 @@ use rustc_expand::base::ExtCtxt; 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, pathvec}; +use crate::util::{path, path_std}; pub(crate) fn expand_deriving_partial_ord( cx: &ExtCtxt<'_>, @@ -16,7 +17,7 @@ pub(crate) fn expand_deriving_partial_ord( let ordering_ty = cx.ty_path(path_std!(cx, span, cmp::Ordering)); let ret_ty = cx.ty_path(cx.std_path_all( span, - pathvec!(option::Option), + path!(option::Option), vec![ast::GenericArg::Type(ordering_ty)], )); @@ -105,7 +106,7 @@ 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(span, &[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)) @@ -147,7 +148,7 @@ pub(crate) fn cmp_body( } else { [sym::cmp, sym::Ord, sym::cmp] }; - let equal_path = cx.std_path(span, &[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 ` && `. diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index ccdebaa88a843..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}; @@ -67,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(sp, &[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 4428cf8dddd76..c5da0026c2460 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -10,7 +10,7 @@ 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<'_>, @@ -130,10 +130,8 @@ impl AllocFnFactory<'_, '_> { let ty_align = self.ptr_alignment(); args.push(self.cx.param(self.span, sym::align, ty_align)); - let layout_new = self.cx.std_path( - self.span, - &[sym::alloc, sym::Layout, sym::from_size_alignment_unchecked], - ); + 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); @@ -176,7 +174,7 @@ impl AllocFnFactory<'_, '_> { } fn ptr_alignment(&self) -> Box { - let path = self.cx.std_path(self.span, &[sym::mem, sym::Alignment]); + let path = path_std!(self.cx, self.span, mem::Alignment); self.cx.ty_path(path) } 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() }; From 801f25ad8a9fa464c918f43862c1e42dfdaa783e Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 8 Oct 2026 09:00:20 +0000 Subject: [PATCH 16/18] do the `Self` constructor fix properly Passing around `type_ident` everywhere is what the old code did as well, but it's actually only needed in two places. --- .../src/deriving/clone.rs | 23 ++++--- .../src/deriving/debug.rs | 2 +- .../src/deriving/default.rs | 12 ++-- .../rustc_builtin_macros/src/deriving/eq.rs | 2 +- .../rustc_builtin_macros/src/deriving/from.rs | 2 +- .../src/deriving/generic/mod.rs | 62 +++++-------------- .../rustc_builtin_macros/src/deriving/hash.rs | 2 +- .../src/deriving/partial_eq.rs | 2 +- .../src/deriving/partial_ord.rs | 2 +- 9 files changed, 45 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index da23ce9b2da9e..f9489a146332b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -1,7 +1,7 @@ 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, Span, sym}; +use rustc_span::{DUMMY_SP, Ident, Span, sym}; use thin_vec::{ThinVec, thin_vec}; use crate::deriving::generic::*; @@ -45,7 +45,9 @@ pub(crate) fn expand_deriving_clone( substructure = combine_substructure(|c, s, sub| cs_clone_simple(c, s, sub, false)); } else { is_simple = false; - substructure = combine_substructure(cs_clone); + substructure = combine_substructure(|c, s, sub| { + cs_clone(c, s, sub, item.kind.ident().unwrap()) + }); } } ItemKind::Union(..) => { @@ -145,7 +147,7 @@ fn cs_clone_simple( &[sym::clone, sym::AssertParamIsCopy], ); } else { - match substr.fields { + match substr { StaticStruct(vdata, ..) => { process_variant(vdata); } @@ -160,7 +162,12 @@ fn cs_clone_simple( BlockOrExpr::new_mixed(stmts, Some(cx.expr_deref(trait_span, cx.expr_self(trait_span)))) } -fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> BlockOrExpr { +fn cs_clone( + cx: &ExtCtxt<'_>, + trait_span: Span, + substr: Substructure<'_>, + type_ident: Ident, +) -> BlockOrExpr { let subcall = |field: FieldInfo| { let args = thin_vec![field.self_expr]; cx.expr_call_global(field.span, path_std!(cx, field.span, clone::Clone::clone), args) @@ -169,14 +176,16 @@ fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> Blo let ctor_path; let all_fields; let vdata; - match substr.fields { + // We need to use `type_ident` instead of `Self` here, + // see https://github.com/rust-lang/rust/issues/163800 + match substr { Struct(vdata_, af) => { - ctor_path = cx.path(trait_span, &[substr.type_ident]); + ctor_path = cx.path(trait_span, &[type_ident]); all_fields = af; vdata = vdata_; } EnumMatching(.., variant, af) => { - ctor_path = cx.path(trait_span, &[substr.type_ident, variant.ident]); + ctor_path = cx.path(trait_span, &[type_ident, variant.ident]); all_fields = af; vdata = &variant.data; } diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index f0c18f5cb687a..a5cb1d10d88e4 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -68,7 +68,7 @@ fn show_substructure( return BlockOrExpr::new_expr(cx.expr_ok(span, cx.expr_tuple(span, ThinVec::new()))); } - let (ident, vdata, fields) = match substr.fields { + let (ident, vdata, fields) = match substr { Struct(vdata, fields) => (type_ident, vdata, fields), EnumMatching(v, fields) => (v.ident, &v.data, fields), StaticEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, type_ident), diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 0c5de106f000a..316a9d5114f26 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -36,10 +36,14 @@ pub(crate) fn expand_deriving_default( attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: FieldlessVariantsStrategy::Default, combine_substructure: combine_substructure(|cx, trait_span, substr| { - match substr.fields { - StaticStruct(variant_data) => { - default_struct_substructure(cx, trait_span, variant_data, substr.type_ident) - } + match substr { + StaticStruct(variant_data) => default_struct_substructure( + cx, + trait_span, + variant_data, + // We cannot use `Self` here, see https://github.com/rust-lang/rust/issues/163800 + item.kind.ident().unwrap(), + ), StaticEnum(enum_def) => { default_enum_substructure(cx, trait_span, enum_def, item.span) } diff --git a/compiler/rustc_builtin_macros/src/deriving/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs index cebd187139463..aa52d20aa20f0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/eq.rs @@ -70,7 +70,7 @@ fn cs_total_eq_assert(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<' } }; - match substr.fields { + match substr { StaticStruct(vdata, ..) => { process_variant(vdata); } diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index 5d975fbb7b984..f630313df59a4 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -89,7 +89,7 @@ pub(crate) fn expand_deriving_from( }; let self_kw = Ident::new(kw::SelfUpper, span); - let expr: Box = match substructure.fields { + let expr: Box = match substructure { StaticStruct(variant) => match variant { // Self { field: value } VariantData::Struct { .. } => cx.expr_struct_ident( diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 9aca677cef178..2105859295593 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -176,7 +176,7 @@ use std::ops::Not; -pub(crate) use SubstructureFields::*; +pub(crate) use Substructure::*; pub(crate) use rustc_ast as ast; use rustc_ast::token::{IdentKind, LitKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenTree}; @@ -277,16 +277,8 @@ pub(crate) struct FieldInfo { pub maybe_scalar: bool, } -pub(crate) struct Substructure<'a> { - pub fields: SubstructureFields<'a>, - // FIXME: this is currently required to avoid issues with attribute macros after derives, - // such as https://github.com/rust-lang/rust/issues/163800. - // Ideally we would just use `Self` instead. - pub type_ident: Ident, -} - /// A summary of the possible sets of fields. -pub(crate) enum SubstructureFields<'a> { +pub(crate) enum Substructure<'a> { /// A non-static method where `Self` is a struct. Struct(&'a ast::VariantData, Vec), @@ -473,15 +465,9 @@ impl<'a> TraitDef<'a> { let fields = struct_def.fields().iter(); 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, - StaticStruct(struct_def), - *ident, - ) + method_def.call_substructure_method(cx, span, StaticStruct(struct_def)) } 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) }; method_def.create_method(cx, span, body) @@ -499,9 +485,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)) } else { - method_def.expand_enum_method_body(cx, span, enum_def, *ident) + method_def.expand_enum_method_body(cx, span, enum_def) }; method_def.create_method(cx, span, body) @@ -781,10 +767,9 @@ impl<'a> MethodDef<'a> { &self, cx: &ExtCtxt<'_>, span: Span, - fields: SubstructureFields<'_>, - type_ident: Ident, + fields: Substructure<'_>, ) -> BlockOrExpr { - (self.combine_substructure)(cx, span, Substructure { fields, type_ident }) + (self.combine_substructure)(cx, span, fields) } fn is_static(&self) -> bool { @@ -884,7 +869,6 @@ impl<'a> MethodDef<'a> { span: Span, struct_def: &'b VariantData, is_packed: bool, - type_ident: Ident, ) -> BlockOrExpr { let self_expr = cx.expr_self(span); let selflike_args = if self.has_other_selflike_arg { @@ -895,7 +879,7 @@ impl<'a> MethodDef<'a> { 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) + self.call_substructure_method(cx, span, Struct(struct_def, selflike_fields)) } /// ``` @@ -938,7 +922,6 @@ impl<'a> MethodDef<'a> { cx: &ExtCtxt<'_>, span: Span, enum_def: &'b EnumDef, - type_ident: Ident, ) -> BlockOrExpr { let variants = &enum_def.variants; @@ -962,24 +945,14 @@ 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, - ); + return self.call_substructure_method(cx, span, EnumDiscr(None)); } FieldlessVariantsStrategy::Default => (), } } else if let [variant] = variants.as_slice() { // If there is a single variant, we don't need an operation on // the discriminant(s). Just use the most degenerate result. - return self.call_substructure_method( - cx, - span, - EnumMatching(variant, Vec::new()), - type_ident, - ); + return self.call_substructure_method(cx, span, EnumMatching(variant, Vec::new())); } } @@ -1025,7 +998,7 @@ impl<'a> MethodDef<'a> { // Self arg, assuming all are instances of VariantK. // Build up code associated with such a case. let arm_expr = self - .call_substructure_method(cx, span, EnumMatching(variant, fields), type_ident) + .call_substructure_method(cx, span, EnumMatching(variant, fields)) .into_expr(cx, span); cx.arm(span, single_pat, arm_expr) @@ -1038,13 +1011,8 @@ 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())) + .into_expr(cx, span), ) } _ if variants.len() > 1 && self.has_other_selflike_arg => { @@ -1084,7 +1052,7 @@ impl<'a> MethodDef<'a> { // is enough. if unify_fieldless_variants && variants.len() > 1 { // Combine a discriminant check with the match. - self.call_substructure_method(cx, span, EnumDiscr(Some(match_expr)), type_ident) + self.call_substructure_method(cx, span, EnumDiscr(Some(match_expr))) } else { BlockOrExpr(ThinVec::new(), Some(match_expr)) } diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 5ef92723dbaa7..066b3b2aa9124 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -62,7 +62,7 @@ fn hash_substructure(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> cx.stmt_expr(expr) }; - let (stmts, match_expr) = match substr.fields { + let (stmts, match_expr) = match substr { Struct(_, fields) | EnumMatching(.., fields) => { let stmts = fields.into_iter().map(|field| call_hash(field.span, field.self_expr)).collect(); diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index 34e4bf6bf4cd0..d521247c50853 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -117,7 +117,7 @@ fn get_substructure_equality_expr( span: Span, substructure: Substructure<'_>, ) -> BlockOrExpr { - BlockOrExpr::new_expr(match substructure.fields { + BlockOrExpr::new_expr(match substructure { EnumMatching(.., fields) | Struct(.., fields) => { let combine = move |acc, field: &FieldInfo| { let rhs = field diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index 2a3417fb7eb96..be062ef3115a9 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -204,7 +204,7 @@ pub(crate) fn cmp_body( } }; - match substructure.fields { + match substructure { EnumMatching(.., all_fields) | Struct(_, all_fields) => { let op = |old, field: FieldInfo| { // The basic case: a field expression for one or more selflike args. E.g. From 3bc62af775ab6aade6a55c84e981a8556e99c1b2 Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 8 Oct 2026 13:58:55 +0000 Subject: [PATCH 17/18] Revert "do the `Self` constructor fix properly" This reverts commit c28f2fece8497fb2119e17a47188c6ab1dc5da7b. (This revert only exists to make the diff for the next commit clearer and will be removed before merging.) --- .../src/deriving/clone.rs | 23 +++---- .../src/deriving/debug.rs | 2 +- .../src/deriving/default.rs | 12 ++-- .../rustc_builtin_macros/src/deriving/eq.rs | 2 +- .../rustc_builtin_macros/src/deriving/from.rs | 2 +- .../src/deriving/generic/mod.rs | 62 ++++++++++++++----- .../rustc_builtin_macros/src/deriving/hash.rs | 2 +- .../src/deriving/partial_eq.rs | 2 +- .../src/deriving/partial_ord.rs | 2 +- 9 files changed, 64 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index f9489a146332b..da23ce9b2da9e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -1,7 +1,7 @@ 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, sym}; +use rustc_span::{DUMMY_SP, Span, sym}; use thin_vec::{ThinVec, thin_vec}; use crate::deriving::generic::*; @@ -45,9 +45,7 @@ pub(crate) fn expand_deriving_clone( substructure = combine_substructure(|c, s, sub| cs_clone_simple(c, s, sub, false)); } else { is_simple = false; - substructure = combine_substructure(|c, s, sub| { - cs_clone(c, s, sub, item.kind.ident().unwrap()) - }); + substructure = combine_substructure(cs_clone); } } ItemKind::Union(..) => { @@ -147,7 +145,7 @@ fn cs_clone_simple( &[sym::clone, sym::AssertParamIsCopy], ); } else { - match substr { + match substr.fields { StaticStruct(vdata, ..) => { process_variant(vdata); } @@ -162,12 +160,7 @@ fn cs_clone_simple( BlockOrExpr::new_mixed(stmts, Some(cx.expr_deref(trait_span, cx.expr_self(trait_span)))) } -fn cs_clone( - cx: &ExtCtxt<'_>, - trait_span: Span, - substr: Substructure<'_>, - type_ident: Ident, -) -> BlockOrExpr { +fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> BlockOrExpr { let subcall = |field: FieldInfo| { let args = thin_vec![field.self_expr]; cx.expr_call_global(field.span, path_std!(cx, field.span, clone::Clone::clone), args) @@ -176,16 +169,14 @@ fn cs_clone( let ctor_path; let all_fields; let vdata; - // We need to use `type_ident` instead of `Self` here, - // see https://github.com/rust-lang/rust/issues/163800 - match substr { + match substr.fields { Struct(vdata_, af) => { - ctor_path = cx.path(trait_span, &[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, &[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/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index a5cb1d10d88e4..f0c18f5cb687a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -68,7 +68,7 @@ fn show_substructure( return BlockOrExpr::new_expr(cx.expr_ok(span, cx.expr_tuple(span, ThinVec::new()))); } - let (ident, vdata, fields) = match substr { + let (ident, vdata, fields) = match substr.fields { Struct(vdata, fields) => (type_ident, vdata, fields), EnumMatching(v, fields) => (v.ident, &v.data, fields), StaticEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, type_ident), diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 316a9d5114f26..0c5de106f000a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -36,14 +36,10 @@ pub(crate) fn expand_deriving_default( attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: FieldlessVariantsStrategy::Default, combine_substructure: combine_substructure(|cx, trait_span, substr| { - match substr { - StaticStruct(variant_data) => default_struct_substructure( - cx, - trait_span, - variant_data, - // We cannot use `Self` here, see https://github.com/rust-lang/rust/issues/163800 - item.kind.ident().unwrap(), - ), + 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) } diff --git a/compiler/rustc_builtin_macros/src/deriving/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs index aa52d20aa20f0..cebd187139463 100644 --- a/compiler/rustc_builtin_macros/src/deriving/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/eq.rs @@ -70,7 +70,7 @@ fn cs_total_eq_assert(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<' } }; - match substr { + match substr.fields { StaticStruct(vdata, ..) => { process_variant(vdata); } diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index f630313df59a4..5d975fbb7b984 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -89,7 +89,7 @@ pub(crate) fn expand_deriving_from( }; let self_kw = Ident::new(kw::SelfUpper, span); - let expr: Box = match substructure { + let expr: Box = match substructure.fields { StaticStruct(variant) => match variant { // Self { field: value } VariantData::Struct { .. } => cx.expr_struct_ident( diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 2105859295593..9aca677cef178 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -176,7 +176,7 @@ use std::ops::Not; -pub(crate) use Substructure::*; +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}; @@ -277,8 +277,16 @@ pub(crate) struct FieldInfo { pub maybe_scalar: bool, } +pub(crate) struct Substructure<'a> { + pub fields: SubstructureFields<'a>, + // FIXME: this is currently required to avoid issues with attribute macros after derives, + // such as https://github.com/rust-lang/rust/issues/163800. + // Ideally we would just use `Self` instead. + pub type_ident: Ident, +} + /// A summary of the possible sets of fields. -pub(crate) enum Substructure<'a> { +pub(crate) enum SubstructureFields<'a> { /// A non-static method where `Self` is a struct. Struct(&'a ast::VariantData, Vec), @@ -465,9 +473,15 @@ impl<'a> TraitDef<'a> { let fields = struct_def.fields().iter(); 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, StaticStruct(struct_def)) + method_def.call_substructure_method( + cx, + span, + StaticStruct(struct_def), + *ident, + ) } else { - method_def.expand_struct_method_body(cx, span, struct_def, is_packed) + method_def + .expand_struct_method_body(cx, span, struct_def, is_packed, *ident) }; method_def.create_method(cx, span, body) @@ -485,9 +499,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)) + method_def.call_substructure_method(cx, span, StaticEnum(enum_def), *ident) } else { - method_def.expand_enum_method_body(cx, span, enum_def) + method_def.expand_enum_method_body(cx, span, enum_def, *ident) }; method_def.create_method(cx, span, body) @@ -767,9 +781,10 @@ impl<'a> MethodDef<'a> { &self, cx: &ExtCtxt<'_>, span: Span, - fields: Substructure<'_>, + fields: SubstructureFields<'_>, + type_ident: Ident, ) -> BlockOrExpr { - (self.combine_substructure)(cx, span, fields) + (self.combine_substructure)(cx, span, Substructure { fields, type_ident }) } fn is_static(&self) -> bool { @@ -869,6 +884,7 @@ impl<'a> MethodDef<'a> { span: Span, struct_def: &'b VariantData, is_packed: bool, + type_ident: Ident, ) -> BlockOrExpr { let self_expr = cx.expr_self(span); let selflike_args = if self.has_other_selflike_arg { @@ -879,7 +895,7 @@ impl<'a> MethodDef<'a> { 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)) + self.call_substructure_method(cx, span, Struct(struct_def, selflike_fields), type_ident) } /// ``` @@ -922,6 +938,7 @@ impl<'a> MethodDef<'a> { cx: &ExtCtxt<'_>, span: Span, enum_def: &'b EnumDef, + type_ident: Ident, ) -> BlockOrExpr { let variants = &enum_def.variants; @@ -945,14 +962,24 @@ 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)); + return self.call_substructure_method( + cx, + span, + EnumDiscr(None), + type_ident, + ); } FieldlessVariantsStrategy::Default => (), } } else if let [variant] = variants.as_slice() { // If there is a single variant, we don't need an operation on // the discriminant(s). Just use the most degenerate result. - return self.call_substructure_method(cx, span, EnumMatching(variant, Vec::new())); + return self.call_substructure_method( + cx, + span, + EnumMatching(variant, Vec::new()), + type_ident, + ); } } @@ -998,7 +1025,7 @@ impl<'a> MethodDef<'a> { // Self arg, assuming all are instances of VariantK. // Build up code associated with such a case. let arm_expr = self - .call_substructure_method(cx, span, EnumMatching(variant, fields)) + .call_substructure_method(cx, span, EnumMatching(variant, fields), type_ident) .into_expr(cx, span); cx.arm(span, single_pat, arm_expr) @@ -1011,8 +1038,13 @@ 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())) - .into_expr(cx, span), + self.call_substructure_method( + cx, + span, + EnumMatching(v, Vec::new()), + type_ident, + ) + .into_expr(cx, span), ) } _ if variants.len() > 1 && self.has_other_selflike_arg => { @@ -1052,7 +1084,7 @@ impl<'a> MethodDef<'a> { // is enough. if unify_fieldless_variants && variants.len() > 1 { // Combine a discriminant check with the match. - self.call_substructure_method(cx, span, EnumDiscr(Some(match_expr))) + self.call_substructure_method(cx, span, EnumDiscr(Some(match_expr)), type_ident) } else { BlockOrExpr(ThinVec::new(), Some(match_expr)) } diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 066b3b2aa9124..5ef92723dbaa7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -62,7 +62,7 @@ fn hash_substructure(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> cx.stmt_expr(expr) }; - let (stmts, match_expr) = match substr { + let (stmts, match_expr) = match substr.fields { Struct(_, fields) | EnumMatching(.., fields) => { let stmts = fields.into_iter().map(|field| call_hash(field.span, field.self_expr)).collect(); diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index d521247c50853..34e4bf6bf4cd0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -117,7 +117,7 @@ fn get_substructure_equality_expr( span: Span, substructure: Substructure<'_>, ) -> BlockOrExpr { - BlockOrExpr::new_expr(match substructure { + BlockOrExpr::new_expr(match substructure.fields { EnumMatching(.., fields) | Struct(.., fields) => { let combine = move |acc, field: &FieldInfo| { let rhs = field diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index be062ef3115a9..2a3417fb7eb96 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -204,7 +204,7 @@ pub(crate) fn cmp_body( } }; - match substructure { + match substructure.fields { EnumMatching(.., all_fields) | Struct(_, all_fields) => { let op = |old, field: FieldInfo| { // The basic case: a field expression for one or more selflike args. E.g. From c96f45ebcd11f7332211c6e0f2b662b84f2a1d8b Mon Sep 17 00:00:00 2001 From: cyrgani Date: Thu, 8 Oct 2026 21:26:08 +0000 Subject: [PATCH 18/18] or add the `Item` to `Substructure` and drop `combine_substructure` This leads to `CombineSubstructureFunc` becoming a `fn`, allows some cleanups and requires restructuring `From` a bit. It also means that it is no longer easily possible to generate the dummy method body after encountering an error, so the code just skips generating anything. --- .../src/deriving/clone.rs | 8 +- .../src/deriving/debug.rs | 15 +-- .../src/deriving/default.rs | 6 +- .../rustc_builtin_macros/src/deriving/eq.rs | 2 +- .../rustc_builtin_macros/src/deriving/from.rs | 91 +++++++++---------- .../src/deriving/generic/mod.rs | 82 +++++++---------- .../rustc_builtin_macros/src/deriving/hash.rs | 2 +- .../rustc_builtin_macros/src/deriving/ord.rs | 20 +--- .../src/deriving/partial_eq.rs | 2 +- .../src/deriving/partial_ord.rs | 27 ++---- .../ui/derives/deriving-from-wrong-target.rs | 2 + .../derives/deriving-from-wrong-target.stderr | 43 ++++++++- 12 files changed, 145 insertions(+), 155 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index da23ce9b2da9e..f1d9487ea741f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -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"), } diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index f0c18f5cb687a..f014ee92aa4f2 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -44,12 +44,7 @@ pub(crate) fn expand_deriving_debug( ret_ty: cx.ty_path(path_std!(cx, span, fmt::Result)), attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: FieldlessVariantsStrategy::Default, - combine_substructure: combine_substructure(|cx, span, substr| show_substructure( - cx, - span, - substr, - item.kind.ident().unwrap() - )), + combine_substructure: show_substructure, }], is_const, .. @@ -57,16 +52,12 @@ pub(crate) fn expand_deriving_debug( 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), diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 0c5de106f000a..1142f26b0fe64 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -35,19 +35,19 @@ 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, .. diff --git a/compiler/rustc_builtin_macros/src/deriving/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs index cebd187139463..0268c74e47f05 100644 --- a/compiler/rustc_builtin_macros/src/deriving/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/eq.rs @@ -37,7 +37,7 @@ 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, .. diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index 5d975fbb7b984..4971cd3407fec 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -1,7 +1,7 @@ use rustc_ast as ast; 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; @@ -22,35 +22,29 @@ 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 = cx.std_path_all(span, path!(convert::From), vec![ast::GenericArg::Type(from_type.clone())]); @@ -80,41 +74,7 @@ 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, .. @@ -122,3 +82,38 @@ pub(crate) fn expand_deriving_from( 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 9aca677cef178..f2a216fa6ba3d 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -181,7 +181,7 @@ 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, + AttrArgs, DelimArgs, EnumDef, Expr, GenericArg, GenericParam, GenericParamKind, Generics, Item, Safety, VariantData, }; use rustc_attr_ir::{Attribute, AttributeKind, ReprPacked}; @@ -194,7 +194,7 @@ 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, @@ -214,7 +214,7 @@ 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, @@ -225,7 +225,7 @@ pub(crate) struct TraitDef<'a> { 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. @@ -283,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. @@ -308,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, @@ -440,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; @@ -477,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) @@ -499,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) @@ -573,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(); @@ -776,15 +764,19 @@ 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 { @@ -884,7 +876,7 @@ impl<'a> MethodDef<'a> { span: Span, struct_def: &'b VariantData, is_packed: bool, - type_ident: Ident, + item: &Item, ) -> BlockOrExpr { let self_expr = cx.expr_self(span); let selflike_args = if self.has_other_selflike_arg { @@ -895,7 +887,7 @@ impl<'a> MethodDef<'a> { 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) + self.call_substructure_method(cx, span, Struct(struct_def, selflike_fields), item) } /// ``` @@ -938,7 +930,7 @@ impl<'a> MethodDef<'a> { cx: &ExtCtxt<'_>, span: Span, enum_def: &'b EnumDef, - type_ident: Ident, + item: &Item, ) -> BlockOrExpr { let variants = &enum_def.variants; @@ -962,12 +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, - ); + return self.call_substructure_method(cx, span, EnumDiscr(None), item); } FieldlessVariantsStrategy::Default => (), } @@ -978,7 +965,7 @@ impl<'a> MethodDef<'a> { cx, span, EnumMatching(variant, Vec::new()), - type_ident, + item, ); } } @@ -1025,7 +1012,7 @@ impl<'a> MethodDef<'a> { // Self arg, assuming all are instances of VariantK. // Build up code associated with such a case. let arm_expr = self - .call_substructure_method(cx, span, EnumMatching(variant, fields), type_ident) + .call_substructure_method(cx, span, EnumMatching(variant, fields), item) .into_expr(cx, span); cx.arm(span, single_pat, arm_expr) @@ -1038,13 +1025,8 @@ 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 && self.has_other_selflike_arg => { @@ -1084,7 +1066,7 @@ impl<'a> MethodDef<'a> { // is enough. if unify_fieldless_variants && variants.len() > 1 { // Combine a discriminant check with the match. - self.call_substructure_method(cx, span, EnumDiscr(Some(match_expr)), type_ident) + self.call_substructure_method(cx, span, EnumDiscr(Some(match_expr)), item) } else { BlockOrExpr(ThinVec::new(), Some(match_expr)) } diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 5ef92723dbaa7..57b2dda4387b2 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -44,7 +44,7 @@ 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, .. diff --git a/compiler/rustc_builtin_macros/src/deriving/ord.rs b/compiler/rustc_builtin_macros/src/deriving/ord.rs index 36046e9d931ab..2daab160a80a0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/ord.rs @@ -3,7 +3,7 @@ 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::partial_ord::{OrdlikeDerive, cmp_body}; use crate::util::path_std; pub(crate) fn expand_deriving_ord( @@ -13,8 +13,6 @@ 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), @@ -30,12 +28,7 @@ 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, .. @@ -44,12 +37,7 @@ pub(crate) fn expand_deriving_ord( 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) { @@ -57,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 34e4bf6bf4cd0..9eb239be12afe 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -45,7 +45,7 @@ pub(crate) fn expand_deriving_partial_eq( 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 { diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index 2a3417fb7eb96..a44bc77735570 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -21,16 +21,9 @@ pub(crate) fn expand_deriving_partial_ord( vec![ast::GenericArg::Type(ordering_ty)], )); - // Order in which to perform matching - let discr_then_data = discr_data_order(item); - 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, @@ -63,7 +56,11 @@ 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 { @@ -112,12 +109,7 @@ fn cs_partial_cmp_simple(cx: &ExtCtxt<'_>, span: Span, other_expr: Box, - 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) { @@ -125,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) } @@ -139,9 +131,10 @@ 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 { [sym::cmp, sym::PartialOrd, sym::partial_cmp] 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`.