From e1ec059fb2908a37ae224d52315f854a47a8a1eb Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Tue, 13 Jan 2026 16:52:02 +0200 Subject: [PATCH 01/16] abi: add a rust-preserve-none calling convention This is the conceptual opposite of the rust-cold calling convention and is particularly useful in combination with the new `explicit_tail_calls` feature. For relatively tight loops implemented with tail calling (`become`) each of the function with the regular calling convention is still responsible for restoring the initial value of the preserved registers. So it is not unusual to end up with a situation where each step in the tail call loop is spilling and reloading registers, along the lines of: foo: push r12 ; do things pop r12 jmp next_step This adds up quickly, especially when most of the clobberable registers are already used to pass arguments or other uses. I was thinking of making the name of this ABI a little less LLVM-derived and more like a conceptual inverse of `rust-cold`, but could not come with a great name (`rust-cold` is itself not a great name: cold in what context? from which perspective? is it supposed to mean that the function is rarely called?) --- compiler/rustc_abi/src/canon_abi.rs | 4 +- compiler/rustc_abi/src/extern_abi.rs | 13 +++- compiler/rustc_ast_lowering/src/stability.rs | 5 ++ .../rustc_ast_passes/src/ast_validation.rs | 1 + .../rustc_codegen_cranelift/src/abi/mod.rs | 3 + compiler/rustc_codegen_gcc/src/abi.rs | 2 + compiler/rustc_codegen_llvm/src/abi.rs | 1 + compiler/rustc_codegen_llvm/src/attributes.rs | 2 +- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_hir_typeck/src/callee.rs | 1 + compiler/rustc_middle/src/ty/layout.rs | 2 +- compiler/rustc_public/src/abi.rs | 1 + compiler/rustc_public/src/ty.rs | 1 + .../src/unstable/convert/internal.rs | 1 + .../src/unstable/convert/stable/abi.rs | 1 + .../src/unstable/convert/stable/ty.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_target/src/spec/abi_map.rs | 1 + .../rust-analyzer/crates/hir-ty/src/lib.rs | 3 + .../crates/intern/src/symbol/symbols.rs | 1 + tests/codegen-llvm/preserve-none.rs | 18 +++++ tests/ui/abi/rust-preserve-none-cc.rs | 67 +++++++++++++++++ .../feature-gate-rust-preserve-none-cc.rs | 21 ++++++ .../feature-gate-rust-preserve-none-cc.stderr | 73 +++++++++++++++++++ .../print-calling-conventions.stdout | 1 + 26 files changed, 223 insertions(+), 5 deletions(-) create mode 100644 tests/codegen-llvm/preserve-none.rs create mode 100644 tests/ui/abi/rust-preserve-none-cc.rs create mode 100644 tests/ui/feature-gates/feature-gate-rust-preserve-none-cc.rs create mode 100644 tests/ui/feature-gates/feature-gate-rust-preserve-none-cc.stderr diff --git a/compiler/rustc_abi/src/canon_abi.rs b/compiler/rustc_abi/src/canon_abi.rs index a5294bbf71717..fd45f0ea0e9ec 100644 --- a/compiler/rustc_abi/src/canon_abi.rs +++ b/compiler/rustc_abi/src/canon_abi.rs @@ -27,6 +27,7 @@ pub enum CanonAbi { C, Rust, RustCold, + RustPreserveNone, /// An ABI that rustc does not know how to call or define. Custom, @@ -54,7 +55,7 @@ pub enum CanonAbi { impl CanonAbi { pub fn is_rustic_abi(self) -> bool { match self { - CanonAbi::Rust | CanonAbi::RustCold => true, + CanonAbi::Rust | CanonAbi::RustCold | CanonAbi::RustPreserveNone => true, CanonAbi::C | CanonAbi::Custom | CanonAbi::Arm(_) @@ -74,6 +75,7 @@ impl fmt::Display for CanonAbi { CanonAbi::C => ExternAbi::C { unwind: false }, CanonAbi::Rust => ExternAbi::Rust, CanonAbi::RustCold => ExternAbi::RustCold, + CanonAbi::RustPreserveNone => ExternAbi::RustPreserveNone, CanonAbi::Custom => ExternAbi::Custom, CanonAbi::Arm(arm_call) => match arm_call { ArmCall::Aapcs => ExternAbi::Aapcs { unwind: false }, diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs index e44dea1ce593b..9173245d8aa4e 100644 --- a/compiler/rustc_abi/src/extern_abi.rs +++ b/compiler/rustc_abi/src/extern_abi.rs @@ -42,6 +42,13 @@ pub enum ExternAbi { /// in a platform-agnostic way. RustInvalid, + /// Preserves no registers. + /// + /// Note, that this ABI is not stable in the registers it uses, is intended as an optimization + /// and may fall-back to a more conservative calling convention if the backend does not support + /// forcing callers to save all registers. + RustPreserveNone, + /// Unstable impl detail that directly uses Rust types to describe the ABI to LLVM. /// Even normally-compatible Rust types can become ABI-incompatible with this ABI! Unadjusted, @@ -163,6 +170,7 @@ abi_impls! { RustCall =><= "rust-call", RustCold =><= "rust-cold", RustInvalid =><= "rust-invalid", + RustPreserveNone =><= "rust-preserve-none", Stdcall { unwind: false } =><= "stdcall", Stdcall { unwind: true } =><= "stdcall-unwind", System { unwind: false } =><= "system", @@ -243,7 +251,7 @@ impl ExternAbi { /// - are subject to change between compiler versions pub fn is_rustic_abi(self) -> bool { use ExternAbi::*; - matches!(self, Rust | RustCall | RustCold) + matches!(self, Rust | RustCall | RustCold | RustPreserveNone) } /// Returns whether the ABI supports C variadics. This only controls whether we allow *imports* @@ -315,7 +323,8 @@ impl ExternAbi { | Self::Thiscall { .. } | Self::Vectorcall { .. } | Self::SysV64 { .. } - | Self::Win64 { .. } => true, + | Self::Win64 { .. } + | Self::RustPreserveNone => true, } } } diff --git a/compiler/rustc_ast_lowering/src/stability.rs b/compiler/rustc_ast_lowering/src/stability.rs index 6752218fa0d4b..7674c7df42275 100644 --- a/compiler/rustc_ast_lowering/src/stability.rs +++ b/compiler/rustc_ast_lowering/src/stability.rs @@ -96,6 +96,11 @@ pub fn extern_abi_stability(abi: ExternAbi) -> Result<(), UnstableAbi> { ExternAbi::RustCold => { Err(UnstableAbi { abi, feature: sym::rust_cold_cc, explain: GateReason::Experimental }) } + ExternAbi::RustPreserveNone => Err(UnstableAbi { + abi, + feature: sym::rust_preserve_none_cc, + explain: GateReason::Experimental, + }), ExternAbi::RustInvalid => { Err(UnstableAbi { abi, feature: sym::rustc_attrs, explain: GateReason::ImplDetail }) } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index eddcf12fca29c..2457e0a777e44 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -400,6 +400,7 @@ impl<'a> AstValidator<'a> { CanonAbi::C | CanonAbi::Rust | CanonAbi::RustCold + | CanonAbi::RustPreserveNone | CanonAbi::Arm(_) | CanonAbi::X86(_) => { /* nothing to check */ } diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 09d71f5dd5579..5a46f79e2ba00 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -56,6 +56,9 @@ pub(crate) fn conv_to_call_conv( CanonAbi::Rust | CanonAbi::C => default_call_conv, CanonAbi::RustCold => CallConv::Cold, + // Cranelift doesn't currently have anything for this. + CanonAbi::RustPreserveNone => default_call_conv, + // Functions with this calling convention can only be called from assembly, but it is // possible to declare an `extern "custom"` block, so the backend still needs a calling // convention for declaring foreign functions. diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index cc2c9fca94dfb..56ed7c01ed20b 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -243,6 +243,8 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &Arch) -> Option> { let attribute = match conv { CanonAbi::C | CanonAbi::Rust => return None, + // gcc/gccjit does not have anything for this. + CanonAbi::RustPreserveNone => return None, CanonAbi::RustCold => FnAttribute::Cold, // Functions with this calling convention can only be called from assembly, but it is // possible to declare an `extern "custom"` block, so the backend still needs a calling diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index c3c1caf086f09..bb5c13fb6e025 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -694,6 +694,7 @@ pub(crate) fn to_llvm_calling_convention(sess: &Session, abi: CanonAbi) -> llvm: match abi { CanonAbi::C | CanonAbi::Rust => llvm::CCallConv, CanonAbi::RustCold => llvm::PreserveMost, + CanonAbi::RustPreserveNone => llvm::PreserveNone, // Functions with this calling convention can only be called from assembly, but it is // possible to declare an `extern "custom"` block, so the backend still needs a calling // convention for declaring foreign functions. diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index a25ce9e5a90ac..d02838e00955e 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -369,7 +369,7 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute { llvm::CreateAttrStringValue(llcx, "alloc-family", "__rust_alloc") } -/// Helper for `FnAbi::apply_attrs_llfn`: +/// Helper for `FnAbiLlvmExt::apply_attrs_llfn`: /// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`) /// attributes. pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index a90013801c8c0..4b391a489c134 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -167,6 +167,7 @@ pub(crate) enum CallConv { PreserveMost = 14, PreserveAll = 15, Tail = 18, + PreserveNone = 21, X86StdcallCallConv = 64, X86FastcallCallConv = 65, ArmAapcsCallConv = 67, diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 8959bc586af7b..e4db420a9d760 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -632,6 +632,8 @@ declare_features! ( (unstable, rtm_target_feature, "1.35.0", Some(150258)), /// Allows `extern "rust-cold"`. (unstable, rust_cold_cc, "1.63.0", Some(97544)), + /// Allows `extern "rust-preserve-none"`. + (unstable, rust_preserve_none_cc, "CURRENT_RUSTC_VERSION", Some(151401)), /// Target features on s390x. (unstable, s390x_target_feature, "1.82.0", Some(150259)), /// Allows the use of the `sanitize` attribute. diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index b60d053957a9b..457ae1289792c 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -188,6 +188,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { CanonAbi::C | CanonAbi::Rust | CanonAbi::RustCold + | CanonAbi::RustPreserveNone | CanonAbi::Arm(_) | CanonAbi::X86(_) => {} } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 81b8142d03f37..14ebcc968f7af 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1288,7 +1288,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option, abi: ExternAbi) | RiscvInterruptS | RustInvalid | Unadjusted => false, - Rust | RustCall | RustCold => tcx.sess.panic_strategy().unwinds(), + Rust | RustCall | RustCold | RustPreserveNone => tcx.sess.panic_strategy().unwinds(), } } diff --git a/compiler/rustc_public/src/abi.rs b/compiler/rustc_public/src/abi.rs index aced39059f6ba..bc18068cfa051 100644 --- a/compiler/rustc_public/src/abi.rs +++ b/compiler/rustc_public/src/abi.rs @@ -432,6 +432,7 @@ pub enum CallConvention { Cold, PreserveMost, PreserveAll, + PreserveNone, Custom, diff --git a/compiler/rustc_public/src/ty.rs b/compiler/rustc_public/src/ty.rs index 14656a2e594ad..f4a7873c10f90 100644 --- a/compiler/rustc_public/src/ty.rs +++ b/compiler/rustc_public/src/ty.rs @@ -1139,6 +1139,7 @@ pub enum Abi { RustCold, RiscvInterruptM, RiscvInterruptS, + RustPreserveNone, RustInvalid, Custom, } diff --git a/compiler/rustc_public/src/unstable/convert/internal.rs b/compiler/rustc_public/src/unstable/convert/internal.rs index d9f314a8e29cc..73a3fed111b36 100644 --- a/compiler/rustc_public/src/unstable/convert/internal.rs +++ b/compiler/rustc_public/src/unstable/convert/internal.rs @@ -615,6 +615,7 @@ impl RustcInternal for Abi { Abi::RustInvalid => rustc_abi::ExternAbi::RustInvalid, Abi::RiscvInterruptM => rustc_abi::ExternAbi::RiscvInterruptM, Abi::RiscvInterruptS => rustc_abi::ExternAbi::RiscvInterruptS, + Abi::RustPreserveNone => rustc_abi::ExternAbi::RustPreserveNone, Abi::Custom => rustc_abi::ExternAbi::Custom, } } diff --git a/compiler/rustc_public/src/unstable/convert/stable/abi.rs b/compiler/rustc_public/src/unstable/convert/stable/abi.rs index 03328d084ee94..e4130d7fa4cb2 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/abi.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/abi.rs @@ -123,6 +123,7 @@ impl<'tcx> Stable<'tcx> for CanonAbi { CanonAbi::C => CallConvention::C, CanonAbi::Rust => CallConvention::Rust, CanonAbi::RustCold => CallConvention::Cold, + CanonAbi::RustPreserveNone => CallConvention::PreserveNone, CanonAbi::Custom => CallConvention::Custom, CanonAbi::Arm(arm_call) => match arm_call { ArmCall::Aapcs => CallConvention::ArmAapcs, diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index ca8234280be85..9215c41c27ebb 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -1020,6 +1020,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi { ExternAbi::RustCall => Abi::RustCall, ExternAbi::Unadjusted => Abi::Unadjusted, ExternAbi::RustCold => Abi::RustCold, + ExternAbi::RustPreserveNone => Abi::RustPreserveNone, ExternAbi::RustInvalid => Abi::RustInvalid, ExternAbi::RiscvInterruptM => Abi::RiscvInterruptM, ExternAbi::RiscvInterruptS => Abi::RiscvInterruptS, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index f56c3421ce0f5..dee2c3ca73230 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1907,6 +1907,7 @@ symbols! { rust_future, rust_logo, rust_out, + rust_preserve_none_cc, rustc, rustc_abi, // FIXME(#82232, #143834): temporary name to mitigate `#[align]` nameres ambiguity diff --git a/compiler/rustc_target/src/spec/abi_map.rs b/compiler/rustc_target/src/spec/abi_map.rs index d7fc18cd3761e..c0fdd946778be 100644 --- a/compiler/rustc_target/src/spec/abi_map.rs +++ b/compiler/rustc_target/src/spec/abi_map.rs @@ -88,6 +88,7 @@ impl AbiMap { (ExternAbi::RustCold, _) if self.os == OsKind::Windows => CanonAbi::Rust, (ExternAbi::RustCold, _) => CanonAbi::RustCold, + (ExternAbi::RustPreserveNone, _) => CanonAbi::RustPreserveNone, (ExternAbi::Custom, _) => CanonAbi::Custom, diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 41c381220cfd1..f8920904f06f2 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -230,6 +230,7 @@ pub enum FnAbi { Win64, Win64Unwind, X86Interrupt, + RustPreserveNone, Unknown, } @@ -271,6 +272,7 @@ impl FnAbi { s if *s == sym::riscv_dash_interrupt_dash_s => FnAbi::RiscvInterruptS, s if *s == sym::rust_dash_call => FnAbi::RustCall, s if *s == sym::rust_dash_cold => FnAbi::RustCold, + s if *s == sym::rust_dash_preserve_dash_none => FnAbi::RustPreserveNone, s if *s == sym::rust_dash_intrinsic => FnAbi::RustIntrinsic, s if *s == sym::Rust => FnAbi::Rust, s if *s == sym::stdcall_dash_unwind => FnAbi::StdcallUnwind, @@ -314,6 +316,7 @@ impl FnAbi { FnAbi::Rust => "Rust", FnAbi::RustCall => "rust-call", FnAbi::RustCold => "rust-cold", + FnAbi::RustPreserveNone => "rust-preserve-none", FnAbi::RustIntrinsic => "rust-intrinsic", FnAbi::Stdcall => "stdcall", FnAbi::StdcallUnwind => "stdcall-unwind", diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 6181413a46dbc..cbaac64be4bd0 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -109,6 +109,7 @@ define_symbols! { vectorcall_dash_unwind = "vectorcall-unwind", win64_dash_unwind = "win64-unwind", x86_dash_interrupt = "x86-interrupt", + rust_dash_preserve_dash_none = "preserve-none", @PLAIN: __ra_fixup, diff --git a/tests/codegen-llvm/preserve-none.rs b/tests/codegen-llvm/preserve-none.rs new file mode 100644 index 0000000000000..4c13c1b97dcea --- /dev/null +++ b/tests/codegen-llvm/preserve-none.rs @@ -0,0 +1,18 @@ +//@ compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] +#![feature(rust_preserve_none_cc)] + +// CHECK: define{{( dso_local)?}} preserve_nonecc void @peach(i16 +#[no_mangle] +#[inline(never)] +pub extern "rust-preserve-none" fn peach(x: u16) { + panic!("unwinding works too") +} + +// CHECK: call preserve_nonecc void @peach(i16 +pub fn quince(x: u16) { + if x == 12345 { + peach(54321); + } +} diff --git a/tests/ui/abi/rust-preserve-none-cc.rs b/tests/ui/abi/rust-preserve-none-cc.rs new file mode 100644 index 0000000000000..deacb926971c8 --- /dev/null +++ b/tests/ui/abi/rust-preserve-none-cc.rs @@ -0,0 +1,67 @@ +//@ run-pass +//@ needs-unwind + +#![feature(rust_preserve_none_cc)] + +struct CrateOf<'a> { + mcintosh: f64, + golden_delicious: u64, + jonagold: Option<&'a u64>, + rome: [u64; 12], +} + +#[inline(never)] +extern "rust-preserve-none" fn oven_explosion() { + panic!("bad time"); +} + +#[inline(never)] +fn bite_into(yummy: u64) -> u64 { + let did_it_actually = std::panic::catch_unwind(move || { + oven_explosion() + }); + assert!(did_it_actually.is_err()); + yummy - 25 +} + +#[inline(never)] +extern "rust-preserve-none" fn lotsa_apples( + honeycrisp: u64, + gala: u32, + fuji: f64, + granny_smith: &[u64], + pink_lady: (), + and_a: CrateOf<'static>, + cosmic_crisp: u64, + ambrosia: f64, + winesap: &[u64], +) -> (u64, f64, u64, u64) { + assert_eq!(honeycrisp, 220); + assert_eq!(gala, 140); + assert_eq!(fuji, 210.54201234); + assert_eq!(granny_smith, &[180, 210]); + assert_eq!(pink_lady, ()); + assert_eq!(and_a.mcintosh, 150.0); + assert_eq!(and_a.golden_delicious, 185); + assert_eq!(and_a.jonagold, None); // my scales can't weight these gargantuans. + assert_eq!(and_a.rome, [180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202]); + assert_eq!(cosmic_crisp, 270); + assert_eq!(ambrosia, 193.1); + assert_eq!(winesap, &[]); + ( + and_a.rome.iter().sum(), + fuji + ambrosia, + cosmic_crisp - honeycrisp, + bite_into(and_a.golden_delicious) + ) +} + +fn main() { + let pie = lotsa_apples(220, 140, 210.54201234, &[180, 210], (), CrateOf { + mcintosh: 150.0, + golden_delicious: 185, + jonagold: None, + rome: [180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202] + }, 270, 193.1, &[]); + assert_eq!(pie, (2292, 403.64201234, 50, 160)); +} diff --git a/tests/ui/feature-gates/feature-gate-rust-preserve-none-cc.rs b/tests/ui/feature-gates/feature-gate-rust-preserve-none-cc.rs new file mode 100644 index 0000000000000..e503e353104a7 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-rust-preserve-none-cc.rs @@ -0,0 +1,21 @@ +#![crate_type = "lib"] + +extern "rust-preserve-none" fn apple() {} //~ ERROR "rust-preserve-none" ABI is experimental + +trait T { + extern "rust-preserve-none" fn banana(); //~ ERROR "rust-preserve-none" ABI is experimental + extern "rust-preserve-none" fn citrus() {} //~ ERROR "rust-preserve-none" ABI is experimental +} + +struct S; +impl T for S { + extern "rust-preserve-none" fn banana() {} //~ ERROR "rust-preserve-none" ABI is experimental +} + +impl S { + extern "rust-preserve-none" fn durian() {} //~ ERROR "rust-preserve-none" ABI is experimental +} + +type Fig = extern "rust-preserve-none" fn(); //~ ERROR "rust-preserve-none" ABI is experimental + +extern "rust-preserve-none" {} //~ ERROR "rust-preserve-none" ABI is experimental diff --git a/tests/ui/feature-gates/feature-gate-rust-preserve-none-cc.stderr b/tests/ui/feature-gates/feature-gate-rust-preserve-none-cc.stderr new file mode 100644 index 0000000000000..b9d00e317b1fc --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-rust-preserve-none-cc.stderr @@ -0,0 +1,73 @@ +error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change + --> $DIR/feature-gate-rust-preserve-none-cc.rs:3:8 + | +LL | extern "rust-preserve-none" fn apple() {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #151401 for more information + = help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change + --> $DIR/feature-gate-rust-preserve-none-cc.rs:6:12 + | +LL | extern "rust-preserve-none" fn banana(); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #151401 for more information + = help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change + --> $DIR/feature-gate-rust-preserve-none-cc.rs:7:12 + | +LL | extern "rust-preserve-none" fn citrus() {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #151401 for more information + = help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change + --> $DIR/feature-gate-rust-preserve-none-cc.rs:12:12 + | +LL | extern "rust-preserve-none" fn banana() {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #151401 for more information + = help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change + --> $DIR/feature-gate-rust-preserve-none-cc.rs:16:12 + | +LL | extern "rust-preserve-none" fn durian() {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #151401 for more information + = help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change + --> $DIR/feature-gate-rust-preserve-none-cc.rs:19:19 + | +LL | type Fig = extern "rust-preserve-none" fn(); + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #151401 for more information + = help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the extern "rust-preserve-none" ABI is experimental and subject to change + --> $DIR/feature-gate-rust-preserve-none-cc.rs:21:8 + | +LL | extern "rust-preserve-none" {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #151401 for more information + = help: add `#![feature(rust_preserve_none_cc)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/print-request/print-calling-conventions.stdout b/tests/ui/print-request/print-calling-conventions.stdout index b8b939e1c04e9..8366697d0fb0d 100644 --- a/tests/ui/print-request/print-calling-conventions.stdout +++ b/tests/ui/print-request/print-calling-conventions.stdout @@ -21,6 +21,7 @@ riscv-interrupt-s rust-call rust-cold rust-invalid +rust-preserve-none stdcall stdcall-unwind system From 03fa11abb4de71301c2fb11299c82a982d373a1c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 3 Oct 2025 21:35:29 +0000 Subject: [PATCH 02/16] Remove a couple of unnecessary impls --- library/proc_macro/src/bridge/client.rs | 6 ------ library/proc_macro/src/bridge/handle.rs | 8 +------- library/proc_macro/src/bridge/server.rs | 11 ----------- 3 files changed, 1 insertion(+), 24 deletions(-) diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index bdaa865a998d6..48a43a7bac34c 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -52,12 +52,6 @@ macro_rules! define_client_handles { } } - impl Encode for &mut $oty { - fn encode(self, w: &mut Writer, s: &mut S) { - self.handle.encode(w, s); - } - } - impl Decode<'_, '_, S> for $oty { fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { $oty { diff --git a/library/proc_macro/src/bridge/handle.rs b/library/proc_macro/src/bridge/handle.rs index 8c53bb609f60c..f0c01e39de32d 100644 --- a/library/proc_macro/src/bridge/handle.rs +++ b/library/proc_macro/src/bridge/handle.rs @@ -3,7 +3,7 @@ use std::collections::BTreeMap; use std::hash::Hash; use std::num::NonZero; -use std::ops::{Index, IndexMut}; +use std::ops::Index; use std::sync::atomic::{AtomicU32, Ordering}; use super::fxhash::FxHashMap; @@ -47,12 +47,6 @@ impl Index for OwnedStore { } } -impl IndexMut for OwnedStore { - fn index_mut(&mut self, h: Handle) -> &mut T { - self.data.get_mut(&h).expect("use-after-free in `proc_macro` handle") - } -} - /// Like `OwnedStore`, but avoids storing any value more than once. pub(super) struct InternedStore { owned: OwnedStore, diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs index e9ef26c07f24f..27cc5e5d57e33 100644 --- a/library/proc_macro/src/bridge/server.rs +++ b/library/proc_macro/src/bridge/server.rs @@ -47,17 +47,6 @@ macro_rules! define_server_handles { &s.$oty[handle::Handle::decode(r, &mut ())] } } - - impl<'s, S: Types> Decode<'_, 's, HandleStore>> - for &'s mut Marked - { - fn decode( - r: &mut Reader<'_>, - s: &'s mut HandleStore> - ) -> Self { - &mut s.$oty[handle::Handle::decode(r, &mut ())] - } - } )* $( From c65076a0f0367e5e1cf1e556566b09e9a7f2fff5 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 3 Oct 2025 21:27:26 +0000 Subject: [PATCH 03/16] Handle FreeFunctions outside with_api_handle_types It is a singleton which doesn't actually need to be passed through over the bridge. --- library/proc_macro/src/bridge/client.rs | 1 + library/proc_macro/src/bridge/mod.rs | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index 48a43a7bac34c..e75902eca6bb6 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -120,6 +120,7 @@ impl fmt::Debug for Span { } } +pub(crate) use super::FreeFunctions; pub(crate) use super::symbol::Symbol; macro_rules! define_client_side { diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index b0ee9c0cc3027..15a81bd5f96f2 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -49,7 +49,6 @@ macro_rules! with_api { ($S:ident, $self:ident, $m:ident) => { $m! { FreeFunctions { - fn drop($self: $S::FreeFunctions); fn injected_env_var(var: &str) -> Option; fn track_env_var(var: &str, value: Option<&str>); fn track_path(path: &str); @@ -109,7 +108,7 @@ macro_rules! with_api_handle_types { ($m:ident) => { $m! { 'owned: - FreeFunctions, + // FreeFunctions is handled manually TokenStream, 'interned: @@ -119,6 +118,8 @@ macro_rules! with_api_handle_types { }; } +pub(crate) struct FreeFunctions; + #[allow(unsafe_code)] mod arena; #[allow(unsafe_code)] From 5dd7c0b5aba324bf127e07bf1406926b329b031b Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Wed, 31 Dec 2025 21:49:48 +0000 Subject: [PATCH 04/16] Rationalise the Armv7-A, Armv7-R and Armv8-R bare-metal target configs --- .../src/spec/targets/armv7a_none_eabi.rs | 45 +++++-------------- .../src/spec/targets/armv7a_none_eabihf.rs | 37 +++++---------- .../src/spec/targets/armv7r_none_eabi.rs | 17 ++----- .../src/spec/targets/armv7r_none_eabihf.rs | 17 ++----- .../src/spec/targets/armv8r_none_eabihf.rs | 14 +----- 5 files changed, 28 insertions(+), 102 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs index 6b7707a47390a..e8c5c16d8eb5e 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs @@ -1,40 +1,8 @@ -// Generic ARMv7-A target for bare-metal code - floating point disabled -// -// This is basically the `armv7-unknown-linux-gnueabi` target with some changes -// (listed below) to bring it closer to the bare-metal `thumb` & `aarch64` -// targets: -// -// - `TargetOptions.features`: added `+strict-align`. rationale: unaligned -// memory access is disabled on boot on these cores -// - linker changed to LLD. rationale: C is not strictly needed to build -// bare-metal binaries (the `gcc` linker has the advantage that it knows where C -// libraries and crt*.o are but it's not much of an advantage here); LLD is also -// faster -// - `panic_strategy` set to `abort`. rationale: matches `thumb` targets -// - `relocation-model` set to `static`; also no PIE, no relro and no dynamic -// linking. rationale: matches `thumb` targets +// Targets the Little-endian Cortex-A8 (and similar) processors (ARMv7-A) -use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, -}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { - let opts = TargetOptions { - abi: Abi::Eabi, - llvm_floatabi: Some(FloatAbi::Soft), - linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), - linker: Some("rust-lld".into()), - features: "+v7,+thumb2,+soft-float,-neon,+strict-align".into(), - relocation_model: RelocModel::Static, - disable_redzone: true, - max_atomic_width: Some(64), - panic_strategy: PanicStrategy::Abort, - emit_debug_gdb_scripts: false, - c_enum_min_bits: Some(8), - has_thumb_interworking: true, - ..Default::default() - }; Target { llvm_target: "armv7a-none-eabi".into(), metadata: TargetMetadata { @@ -46,6 +14,13 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, - options: opts, + options: TargetOptions { + abi: Abi::Eabi, + llvm_floatabi: Some(FloatAbi::Soft), + features: "+soft-float,-neon,+strict-align".into(), + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs index 993390543b96d..32a79e346adcf 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs @@ -1,32 +1,8 @@ -// Generic ARMv7-A target for bare-metal code - floating point enabled (assumes -// FPU is present and emits FPU instructions) -// -// This is basically the `armv7-unknown-linux-gnueabihf` target with some -// changes (list in `armv7a_none_eabi.rs`) to bring it closer to the bare-metal -// `thumb` & `aarch64` targets. +// Targets the Little-endian Cortex-A8 (and similar) processors (ARMv7-A) -use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, -}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { - let opts = TargetOptions { - abi: Abi::EabiHf, - llvm_floatabi: Some(FloatAbi::Hard), - linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), - linker: Some("rust-lld".into()), - features: "+v7,+vfp3d16,+thumb2,-neon,+strict-align".into(), - relocation_model: RelocModel::Static, - disable_redzone: true, - max_atomic_width: Some(64), - panic_strategy: PanicStrategy::Abort, - emit_debug_gdb_scripts: false, - // GCC defaults to 8 for arm-none here. - c_enum_min_bits: Some(8), - has_thumb_interworking: true, - ..Default::default() - }; Target { llvm_target: "armv7a-none-eabihf".into(), metadata: TargetMetadata { @@ -38,6 +14,13 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, - options: opts, + options: TargetOptions { + abi: Abi::EabiHf, + llvm_floatabi: Some(FloatAbi::Hard), + features: "+vfp3d16,-neon,+strict-align".into(), + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs index 551cbf4a589fa..114b079f360b7 100644 --- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs @@ -1,15 +1,12 @@ // Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R) -use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, -}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { llvm_target: "armv7r-none-eabi".into(), metadata: TargetMetadata { - description: Some("Armv7-R".into()), + description: Some("Bare Armv7-R".into()), tier: Some(2), host_tools: Some(false), std: Some(false), @@ -17,20 +14,12 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, - options: TargetOptions { abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), - linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), - linker: Some("rust-lld".into()), - relocation_model: RelocModel::Static, - panic_strategy: PanicStrategy::Abort, max_atomic_width: Some(64), - emit_debug_gdb_scripts: false, - // GCC defaults to 8 for arm-none here. - c_enum_min_bits: Some(8), has_thumb_interworking: true, - ..Default::default() + ..base::arm_none::opts() }, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs index 97c911ec80909..1c6114f9fc83a 100644 --- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs @@ -1,15 +1,12 @@ // Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R) -use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, -}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { llvm_target: "armv7r-none-eabihf".into(), metadata: TargetMetadata { - description: Some("Armv7-R, hardfloat".into()), + description: Some("Bare Armv7-R, hardfloat".into()), tier: Some(2), host_tools: Some(false), std: Some(false), @@ -17,21 +14,13 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, - options: TargetOptions { abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), - linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), - linker: Some("rust-lld".into()), - relocation_model: RelocModel::Static, - panic_strategy: PanicStrategy::Abort, features: "+vfp3d16".into(), max_atomic_width: Some(64), - emit_debug_gdb_scripts: false, - // GCC defaults to 8 for arm-none here. - c_enum_min_bits: Some(8), has_thumb_interworking: true, - ..Default::default() + ..base::arm_none::opts() }, } } diff --git a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs index e36240b9c2234..16006e4c52cfb 100644 --- a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs @@ -1,9 +1,6 @@ // Targets the Little-endian Cortex-R52 processor (ARMv8-R) -use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, -}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -21,10 +18,6 @@ pub(crate) fn target() -> Target { options: TargetOptions { abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), - linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), - linker: Some("rust-lld".into()), - relocation_model: RelocModel::Static, - panic_strategy: PanicStrategy::Abort, // Armv8-R requires a minimum set of floating-point features equivalent to: // fp-armv8, SP-only, with 16 DP (32 SP) registers // LLVM defines Armv8-R to include these features automatically. @@ -36,11 +29,8 @@ pub(crate) fn target() -> Target { // Arm Cortex-R52 Processor Technical Reference Manual // - Chapter 15 Advanced SIMD and floating-point support max_atomic_width: Some(64), - emit_debug_gdb_scripts: false, - // GCC defaults to 8 for arm-none here. - c_enum_min_bits: Some(8), has_thumb_interworking: true, - ..Default::default() + ..base::arm_none::opts() }, } } From 96647dde7752334ac9a2137ffca9cc4f909ceee8 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Wed, 31 Dec 2025 21:52:36 +0000 Subject: [PATCH 05/16] Add Thumb-mode targets for Armv7-R, Armv7-A and Armv8-R. --- compiler/rustc_target/src/spec/mod.rs | 5 +++ .../src/spec/targets/thumbv7a_none_eabi.rs | 26 ++++++++++++++ .../src/spec/targets/thumbv7a_none_eabihf.rs | 26 ++++++++++++++ .../src/spec/targets/thumbv7r_none_eabi.rs | 25 +++++++++++++ .../src/spec/targets/thumbv7r_none_eabihf.rs | 26 ++++++++++++++ .../src/spec/targets/thumbv8r_none_eabihf.rs | 36 +++++++++++++++++++ src/bootstrap/src/core/sanity.rs | 5 +++ src/doc/rustc/src/platform-support.md | 9 +++-- .../src/platform-support/armv7a-none-eabi.md | 10 +++--- .../src/platform-support/armv7r-none-eabi.md | 8 +++-- .../platform-support/armv8r-none-eabihf.md | 10 +++--- tests/assembly-llvm/targets/targets-elf.rs | 15 ++++++++ 12 files changed, 188 insertions(+), 13 deletions(-) create mode 100644 compiler/rustc_target/src/spec/targets/thumbv7a_none_eabi.rs create mode 100644 compiler/rustc_target/src/spec/targets/thumbv7a_none_eabihf.rs create mode 100644 compiler/rustc_target/src/spec/targets/thumbv7r_none_eabi.rs create mode 100644 compiler/rustc_target/src/spec/targets/thumbv7r_none_eabihf.rs create mode 100644 compiler/rustc_target/src/spec/targets/thumbv8r_none_eabihf.rs diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index ef475630d4943..c5a7f119118c9 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1596,8 +1596,11 @@ supported_targets! { ("armebv7r-none-eabi", armebv7r_none_eabi), ("armebv7r-none-eabihf", armebv7r_none_eabihf), ("armv7r-none-eabi", armv7r_none_eabi), + ("thumbv7r-none-eabi", thumbv7r_none_eabi), ("armv7r-none-eabihf", armv7r_none_eabihf), + ("thumbv7r-none-eabihf", thumbv7r_none_eabihf), ("armv8r-none-eabihf", armv8r_none_eabihf), + ("thumbv8r-none-eabihf", thumbv8r_none_eabihf), ("armv7-rtems-eabihf", armv7_rtems_eabihf), @@ -1649,7 +1652,9 @@ supported_targets! { ("thumbv8m.main-none-eabihf", thumbv8m_main_none_eabihf), ("armv7a-none-eabi", armv7a_none_eabi), + ("thumbv7a-none-eabi", thumbv7a_none_eabi), ("armv7a-none-eabihf", armv7a_none_eabihf), + ("thumbv7a-none-eabihf", thumbv7a_none_eabihf), ("armv7a-nuttx-eabi", armv7a_nuttx_eabi), ("armv7a-nuttx-eabihf", armv7a_nuttx_eabihf), ("armv7a-vex-v5", armv7a_vex_v5), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabi.rs new file mode 100644 index 0000000000000..ce11e3f0875c9 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabi.rs @@ -0,0 +1,26 @@ +// Targets the Little-endian Cortex-A8 (and similar) processors (ARMv7-A) + +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "thumbv7a-none-eabi".into(), + metadata: TargetMetadata { + description: Some("Thumb-mode Bare Armv7-A".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: Arch::Arm, + options: TargetOptions { + abi: Abi::Eabi, + llvm_floatabi: Some(FloatAbi::Soft), + features: "+soft-float,-neon,+strict-align".into(), + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabihf.rs new file mode 100644 index 0000000000000..12210e9c2b014 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabihf.rs @@ -0,0 +1,26 @@ +// Targets the Little-endian Cortex-A8 (and similar) processors (ARMv7-A) + +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "thumbv7a-none-eabihf".into(), + metadata: TargetMetadata { + description: Some("Thumb-mode Bare Armv7-A, hardfloat".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: Arch::Arm, + options: TargetOptions { + abi: Abi::EabiHf, + llvm_floatabi: Some(FloatAbi::Hard), + features: "+vfp3d16,-neon,+strict-align".into(), + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabi.rs new file mode 100644 index 0000000000000..bf71d31a06ecf --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabi.rs @@ -0,0 +1,25 @@ +// Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R) + +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "thumbv7r-none-eabi".into(), + metadata: TargetMetadata { + description: Some("Thumb-mode Bare Armv7-R".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: Arch::Arm, + options: TargetOptions { + abi: Abi::Eabi, + llvm_floatabi: Some(FloatAbi::Soft), + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabihf.rs new file mode 100644 index 0000000000000..88b5e67644035 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabihf.rs @@ -0,0 +1,26 @@ +// Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R) + +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "thumbv7r-none-eabihf".into(), + metadata: TargetMetadata { + description: Some("Thumb-mode Bare Armv7-R, hardfloat".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: Arch::Arm, + options: TargetOptions { + abi: Abi::EabiHf, + llvm_floatabi: Some(FloatAbi::Hard), + features: "+vfp3d16".into(), + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/thumbv8r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv8r_none_eabihf.rs new file mode 100644 index 0000000000000..87434cd7353c0 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/thumbv8r_none_eabihf.rs @@ -0,0 +1,36 @@ +// Targets the Little-endian Cortex-R52 processor (ARMv8-R) + +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "thumbv8r-none-eabihf".into(), + metadata: TargetMetadata { + description: Some("Thumb-mode Bare Armv8-R, hardfloat".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: Arch::Arm, + + options: TargetOptions { + abi: Abi::EabiHf, + llvm_floatabi: Some(FloatAbi::Hard), + // Armv8-R requires a minimum set of floating-point features equivalent to: + // fp-armv8, SP-only, with 16 DP (32 SP) registers + // LLVM defines Armv8-R to include these features automatically. + // + // The Cortex-R52 supports these default features and optionally includes: + // neon-fp-armv8, SP+DP, with 32 DP registers + // + // Reference: + // Arm Cortex-R52 Processor Technical Reference Manual + // - Chapter 15 Advanced SIMD and floating-point support + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, + } +} diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 607b9a384d196..235bbf8ddb783 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -38,6 +38,11 @@ pub struct Finder { const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined "x86_64-unknown-linux-gnuasan", + "thumbv7a-none-eabi", + "thumbv7a-none-eabihf", + "thumbv7r-none-eabi", + "thumbv7r-none-eabihf", + "thumbv8r-none-eabihf", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 889f96f5fefab..9362c8b98fe3d 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -411,17 +411,22 @@ target | std | host | notes [`thumbv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Thumb-mode Bare Armv4T [`thumbv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Thumb-mode Bare Armv5TE [`thumbv6m-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv6M with NuttX -`thumbv7a-pc-windows-msvc` | | | -[`thumbv7a-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | | | +[`thumbv7a-none-eabi`](platform-support/armv7a-none-eabi.md) | * | | Thumb-mode Bare Armv7-A +[`thumbv7a-none-eabihf`](platform-support/armv7a-none-eabi.md) | * | | Thumb-mode Bare Armv7-A, hardfloat [`thumbv7a-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX [`thumbv7a-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX, hardfloat +`thumbv7a-pc-windows-msvc` | | | +[`thumbv7a-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | | | [`thumbv7em-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7EM with NuttX [`thumbv7em-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7EM with NuttX, hardfloat [`thumbv7m-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7M with NuttX `thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode Armv7-A Linux with NEON, musl 1.2.5 +[`thumbv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | | Thumb-mode Bare Armv7-R +[`thumbv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | | Thumb-mode Bare Armv7-R, hardfloat [`thumbv8m.base-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv8M Baseline with NuttX [`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX [`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX, hardfloat +[`thumbv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Thumb-mode Bare Armv8-R, hardfloat [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly [`wasm32-wali-linux-musl`](platform-support/wasm32-wali-linux.md) | ? | | WebAssembly with [WALI](https://github.com/arjunr2/WALI) [`wasm32-wasip3`](platform-support/wasm32-wasip3.md) | ✓ | | WebAssembly with WASIp3 diff --git a/src/doc/rustc/src/platform-support/armv7a-none-eabi.md b/src/doc/rustc/src/platform-support/armv7a-none-eabi.md index 05afb4f4321be..6e08bbb26e466 100644 --- a/src/doc/rustc/src/platform-support/armv7a-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv7a-none-eabi.md @@ -1,10 +1,12 @@ -# `armv7a-none-eabi` and `armv7a-none-eabihf` +# `armv7a-none-eabi` and `thumbv7a-none-eabihf` -* **Tier: 2** +* **Tier: 2** (`armv7a-none-eabi`) +* **Tier: 3** (`thumbv7a-none-eabi`) * **Library Support:** core and alloc (bare-metal, `#![no_std]`) -Bare-metal target for CPUs in the Armv7-A architecture family, supporting -dual ARM/Thumb mode, with ARM mode as the default. +Bare-metal target for CPUs in the Armv7-A architecture family, supporting dual +ARM/Thumb mode. The `armv7a-none-eabi` target uses Arm mode by default and +the `thumbv7a-none-eabihf` target uses Thumb mode by default. Note, this is for processors running in AArch32 mode. For the AArch64 mode added in Armv8-A, see [`aarch64-unknown-none`](aarch64-unknown-none.md) instead. diff --git a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md index 7f22a29f2ee68..16755ff8c520c 100644 --- a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md @@ -1,10 +1,12 @@ # `armv7r-none-eabi` and `armv7r-none-eabihf` -* **Tier: 2** +* **Tier: 2** (`armv7r-none-eabi`) +* **Tier: 3** (`thumbv7r-none-eabi`) * **Library Support:** core and alloc (bare-metal, `#![no_std]`) -Bare-metal target for CPUs in the Armv7-R architecture family, supporting -dual ARM/Thumb mode, with ARM mode as the default. +Bare-metal target for CPUs in the Armv7-R architecture family, supporting dual +ARM/Thumb mode. The `armv7r-none-eabi` target uses Arm mode by default and +the `thumbv7r-none-eabihf` target uses Thumb mode by default. Processors in this family include the [Arm Cortex-R4, 5, 7, and 8][cortex-r]. diff --git a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md index 369e86dbfc7e8..ad4764122446e 100644 --- a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md +++ b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md @@ -1,10 +1,12 @@ -# `armv8r-none-eabihf` +# `armv8r-none-eabihf` and `thumbv8r-none-eabihf` -* **Tier: 2** +* **Tier: 2**: `armv8r-none-eabihf` +* **Tier: 3**: `thumbv8r-none-eabihf` * **Library Support:** core and alloc (bare-metal, `#![no_std]`) -Bare-metal target for CPUs in the Armv8-R architecture family, supporting -dual ARM/Thumb mode, with ARM mode as the default. +Bare-metal target for CPUs in the Armv8-R architecture family, supporting dual +ARM/Thumb mode. The `armv8r-none-eabi` target uses Arm mode by default and +the `thumbv8r-none-eabihf` target uses Thumb mode by default. Processors in this family include the Arm [Cortex-R52][cortex-r52] and [Cortex-R52+][cortex-r52-plus]. diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs index 0eced9df3c46d..17553fc8f4e40 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs @@ -559,6 +559,21 @@ //@ revisions: thumbv5te_none_eabi //@ [thumbv5te_none_eabi] compile-flags: --target thumbv5te-none-eabi //@ [thumbv5te_none_eabi] needs-llvm-components: arm +//@ revisions: thumbv7a_none_eabi +//@ [thumbv7a_none_eabi] compile-flags: --target thumbv7a-none-eabi +//@ [thumbv7a_none_eabi] needs-llvm-components: arm +//@ revisions: thumbv7a_none_eabihf +//@ [thumbv7a_none_eabihf] compile-flags: --target thumbv7a-none-eabihf +//@ [thumbv7a_none_eabihf] needs-llvm-components: arm +//@ revisions: thumbv7r_none_eabi +//@ [thumbv7r_none_eabi] compile-flags: --target thumbv7r-none-eabi +//@ [thumbv7r_none_eabi] needs-llvm-components: arm +//@ revisions: thumbv7r_none_eabihf +//@ [thumbv7r_none_eabihf] compile-flags: --target thumbv7r-none-eabihf +//@ [thumbv7r_none_eabihf] needs-llvm-components: arm +//@ revisions: thumbv8r_none_eabihf +//@ [thumbv8r_none_eabihf] compile-flags: --target thumbv8r-none-eabihf +//@ [thumbv8r_none_eabihf] needs-llvm-components: arm //@ revisions: thumbv6m_none_eabi //@ [thumbv6m_none_eabi] compile-flags: --target thumbv6m-none-eabi //@ [thumbv6m_none_eabi] needs-llvm-components: arm From fb05cac2aa0c5eb23a8b1603955daa9426f9ae85 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Thu, 1 Jan 2026 17:18:48 +0000 Subject: [PATCH 06/16] Update SUMMARY.md too --- src/doc/rustc/src/SUMMARY.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 8ceeff2c9685e..5d000c900aaaf 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -56,15 +56,15 @@ - [arm-none-eabi](platform-support/arm-none-eabi.md) - [{arm,thumb}v4t-none-eabi](platform-support/armv4t-none-eabi.md) - [{arm,thumb}v5te-none-eabi](platform-support/armv5te-none-eabi.md) - - [armv7a-none-eabi{,hf}](platform-support/armv7a-none-eabi.md) - - [armv7r-none-eabi{,hf}](platform-support/armv7r-none-eabi.md) - - [armebv7r-none-eabi{,hf}](platform-support/armebv7r-none-eabi.md) - - [armv8r-none-eabihf](platform-support/armv8r-none-eabihf.md) + - [{arm,thumb}v7a-none-eabi{,hf}](platform-support/armv7a-none-eabi.md) + - [{arm,thumb}v7r-none-eabi{,hf}](platform-support/armv7r-none-eabi.md) + - [{arm,thumb}v8r-none-eabihf](platform-support/armv8r-none-eabihf.md) - [thumbv6m-none-eabi](./platform-support/thumbv6m-none-eabi.md) - [thumbv7em-none-eabi\*](./platform-support/thumbv7em-none-eabi.md) - [thumbv7m-none-eabi](./platform-support/thumbv7m-none-eabi.md) - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md) - [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md) + - [armebv7r-none-eabi{,hf}](platform-support/armebv7r-none-eabi.md) - [arm\*-unknown-linux-\*](./platform-support/arm-linux.md) - [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md) - [armv5te-unknown-linux-gnueabi](platform-support/armv5te-unknown-linux-gnueabi.md) From 1652f3f1569bf56f84a52e5462ab661151c2ccf1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 3 Oct 2025 21:29:58 +0000 Subject: [PATCH 07/16] Expand with_api_handle_types --- library/proc_macro/src/bridge/client.rs | 115 ++++++++++-------------- library/proc_macro/src/bridge/mod.rs | 16 ---- library/proc_macro/src/bridge/server.rs | 91 ++++++++----------- 3 files changed, 85 insertions(+), 137 deletions(-) diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index e75902eca6bb6..10302cf24f997 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -6,87 +6,66 @@ use std::sync::atomic::AtomicU32; use super::*; -macro_rules! define_client_handles { - ( - 'owned: $($oty:ident,)* - 'interned: $($ity:ident,)* - ) => { - #[repr(C)] - #[allow(non_snake_case)] - pub(super) struct HandleCounters { - $(pub(super) $oty: AtomicU32,)* - $(pub(super) $ity: AtomicU32,)* - } +#[repr(C)] +pub(super) struct HandleCounters { + pub(super) token_stream: AtomicU32, + pub(super) span: AtomicU32, +} - static COUNTERS: HandleCounters = HandleCounters { - $($oty: AtomicU32::new(1),)* - $($ity: AtomicU32::new(1),)* - }; +static COUNTERS: HandleCounters = + HandleCounters { token_stream: AtomicU32::new(1), span: AtomicU32::new(1) }; - $( - pub(crate) struct $oty { - handle: handle::Handle, - } +pub(crate) struct TokenStream { + handle: handle::Handle, +} - impl !Send for $oty {} - impl !Sync for $oty {} +impl !Send for TokenStream {} +impl !Sync for TokenStream {} - // Forward `Drop::drop` to the inherent `drop` method. - impl Drop for $oty { - fn drop(&mut self) { - $oty { - handle: self.handle, - }.drop(); - } - } +// Forward `Drop::drop` to the inherent `drop` method. +impl Drop for TokenStream { + fn drop(&mut self) { + TokenStream { handle: self.handle }.drop(); + } +} - impl Encode for $oty { - fn encode(self, w: &mut Writer, s: &mut S) { - mem::ManuallyDrop::new(self).handle.encode(w, s); - } - } +impl Encode for TokenStream { + fn encode(self, w: &mut Writer, s: &mut S) { + mem::ManuallyDrop::new(self).handle.encode(w, s); + } +} - impl Encode for &$oty { - fn encode(self, w: &mut Writer, s: &mut S) { - self.handle.encode(w, s); - } - } +impl Encode for &TokenStream { + fn encode(self, w: &mut Writer, s: &mut S) { + self.handle.encode(w, s); + } +} - impl Decode<'_, '_, S> for $oty { - fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { - $oty { - handle: handle::Handle::decode(r, s), - } - } - } - )* +impl Decode<'_, '_, S> for TokenStream { + fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { + TokenStream { handle: handle::Handle::decode(r, s) } + } +} - $( - #[derive(Copy, Clone, PartialEq, Eq, Hash)] - pub(crate) struct $ity { - handle: handle::Handle, - } +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub(crate) struct Span { + handle: handle::Handle, +} - impl !Send for $ity {} - impl !Sync for $ity {} +impl !Send for Span {} +impl !Sync for Span {} - impl Encode for $ity { - fn encode(self, w: &mut Writer, s: &mut S) { - self.handle.encode(w, s); - } - } +impl Encode for Span { + fn encode(self, w: &mut Writer, s: &mut S) { + self.handle.encode(w, s); + } +} - impl Decode<'_, '_, S> for $ity { - fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { - $ity { - handle: handle::Handle::decode(r, s), - } - } - } - )* +impl Decode<'_, '_, S> for Span { + fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { + Span { handle: handle::Handle::decode(r, s) } } } -with_api_handle_types!(define_client_handles); // FIXME(eddyb) generate these impls by pattern-matching on the // names of methods - also could use the presence of `fn drop` diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 15a81bd5f96f2..04a75ed797c8e 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -102,22 +102,6 @@ macro_rules! with_api { }; } -// Similar to `with_api`, but only lists the types requiring handles, and they -// are divided into the two storage categories. -macro_rules! with_api_handle_types { - ($m:ident) => { - $m! { - 'owned: - // FreeFunctions is handled manually - TokenStream, - - 'interned: - Span, - // Symbol is handled manually - } - }; -} - pub(crate) struct FreeFunctions; #[allow(unsafe_code)] diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs index 27cc5e5d57e33..c9e42bd1dd15c 100644 --- a/library/proc_macro/src/bridge/server.rs +++ b/library/proc_macro/src/bridge/server.rs @@ -5,68 +5,53 @@ use std::marker::PhantomData; use super::*; -macro_rules! define_server_handles { - ( - 'owned: $($oty:ident,)* - 'interned: $($ity:ident,)* - ) => { - #[allow(non_snake_case)] - pub(super) struct HandleStore { - $($oty: handle::OwnedStore,)* - $($ity: handle::InternedStore,)* - } +pub(super) struct HandleStore { + token_stream: handle::OwnedStore, + span: handle::InternedStore, +} - impl HandleStore { - fn new(handle_counters: &'static client::HandleCounters) -> Self { - HandleStore { - $($oty: handle::OwnedStore::new(&handle_counters.$oty),)* - $($ity: handle::InternedStore::new(&handle_counters.$ity),)* - } - } +impl HandleStore { + fn new(handle_counters: &'static client::HandleCounters) -> Self { + HandleStore { + token_stream: handle::OwnedStore::new(&handle_counters.token_stream), + span: handle::InternedStore::new(&handle_counters.span), } + } +} - $( - impl Encode>> for Marked { - fn encode(self, w: &mut Writer, s: &mut HandleStore>) { - s.$oty.alloc(self).encode(w, s); - } - } +impl Encode>> for Marked { + fn encode(self, w: &mut Writer, s: &mut HandleStore>) { + s.token_stream.alloc(self).encode(w, s); + } +} - impl Decode<'_, '_, HandleStore>> - for Marked - { - fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { - s.$oty.take(handle::Handle::decode(r, &mut ())) - } - } +impl Decode<'_, '_, HandleStore>> + for Marked +{ + fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { + s.token_stream.take(handle::Handle::decode(r, &mut ())) + } +} - impl<'s, S: Types> Decode<'_, 's, HandleStore>> - for &'s Marked - { - fn decode(r: &mut Reader<'_>, s: &'s mut HandleStore>) -> Self { - &s.$oty[handle::Handle::decode(r, &mut ())] - } - } - )* +impl<'s, S: Types> Decode<'_, 's, HandleStore>> + for &'s Marked +{ + fn decode(r: &mut Reader<'_>, s: &'s mut HandleStore>) -> Self { + &s.token_stream[handle::Handle::decode(r, &mut ())] + } +} - $( - impl Encode>> for Marked { - fn encode(self, w: &mut Writer, s: &mut HandleStore>) { - s.$ity.alloc(self).encode(w, s); - } - } +impl Encode>> for Marked { + fn encode(self, w: &mut Writer, s: &mut HandleStore>) { + s.span.alloc(self).encode(w, s); + } +} - impl Decode<'_, '_, HandleStore>> - for Marked - { - fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { - s.$ity.copy(handle::Handle::decode(r, &mut ())) - } - } - )* +impl Decode<'_, '_, HandleStore>> for Marked { + fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { + s.span.copy(handle::Handle::decode(r, &mut ())) } } -with_api_handle_types!(define_server_handles); pub trait Types { type FreeFunctions: 'static; From d3b5f72bc65b37cf8df01915c55e252dc5cd8c40 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 22 Jan 2026 18:10:03 +0000 Subject: [PATCH 08/16] Move all bridge methods into a single type --- .../rustc_expand/src/proc_macro_server.rs | 70 +++++++------- library/proc_macro/src/bridge/client.rs | 6 +- library/proc_macro/src/bridge/mod.rs | 92 ++++++++++--------- library/proc_macro/src/bridge/server.rs | 33 +++---- library/proc_macro/src/bridge/symbol.rs | 2 +- library/proc_macro/src/lib.rs | 62 ++++++++----- .../src/server_impl/rust_analyzer_span.rs | 70 +++++++------- .../src/server_impl/token_id.rs | 70 +++++++------- 8 files changed, 218 insertions(+), 187 deletions(-) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 7688df2d3a55d..4f8ff5588581d 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -552,14 +552,20 @@ impl server::FreeFunctions for Rustc<'_, '_> { } diag.emit(); } -} -impl server::TokenStream for Rustc<'_, '_> { - fn is_empty(&mut self, stream: &Self::TokenStream) -> bool { + fn tt_drop(&mut self, stream: Self::TokenStream) { + drop(stream); + } + + fn tt_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream { + stream.clone() + } + + fn tt_is_empty(&mut self, stream: &Self::TokenStream) -> bool { stream.is_empty() } - fn from_str(&mut self, src: &str) -> Self::TokenStream { + fn tt_from_str(&mut self, src: &str) -> Self::TokenStream { unwrap_or_emit_fatal(source_str_to_stream( self.psess(), FileName::proc_macro_source_code(src), @@ -568,11 +574,11 @@ impl server::TokenStream for Rustc<'_, '_> { )) } - fn to_string(&mut self, stream: &Self::TokenStream) -> String { + fn tt_to_string(&mut self, stream: &Self::TokenStream) -> String { pprust::tts_to_string(stream) } - fn expand_expr(&mut self, stream: &Self::TokenStream) -> Result { + fn tt_expand_expr(&mut self, stream: &Self::TokenStream) -> Result { // Parse the expression from our tokenstream. let expr: PResult<'_, _> = try { let mut p = Parser::new(self.psess(), stream.clone(), Some("proc_macro expand expr")); @@ -633,14 +639,14 @@ impl server::TokenStream for Rustc<'_, '_> { } } - fn from_token_tree( + fn tt_from_token_tree( &mut self, tree: TokenTree, ) -> Self::TokenStream { Self::TokenStream::new((tree, &mut *self).to_internal().into_iter().collect::>()) } - fn concat_trees( + fn tt_concat_trees( &mut self, base: Option, trees: Vec>, @@ -654,7 +660,7 @@ impl server::TokenStream for Rustc<'_, '_> { stream } - fn concat_streams( + fn tt_concat_streams( &mut self, base: Option, streams: Vec, @@ -666,16 +672,14 @@ impl server::TokenStream for Rustc<'_, '_> { stream } - fn into_trees( + fn tt_into_trees( &mut self, stream: Self::TokenStream, ) -> Vec> { FromInternal::from_internal((stream, self)) } -} -impl server::Span for Rustc<'_, '_> { - fn debug(&mut self, span: Self::Span) -> String { + fn span_debug(&mut self, span: Self::Span) -> String { if self.ecx.ecfg.span_debug { format!("{span:?}") } else { @@ -683,7 +687,7 @@ impl server::Span for Rustc<'_, '_> { } } - fn file(&mut self, span: Self::Span) -> String { + fn span_file(&mut self, span: Self::Span) -> String { self.psess() .source_map() .lookup_char_pos(span.lo()) @@ -693,7 +697,7 @@ impl server::Span for Rustc<'_, '_> { .to_string() } - fn local_file(&mut self, span: Self::Span) -> Option { + fn span_local_file(&mut self, span: Self::Span) -> Option { self.psess() .source_map() .lookup_char_pos(span.lo()) @@ -708,15 +712,15 @@ impl server::Span for Rustc<'_, '_> { }) } - fn parent(&mut self, span: Self::Span) -> Option { + fn span_parent(&mut self, span: Self::Span) -> Option { span.parent_callsite() } - fn source(&mut self, span: Self::Span) -> Self::Span { + fn span_source(&mut self, span: Self::Span) -> Self::Span { span.source_callsite() } - fn byte_range(&mut self, span: Self::Span) -> Range { + fn span_byte_range(&mut self, span: Self::Span) -> Range { let source_map = self.psess().source_map(); let relative_start_pos = source_map.lookup_byte_offset(span.lo()).pos; @@ -724,25 +728,25 @@ impl server::Span for Rustc<'_, '_> { Range { start: relative_start_pos.0 as usize, end: relative_end_pos.0 as usize } } - fn start(&mut self, span: Self::Span) -> Self::Span { + fn span_start(&mut self, span: Self::Span) -> Self::Span { span.shrink_to_lo() } - fn end(&mut self, span: Self::Span) -> Self::Span { + fn span_end(&mut self, span: Self::Span) -> Self::Span { span.shrink_to_hi() } - fn line(&mut self, span: Self::Span) -> usize { + fn span_line(&mut self, span: Self::Span) -> usize { let loc = self.psess().source_map().lookup_char_pos(span.lo()); loc.line } - fn column(&mut self, span: Self::Span) -> usize { + fn span_column(&mut self, span: Self::Span) -> usize { let loc = self.psess().source_map().lookup_char_pos(span.lo()); loc.col.to_usize() + 1 } - fn join(&mut self, first: Self::Span, second: Self::Span) -> Option { + fn span_join(&mut self, first: Self::Span, second: Self::Span) -> Option { let self_loc = self.psess().source_map().lookup_char_pos(first.lo()); let other_loc = self.psess().source_map().lookup_char_pos(second.lo()); @@ -753,7 +757,7 @@ impl server::Span for Rustc<'_, '_> { Some(first.to(second)) } - fn subspan( + fn span_subspan( &mut self, span: Self::Span, start: Bound, @@ -789,11 +793,11 @@ impl server::Span for Rustc<'_, '_> { Some(span.with_lo(new_lo).with_hi(new_hi)) } - fn resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span { + fn span_resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span { span.with_ctxt(at.ctxt()) } - fn source_text(&mut self, span: Self::Span) -> Option { + fn span_source_text(&mut self, span: Self::Span) -> Option { self.psess().source_map().span_to_snippet(span).ok() } @@ -821,11 +825,11 @@ impl server::Span for Rustc<'_, '_> { /// span from the metadata of `my_proc_macro` (which we have access to, /// since we've loaded `my_proc_macro` from disk in order to execute it). /// In this way, we have obtained a span pointing into `my_proc_macro` - fn save_span(&mut self, span: Self::Span) -> usize { + fn span_save_span(&mut self, span: Self::Span) -> usize { self.psess().save_proc_macro_span(span) } - fn recover_proc_macro_span(&mut self, id: usize) -> Self::Span { + fn span_recover_proc_macro_span(&mut self, id: usize) -> Self::Span { let (resolver, krate, def_site) = (&*self.ecx.resolver, self.krate, self.def_site); *self.rebased_spans.entry(id).or_insert_with(|| { // FIXME: `SyntaxContext` for spans from proc macro crates is lost during encoding, @@ -833,15 +837,19 @@ impl server::Span for Rustc<'_, '_> { resolver.get_proc_macro_quoted_span(krate, id).with_ctxt(def_site.ctxt()) }) } -} -impl server::Symbol for Rustc<'_, '_> { - fn normalize_and_validate_ident(&mut self, string: &str) -> Result { + fn symbol_normalize_and_validate_ident(&mut self, string: &str) -> Result { let sym = nfc_normalize(string); if rustc_lexer::is_ident(sym.as_str()) { Ok(sym) } else { Err(()) } } } +impl server::TokenStream for Rustc<'_, '_> {} + +impl server::Span for Rustc<'_, '_> {} + +impl server::Symbol for Rustc<'_, '_> {} + impl server::Server for Rustc<'_, '_> { fn globals(&mut self) -> ExpnGlobals { ExpnGlobals { diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index 10302cf24f997..d954177e7df55 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -25,7 +25,7 @@ impl !Sync for TokenStream {} // Forward `Drop::drop` to the inherent `drop` method. impl Drop for TokenStream { fn drop(&mut self) { - TokenStream { handle: self.handle }.drop(); + FreeFunctions::tt_drop(TokenStream { handle: self.handle }); } } @@ -75,7 +75,7 @@ impl Decode<'_, '_, S> for Span { impl Clone for TokenStream { fn clone(&self) -> Self { - self.clone() + FreeFunctions::tt_clone(self) } } @@ -95,7 +95,7 @@ impl Span { impl fmt::Debug for Span { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&self.debug()) + f.write_str(&FreeFunctions::span_debug(*self)) } } diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 04a75ed797c8e..027f94c36ff27 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -54,50 +54,50 @@ macro_rules! with_api { fn track_path(path: &str); fn literal_from_str(s: &str) -> Result, ()>; fn emit_diagnostic(diagnostic: Diagnostic<$S::Span>); - }, - TokenStream { - fn drop($self: $S::TokenStream); - fn clone($self: &$S::TokenStream) -> $S::TokenStream; - fn is_empty($self: &$S::TokenStream) -> bool; - fn expand_expr($self: &$S::TokenStream) -> Result<$S::TokenStream, ()>; - fn from_str(src: &str) -> $S::TokenStream; - fn to_string($self: &$S::TokenStream) -> String; - fn from_token_tree( + + fn tt_drop(stream: $S::TokenStream); + fn tt_clone(stream: &$S::TokenStream) -> $S::TokenStream; + fn tt_is_empty(stream: &$S::TokenStream) -> bool; + fn tt_expand_expr(stream: &$S::TokenStream) -> Result<$S::TokenStream, ()>; + fn tt_from_str(src: &str) -> $S::TokenStream; + fn tt_to_string(stream: &$S::TokenStream) -> String; + fn tt_from_token_tree( tree: TokenTree<$S::TokenStream, $S::Span, $S::Symbol>, ) -> $S::TokenStream; - fn concat_trees( + fn tt_concat_trees( base: Option<$S::TokenStream>, trees: Vec>, ) -> $S::TokenStream; - fn concat_streams( + fn tt_concat_streams( base: Option<$S::TokenStream>, streams: Vec<$S::TokenStream>, ) -> $S::TokenStream; - fn into_trees( - $self: $S::TokenStream + fn tt_into_trees( + stream: $S::TokenStream ) -> Vec>; + + fn span_debug(span: $S::Span) -> String; + fn span_parent(span: $S::Span) -> Option<$S::Span>; + fn span_source(span: $S::Span) -> $S::Span; + fn span_byte_range(span: $S::Span) -> Range; + fn span_start(span: $S::Span) -> $S::Span; + fn span_end(span: $S::Span) -> $S::Span; + fn span_line(span: $S::Span) -> usize; + fn span_column(span: $S::Span) -> usize; + fn span_file(span: $S::Span) -> String; + fn span_local_file(span: $S::Span) -> Option; + fn span_join(span: $S::Span, other: $S::Span) -> Option<$S::Span>; + fn span_subspan(span: $S::Span, start: Bound, end: Bound) -> Option<$S::Span>; + fn span_resolved_at(span: $S::Span, at: $S::Span) -> $S::Span; + fn span_source_text(span: $S::Span) -> Option; + fn span_save_span(span: $S::Span) -> usize; + fn span_recover_proc_macro_span(id: usize) -> $S::Span; + + fn symbol_normalize_and_validate_ident(string: &str) -> Result<$S::Symbol, ()>; }, - Span { - fn debug($self: $S::Span) -> String; - fn parent($self: $S::Span) -> Option<$S::Span>; - fn source($self: $S::Span) -> $S::Span; - fn byte_range($self: $S::Span) -> Range; - fn start($self: $S::Span) -> $S::Span; - fn end($self: $S::Span) -> $S::Span; - fn line($self: $S::Span) -> usize; - fn column($self: $S::Span) -> usize; - fn file($self: $S::Span) -> String; - fn local_file($self: $S::Span) -> Option; - fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>; - fn subspan($self: $S::Span, start: Bound, end: Bound) -> Option<$S::Span>; - fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span; - fn source_text($self: $S::Span) -> Option; - fn save_span($self: $S::Span) -> usize; - fn recover_proc_macro_span(id: usize) -> $S::Span; - }, - Symbol { - fn normalize_and_validate_ident(string: &str) -> Result<$S::Symbol, ()>; - }, + TokenStream {}, + Span {}, + Symbol {}, } }; } @@ -156,20 +156,22 @@ mod api_tags { use super::rpc::{Decode, Encode, Reader, Writer}; macro_rules! declare_tags { - ($($name:ident { - $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* - }),* $(,)?) => { - $( - pub(super) enum $name { - $($method),* - } - rpc_encode_decode!(enum $name { $($method),* }); - )* + ( + FreeFunctions { + $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* + }, + $($name:ident { $($x:tt)* }),* $(,)? + ) => { + pub(super) enum FreeFunctions { + $($method),* + } + rpc_encode_decode!(enum FreeFunctions { $($method),* }); + pub(super) enum Method { - $($name($name)),* + FreeFunctions(FreeFunctions), } - rpc_encode_decode!(enum Method { $($name(m)),* }); + rpc_encode_decode!(enum Method { FreeFunctions(m) }); } } with_api!(self, self, declare_tags); diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs index c9e42bd1dd15c..16037ed46f063 100644 --- a/library/proc_macro/src/bridge/server.rs +++ b/library/proc_macro/src/bridge/server.rs @@ -60,24 +60,12 @@ pub trait Types { type Symbol: 'static; } -/// Declare an associated fn of one of the traits below, adding necessary -/// default bodies. -macro_rules! associated_fn { - (fn drop(&mut self, $arg:ident: $arg_ty:ty)) => - (fn drop(&mut self, $arg: $arg_ty) { mem::drop($arg) }); - - (fn clone(&mut self, $arg:ident: $arg_ty:ty) -> $ret_ty:ty) => - (fn clone(&mut self, $arg: $arg_ty) -> $ret_ty { $arg.clone() }); - - ($($item:tt)*) => ($($item)*;) -} - macro_rules! declare_server_traits { ($($name:ident { $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* }),* $(,)?) => { $(pub trait $name: Types { - $(associated_fn!(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?);)* + $(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?;)* })* pub trait Server: Types $(+ $name)* { @@ -130,18 +118,23 @@ struct Dispatcher { } macro_rules! define_dispatcher_impl { - ($($name:ident { - $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* - }),* $(,)?) => { + ( + FreeFunctions { + $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* + }, + $($name:ident { $($x:tt)* }),* $(,)? + ) => { // FIXME(eddyb) `pub` only for `ExecutionStrategy` below. pub trait DispatcherTrait { // HACK(eddyb) these are here to allow `Self::$name` to work below. + type FreeFunctions; $(type $name;)* fn dispatch(&mut self, buf: Buffer) -> Buffer; } impl DispatcherTrait for Dispatcher> { + type FreeFunctions = as Types>::FreeFunctions; $(type $name = as Types>::$name;)* fn dispatch(&mut self, mut buf: Buffer) -> Buffer { @@ -149,11 +142,11 @@ macro_rules! define_dispatcher_impl { let mut reader = &buf[..]; match api_tags::Method::decode(&mut reader, &mut ()) { - $(api_tags::Method::$name(m) => match m { - $(api_tags::$name::$method => { + api_tags::Method::FreeFunctions(m) => match m { + $(api_tags::FreeFunctions::$method => { let mut call_method = || { $(let $arg = <$arg_ty>::decode(&mut reader, handle_store);)* - $name::$method(server, $($arg),*) + FreeFunctions::$method(server, $($arg),*) }; // HACK(eddyb) don't use `panic::catch_unwind` in a panic. // If client and server happen to use the same `std`, @@ -169,7 +162,7 @@ macro_rules! define_dispatcher_impl { buf.clear(); r.encode(&mut buf, handle_store); })* - }),* + } } buf } diff --git a/library/proc_macro/src/bridge/symbol.rs b/library/proc_macro/src/bridge/symbol.rs index e070ec07681d3..6366ac2e6a939 100644 --- a/library/proc_macro/src/bridge/symbol.rs +++ b/library/proc_macro/src/bridge/symbol.rs @@ -46,7 +46,7 @@ impl Symbol { if string.is_ascii() { Err(()) } else { - client::Symbol::normalize_and_validate_ident(string) + client::FreeFunctions::symbol_normalize_and_validate_ident(string) } .unwrap_or_else(|_| panic!("`{:?}` is not a valid identifier", string)) } diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index a005f743ddfac..8d5491e918510 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -158,7 +158,7 @@ impl TokenStream { /// Checks if this `TokenStream` is empty. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub fn is_empty(&self) -> bool { - self.0.as_ref().map(|h| h.is_empty()).unwrap_or(true) + self.0.as_ref().map(|h| bridge::client::FreeFunctions::tt_is_empty(h)).unwrap_or(true) } /// Parses this `TokenStream` as an expression and attempts to expand any @@ -174,7 +174,7 @@ impl TokenStream { #[unstable(feature = "proc_macro_expand", issue = "90765")] pub fn expand_expr(&self) -> Result { let stream = self.0.as_ref().ok_or(ExpandError)?; - match bridge::client::TokenStream::expand_expr(stream) { + match bridge::client::FreeFunctions::tt_expand_expr(stream) { Ok(stream) => Ok(TokenStream(Some(stream))), Err(_) => Err(ExpandError), } @@ -193,7 +193,7 @@ impl FromStr for TokenStream { type Err = LexError; fn from_str(src: &str) -> Result { - Ok(TokenStream(Some(bridge::client::TokenStream::from_str(src)))) + Ok(TokenStream(Some(bridge::client::FreeFunctions::tt_from_str(src)))) } } @@ -212,7 +212,7 @@ impl FromStr for TokenStream { impl fmt::Display for TokenStream { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.0 { - Some(ts) => write!(f, "{}", ts.to_string()), + Some(ts) => write!(f, "{}", bridge::client::FreeFunctions::tt_to_string(ts)), None => Ok(()), } } @@ -252,7 +252,9 @@ fn tree_to_bridge_tree( #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl From for TokenStream { fn from(tree: TokenTree) -> TokenStream { - TokenStream(Some(bridge::client::TokenStream::from_token_tree(tree_to_bridge_tree(tree)))) + TokenStream(Some(bridge::client::FreeFunctions::tt_from_token_tree(tree_to_bridge_tree( + tree, + )))) } } @@ -281,7 +283,7 @@ impl ConcatTreesHelper { if self.trees.is_empty() { TokenStream(None) } else { - TokenStream(Some(bridge::client::TokenStream::concat_trees(None, self.trees))) + TokenStream(Some(bridge::client::FreeFunctions::tt_concat_trees(None, self.trees))) } } @@ -289,7 +291,7 @@ impl ConcatTreesHelper { if self.trees.is_empty() { return; } - stream.0 = Some(bridge::client::TokenStream::concat_trees(stream.0.take(), self.trees)) + stream.0 = Some(bridge::client::FreeFunctions::tt_concat_trees(stream.0.take(), self.trees)) } } @@ -314,7 +316,7 @@ impl ConcatStreamsHelper { if self.streams.len() <= 1 { TokenStream(self.streams.pop()) } else { - TokenStream(Some(bridge::client::TokenStream::concat_streams(None, self.streams))) + TokenStream(Some(bridge::client::FreeFunctions::tt_concat_streams(None, self.streams))) } } @@ -326,7 +328,7 @@ impl ConcatStreamsHelper { if base.is_none() && self.streams.len() == 1 { stream.0 = self.streams.pop(); } else { - stream.0 = Some(bridge::client::TokenStream::concat_streams(base, self.streams)); + stream.0 = Some(bridge::client::FreeFunctions::tt_concat_streams(base, self.streams)); } } } @@ -437,7 +439,12 @@ pub mod token_stream { type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { - IntoIter(self.0.map(|v| v.into_trees()).unwrap_or_default().into_iter()) + IntoIter( + self.0 + .map(|v| bridge::client::FreeFunctions::tt_into_trees(v)) + .unwrap_or_default() + .into_iter(), + ) } } } @@ -509,7 +516,7 @@ impl Span { /// `self` was generated from, if any. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn parent(&self) -> Option { - self.0.parent().map(Span) + bridge::client::FreeFunctions::span_parent(self.0).map(Span) } /// The span for the origin source code that `self` was generated from. If @@ -517,25 +524,25 @@ impl Span { /// value is the same as `*self`. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn source(&self) -> Span { - Span(self.0.source()) + Span(bridge::client::FreeFunctions::span_source(self.0)) } /// Returns the span's byte position range in the source file. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn byte_range(&self) -> Range { - self.0.byte_range() + bridge::client::FreeFunctions::span_byte_range(self.0) } /// Creates an empty span pointing to directly before this span. #[stable(feature = "proc_macro_span_location", since = "1.88.0")] pub fn start(&self) -> Span { - Span(self.0.start()) + Span(bridge::client::FreeFunctions::span_start(self.0)) } /// Creates an empty span pointing to directly after this span. #[stable(feature = "proc_macro_span_location", since = "1.88.0")] pub fn end(&self) -> Span { - Span(self.0.end()) + Span(bridge::client::FreeFunctions::span_end(self.0)) } /// The one-indexed line of the source file where the span starts. @@ -543,7 +550,7 @@ impl Span { /// To obtain the line of the span's end, use `span.end().line()`. #[stable(feature = "proc_macro_span_location", since = "1.88.0")] pub fn line(&self) -> usize { - self.0.line() + bridge::client::FreeFunctions::span_line(self.0) } /// The one-indexed column of the source file where the span starts. @@ -551,7 +558,7 @@ impl Span { /// To obtain the column of the span's end, use `span.end().column()`. #[stable(feature = "proc_macro_span_location", since = "1.88.0")] pub fn column(&self) -> usize { - self.0.column() + bridge::client::FreeFunctions::span_column(self.0) } /// The path to the source file in which this span occurs, for display purposes. @@ -560,7 +567,7 @@ impl Span { /// It might be remapped (e.g. `"/src/lib.rs"`) or an artificial path (e.g. `""`). #[stable(feature = "proc_macro_span_file", since = "1.88.0")] pub fn file(&self) -> String { - self.0.file() + bridge::client::FreeFunctions::span_file(self.0) } /// The path to the source file in which this span occurs on the local file system. @@ -570,7 +577,7 @@ impl Span { /// This path should not be embedded in the output of the macro; prefer `file()` instead. #[stable(feature = "proc_macro_span_file", since = "1.88.0")] pub fn local_file(&self) -> Option { - self.0.local_file().map(PathBuf::from) + bridge::client::FreeFunctions::span_local_file(self.0).map(PathBuf::from) } /// Creates a new span encompassing `self` and `other`. @@ -578,14 +585,14 @@ impl Span { /// Returns `None` if `self` and `other` are from different files. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn join(&self, other: Span) -> Option { - self.0.join(other.0).map(Span) + bridge::client::FreeFunctions::span_join(self.0, other.0).map(Span) } /// Creates a new span with the same line/column information as `self` but /// that resolves symbols as though it were at `other`. #[stable(feature = "proc_macro_span_resolved_at", since = "1.45.0")] pub fn resolved_at(&self, other: Span) -> Span { - Span(self.0.resolved_at(other.0)) + Span(bridge::client::FreeFunctions::span_resolved_at(self.0, other.0)) } /// Creates a new span with the same name resolution behavior as `self` but @@ -610,21 +617,21 @@ impl Span { /// be used for diagnostics only. #[stable(feature = "proc_macro_source_text", since = "1.66.0")] pub fn source_text(&self) -> Option { - self.0.source_text() + bridge::client::FreeFunctions::span_source_text(self.0) } // Used by the implementation of `Span::quote` #[doc(hidden)] #[unstable(feature = "proc_macro_internals", issue = "27812")] pub fn save_span(&self) -> usize { - self.0.save_span() + bridge::client::FreeFunctions::span_save_span(self.0) } // Used by the implementation of `Span::quote` #[doc(hidden)] #[unstable(feature = "proc_macro_internals", issue = "27812")] pub fn recover_proc_macro_span(id: usize) -> Span { - Span(bridge::client::Span::recover_proc_macro_span(id)) + Span(bridge::client::FreeFunctions::span_recover_proc_macro_span(id)) } diagnostic_method!(error, Level::Error); @@ -1389,7 +1396,12 @@ impl Literal { // was 'c' or whether it was '\u{63}'. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn subspan>(&self, range: R) -> Option { - self.0.span.subspan(range.start_bound().cloned(), range.end_bound().cloned()).map(Span) + bridge::client::FreeFunctions::span_subspan( + self.0.span, + range.start_bound().cloned(), + range.end_bound().cloned(), + ) + .map(Span) } fn with_symbol_and_suffix(&self, f: impl FnOnce(&str, &str) -> R) -> R { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 32725afc55272..11bef8fbb85be 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -58,13 +58,19 @@ impl server::FreeFunctions for RaSpanServer<'_> { fn emit_diagnostic(&mut self, _: Diagnostic) { // FIXME handle diagnostic } -} -impl server::TokenStream for RaSpanServer<'_> { - fn is_empty(&mut self, stream: &Self::TokenStream) -> bool { + fn tt_drop(&mut self, stream: Self::TokenStream) { + drop(stream); + } + + fn tt_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream { + stream.clone() + } + + fn tt_is_empty(&mut self, stream: &Self::TokenStream) -> bool { stream.is_empty() } - fn from_str(&mut self, src: &str) -> Self::TokenStream { + fn tt_from_str(&mut self, src: &str) -> Self::TokenStream { Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| { Self::TokenStream::from_str( &format!("compile_error!(\"failed to parse str to token stream: {e}\")"), @@ -73,15 +79,15 @@ impl server::TokenStream for RaSpanServer<'_> { .unwrap() }) } - fn to_string(&mut self, stream: &Self::TokenStream) -> String { + fn tt_to_string(&mut self, stream: &Self::TokenStream) -> String { stream.to_string() } - fn from_token_tree(&mut self, tree: TokenTree) -> Self::TokenStream { + fn tt_from_token_tree(&mut self, tree: TokenTree) -> Self::TokenStream { Self::TokenStream::new(vec![tree]) } - fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result { + fn tt_expand_expr(&mut self, self_: &Self::TokenStream) -> Result { // FIXME: requires db, more importantly this requires name resolution so we would need to // eagerly expand this proc-macro, but we can't know that this proc-macro is eager until we // expand it ... @@ -90,7 +96,7 @@ impl server::TokenStream for RaSpanServer<'_> { Ok(self_.clone()) } - fn concat_trees( + fn tt_concat_trees( &mut self, base: Option, trees: Vec>, @@ -106,7 +112,7 @@ impl server::TokenStream for RaSpanServer<'_> { } } - fn concat_streams( + fn tt_concat_streams( &mut self, base: Option, streams: Vec, @@ -118,28 +124,26 @@ impl server::TokenStream for RaSpanServer<'_> { stream } - fn into_trees(&mut self, stream: Self::TokenStream) -> Vec> { + fn tt_into_trees(&mut self, stream: Self::TokenStream) -> Vec> { (*stream.0).clone() } -} -impl server::Span for RaSpanServer<'_> { - fn debug(&mut self, span: Self::Span) -> String { + fn span_debug(&mut self, span: Self::Span) -> String { format!("{:?}", span) } - fn file(&mut self, span: Self::Span) -> String { + fn span_file(&mut self, span: Self::Span) -> String { self.callback.as_mut().map(|cb| cb.file(span.anchor.file_id.file_id())).unwrap_or_default() } - fn local_file(&mut self, span: Self::Span) -> Option { + fn span_local_file(&mut self, span: Self::Span) -> Option { self.callback.as_mut().and_then(|cb| cb.local_file(span.anchor.file_id.file_id())) } - fn save_span(&mut self, _span: Self::Span) -> usize { + fn span_save_span(&mut self, _span: Self::Span) -> usize { // FIXME, quote is incompatible with third-party tools // This is called by the quote proc-macro which is expanded when the proc-macro is compiled // As such, r-a will never observe this 0 } - fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span { + fn span_recover_proc_macro_span(&mut self, _id: usize) -> Self::Span { // FIXME, quote is incompatible with third-party tools // This is called by the expansion of quote!, r-a will observe this, but we don't have // access to the spans that were encoded @@ -149,23 +153,23 @@ impl server::Span for RaSpanServer<'_> { /// /// See PR: /// https://github.com/rust-lang/rust/pull/55780 - fn source_text(&mut self, span: Self::Span) -> Option { + fn span_source_text(&mut self, span: Self::Span) -> Option { self.callback.as_mut()?.source_text(span) } - fn parent(&mut self, _span: Self::Span) -> Option { + fn span_parent(&mut self, _span: Self::Span) -> Option { // FIXME requires db, looks up the parent call site None } - fn source(&mut self, span: Self::Span) -> Self::Span { + fn span_source(&mut self, span: Self::Span) -> Self::Span { // FIXME requires db, returns the top level call site span } - fn byte_range(&mut self, span: Self::Span) -> Range { + fn span_byte_range(&mut self, span: Self::Span) -> Range { // FIXME requires db to resolve the ast id, THIS IS NOT INCREMENTAL Range { start: span.range.start().into(), end: span.range.end().into() } } - fn join(&mut self, first: Self::Span, second: Self::Span) -> Option { + fn span_join(&mut self, first: Self::Span, second: Self::Span) -> Option { // We can't modify the span range for fixup spans, those are meaningful to fixup, so just // prefer the non-fixup span. if first.anchor.ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER { @@ -193,7 +197,7 @@ impl server::Span for RaSpanServer<'_> { ctx: second.ctx, }) } - fn subspan( + fn span_subspan( &mut self, span: Self::Span, start: Bound, @@ -237,11 +241,11 @@ impl server::Span for RaSpanServer<'_> { }) } - fn resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span { + fn span_resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span { Span { ctx: at.ctx, ..span } } - fn end(&mut self, span: Self::Span) -> Self::Span { + fn span_end(&mut self, span: Self::Span) -> Self::Span { // We can't modify the span range for fixup spans, those are meaningful to fixup. if span.anchor.ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER { return span; @@ -249,7 +253,7 @@ impl server::Span for RaSpanServer<'_> { Span { range: TextRange::empty(span.range.end()), ..span } } - fn start(&mut self, span: Self::Span) -> Self::Span { + fn span_start(&mut self, span: Self::Span) -> Self::Span { // We can't modify the span range for fixup spans, those are meaningful to fixup. if span.anchor.ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER { return span; @@ -257,24 +261,28 @@ impl server::Span for RaSpanServer<'_> { Span { range: TextRange::empty(span.range.start()), ..span } } - fn line(&mut self, _span: Self::Span) -> usize { + fn span_line(&mut self, _span: Self::Span) -> usize { // FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL 1 } - fn column(&mut self, _span: Self::Span) -> usize { + fn span_column(&mut self, _span: Self::Span) -> usize { // FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL 1 } -} -impl server::Symbol for RaSpanServer<'_> { - fn normalize_and_validate_ident(&mut self, string: &str) -> Result { + fn symbol_normalize_and_validate_ident(&mut self, string: &str) -> Result { // FIXME: nfc-normalize and validate idents Ok(::intern_symbol(string)) } } +impl server::TokenStream for RaSpanServer<'_> {} + +impl server::Span for RaSpanServer<'_> {} + +impl server::Symbol for RaSpanServer<'_> {} + impl server::Server for RaSpanServer<'_> { fn globals(&mut self) -> ExpnGlobals { ExpnGlobals { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index a968ea4cd225e..be843d5c878a8 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -61,13 +61,19 @@ impl server::FreeFunctions for SpanIdServer<'_> { } fn emit_diagnostic(&mut self, _: Diagnostic) {} -} -impl server::TokenStream for SpanIdServer<'_> { - fn is_empty(&mut self, stream: &Self::TokenStream) -> bool { + fn tt_drop(&mut self, stream: Self::TokenStream) { + drop(stream); + } + + fn tt_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream { + stream.clone() + } + + fn tt_is_empty(&mut self, stream: &Self::TokenStream) -> bool { stream.is_empty() } - fn from_str(&mut self, src: &str) -> Self::TokenStream { + fn tt_from_str(&mut self, src: &str) -> Self::TokenStream { Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| { Self::TokenStream::from_str( &format!("compile_error!(\"failed to parse str to token stream: {e}\")"), @@ -76,18 +82,18 @@ impl server::TokenStream for SpanIdServer<'_> { .unwrap() }) } - fn to_string(&mut self, stream: &Self::TokenStream) -> String { + fn tt_to_string(&mut self, stream: &Self::TokenStream) -> String { stream.to_string() } - fn from_token_tree(&mut self, tree: TokenTree) -> Self::TokenStream { + fn tt_from_token_tree(&mut self, tree: TokenTree) -> Self::TokenStream { Self::TokenStream::new(vec![tree]) } - fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result { + fn tt_expand_expr(&mut self, self_: &Self::TokenStream) -> Result { Ok(self_.clone()) } - fn concat_trees( + fn tt_concat_trees( &mut self, base: Option, trees: Vec>, @@ -103,7 +109,7 @@ impl server::TokenStream for SpanIdServer<'_> { } } - fn concat_streams( + fn tt_concat_streams( &mut self, base: Option, streams: Vec, @@ -115,49 +121,47 @@ impl server::TokenStream for SpanIdServer<'_> { stream } - fn into_trees(&mut self, stream: Self::TokenStream) -> Vec> { + fn tt_into_trees(&mut self, stream: Self::TokenStream) -> Vec> { (*stream.0).clone() } -} -impl server::Span for SpanIdServer<'_> { - fn debug(&mut self, span: Self::Span) -> String { + fn span_debug(&mut self, span: Self::Span) -> String { format!("{:?}", span.0) } - fn file(&mut self, _span: Self::Span) -> String { + fn span_file(&mut self, _span: Self::Span) -> String { String::new() } - fn local_file(&mut self, _span: Self::Span) -> Option { + fn span_local_file(&mut self, _span: Self::Span) -> Option { None } - fn save_span(&mut self, _span: Self::Span) -> usize { + fn span_save_span(&mut self, _span: Self::Span) -> usize { 0 } - fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span { + fn span_recover_proc_macro_span(&mut self, _id: usize) -> Self::Span { self.call_site } /// Recent feature, not yet in the proc_macro /// /// See PR: /// https://github.com/rust-lang/rust/pull/55780 - fn source_text(&mut self, _span: Self::Span) -> Option { + fn span_source_text(&mut self, _span: Self::Span) -> Option { None } - fn parent(&mut self, _span: Self::Span) -> Option { + fn span_parent(&mut self, _span: Self::Span) -> Option { None } - fn source(&mut self, span: Self::Span) -> Self::Span { + fn span_source(&mut self, span: Self::Span) -> Self::Span { span } - fn byte_range(&mut self, _span: Self::Span) -> Range { + fn span_byte_range(&mut self, _span: Self::Span) -> Range { Range { start: 0, end: 0 } } - fn join(&mut self, first: Self::Span, _second: Self::Span) -> Option { + fn span_join(&mut self, first: Self::Span, _second: Self::Span) -> Option { // Just return the first span again, because some macros will unwrap the result. Some(first) } - fn subspan( + fn span_subspan( &mut self, span: Self::Span, _start: Bound, @@ -166,34 +170,38 @@ impl server::Span for SpanIdServer<'_> { // Just return the span again, because some macros will unwrap the result. Some(span) } - fn resolved_at(&mut self, _span: Self::Span, _at: Self::Span) -> Self::Span { + fn span_resolved_at(&mut self, _span: Self::Span, _at: Self::Span) -> Self::Span { self.call_site } - fn end(&mut self, _self_: Self::Span) -> Self::Span { + fn span_end(&mut self, _self_: Self::Span) -> Self::Span { self.call_site } - fn start(&mut self, _self_: Self::Span) -> Self::Span { + fn span_start(&mut self, _self_: Self::Span) -> Self::Span { self.call_site } - fn line(&mut self, _span: Self::Span) -> usize { + fn span_line(&mut self, _span: Self::Span) -> usize { 1 } - fn column(&mut self, _span: Self::Span) -> usize { + fn span_column(&mut self, _span: Self::Span) -> usize { 1 } -} -impl server::Symbol for SpanIdServer<'_> { - fn normalize_and_validate_ident(&mut self, string: &str) -> Result { + fn symbol_normalize_and_validate_ident(&mut self, string: &str) -> Result { // FIXME: nfc-normalize and validate idents Ok(::intern_symbol(string)) } } +impl server::TokenStream for SpanIdServer<'_> {} + +impl server::Span for SpanIdServer<'_> {} + +impl server::Symbol for SpanIdServer<'_> {} + impl server::Server for SpanIdServer<'_> { fn globals(&mut self) -> ExpnGlobals { ExpnGlobals { From 31c696d0623ca7d35ceb7b4f8a94d24b7bc166b0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 22 Jan 2026 18:28:51 +0000 Subject: [PATCH 09/16] Various simplifications after moving all bridge methods to a single type --- .../rustc_expand/src/proc_macro_server.rs | 6 -- library/proc_macro/src/bridge/client.rs | 15 ++-- library/proc_macro/src/bridge/mod.rs | 29 +++----- library/proc_macro/src/bridge/server.rs | 73 ++++++++++--------- .../src/server_impl/rust_analyzer_span.rs | 6 -- .../src/server_impl/token_id.rs | 6 -- 6 files changed, 60 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 4f8ff5588581d..1bf2edafd7fdb 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -844,12 +844,6 @@ impl server::FreeFunctions for Rustc<'_, '_> { } } -impl server::TokenStream for Rustc<'_, '_> {} - -impl server::Span for Rustc<'_, '_> {} - -impl server::Symbol for Rustc<'_, '_> {} - impl server::Server for Rustc<'_, '_> { fn globals(&mut self) -> ExpnGlobals { ExpnGlobals { diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index d954177e7df55..ffbf6767833f9 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -103,16 +103,19 @@ pub(crate) use super::FreeFunctions; pub(crate) use super::symbol::Symbol; macro_rules! define_client_side { - ($($name:ident { - $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* - }),* $(,)?) => { - $(impl $name { + ( + FreeFunctions { + $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* + }, + $($name:ident),* $(,)? + ) => { + impl FreeFunctions { $(pub(crate) fn $method($($arg: $arg_ty),*) $(-> $ret_ty)? { Bridge::with(|bridge| { let mut buf = bridge.cached_buffer.take(); buf.clear(); - api_tags::Method::$name(api_tags::$name::$method).encode(&mut buf, &mut ()); + api_tags::Method::$method.encode(&mut buf, &mut ()); $($arg.encode(&mut buf, &mut ());)* buf = bridge.dispatch.call(buf); @@ -124,7 +127,7 @@ macro_rules! define_client_side { r.unwrap_or_else(|e| panic::resume_unwind(e.into())) }) })* - })* + } } } with_api!(self, self, define_client_side); diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 027f94c36ff27..ae0f5974de520 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -21,14 +21,15 @@ use crate::{Delimiter, Level, Spacing}; /// `with_api!(MySelf, my_self, my_macro)` expands to: /// ```rust,ignore (pseudo-code) /// my_macro! { -/// // ... -/// Literal { +/// FreeFunctions { /// // ... -/// fn character(ch: char) -> MySelf::Literal; +/// fn lit_character(ch: char) -> MySelf::Literal; /// // ... -/// fn span(my_self: &MySelf::Literal) -> MySelf::Span; -/// fn set_span(my_self: &mut MySelf::Literal, span: MySelf::Span); +/// fn lit_span(my_self: &MySelf::Literal) -> MySelf::Span; +/// fn lit_set_span(my_self: &mut MySelf::Literal, span: MySelf::Span); /// }, +/// Literal, +/// Span, /// // ... /// } /// ``` @@ -95,9 +96,9 @@ macro_rules! with_api { fn symbol_normalize_and_validate_ident(string: &str) -> Result<$S::Symbol, ()>; }, - TokenStream {}, - Span {}, - Symbol {}, + TokenStream, + Span, + Symbol, } }; } @@ -160,18 +161,12 @@ mod api_tags { FreeFunctions { $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* }, - $($name:ident { $($x:tt)* }),* $(,)? + $($name:ident),* $(,)? ) => { - pub(super) enum FreeFunctions { - $($method),* - } - rpc_encode_decode!(enum FreeFunctions { $($method),* }); - - pub(super) enum Method { - FreeFunctions(FreeFunctions), + $($method),* } - rpc_encode_decode!(enum Method { FreeFunctions(m) }); + rpc_encode_decode!(enum Method { $($method),* }); } } with_api!(self, self, declare_tags); diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs index 16037ed46f063..7701ba6899f63 100644 --- a/library/proc_macro/src/bridge/server.rs +++ b/library/proc_macro/src/bridge/server.rs @@ -61,14 +61,17 @@ pub trait Types { } macro_rules! declare_server_traits { - ($($name:ident { - $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* - }),* $(,)?) => { - $(pub trait $name: Types { + ( + FreeFunctions { + $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* + }, + $($name:ident),* $(,)? + ) => { + pub trait FreeFunctions: Types { $(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?;)* - })* + } - pub trait Server: Types $(+ $name)* { + pub trait Server: Types + FreeFunctions { fn globals(&mut self) -> ExpnGlobals; /// Intern a symbol received from RPC @@ -96,18 +99,22 @@ impl Server for MarkedTypes { } macro_rules! define_mark_types_impls { - ($($name:ident { - $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* - }),* $(,)?) => { + ( + FreeFunctions { + $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* + }, + $($name:ident),* $(,)? + ) => { impl Types for MarkedTypes { + type FreeFunctions = Marked; $(type $name = Marked;)* } - $(impl $name for MarkedTypes { + impl FreeFunctions for MarkedTypes { $(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)? { - <_>::mark($name::$method(&mut self.0, $($arg.unmark()),*)) + <_>::mark(FreeFunctions::$method(&mut self.0, $($arg.unmark()),*)) })* - })* + } } } with_api!(Self, self_, define_mark_types_impls); @@ -122,7 +129,7 @@ macro_rules! define_dispatcher_impl { FreeFunctions { $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* }, - $($name:ident { $($x:tt)* }),* $(,)? + $($name:ident),* $(,)? ) => { // FIXME(eddyb) `pub` only for `ExecutionStrategy` below. pub trait DispatcherTrait { @@ -142,27 +149,25 @@ macro_rules! define_dispatcher_impl { let mut reader = &buf[..]; match api_tags::Method::decode(&mut reader, &mut ()) { - api_tags::Method::FreeFunctions(m) => match m { - $(api_tags::FreeFunctions::$method => { - let mut call_method = || { - $(let $arg = <$arg_ty>::decode(&mut reader, handle_store);)* - FreeFunctions::$method(server, $($arg),*) - }; - // HACK(eddyb) don't use `panic::catch_unwind` in a panic. - // If client and server happen to use the same `std`, - // `catch_unwind` asserts that the panic counter was 0, - // even when the closure passed to it didn't panic. - let r = if thread::panicking() { - Ok(call_method()) - } else { - panic::catch_unwind(panic::AssertUnwindSafe(call_method)) - .map_err(PanicMessage::from) - }; - - buf.clear(); - r.encode(&mut buf, handle_store); - })* - } + $(api_tags::Method::$method => { + let mut call_method = || { + $(let $arg = <$arg_ty>::decode(&mut reader, handle_store);)* + FreeFunctions::$method(server, $($arg),*) + }; + // HACK(eddyb) don't use `panic::catch_unwind` in a panic. + // If client and server happen to use the same `std`, + // `catch_unwind` asserts that the panic counter was 0, + // even when the closure passed to it didn't panic. + let r = if thread::panicking() { + Ok(call_method()) + } else { + panic::catch_unwind(panic::AssertUnwindSafe(call_method)) + .map_err(PanicMessage::from) + }; + + buf.clear(); + r.encode(&mut buf, handle_store); + })* } buf } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 11bef8fbb85be..de81ad58239f0 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -277,12 +277,6 @@ impl server::FreeFunctions for RaSpanServer<'_> { } } -impl server::TokenStream for RaSpanServer<'_> {} - -impl server::Span for RaSpanServer<'_> {} - -impl server::Symbol for RaSpanServer<'_> {} - impl server::Server for RaSpanServer<'_> { fn globals(&mut self) -> ExpnGlobals { ExpnGlobals { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index be843d5c878a8..55b4c37ec7bd4 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -196,12 +196,6 @@ impl server::FreeFunctions for SpanIdServer<'_> { } } -impl server::TokenStream for SpanIdServer<'_> {} - -impl server::Span for SpanIdServer<'_> {} - -impl server::Symbol for SpanIdServer<'_> {} - impl server::Server for SpanIdServer<'_> { fn globals(&mut self) -> ExpnGlobals { ExpnGlobals { From 5c2052aa2ebe4b8dc24047d9402bfad2b90ebfda Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 22 Jan 2026 19:00:17 +0000 Subject: [PATCH 10/16] Merge FreeFunctions trait into Server trait And rename FreeFunctions struct to Methods. --- .../rustc_expand/src/proc_macro_server.rs | 39 +++++------- library/proc_macro/src/bridge/client.rs | 12 ++-- library/proc_macro/src/bridge/mod.rs | 8 +-- library/proc_macro/src/bridge/server.rs | 46 ++++++-------- library/proc_macro/src/bridge/symbol.rs | 2 +- library/proc_macro/src/diagnostic.rs | 2 +- library/proc_macro/src/lib.rs | 62 +++++++++---------- .../src/server_impl/rust_analyzer_span.rs | 39 +++++------- .../src/server_impl/token_id.rs | 39 +++++------- 9 files changed, 112 insertions(+), 137 deletions(-) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 1bf2edafd7fdb..4719829d6d3ab 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -431,8 +431,6 @@ impl ToInternal for Level { } } -pub(crate) struct FreeFunctions; - pub(crate) struct Rustc<'a, 'b> { ecx: &'a mut ExtCtxt<'b>, def_site: Span, @@ -461,13 +459,28 @@ impl<'a, 'b> Rustc<'a, 'b> { } impl server::Types for Rustc<'_, '_> { - type FreeFunctions = FreeFunctions; type TokenStream = TokenStream; type Span = Span; type Symbol = Symbol; } -impl server::FreeFunctions for Rustc<'_, '_> { +impl server::Server for Rustc<'_, '_> { + fn globals(&mut self) -> ExpnGlobals { + ExpnGlobals { + def_site: self.def_site, + call_site: self.call_site, + mixed_site: self.mixed_site, + } + } + + fn intern_symbol(string: &str) -> Self::Symbol { + Symbol::intern(string) + } + + fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { + f(symbol.as_str()) + } + fn injected_env_var(&mut self, var: &str) -> Option { self.ecx.sess.opts.logical_env.get(var).cloned() } @@ -843,21 +856,3 @@ impl server::FreeFunctions for Rustc<'_, '_> { if rustc_lexer::is_ident(sym.as_str()) { Ok(sym) } else { Err(()) } } } - -impl server::Server for Rustc<'_, '_> { - fn globals(&mut self) -> ExpnGlobals { - ExpnGlobals { - def_site: self.def_site, - call_site: self.call_site, - mixed_site: self.mixed_site, - } - } - - fn intern_symbol(string: &str) -> Self::Symbol { - Symbol::intern(string) - } - - fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { - f(symbol.as_str()) - } -} diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index ffbf6767833f9..058a9420f6e0f 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -25,7 +25,7 @@ impl !Sync for TokenStream {} // Forward `Drop::drop` to the inherent `drop` method. impl Drop for TokenStream { fn drop(&mut self) { - FreeFunctions::tt_drop(TokenStream { handle: self.handle }); + Methods::tt_drop(TokenStream { handle: self.handle }); } } @@ -75,7 +75,7 @@ impl Decode<'_, '_, S> for Span { impl Clone for TokenStream { fn clone(&self) -> Self { - FreeFunctions::tt_clone(self) + Methods::tt_clone(self) } } @@ -95,21 +95,21 @@ impl Span { impl fmt::Debug for Span { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&FreeFunctions::span_debug(*self)) + f.write_str(&Methods::span_debug(*self)) } } -pub(crate) use super::FreeFunctions; +pub(crate) use super::Methods; pub(crate) use super::symbol::Symbol; macro_rules! define_client_side { ( - FreeFunctions { + Methods { $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* }, $($name:ident),* $(,)? ) => { - impl FreeFunctions { + impl Methods { $(pub(crate) fn $method($($arg: $arg_ty),*) $(-> $ret_ty)? { Bridge::with(|bridge| { let mut buf = bridge.cached_buffer.take(); diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index ae0f5974de520..429335456316a 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -21,7 +21,7 @@ use crate::{Delimiter, Level, Spacing}; /// `with_api!(MySelf, my_self, my_macro)` expands to: /// ```rust,ignore (pseudo-code) /// my_macro! { -/// FreeFunctions { +/// Methods { /// // ... /// fn lit_character(ch: char) -> MySelf::Literal; /// // ... @@ -49,7 +49,7 @@ use crate::{Delimiter, Level, Spacing}; macro_rules! with_api { ($S:ident, $self:ident, $m:ident) => { $m! { - FreeFunctions { + Methods { fn injected_env_var(var: &str) -> Option; fn track_env_var(var: &str, value: Option<&str>); fn track_path(path: &str); @@ -103,7 +103,7 @@ macro_rules! with_api { }; } -pub(crate) struct FreeFunctions; +pub(crate) struct Methods; #[allow(unsafe_code)] mod arena; @@ -158,7 +158,7 @@ mod api_tags { macro_rules! declare_tags { ( - FreeFunctions { + Methods { $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* }, $($name:ident),* $(,)? diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs index 7701ba6899f63..501c105111091 100644 --- a/library/proc_macro/src/bridge/server.rs +++ b/library/proc_macro/src/bridge/server.rs @@ -54,7 +54,6 @@ impl Decode<'_, '_, HandleStore>> for Marked $ret_ty:ty)*;)* }, $($name:ident),* $(,)? ) => { - pub trait FreeFunctions: Types { - $(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?;)* - } - - pub trait Server: Types + FreeFunctions { + pub trait Server: Types { fn globals(&mut self) -> ExpnGlobals; /// Intern a symbol received from RPC @@ -79,6 +74,8 @@ macro_rules! declare_server_traits { /// Recover the string value of a symbol, and invoke a callback with it. fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)); + + $(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?;)* } } } @@ -86,33 +83,30 @@ with_api!(Self, self_, declare_server_traits); pub(super) struct MarkedTypes(S); -impl Server for MarkedTypes { - fn globals(&mut self) -> ExpnGlobals { - <_>::mark(Server::globals(&mut self.0)) - } - fn intern_symbol(ident: &str) -> Self::Symbol { - <_>::mark(S::intern_symbol(ident)) - } - fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { - S::with_symbol_string(symbol.unmark(), f) - } -} - macro_rules! define_mark_types_impls { ( - FreeFunctions { + Methods { $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* }, $($name:ident),* $(,)? ) => { impl Types for MarkedTypes { - type FreeFunctions = Marked; $(type $name = Marked;)* } - impl FreeFunctions for MarkedTypes { + impl Server for MarkedTypes { + fn globals(&mut self) -> ExpnGlobals { + <_>::mark(Server::globals(&mut self.0)) + } + fn intern_symbol(ident: &str) -> Self::Symbol { + <_>::mark(S::intern_symbol(ident)) + } + fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { + S::with_symbol_string(symbol.unmark(), f) + } + $(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)? { - <_>::mark(FreeFunctions::$method(&mut self.0, $($arg.unmark()),*)) + <_>::mark(S::$method(&mut self.0, $($arg.unmark()),*)) })* } } @@ -126,7 +120,7 @@ struct Dispatcher { macro_rules! define_dispatcher_impl { ( - FreeFunctions { + Methods { $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* }, $($name:ident),* $(,)? @@ -134,14 +128,12 @@ macro_rules! define_dispatcher_impl { // FIXME(eddyb) `pub` only for `ExecutionStrategy` below. pub trait DispatcherTrait { // HACK(eddyb) these are here to allow `Self::$name` to work below. - type FreeFunctions; $(type $name;)* fn dispatch(&mut self, buf: Buffer) -> Buffer; } impl DispatcherTrait for Dispatcher> { - type FreeFunctions = as Types>::FreeFunctions; $(type $name = as Types>::$name;)* fn dispatch(&mut self, mut buf: Buffer) -> Buffer { @@ -152,7 +144,7 @@ macro_rules! define_dispatcher_impl { $(api_tags::Method::$method => { let mut call_method = || { $(let $arg = <$arg_ty>::decode(&mut reader, handle_store);)* - FreeFunctions::$method(server, $($arg),*) + server.$method($($arg),*) }; // HACK(eddyb) don't use `panic::catch_unwind` in a panic. // If client and server happen to use the same `std`, diff --git a/library/proc_macro/src/bridge/symbol.rs b/library/proc_macro/src/bridge/symbol.rs index 6366ac2e6a939..995527653095d 100644 --- a/library/proc_macro/src/bridge/symbol.rs +++ b/library/proc_macro/src/bridge/symbol.rs @@ -46,7 +46,7 @@ impl Symbol { if string.is_ascii() { Err(()) } else { - client::FreeFunctions::symbol_normalize_and_validate_ident(string) + client::Methods::symbol_normalize_and_validate_ident(string) } .unwrap_or_else(|_| panic!("`{:?}` is not a valid identifier", string)) } diff --git a/library/proc_macro/src/diagnostic.rs b/library/proc_macro/src/diagnostic.rs index 5a209f7c7aa18..39a8ecb2ee52e 100644 --- a/library/proc_macro/src/diagnostic.rs +++ b/library/proc_macro/src/diagnostic.rs @@ -170,6 +170,6 @@ impl Diagnostic { } } - crate::bridge::client::FreeFunctions::emit_diagnostic(to_internal(self)); + crate::bridge::client::Methods::emit_diagnostic(to_internal(self)); } } diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 8d5491e918510..cc2de8d470c9d 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -158,7 +158,7 @@ impl TokenStream { /// Checks if this `TokenStream` is empty. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub fn is_empty(&self) -> bool { - self.0.as_ref().map(|h| bridge::client::FreeFunctions::tt_is_empty(h)).unwrap_or(true) + self.0.as_ref().map(|h| bridge::client::Methods::tt_is_empty(h)).unwrap_or(true) } /// Parses this `TokenStream` as an expression and attempts to expand any @@ -174,7 +174,7 @@ impl TokenStream { #[unstable(feature = "proc_macro_expand", issue = "90765")] pub fn expand_expr(&self) -> Result { let stream = self.0.as_ref().ok_or(ExpandError)?; - match bridge::client::FreeFunctions::tt_expand_expr(stream) { + match bridge::client::Methods::tt_expand_expr(stream) { Ok(stream) => Ok(TokenStream(Some(stream))), Err(_) => Err(ExpandError), } @@ -193,7 +193,7 @@ impl FromStr for TokenStream { type Err = LexError; fn from_str(src: &str) -> Result { - Ok(TokenStream(Some(bridge::client::FreeFunctions::tt_from_str(src)))) + Ok(TokenStream(Some(bridge::client::Methods::tt_from_str(src)))) } } @@ -212,7 +212,7 @@ impl FromStr for TokenStream { impl fmt::Display for TokenStream { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.0 { - Some(ts) => write!(f, "{}", bridge::client::FreeFunctions::tt_to_string(ts)), + Some(ts) => write!(f, "{}", bridge::client::Methods::tt_to_string(ts)), None => Ok(()), } } @@ -252,9 +252,7 @@ fn tree_to_bridge_tree( #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl From for TokenStream { fn from(tree: TokenTree) -> TokenStream { - TokenStream(Some(bridge::client::FreeFunctions::tt_from_token_tree(tree_to_bridge_tree( - tree, - )))) + TokenStream(Some(bridge::client::Methods::tt_from_token_tree(tree_to_bridge_tree(tree)))) } } @@ -283,7 +281,7 @@ impl ConcatTreesHelper { if self.trees.is_empty() { TokenStream(None) } else { - TokenStream(Some(bridge::client::FreeFunctions::tt_concat_trees(None, self.trees))) + TokenStream(Some(bridge::client::Methods::tt_concat_trees(None, self.trees))) } } @@ -291,7 +289,7 @@ impl ConcatTreesHelper { if self.trees.is_empty() { return; } - stream.0 = Some(bridge::client::FreeFunctions::tt_concat_trees(stream.0.take(), self.trees)) + stream.0 = Some(bridge::client::Methods::tt_concat_trees(stream.0.take(), self.trees)) } } @@ -316,7 +314,7 @@ impl ConcatStreamsHelper { if self.streams.len() <= 1 { TokenStream(self.streams.pop()) } else { - TokenStream(Some(bridge::client::FreeFunctions::tt_concat_streams(None, self.streams))) + TokenStream(Some(bridge::client::Methods::tt_concat_streams(None, self.streams))) } } @@ -328,7 +326,7 @@ impl ConcatStreamsHelper { if base.is_none() && self.streams.len() == 1 { stream.0 = self.streams.pop(); } else { - stream.0 = Some(bridge::client::FreeFunctions::tt_concat_streams(base, self.streams)); + stream.0 = Some(bridge::client::Methods::tt_concat_streams(base, self.streams)); } } } @@ -441,7 +439,7 @@ pub mod token_stream { fn into_iter(self) -> IntoIter { IntoIter( self.0 - .map(|v| bridge::client::FreeFunctions::tt_into_trees(v)) + .map(|v| bridge::client::Methods::tt_into_trees(v)) .unwrap_or_default() .into_iter(), ) @@ -516,7 +514,7 @@ impl Span { /// `self` was generated from, if any. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn parent(&self) -> Option { - bridge::client::FreeFunctions::span_parent(self.0).map(Span) + bridge::client::Methods::span_parent(self.0).map(Span) } /// The span for the origin source code that `self` was generated from. If @@ -524,25 +522,25 @@ impl Span { /// value is the same as `*self`. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn source(&self) -> Span { - Span(bridge::client::FreeFunctions::span_source(self.0)) + Span(bridge::client::Methods::span_source(self.0)) } /// Returns the span's byte position range in the source file. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn byte_range(&self) -> Range { - bridge::client::FreeFunctions::span_byte_range(self.0) + bridge::client::Methods::span_byte_range(self.0) } /// Creates an empty span pointing to directly before this span. #[stable(feature = "proc_macro_span_location", since = "1.88.0")] pub fn start(&self) -> Span { - Span(bridge::client::FreeFunctions::span_start(self.0)) + Span(bridge::client::Methods::span_start(self.0)) } /// Creates an empty span pointing to directly after this span. #[stable(feature = "proc_macro_span_location", since = "1.88.0")] pub fn end(&self) -> Span { - Span(bridge::client::FreeFunctions::span_end(self.0)) + Span(bridge::client::Methods::span_end(self.0)) } /// The one-indexed line of the source file where the span starts. @@ -550,7 +548,7 @@ impl Span { /// To obtain the line of the span's end, use `span.end().line()`. #[stable(feature = "proc_macro_span_location", since = "1.88.0")] pub fn line(&self) -> usize { - bridge::client::FreeFunctions::span_line(self.0) + bridge::client::Methods::span_line(self.0) } /// The one-indexed column of the source file where the span starts. @@ -558,7 +556,7 @@ impl Span { /// To obtain the column of the span's end, use `span.end().column()`. #[stable(feature = "proc_macro_span_location", since = "1.88.0")] pub fn column(&self) -> usize { - bridge::client::FreeFunctions::span_column(self.0) + bridge::client::Methods::span_column(self.0) } /// The path to the source file in which this span occurs, for display purposes. @@ -567,7 +565,7 @@ impl Span { /// It might be remapped (e.g. `"/src/lib.rs"`) or an artificial path (e.g. `""`). #[stable(feature = "proc_macro_span_file", since = "1.88.0")] pub fn file(&self) -> String { - bridge::client::FreeFunctions::span_file(self.0) + bridge::client::Methods::span_file(self.0) } /// The path to the source file in which this span occurs on the local file system. @@ -577,7 +575,7 @@ impl Span { /// This path should not be embedded in the output of the macro; prefer `file()` instead. #[stable(feature = "proc_macro_span_file", since = "1.88.0")] pub fn local_file(&self) -> Option { - bridge::client::FreeFunctions::span_local_file(self.0).map(PathBuf::from) + bridge::client::Methods::span_local_file(self.0).map(PathBuf::from) } /// Creates a new span encompassing `self` and `other`. @@ -585,14 +583,14 @@ impl Span { /// Returns `None` if `self` and `other` are from different files. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn join(&self, other: Span) -> Option { - bridge::client::FreeFunctions::span_join(self.0, other.0).map(Span) + bridge::client::Methods::span_join(self.0, other.0).map(Span) } /// Creates a new span with the same line/column information as `self` but /// that resolves symbols as though it were at `other`. #[stable(feature = "proc_macro_span_resolved_at", since = "1.45.0")] pub fn resolved_at(&self, other: Span) -> Span { - Span(bridge::client::FreeFunctions::span_resolved_at(self.0, other.0)) + Span(bridge::client::Methods::span_resolved_at(self.0, other.0)) } /// Creates a new span with the same name resolution behavior as `self` but @@ -617,21 +615,21 @@ impl Span { /// be used for diagnostics only. #[stable(feature = "proc_macro_source_text", since = "1.66.0")] pub fn source_text(&self) -> Option { - bridge::client::FreeFunctions::span_source_text(self.0) + bridge::client::Methods::span_source_text(self.0) } // Used by the implementation of `Span::quote` #[doc(hidden)] #[unstable(feature = "proc_macro_internals", issue = "27812")] pub fn save_span(&self) -> usize { - bridge::client::FreeFunctions::span_save_span(self.0) + bridge::client::Methods::span_save_span(self.0) } // Used by the implementation of `Span::quote` #[doc(hidden)] #[unstable(feature = "proc_macro_internals", issue = "27812")] pub fn recover_proc_macro_span(id: usize) -> Span { - Span(bridge::client::FreeFunctions::span_recover_proc_macro_span(id)) + Span(bridge::client::Methods::span_recover_proc_macro_span(id)) } diagnostic_method!(error, Level::Error); @@ -1396,7 +1394,7 @@ impl Literal { // was 'c' or whether it was '\u{63}'. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn subspan>(&self, range: R) -> Option { - bridge::client::FreeFunctions::span_subspan( + bridge::client::Methods::span_subspan( self.0.span, range.start_bound().cloned(), range.end_bound().cloned(), @@ -1571,7 +1569,7 @@ impl FromStr for Literal { type Err = LexError; fn from_str(src: &str) -> Result { - match bridge::client::FreeFunctions::literal_from_str(src) { + match bridge::client::Methods::literal_from_str(src) { Ok(literal) => Ok(Literal(literal)), Err(()) => Err(LexError), } @@ -1626,9 +1624,9 @@ pub mod tracked { #[unstable(feature = "proc_macro_tracked_env", issue = "99515")] pub fn env_var + AsRef>(key: K) -> Result { let key: &str = key.as_ref(); - let value = crate::bridge::client::FreeFunctions::injected_env_var(key) - .map_or_else(|| env::var(key), Ok); - crate::bridge::client::FreeFunctions::track_env_var(key, value.as_deref().ok()); + let value = + crate::bridge::client::Methods::injected_env_var(key).map_or_else(|| env::var(key), Ok); + crate::bridge::client::Methods::track_env_var(key, value.as_deref().ok()); value } @@ -1638,6 +1636,6 @@ pub mod tracked { #[unstable(feature = "proc_macro_tracked_path", issue = "99515")] pub fn path>(path: P) { let path: &str = path.as_ref().to_str().unwrap(); - crate::bridge::client::FreeFunctions::track_path(path); + crate::bridge::client::Methods::track_path(path); } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index de81ad58239f0..609eee0bd4666 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -19,8 +19,6 @@ use crate::{ server_impl::literal_from_str, }; -pub struct FreeFunctions; - pub struct RaSpanServer<'a> { // FIXME: Report this back to the caller to track as dependencies pub tracked_env_vars: HashMap, Option>>, @@ -33,13 +31,28 @@ pub struct RaSpanServer<'a> { } impl server::Types for RaSpanServer<'_> { - type FreeFunctions = FreeFunctions; type TokenStream = crate::token_stream::TokenStream; type Span = Span; type Symbol = Symbol; } -impl server::FreeFunctions for RaSpanServer<'_> { +impl server::Server for RaSpanServer<'_> { + fn globals(&mut self) -> ExpnGlobals { + ExpnGlobals { + def_site: self.def_site, + call_site: self.call_site, + mixed_site: self.mixed_site, + } + } + + fn intern_symbol(ident: &str) -> Self::Symbol { + Symbol::intern(ident) + } + + fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { + f(symbol.as_str()) + } + fn injected_env_var(&mut self, _: &str) -> Option { None } @@ -276,21 +289,3 @@ impl server::FreeFunctions for RaSpanServer<'_> { Ok(::intern_symbol(string)) } } - -impl server::Server for RaSpanServer<'_> { - fn globals(&mut self) -> ExpnGlobals { - ExpnGlobals { - def_site: self.def_site, - call_site: self.call_site, - mixed_site: self.mixed_site, - } - } - - fn intern_symbol(ident: &str) -> Self::Symbol { - Symbol::intern(ident) - } - - fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { - f(symbol.as_str()) - } -} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index 55b4c37ec7bd4..d6b1cf4b743f3 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -25,8 +25,6 @@ impl std::fmt::Debug for SpanId { type Span = SpanId; -pub struct FreeFunctions; - pub struct SpanIdServer<'a> { // FIXME: Report this back to the caller to track as dependencies pub tracked_env_vars: HashMap, Option>>, @@ -39,13 +37,28 @@ pub struct SpanIdServer<'a> { } impl server::Types for SpanIdServer<'_> { - type FreeFunctions = FreeFunctions; type TokenStream = crate::token_stream::TokenStream; type Span = Span; type Symbol = Symbol; } -impl server::FreeFunctions for SpanIdServer<'_> { +impl server::Server for SpanIdServer<'_> { + fn globals(&mut self) -> ExpnGlobals { + ExpnGlobals { + def_site: self.def_site, + call_site: self.call_site, + mixed_site: self.mixed_site, + } + } + + fn intern_symbol(ident: &str) -> Self::Symbol { + Symbol::intern(ident) + } + + fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { + f(symbol.as_str()) + } + fn injected_env_var(&mut self, _: &str) -> Option { None } @@ -195,21 +208,3 @@ impl server::FreeFunctions for SpanIdServer<'_> { Ok(::intern_symbol(string)) } } - -impl server::Server for SpanIdServer<'_> { - fn globals(&mut self) -> ExpnGlobals { - ExpnGlobals { - def_site: self.def_site, - call_site: self.call_site, - mixed_site: self.mixed_site, - } - } - - fn intern_symbol(ident: &str) -> Self::Symbol { - Symbol::intern(ident) - } - - fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { - f(symbol.as_str()) - } -} From 44fcd0429cd917b7927ac7b1467ee004e88cb7d4 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 3 Oct 2025 21:49:48 +0000 Subject: [PATCH 11/16] Get rid of MarkedTypes --- library/proc_macro/src/bridge/server.rs | 94 +++++++++---------------- library/proc_macro/src/bridge/symbol.rs | 12 ++-- 2 files changed, 38 insertions(+), 68 deletions(-) diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs index 501c105111091..b79de99844533 100644 --- a/library/proc_macro/src/bridge/server.rs +++ b/library/proc_macro/src/bridge/server.rs @@ -6,8 +6,8 @@ use std::marker::PhantomData; use super::*; pub(super) struct HandleStore { - token_stream: handle::OwnedStore, - span: handle::InternedStore, + token_stream: handle::OwnedStore>, + span: handle::InternedStore>, } impl HandleStore { @@ -19,36 +19,34 @@ impl HandleStore { } } -impl Encode>> for Marked { - fn encode(self, w: &mut Writer, s: &mut HandleStore>) { +impl Encode> for Marked { + fn encode(self, w: &mut Writer, s: &mut HandleStore) { s.token_stream.alloc(self).encode(w, s); } } -impl Decode<'_, '_, HandleStore>> - for Marked -{ - fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { +impl Decode<'_, '_, HandleStore> for Marked { + fn decode(r: &mut Reader<'_>, s: &mut HandleStore) -> Self { s.token_stream.take(handle::Handle::decode(r, &mut ())) } } -impl<'s, S: Types> Decode<'_, 's, HandleStore>> +impl<'s, S: Types> Decode<'_, 's, HandleStore> for &'s Marked { - fn decode(r: &mut Reader<'_>, s: &'s mut HandleStore>) -> Self { + fn decode(r: &mut Reader<'_>, s: &'s mut HandleStore) -> Self { &s.token_stream[handle::Handle::decode(r, &mut ())] } } -impl Encode>> for Marked { - fn encode(self, w: &mut Writer, s: &mut HandleStore>) { +impl Encode> for Marked { + fn encode(self, w: &mut Writer, s: &mut HandleStore) { s.span.alloc(self).encode(w, s); } } -impl Decode<'_, '_, HandleStore>> for Marked { - fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { +impl Decode<'_, '_, HandleStore> for Marked { + fn decode(r: &mut Reader<'_>, s: &mut HandleStore) -> Self { s.span.copy(handle::Handle::decode(r, &mut ())) } } @@ -81,38 +79,6 @@ macro_rules! declare_server_traits { } with_api!(Self, self_, declare_server_traits); -pub(super) struct MarkedTypes(S); - -macro_rules! define_mark_types_impls { - ( - Methods { - $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* - }, - $($name:ident),* $(,)? - ) => { - impl Types for MarkedTypes { - $(type $name = Marked;)* - } - - impl Server for MarkedTypes { - fn globals(&mut self) -> ExpnGlobals { - <_>::mark(Server::globals(&mut self.0)) - } - fn intern_symbol(ident: &str) -> Self::Symbol { - <_>::mark(S::intern_symbol(ident)) - } - fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { - S::with_symbol_string(symbol.unmark(), f) - } - - $(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)? { - <_>::mark(S::$method(&mut self.0, $($arg.unmark()),*)) - })* - } - } -} -with_api!(Self, self_, define_mark_types_impls); - struct Dispatcher { handle_store: HandleStore, server: S, @@ -133,8 +99,8 @@ macro_rules! define_dispatcher_impl { fn dispatch(&mut self, buf: Buffer) -> Buffer; } - impl DispatcherTrait for Dispatcher> { - $(type $name = as Types>::$name;)* + impl DispatcherTrait for Dispatcher { + $(type $name = Marked;)* fn dispatch(&mut self, mut buf: Buffer) -> Buffer { let Dispatcher { handle_store, server } = self; @@ -143,8 +109,12 @@ macro_rules! define_dispatcher_impl { match api_tags::Method::decode(&mut reader, &mut ()) { $(api_tags::Method::$method => { let mut call_method = || { - $(let $arg = <$arg_ty>::decode(&mut reader, handle_store);)* - server.$method($($arg),*) + $(let $arg = <$arg_ty>::decode(&mut reader, handle_store).unmark();)* + let r = server.$method($($arg),*); + $( + let r: $ret_ty = Mark::mark(r); + )* + r }; // HACK(eddyb) don't use `panic::catch_unwind` in a panic. // If client and server happen to use the same `std`, @@ -318,8 +288,8 @@ pub trait MessagePipe: Sized { fn run_server< S: Server, - I: Encode>>, - O: for<'a, 's> Decode<'a, 's, HandleStore>>, + I: Encode>, + O: for<'a, 's> Decode<'a, 's, HandleStore>, >( strategy: &impl ExecutionStrategy, handle_counters: &'static client::HandleCounters, @@ -328,13 +298,13 @@ fn run_server< run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer, force_show_panics: bool, ) -> Result { - let mut dispatcher = - Dispatcher { handle_store: HandleStore::new(handle_counters), server: MarkedTypes(server) }; + let mut dispatcher = Dispatcher { handle_store: HandleStore::new(handle_counters), server }; let globals = dispatcher.server.globals(); let mut buf = Buffer::new(); - (globals, input).encode(&mut buf, &mut dispatcher.handle_store); + (> as Mark>::mark(globals), input) + .encode(&mut buf, &mut dispatcher.handle_store); buf = strategy.run_bridge_and_client(&mut dispatcher, buf, run_client, force_show_panics); @@ -358,11 +328,13 @@ impl client::Client { strategy, handle_counters, server, - as Types>::TokenStream::mark(input), + >::mark(input), run, force_show_panics, ) - .map(|s| as Types>::TokenStream>>::unmark(s).unwrap_or_default()) + .map(|s| { + >>::unmark(s).unwrap_or_default() + }) } } @@ -385,12 +357,14 @@ impl client::Client<(crate::TokenStream, crate::TokenStream), crate::TokenStream handle_counters, server, ( - as Types>::TokenStream::mark(input), - as Types>::TokenStream::mark(input2), + >::mark(input), + >::mark(input2), ), run, force_show_panics, ) - .map(|s| as Types>::TokenStream>>::unmark(s).unwrap_or_default()) + .map(|s| { + >>::unmark(s).unwrap_or_default() + }) } } diff --git a/library/proc_macro/src/bridge/symbol.rs b/library/proc_macro/src/bridge/symbol.rs index 995527653095d..edba142bad721 100644 --- a/library/proc_macro/src/bridge/symbol.rs +++ b/library/proc_macro/src/bridge/symbol.rs @@ -99,18 +99,14 @@ impl Encode for Symbol { } } -impl Decode<'_, '_, server::HandleStore>> - for Marked -{ - fn decode(r: &mut Reader<'_>, s: &mut server::HandleStore>) -> Self { +impl Decode<'_, '_, server::HandleStore> for Marked { + fn decode(r: &mut Reader<'_>, s: &mut server::HandleStore) -> Self { Mark::mark(S::intern_symbol(<&str>::decode(r, s))) } } -impl Encode>> - for Marked -{ - fn encode(self, w: &mut Writer, s: &mut server::HandleStore>) { +impl Encode> for Marked { + fn encode(self, w: &mut Writer, s: &mut server::HandleStore) { S::with_symbol_string(&self.unmark(), |sym| sym.encode(w, s)) } } From 76f9a9062ba1f43a30dd4965f40b89a5cbf3b59a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 22 Jan 2026 19:57:13 +0000 Subject: [PATCH 12/16] Use rustc_proc_macro in rust-analyzer-proc-macro-srv This fixes stage1 builds when the proc-macro bridge api changed. The rustc_proc_macro crate is identical to the proc_macro that would end up in the sysroot of the rustc compiler rustc_proc_macro is linked into. --- .../crates/proc-macro-srv/src/bridge.rs | 2 +- .../crates/proc-macro-srv/src/dylib.rs | 2 +- .../proc-macro-srv/src/dylib/proc_macros.rs | 2 +- .../crates/proc-macro-srv/src/lib.rs | 8 ++-- .../src/server_impl/rust_analyzer_span.rs | 2 +- .../src/server_impl/token_id.rs | 2 +- .../crates/proc-macro-srv/src/token_stream.rs | 42 +++++++++---------- 7 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/bridge.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/bridge.rs index fc063a07b5f8a..fc62f9413a34e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/bridge.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/bridge.rs @@ -1,6 +1,6 @@ //! `proc_macro::bridge` newtypes. -use proc_macro::bridge as pm_bridge; +use rustc_proc_macro::bridge as pm_bridge; pub use pm_bridge::{DelimSpan, Diagnostic, ExpnGlobals, LitKind}; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs index 02bdcc50d3871..8680e9180e3ab 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs @@ -3,7 +3,7 @@ mod proc_macros; mod version; -use proc_macro::bridge; +use rustc_proc_macro::bridge; use std::{fmt, fs, io, time::SystemTime}; use temp_dir::TempDir; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs index c763301135ee8..76c5097101c70 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs @@ -1,6 +1,6 @@ //! Proc macro ABI use crate::{ProcMacroClientHandle, ProcMacroKind, ProcMacroSrvSpan, token_stream::TokenStream}; -use proc_macro::bridge; +use rustc_proc_macro::bridge; #[repr(transparent)] pub(crate) struct ProcMacros([bridge::client::ProcMacro]); diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index f2d1dfbba4ccb..920d58b4e981e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -22,9 +22,9 @@ )] #![deny(deprecated_safe, clippy::undocumented_unsafe_blocks)] -extern crate proc_macro; #[cfg(feature = "in-rust-tree")] extern crate rustc_driver as _; +extern crate rustc_proc_macro; #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_lexer as rustc_lexer; @@ -52,7 +52,7 @@ use temp_dir::TempDir; pub use crate::server_impl::token_id::SpanId; -pub use proc_macro::Delimiter; +pub use rustc_proc_macro::Delimiter; pub use span; pub use crate::bridge::*; @@ -181,7 +181,9 @@ impl ProcMacroSrv<'_> { } pub trait ProcMacroSrvSpan: Copy + Send + Sync { - type Server<'a>: proc_macro::bridge::server::Server>; + type Server<'a>: rustc_proc_macro::bridge::server::Server< + TokenStream = crate::token_stream::TokenStream, + >; fn make_server<'a>( call_site: Self, def_site: Self, diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 609eee0bd4666..4f50c04b27996 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -10,7 +10,7 @@ use std::{ }; use intern::Symbol; -use proc_macro::bridge::server; +use rustc_proc_macro::bridge::server; use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span, TextRange, TextSize}; use crate::{ diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index d6b1cf4b743f3..cd5ba59095610 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -6,7 +6,7 @@ use std::{ }; use intern::Symbol; -use proc_macro::bridge::server; +use rustc_proc_macro::bridge::server; use crate::{ ProcMacroClientHandle, diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/token_stream.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/token_stream.rs index 36827d2561f9c..2358f6963c79e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/token_stream.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/token_stream.rs @@ -4,8 +4,8 @@ use core::fmt; use std::{mem, sync::Arc}; use intern::Symbol; -use proc_macro::Delimiter; use rustc_lexer::{DocStyle, LiteralKind}; +use rustc_proc_macro::Delimiter; use crate::bridge::{DelimSpan, Group, Ident, LitKind, Literal, Punct, TokenTree}; @@ -52,7 +52,7 @@ impl TokenStream { S: SpanLike + Copy, { let mut groups = Vec::new(); - groups.push((proc_macro::Delimiter::None, 0..0, vec![])); + groups.push((rustc_proc_macro::Delimiter::None, 0..0, vec![])); let mut offset = 0; let mut tokens = rustc_lexer::tokenize(s, rustc_lexer::FrontmatterAllowed::No).peekable(); while let Some(token) = tokens.next() { @@ -102,7 +102,7 @@ impl TokenStream { }; match token.kind { rustc_lexer::TokenKind::OpenParen => { - groups.push((proc_macro::Delimiter::Parenthesis, range, vec![])) + groups.push((rustc_proc_macro::Delimiter::Parenthesis, range, vec![])) } rustc_lexer::TokenKind::CloseParen if *open_delim != Delimiter::Parenthesis => { return if *open_delim == Delimiter::None { @@ -130,7 +130,7 @@ impl TokenStream { ); } rustc_lexer::TokenKind::OpenBrace => { - groups.push((proc_macro::Delimiter::Brace, range, vec![])) + groups.push((rustc_proc_macro::Delimiter::Brace, range, vec![])) } rustc_lexer::TokenKind::CloseBrace if *open_delim != Delimiter::Brace => { return if *open_delim == Delimiter::None { @@ -158,7 +158,7 @@ impl TokenStream { ); } rustc_lexer::TokenKind::OpenBracket => { - groups.push((proc_macro::Delimiter::Bracket, range, vec![])) + groups.push((rustc_proc_macro::Delimiter::Bracket, range, vec![])) } rustc_lexer::TokenKind::CloseBracket if *open_delim != Delimiter::Bracket => { return if *open_delim == Delimiter::None { @@ -460,10 +460,10 @@ fn display_token_tree( f, "{}", match delimiter { - proc_macro::Delimiter::Parenthesis => "(", - proc_macro::Delimiter::Brace => "{", - proc_macro::Delimiter::Bracket => "[", - proc_macro::Delimiter::None => "", + rustc_proc_macro::Delimiter::Parenthesis => "(", + rustc_proc_macro::Delimiter::Brace => "{", + rustc_proc_macro::Delimiter::Bracket => "[", + rustc_proc_macro::Delimiter::None => "", } )?; if let Some(stream) = stream { @@ -473,10 +473,10 @@ fn display_token_tree( f, "{}", match delimiter { - proc_macro::Delimiter::Parenthesis => ")", - proc_macro::Delimiter::Brace => "}", - proc_macro::Delimiter::Bracket => "]", - proc_macro::Delimiter::None => "", + rustc_proc_macro::Delimiter::Parenthesis => ")", + rustc_proc_macro::Delimiter::Brace => "}", + rustc_proc_macro::Delimiter::Bracket => "]", + rustc_proc_macro::Delimiter::None => "", } )?; } @@ -587,16 +587,16 @@ fn debug_token_tree( f, "GROUP {}{} {:#?} {:#?} {:#?}", match delimiter { - proc_macro::Delimiter::Parenthesis => "(", - proc_macro::Delimiter::Brace => "{", - proc_macro::Delimiter::Bracket => "[", - proc_macro::Delimiter::None => "$", + rustc_proc_macro::Delimiter::Parenthesis => "(", + rustc_proc_macro::Delimiter::Brace => "{", + rustc_proc_macro::Delimiter::Bracket => "[", + rustc_proc_macro::Delimiter::None => "$", }, match delimiter { - proc_macro::Delimiter::Parenthesis => ")", - proc_macro::Delimiter::Brace => "}", - proc_macro::Delimiter::Bracket => "]", - proc_macro::Delimiter::None => "$", + rustc_proc_macro::Delimiter::Parenthesis => ")", + rustc_proc_macro::Delimiter::Brace => "}", + rustc_proc_macro::Delimiter::Bracket => "]", + rustc_proc_macro::Delimiter::None => "$", }, span.open, span.close, From 0a2bb4b45b5b5344895de12759081b81271dd3b3 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Thu, 22 Jan 2026 20:48:04 +0000 Subject: [PATCH 13/16] Ensure armv7a-none-eabi.md mentions all four targets --- .../rustc/src/platform-support/armv7a-none-eabi.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/doc/rustc/src/platform-support/armv7a-none-eabi.md b/src/doc/rustc/src/platform-support/armv7a-none-eabi.md index 6e08bbb26e466..555f69e81a02f 100644 --- a/src/doc/rustc/src/platform-support/armv7a-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv7a-none-eabi.md @@ -1,12 +1,14 @@ -# `armv7a-none-eabi` and `thumbv7a-none-eabihf` +# `armv7a-none-eabi*` and `thumbv7a-none-eabi*` -* **Tier: 2** (`armv7a-none-eabi`) -* **Tier: 3** (`thumbv7a-none-eabi`) +* **Tier: 2** (`armv7a-none-eabi` and `armv7a-none-eabihf`) +* **Tier: 3** (`thumbv7a-none-eabi` and `thumbv7a-none-eabihf`) * **Library Support:** core and alloc (bare-metal, `#![no_std]`) Bare-metal target for CPUs in the Armv7-A architecture family, supporting dual -ARM/Thumb mode. The `armv7a-none-eabi` target uses Arm mode by default and -the `thumbv7a-none-eabihf` target uses Thumb mode by default. +ARM/Thumb mode. The `armv7a-none-eabi*` targets use Arm mode by default and the +`thumbv7a-none-eabi` targets use Thumb mode by default. The `-eabi` targets use +a soft-float ABI and do not require an FPU, while the `-eabihf` targets use a +hard-float ABI and do require an FPU. Note, this is for processors running in AArch32 mode. For the AArch64 mode added in Armv8-A, see [`aarch64-unknown-none`](aarch64-unknown-none.md) instead. From 19d1be5de6d57d56c95c5ee77e493ee894bfbe69 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Thu, 22 Jan 2026 20:48:11 +0000 Subject: [PATCH 14/16] Ensure armv7r-none-eabi.md mentions all four targets --- .../src/platform-support/armv7r-none-eabi.md | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md index 16755ff8c520c..20fd55c6abd68 100644 --- a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md @@ -1,12 +1,14 @@ -# `armv7r-none-eabi` and `armv7r-none-eabihf` +# `armv7r-none-eabi*` and `thumbv7r-none-eabi*` -* **Tier: 2** (`armv7r-none-eabi`) -* **Tier: 3** (`thumbv7r-none-eabi`) +* **Tier: 2** (`armv7r-none-eabi` and `armv7r-none-eabihf`) +* **Tier: 3** (`thumbv7r-none-eabi` and `thumbv7r-none-eabihf`) * **Library Support:** core and alloc (bare-metal, `#![no_std]`) Bare-metal target for CPUs in the Armv7-R architecture family, supporting dual -ARM/Thumb mode. The `armv7r-none-eabi` target uses Arm mode by default and -the `thumbv7r-none-eabihf` target uses Thumb mode by default. +ARM/Thumb mode. The `armv7r-none-eabi*` targets use Arm mode by default and the +`thumbv7r-none-eabi*` targets use Thumb mode by default. The `-eabi` targets use +a soft-float ABI and do not require an FPU, while the `-eabihf` targets use a +hard-float ABI and do require an FPU. Processors in this family include the [Arm Cortex-R4, 5, 7, and 8][cortex-r]. @@ -27,11 +29,11 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all ## Requirements -When using the hardfloat targets, the minimum floating-point features assumed -are those of the `vfpv3-d16`, which includes single- and double-precision, with -16 double-precision registers. This floating-point unit appears in Cortex-R4F -and Cortex-R5F processors. See [VFP in the Cortex-R processors][vfp] -for more details on the possible FPU variants. +When using the hardfloat (`-eabibf`) targets, the minimum floating-point +features assumed are those of the `vfpv3-d16`, which includes single- and +double-precision, with 16 double-precision registers. This floating-point unit +appears in Cortex-R4F and Cortex-R5F processors. See [VFP in the Cortex-R +processors][vfp] for more details on the possible FPU variants. If your processor supports a different set of floating-point features than the default expectations of `vfpv3-d16`, then these should also be enabled or From fa526c47ccdc2bcc184d49bc7548a57434b0e7b9 Mon Sep 17 00:00:00 2001 From: Jonathan 'theJPster' Pallant Date: Thu, 22 Jan 2026 20:50:09 +0000 Subject: [PATCH 15/16] Update armv8r-none-eabi.md - note both targets are hardfloat --- src/doc/rustc/src/platform-support/armv8r-none-eabihf.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md index ad4764122446e..85abac3d7eb89 100644 --- a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md +++ b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md @@ -5,8 +5,9 @@ * **Library Support:** core and alloc (bare-metal, `#![no_std]`) Bare-metal target for CPUs in the Armv8-R architecture family, supporting dual -ARM/Thumb mode. The `armv8r-none-eabi` target uses Arm mode by default and -the `thumbv8r-none-eabihf` target uses Thumb mode by default. +ARM/Thumb mode. The `armv8r-none-eabihf` target uses Arm mode by default and +the `thumbv8r-none-eabihf` target uses Thumb mode by default. Both targets +use a hard-float ABI and require an FPU. Processors in this family include the Arm [Cortex-R52][cortex-r52] and [Cortex-R52+][cortex-r52-plus]. From e47138f43643733d4fdefa5b77e3bc745558a7dc Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 23 Jan 2026 11:19:21 +0000 Subject: [PATCH 16/16] Fix review comments --- .../rustc_expand/src/proc_macro_server.rs | 20 +++--- library/proc_macro/src/bridge/client.rs | 4 +- library/proc_macro/src/bridge/mod.rs | 20 +++--- library/proc_macro/src/lib.rs | 70 +++++++++---------- .../src/server_impl/rust_analyzer_span.rs | 20 +++--- .../src/server_impl/token_id.rs | 20 +++--- 6 files changed, 76 insertions(+), 78 deletions(-) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 4719829d6d3ab..a51aa90355bcd 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -566,19 +566,19 @@ impl server::Server for Rustc<'_, '_> { diag.emit(); } - fn tt_drop(&mut self, stream: Self::TokenStream) { + fn ts_drop(&mut self, stream: Self::TokenStream) { drop(stream); } - fn tt_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream { + fn ts_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream { stream.clone() } - fn tt_is_empty(&mut self, stream: &Self::TokenStream) -> bool { + fn ts_is_empty(&mut self, stream: &Self::TokenStream) -> bool { stream.is_empty() } - fn tt_from_str(&mut self, src: &str) -> Self::TokenStream { + fn ts_from_str(&mut self, src: &str) -> Self::TokenStream { unwrap_or_emit_fatal(source_str_to_stream( self.psess(), FileName::proc_macro_source_code(src), @@ -587,11 +587,11 @@ impl server::Server for Rustc<'_, '_> { )) } - fn tt_to_string(&mut self, stream: &Self::TokenStream) -> String { + fn ts_to_string(&mut self, stream: &Self::TokenStream) -> String { pprust::tts_to_string(stream) } - fn tt_expand_expr(&mut self, stream: &Self::TokenStream) -> Result { + fn ts_expand_expr(&mut self, stream: &Self::TokenStream) -> Result { // Parse the expression from our tokenstream. let expr: PResult<'_, _> = try { let mut p = Parser::new(self.psess(), stream.clone(), Some("proc_macro expand expr")); @@ -652,14 +652,14 @@ impl server::Server for Rustc<'_, '_> { } } - fn tt_from_token_tree( + fn ts_from_token_tree( &mut self, tree: TokenTree, ) -> Self::TokenStream { Self::TokenStream::new((tree, &mut *self).to_internal().into_iter().collect::>()) } - fn tt_concat_trees( + fn ts_concat_trees( &mut self, base: Option, trees: Vec>, @@ -673,7 +673,7 @@ impl server::Server for Rustc<'_, '_> { stream } - fn tt_concat_streams( + fn ts_concat_streams( &mut self, base: Option, streams: Vec, @@ -685,7 +685,7 @@ impl server::Server for Rustc<'_, '_> { stream } - fn tt_into_trees( + fn ts_into_trees( &mut self, stream: Self::TokenStream, ) -> Vec> { diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index 058a9420f6e0f..0d87a727ae40b 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -25,7 +25,7 @@ impl !Sync for TokenStream {} // Forward `Drop::drop` to the inherent `drop` method. impl Drop for TokenStream { fn drop(&mut self) { - Methods::tt_drop(TokenStream { handle: self.handle }); + Methods::ts_drop(TokenStream { handle: self.handle }); } } @@ -75,7 +75,7 @@ impl Decode<'_, '_, S> for Span { impl Clone for TokenStream { fn clone(&self) -> Self { - Methods::tt_clone(self) + Methods::ts_clone(self) } } diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 429335456316a..6f7c8726f9253 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -56,24 +56,24 @@ macro_rules! with_api { fn literal_from_str(s: &str) -> Result, ()>; fn emit_diagnostic(diagnostic: Diagnostic<$S::Span>); - fn tt_drop(stream: $S::TokenStream); - fn tt_clone(stream: &$S::TokenStream) -> $S::TokenStream; - fn tt_is_empty(stream: &$S::TokenStream) -> bool; - fn tt_expand_expr(stream: &$S::TokenStream) -> Result<$S::TokenStream, ()>; - fn tt_from_str(src: &str) -> $S::TokenStream; - fn tt_to_string(stream: &$S::TokenStream) -> String; - fn tt_from_token_tree( + fn ts_drop(stream: $S::TokenStream); + fn ts_clone(stream: &$S::TokenStream) -> $S::TokenStream; + fn ts_is_empty(stream: &$S::TokenStream) -> bool; + fn ts_expand_expr(stream: &$S::TokenStream) -> Result<$S::TokenStream, ()>; + fn ts_from_str(src: &str) -> $S::TokenStream; + fn ts_to_string(stream: &$S::TokenStream) -> String; + fn ts_from_token_tree( tree: TokenTree<$S::TokenStream, $S::Span, $S::Symbol>, ) -> $S::TokenStream; - fn tt_concat_trees( + fn ts_concat_trees( base: Option<$S::TokenStream>, trees: Vec>, ) -> $S::TokenStream; - fn tt_concat_streams( + fn ts_concat_streams( base: Option<$S::TokenStream>, streams: Vec<$S::TokenStream>, ) -> $S::TokenStream; - fn tt_into_trees( + fn ts_into_trees( stream: $S::TokenStream ) -> Vec>; diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index cc2de8d470c9d..95a7ea7d7b3b7 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -58,6 +58,7 @@ use rustc_literal_escaper::{MixedUnit, unescape_byte_str, unescape_c_str, unesca #[unstable(feature = "proc_macro_totokens", issue = "130977")] pub use to_tokens::ToTokens; +use crate::bridge::client::Methods as BridgeMethods; use crate::escape::{EscapeOptions, escape_bytes}; /// Errors returned when trying to retrieve a literal unescaped value. @@ -158,7 +159,7 @@ impl TokenStream { /// Checks if this `TokenStream` is empty. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub fn is_empty(&self) -> bool { - self.0.as_ref().map(|h| bridge::client::Methods::tt_is_empty(h)).unwrap_or(true) + self.0.as_ref().map(|h| BridgeMethods::ts_is_empty(h)).unwrap_or(true) } /// Parses this `TokenStream` as an expression and attempts to expand any @@ -174,7 +175,7 @@ impl TokenStream { #[unstable(feature = "proc_macro_expand", issue = "90765")] pub fn expand_expr(&self) -> Result { let stream = self.0.as_ref().ok_or(ExpandError)?; - match bridge::client::Methods::tt_expand_expr(stream) { + match BridgeMethods::ts_expand_expr(stream) { Ok(stream) => Ok(TokenStream(Some(stream))), Err(_) => Err(ExpandError), } @@ -193,7 +194,7 @@ impl FromStr for TokenStream { type Err = LexError; fn from_str(src: &str) -> Result { - Ok(TokenStream(Some(bridge::client::Methods::tt_from_str(src)))) + Ok(TokenStream(Some(BridgeMethods::ts_from_str(src)))) } } @@ -212,7 +213,7 @@ impl FromStr for TokenStream { impl fmt::Display for TokenStream { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.0 { - Some(ts) => write!(f, "{}", bridge::client::Methods::tt_to_string(ts)), + Some(ts) => write!(f, "{}", BridgeMethods::ts_to_string(ts)), None => Ok(()), } } @@ -252,7 +253,7 @@ fn tree_to_bridge_tree( #[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl From for TokenStream { fn from(tree: TokenTree) -> TokenStream { - TokenStream(Some(bridge::client::Methods::tt_from_token_tree(tree_to_bridge_tree(tree)))) + TokenStream(Some(BridgeMethods::ts_from_token_tree(tree_to_bridge_tree(tree)))) } } @@ -281,7 +282,7 @@ impl ConcatTreesHelper { if self.trees.is_empty() { TokenStream(None) } else { - TokenStream(Some(bridge::client::Methods::tt_concat_trees(None, self.trees))) + TokenStream(Some(BridgeMethods::ts_concat_trees(None, self.trees))) } } @@ -289,7 +290,7 @@ impl ConcatTreesHelper { if self.trees.is_empty() { return; } - stream.0 = Some(bridge::client::Methods::tt_concat_trees(stream.0.take(), self.trees)) + stream.0 = Some(BridgeMethods::ts_concat_trees(stream.0.take(), self.trees)) } } @@ -314,7 +315,7 @@ impl ConcatStreamsHelper { if self.streams.len() <= 1 { TokenStream(self.streams.pop()) } else { - TokenStream(Some(bridge::client::Methods::tt_concat_streams(None, self.streams))) + TokenStream(Some(BridgeMethods::ts_concat_streams(None, self.streams))) } } @@ -326,7 +327,7 @@ impl ConcatStreamsHelper { if base.is_none() && self.streams.len() == 1 { stream.0 = self.streams.pop(); } else { - stream.0 = Some(bridge::client::Methods::tt_concat_streams(base, self.streams)); + stream.0 = Some(BridgeMethods::ts_concat_streams(base, self.streams)); } } } @@ -377,7 +378,7 @@ impl Extend for TokenStream { macro_rules! extend_items { ($($item:ident)*) => { $( - #[stable(feature = "token_stream_extend_tt_items", since = "1.92.0")] + #[stable(feature = "token_stream_extend_ts_items", since = "1.92.0")] impl Extend<$item> for TokenStream { fn extend>(&mut self, iter: T) { self.extend(iter.into_iter().map(TokenTree::$item)); @@ -392,7 +393,7 @@ extend_items!(Group Literal Punct Ident); /// Public implementation details for the `TokenStream` type, such as iterators. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub mod token_stream { - use crate::{Group, Ident, Literal, Punct, TokenStream, TokenTree, bridge}; + use crate::{BridgeMethods, Group, Ident, Literal, Punct, TokenStream, TokenTree, bridge}; /// An iterator over `TokenStream`'s `TokenTree`s. /// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups, @@ -438,10 +439,7 @@ pub mod token_stream { fn into_iter(self) -> IntoIter { IntoIter( - self.0 - .map(|v| bridge::client::Methods::tt_into_trees(v)) - .unwrap_or_default() - .into_iter(), + self.0.map(|v| BridgeMethods::ts_into_trees(v)).unwrap_or_default().into_iter(), ) } } @@ -514,7 +512,7 @@ impl Span { /// `self` was generated from, if any. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn parent(&self) -> Option { - bridge::client::Methods::span_parent(self.0).map(Span) + BridgeMethods::span_parent(self.0).map(Span) } /// The span for the origin source code that `self` was generated from. If @@ -522,25 +520,25 @@ impl Span { /// value is the same as `*self`. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn source(&self) -> Span { - Span(bridge::client::Methods::span_source(self.0)) + Span(BridgeMethods::span_source(self.0)) } /// Returns the span's byte position range in the source file. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn byte_range(&self) -> Range { - bridge::client::Methods::span_byte_range(self.0) + BridgeMethods::span_byte_range(self.0) } /// Creates an empty span pointing to directly before this span. #[stable(feature = "proc_macro_span_location", since = "1.88.0")] pub fn start(&self) -> Span { - Span(bridge::client::Methods::span_start(self.0)) + Span(BridgeMethods::span_start(self.0)) } /// Creates an empty span pointing to directly after this span. #[stable(feature = "proc_macro_span_location", since = "1.88.0")] pub fn end(&self) -> Span { - Span(bridge::client::Methods::span_end(self.0)) + Span(BridgeMethods::span_end(self.0)) } /// The one-indexed line of the source file where the span starts. @@ -548,7 +546,7 @@ impl Span { /// To obtain the line of the span's end, use `span.end().line()`. #[stable(feature = "proc_macro_span_location", since = "1.88.0")] pub fn line(&self) -> usize { - bridge::client::Methods::span_line(self.0) + BridgeMethods::span_line(self.0) } /// The one-indexed column of the source file where the span starts. @@ -556,7 +554,7 @@ impl Span { /// To obtain the column of the span's end, use `span.end().column()`. #[stable(feature = "proc_macro_span_location", since = "1.88.0")] pub fn column(&self) -> usize { - bridge::client::Methods::span_column(self.0) + BridgeMethods::span_column(self.0) } /// The path to the source file in which this span occurs, for display purposes. @@ -565,7 +563,7 @@ impl Span { /// It might be remapped (e.g. `"/src/lib.rs"`) or an artificial path (e.g. `""`). #[stable(feature = "proc_macro_span_file", since = "1.88.0")] pub fn file(&self) -> String { - bridge::client::Methods::span_file(self.0) + BridgeMethods::span_file(self.0) } /// The path to the source file in which this span occurs on the local file system. @@ -575,7 +573,7 @@ impl Span { /// This path should not be embedded in the output of the macro; prefer `file()` instead. #[stable(feature = "proc_macro_span_file", since = "1.88.0")] pub fn local_file(&self) -> Option { - bridge::client::Methods::span_local_file(self.0).map(PathBuf::from) + BridgeMethods::span_local_file(self.0).map(PathBuf::from) } /// Creates a new span encompassing `self` and `other`. @@ -583,14 +581,14 @@ impl Span { /// Returns `None` if `self` and `other` are from different files. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn join(&self, other: Span) -> Option { - bridge::client::Methods::span_join(self.0, other.0).map(Span) + BridgeMethods::span_join(self.0, other.0).map(Span) } /// Creates a new span with the same line/column information as `self` but /// that resolves symbols as though it were at `other`. #[stable(feature = "proc_macro_span_resolved_at", since = "1.45.0")] pub fn resolved_at(&self, other: Span) -> Span { - Span(bridge::client::Methods::span_resolved_at(self.0, other.0)) + Span(BridgeMethods::span_resolved_at(self.0, other.0)) } /// Creates a new span with the same name resolution behavior as `self` but @@ -615,21 +613,21 @@ impl Span { /// be used for diagnostics only. #[stable(feature = "proc_macro_source_text", since = "1.66.0")] pub fn source_text(&self) -> Option { - bridge::client::Methods::span_source_text(self.0) + BridgeMethods::span_source_text(self.0) } // Used by the implementation of `Span::quote` #[doc(hidden)] #[unstable(feature = "proc_macro_internals", issue = "27812")] pub fn save_span(&self) -> usize { - bridge::client::Methods::span_save_span(self.0) + BridgeMethods::span_save_span(self.0) } // Used by the implementation of `Span::quote` #[doc(hidden)] #[unstable(feature = "proc_macro_internals", issue = "27812")] pub fn recover_proc_macro_span(id: usize) -> Span { - Span(bridge::client::Methods::span_recover_proc_macro_span(id)) + Span(BridgeMethods::span_recover_proc_macro_span(id)) } diagnostic_method!(error, Level::Error); @@ -1394,7 +1392,7 @@ impl Literal { // was 'c' or whether it was '\u{63}'. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn subspan>(&self, range: R) -> Option { - bridge::client::Methods::span_subspan( + BridgeMethods::span_subspan( self.0.span, range.start_bound().cloned(), range.end_bound().cloned(), @@ -1569,7 +1567,7 @@ impl FromStr for Literal { type Err = LexError; fn from_str(src: &str) -> Result { - match bridge::client::Methods::literal_from_str(src) { + match BridgeMethods::literal_from_str(src) { Ok(literal) => Ok(Literal(literal)), Err(()) => Err(LexError), } @@ -1611,11 +1609,12 @@ impl fmt::Debug for Literal { )] /// Functionality for adding environment state to the build dependency info. pub mod tracked { - use std::env::{self, VarError}; use std::ffi::OsStr; use std::path::Path; + use crate::BridgeMethods; + /// Retrieve an environment variable and add it to build dependency info. /// The build system executing the compiler will know that the variable was accessed during /// compilation, and will be able to rerun the build when the value of that variable changes. @@ -1624,9 +1623,8 @@ pub mod tracked { #[unstable(feature = "proc_macro_tracked_env", issue = "99515")] pub fn env_var + AsRef>(key: K) -> Result { let key: &str = key.as_ref(); - let value = - crate::bridge::client::Methods::injected_env_var(key).map_or_else(|| env::var(key), Ok); - crate::bridge::client::Methods::track_env_var(key, value.as_deref().ok()); + let value = BridgeMethods::injected_env_var(key).map_or_else(|| env::var(key), Ok); + BridgeMethods::track_env_var(key, value.as_deref().ok()); value } @@ -1636,6 +1634,6 @@ pub mod tracked { #[unstable(feature = "proc_macro_tracked_path", issue = "99515")] pub fn path>(path: P) { let path: &str = path.as_ref().to_str().unwrap(); - crate::bridge::client::Methods::track_path(path); + BridgeMethods::track_path(path); } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 4f50c04b27996..ec30630c10bbe 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -72,18 +72,18 @@ impl server::Server for RaSpanServer<'_> { // FIXME handle diagnostic } - fn tt_drop(&mut self, stream: Self::TokenStream) { + fn ts_drop(&mut self, stream: Self::TokenStream) { drop(stream); } - fn tt_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream { + fn ts_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream { stream.clone() } - fn tt_is_empty(&mut self, stream: &Self::TokenStream) -> bool { + fn ts_is_empty(&mut self, stream: &Self::TokenStream) -> bool { stream.is_empty() } - fn tt_from_str(&mut self, src: &str) -> Self::TokenStream { + fn ts_from_str(&mut self, src: &str) -> Self::TokenStream { Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| { Self::TokenStream::from_str( &format!("compile_error!(\"failed to parse str to token stream: {e}\")"), @@ -92,15 +92,15 @@ impl server::Server for RaSpanServer<'_> { .unwrap() }) } - fn tt_to_string(&mut self, stream: &Self::TokenStream) -> String { + fn ts_to_string(&mut self, stream: &Self::TokenStream) -> String { stream.to_string() } - fn tt_from_token_tree(&mut self, tree: TokenTree) -> Self::TokenStream { + fn ts_from_token_tree(&mut self, tree: TokenTree) -> Self::TokenStream { Self::TokenStream::new(vec![tree]) } - fn tt_expand_expr(&mut self, self_: &Self::TokenStream) -> Result { + fn ts_expand_expr(&mut self, self_: &Self::TokenStream) -> Result { // FIXME: requires db, more importantly this requires name resolution so we would need to // eagerly expand this proc-macro, but we can't know that this proc-macro is eager until we // expand it ... @@ -109,7 +109,7 @@ impl server::Server for RaSpanServer<'_> { Ok(self_.clone()) } - fn tt_concat_trees( + fn ts_concat_trees( &mut self, base: Option, trees: Vec>, @@ -125,7 +125,7 @@ impl server::Server for RaSpanServer<'_> { } } - fn tt_concat_streams( + fn ts_concat_streams( &mut self, base: Option, streams: Vec, @@ -137,7 +137,7 @@ impl server::Server for RaSpanServer<'_> { stream } - fn tt_into_trees(&mut self, stream: Self::TokenStream) -> Vec> { + fn ts_into_trees(&mut self, stream: Self::TokenStream) -> Vec> { (*stream.0).clone() } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index cd5ba59095610..3bf07290c8c05 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -75,18 +75,18 @@ impl server::Server for SpanIdServer<'_> { fn emit_diagnostic(&mut self, _: Diagnostic) {} - fn tt_drop(&mut self, stream: Self::TokenStream) { + fn ts_drop(&mut self, stream: Self::TokenStream) { drop(stream); } - fn tt_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream { + fn ts_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream { stream.clone() } - fn tt_is_empty(&mut self, stream: &Self::TokenStream) -> bool { + fn ts_is_empty(&mut self, stream: &Self::TokenStream) -> bool { stream.is_empty() } - fn tt_from_str(&mut self, src: &str) -> Self::TokenStream { + fn ts_from_str(&mut self, src: &str) -> Self::TokenStream { Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| { Self::TokenStream::from_str( &format!("compile_error!(\"failed to parse str to token stream: {e}\")"), @@ -95,18 +95,18 @@ impl server::Server for SpanIdServer<'_> { .unwrap() }) } - fn tt_to_string(&mut self, stream: &Self::TokenStream) -> String { + fn ts_to_string(&mut self, stream: &Self::TokenStream) -> String { stream.to_string() } - fn tt_from_token_tree(&mut self, tree: TokenTree) -> Self::TokenStream { + fn ts_from_token_tree(&mut self, tree: TokenTree) -> Self::TokenStream { Self::TokenStream::new(vec![tree]) } - fn tt_expand_expr(&mut self, self_: &Self::TokenStream) -> Result { + fn ts_expand_expr(&mut self, self_: &Self::TokenStream) -> Result { Ok(self_.clone()) } - fn tt_concat_trees( + fn ts_concat_trees( &mut self, base: Option, trees: Vec>, @@ -122,7 +122,7 @@ impl server::Server for SpanIdServer<'_> { } } - fn tt_concat_streams( + fn ts_concat_streams( &mut self, base: Option, streams: Vec, @@ -134,7 +134,7 @@ impl server::Server for SpanIdServer<'_> { stream } - fn tt_into_trees(&mut self, stream: Self::TokenStream) -> Vec> { + fn ts_into_trees(&mut self, stream: Self::TokenStream) -> Vec> { (*stream.0).clone() }