Do not get proc_macro from the sysroot in rustc

With the stage0 refactor the proc_macro version found in the sysroot
will no longer always match the proc_macro version that proc-macros get
compiled with by the rustc executable that uses this proc_macro. This
will cause problems as soon as the ABI of the bridge gets changed to
implement new features or change the way existing features work.

To fix this, this commit changes rustc crates to depend directly on the
local version of proc_macro which will also be used in the sysroot that
rustc will build.
This commit is contained in:
bjorn3
2025-05-27 10:30:47 +00:00
parent b5eb9893f4
commit 026baa1c6f
15 changed files with 60 additions and 20 deletions

View File

@@ -3444,6 +3444,7 @@ dependencies = [
"rustc_macros",
"rustc_parse",
"rustc_parse_format",
"rustc_proc_macro",
"rustc_session",
"rustc_span",
"rustc_target",
@@ -3733,6 +3734,7 @@ dependencies = [
"rustc_lint_defs",
"rustc_macros",
"rustc_parse",
"rustc_proc_macro",
"rustc_serialize",
"rustc_session",
"rustc_span",
@@ -4081,6 +4083,7 @@ dependencies = [
"rustc_index",
"rustc_macros",
"rustc_middle",
"rustc_proc_macro",
"rustc_serialize",
"rustc_session",
"rustc_span",
@@ -4337,6 +4340,13 @@ dependencies = [
"tracing",
]
[[package]]
name = "rustc_proc_macro"
version = "0.0.0"
dependencies = [
"rustc-literal-escaper",
]
[[package]]
name = "rustc_query_impl"
version = "0.0.0"

View File

@@ -24,6 +24,9 @@ rustc_lint_defs = { path = "../rustc_lint_defs" }
rustc_macros = { path = "../rustc_macros" }
rustc_parse = { path = "../rustc_parse" }
rustc_parse_format = { path = "../rustc_parse_format" }
# We must use the proc_macro version that we will compile proc-macros against,
# not the one from our own sysroot.
rustc_proc_macro = { path = "../rustc_proc_macro" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }

View File

@@ -20,8 +20,6 @@
#![recursion_limit = "256"]
// tidy-alphabetical-end
extern crate proc_macro;
use std::sync::Arc;
use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
@@ -139,7 +137,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
CoercePointee: coerce_pointee::expand_deriving_coerce_pointee,
}
let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
let client = rustc_proc_macro::bridge::client::Client::expand1(rustc_proc_macro::quote);
register(sym::quote, SyntaxExtensionKind::Bang(Arc::new(BangProcMacro { client })));
let requires = SyntaxExtensionKind::Attr(Arc::new(contracts::ExpandRequires));
register(sym::contracts_requires, requires);

View File

@@ -23,6 +23,9 @@ rustc_lexer = { path = "../rustc_lexer" }
rustc_lint_defs = { path = "../rustc_lint_defs" }
rustc_macros = { path = "../rustc_macros" }
rustc_parse = { path = "../rustc_parse" }
# We must use the proc_macro version that we will compile proc-macros against,
# not the one from our own sysroot.
rustc_proc_macro = { path = "../rustc_proc_macro" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }

View File

@@ -14,8 +14,6 @@
#![feature(yeet_expr)]
// tidy-alphabetical-end
extern crate proc_macro as pm;
mod build;
mod errors;
// FIXME(Nilstrieb) Translate macro_rules diagnostics

View File

@@ -1,4 +1,3 @@
use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::tokenstream::TokenStream;
use rustc_errors::ErrorGuaranteed;
@@ -6,6 +5,7 @@ use rustc_parse::parser::{ForceCollect, Parser};
use rustc_session::config::ProcMacroExecutionStrategy;
use rustc_span::Span;
use rustc_span::profiling::SpannedEventArgRecorder;
use {rustc_ast as ast, rustc_proc_macro as pm};
use crate::base::{self, *};
use crate::{errors, proc_macro_server};

View File

@@ -1,10 +1,6 @@
use std::ops::{Bound, Range};
use ast::token::IdentIsRaw;
use pm::bridge::{
DelimSpan, Diagnostic, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree, server,
};
use pm::{Delimiter, Level};
use rustc_ast as ast;
use rustc_ast::token;
use rustc_ast::tokenstream::{self, DelimSpacing, Spacing, TokenStream};
@@ -15,6 +11,10 @@ use rustc_errors::{Diag, ErrorGuaranteed, MultiSpan, PResult};
use rustc_parse::lexer::nfc_normalize;
use rustc_parse::parser::Parser;
use rustc_parse::{exp, new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal};
use rustc_proc_macro::bridge::{
DelimSpan, Diagnostic, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree, server,
};
use rustc_proc_macro::{Delimiter, Level};
use rustc_session::parse::ParseSess;
use rustc_span::def_id::CrateNum;
use rustc_span::{BytePos, FileName, Pos, Span, Symbol, sym};
@@ -66,7 +66,7 @@ impl FromInternal<token::LitKind> for LitKind {
token::CStr => LitKind::CStr,
token::CStrRaw(n) => LitKind::CStrRaw(n),
token::Err(_guar) => {
// This is the only place a `pm::bridge::LitKind::ErrWithGuar`
// This is the only place a `rustc_proc_macro::bridge::LitKind::ErrWithGuar`
// is constructed. Note that an `ErrorGuaranteed` is available,
// as required. See the comment in `to_internal`.
LitKind::ErrWithGuar
@@ -149,7 +149,7 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
}
trees.push(TokenTree::Group(Group {
delimiter: pm::Delimiter::from_internal(delim),
delimiter: rustc_proc_macro::Delimiter::from_internal(delim),
stream: Some(stream),
span: DelimSpan {
open: span.open,
@@ -270,7 +270,7 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
let stream =
TokenStream::token_alone(token::Lifetime(ident.name, is_raw), ident.span);
trees.push(TokenTree::Group(Group {
delimiter: pm::Delimiter::None,
delimiter: rustc_proc_macro::Delimiter::None,
stream: Some(stream),
span: DelimSpan::from_single(span),
}))
@@ -302,7 +302,7 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
trees.push(TokenTree::Punct(Punct { ch: b'!', joint: false, span }));
}
trees.push(TokenTree::Group(Group {
delimiter: pm::Delimiter::Bracket,
delimiter: rustc_proc_macro::Delimiter::Bracket,
stream: Some(stream),
span: DelimSpan::from_single(span),
}));

View File

@@ -23,6 +23,9 @@ rustc_hir_pretty = { path = "../rustc_hir_pretty" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
# We must use the proc_macro version that we will compile proc-macros against,
# not the one from our own sysroot.
rustc_proc_macro = { path = "../rustc_proc_macro" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }

View File

@@ -7,7 +7,6 @@ use std::str::FromStr;
use std::time::Duration;
use std::{cmp, env, iter};
use proc_macro::bridge::client::ProcMacro;
use rustc_ast::expand::allocator::{AllocatorKind, alloc_error_handler_name, global_fn_name};
use rustc_ast::{self as ast, *};
use rustc_data_structures::fx::FxHashSet;
@@ -23,6 +22,7 @@ use rustc_hir::definitions::Definitions;
use rustc_index::IndexVec;
use rustc_middle::bug;
use rustc_middle::ty::{TyCtxt, TyCtxtFeed};
use rustc_proc_macro::bridge::client::ProcMacro;
use rustc_session::config::{
self, CrateType, ExtendedTargetModifierInfo, ExternLocation, OptionsTargetModifiers,
TargetModifier,

View File

@@ -16,8 +16,6 @@
#![feature(trusted_len)]
// tidy-alphabetical-end
extern crate proc_macro;
pub use rmeta::provide;
mod dependency_format;

View File

@@ -6,7 +6,6 @@ use std::sync::{Arc, OnceLock};
use std::{io, iter, mem};
pub(super) use cstore_impl::provide;
use proc_macro::bridge::client::ProcMacro;
use rustc_ast as ast;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxIndexMap;
@@ -26,6 +25,7 @@ use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
use rustc_middle::ty::Visibility;
use rustc_middle::ty::codec::TyDecoder;
use rustc_middle::{bug, implement_ty_decoder};
use rustc_proc_macro::bridge::client::ProcMacro;
use rustc_serialize::opaque::MemDecoder;
use rustc_serialize::{Decodable, Decoder};
use rustc_session::Session;

View File

@@ -0,0 +1,21 @@
# We need to use a separate crate including library/proc_macro as opposed to a
# direct path dependency on library/proc_macro because doing the latter will
# cause two copies of libproc_macro.rlib to end up in the sysroot, breaking
# proc-macro crates. In addition it confuses the workspace_members function of
# bootstrap.
[package]
name = "rustc_proc_macro"
version = "0.0.0"
edition = "2024"
[lib]
path = "../../library/proc_macro/src/lib.rs"
test = false
doctest = false
[dependencies]
rustc-literal-escaper = "0.0.2"
[features]
rustc-dep-of-std = []

View File

@@ -10,3 +10,7 @@ std = { path = "../std" }
# loaded from sysroot causing duplicate lang items and other similar errors.
core = { path = "../core" }
rustc-literal-escaper = { version = "0.0.2", features = ["rustc-dep-of-std"] }
[features]
default = ["rustc-dep-of-std"]
rustc-dep-of-std = []

View File

@@ -32,6 +32,7 @@
#![recursion_limit = "256"]
#![allow(internal_features)]
#![deny(ffi_unwind_calls)]
#![allow(rustc::internal)] // Can't use FxHashMap when compiled as part of the standard library
#![warn(rustdoc::unescaped_backticks)]
#![warn(unreachable_pub)]
#![deny(unsafe_op_in_unsafe_fn)]
@@ -95,7 +96,7 @@ pub fn is_available() -> bool {
///
/// This is both the input and output of `#[proc_macro]`, `#[proc_macro_attribute]`
/// and `#[proc_macro_derive]` definitions.
#[rustc_diagnostic_item = "TokenStream"]
#[cfg_attr(feature = "rustc-dep-of-std", rustc_diagnostic_item = "TokenStream")]
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
#[derive(Clone)]
pub struct TokenStream(Option<bridge::client::TokenStream>);

View File

@@ -776,7 +776,8 @@ impl Step for RustcDev {
copy_src_dirs(
builder,
&builder.src,
&["compiler"],
// The compiler has a path dependency on proc_macro, so make sure to include it.
&["compiler", "library/proc_macro"],
&[],
&tarball.image_dir().join("lib/rustlib/rustc-src/rust"),
);