11//! Handles dynamic library loading for proc macro
22
33mod proc_macros;
4- mod version;
54
5+ use rustc_codegen_ssa:: back:: metadata:: DefaultMetadataLoader ;
6+ use rustc_interface:: util:: rustc_version_str;
7+ use rustc_metadata:: locator:: MetadataError ;
68use rustc_proc_macro:: bridge;
9+ use rustc_session:: config:: host_tuple;
10+ use rustc_target:: spec:: { Target , TargetTuple } ;
11+ use std:: path:: Path ;
712use std:: { fmt, fs, io, time:: SystemTime } ;
813use temp_dir:: TempDir ;
914
@@ -13,7 +18,8 @@ use paths::{Utf8Path, Utf8PathBuf};
1318
1419use crate :: {
1520 PanicMessage , ProcMacroClientHandle , ProcMacroKind , ProcMacroSrvSpan , TrackedEnv ,
16- dylib:: proc_macros:: ProcMacros , token_stream:: TokenStream ,
21+ dylib:: proc_macros:: { ProcMacroClients , ProcMacros } ,
22+ token_stream:: TokenStream ,
1723} ;
1824
1925pub ( crate ) struct Expander {
@@ -76,18 +82,15 @@ impl Expander {
7682pub enum LoadProcMacroDylibError {
7783 Io ( io:: Error ) ,
7884 LibLoading ( libloading:: Error ) ,
79- AbiMismatch ( String ) ,
85+ MetadataError ( MetadataError < ' static > ) ,
8086}
8187
8288impl fmt:: Display for LoadProcMacroDylibError {
8389 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
8490 match self {
8591 Self :: Io ( e) => e. fmt ( f) ,
86- Self :: AbiMismatch ( v) => {
87- use crate :: RUSTC_VERSION_STRING ;
88- write ! ( f, "mismatched ABI expected: `{RUSTC_VERSION_STRING}`, got `{v}`" )
89- }
9092 Self :: LibLoading ( e) => e. fmt ( f) ,
93+ Self :: MetadataError ( e) => e. fmt ( f) ,
9194 }
9295 }
9396}
@@ -104,25 +107,44 @@ impl From<libloading::Error> for LoadProcMacroDylibError {
104107 }
105108}
106109
110+ impl From < MetadataError < ' _ > > for LoadProcMacroDylibError {
111+ fn from ( e : MetadataError < ' _ > ) -> Self {
112+ LoadProcMacroDylibError :: MetadataError ( match e {
113+ MetadataError :: NotPresent ( path) => MetadataError :: NotPresent ( path. into_owned ( ) . into ( ) ) ,
114+ MetadataError :: LoadFailure ( err) => MetadataError :: LoadFailure ( err) ,
115+ MetadataError :: VersionMismatch { expected_version, found_version } => {
116+ MetadataError :: VersionMismatch { expected_version, found_version }
117+ }
118+ } )
119+ }
120+ }
121+
107122struct ProcMacroLibrary {
108- // 'static is actually the lifetime of library, so make sure this drops before _lib
109- proc_macros : & ' static ProcMacros ,
123+ // this contains references to the library, so make sure this drops before _lib
124+ proc_macros : ProcMacros ,
110125 // Hold on to the library so it doesn't unload
111126 _lib : Library ,
112127}
113128
114129impl ProcMacroLibrary {
115130 fn open ( path : & Utf8Path ) -> Result < Self , LoadProcMacroDylibError > {
131+ let proc_macro_kinds = rustc_span:: create_default_session_globals_then ( || {
132+ let ( target, _) =
133+ Target :: search ( & TargetTuple :: from_tuple ( host_tuple ( ) ) , Path :: new ( "" ) , false )
134+ . unwrap ( ) ;
135+ rustc_metadata:: locator:: get_proc_macro_info (
136+ & target,
137+ path. as_ref ( ) ,
138+ & DefaultMetadataLoader ,
139+ rustc_version_str ( ) . unwrap_or ( "unknown" ) ,
140+ )
141+ } ) ?;
142+
116143 let file = fs:: File :: open ( path) ?;
117144 #[ allow( clippy:: undocumented_unsafe_blocks) ] // FIXME
118145 let file = unsafe { memmap2:: Mmap :: map ( & file) } ?;
119146 let obj = object:: File :: parse ( & * file)
120147 . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: InvalidData , e) ) ?;
121- let version_info = version:: read_dylib_info ( & obj) ?;
122- if version_info. version_string != crate :: RUSTC_VERSION_STRING {
123- return Err ( LoadProcMacroDylibError :: AbiMismatch ( version_info. version_string ) ) ;
124- }
125-
126148 let symbol_name =
127149 find_registrar_symbol ( & obj) . map_err ( invalid_data_err) ?. ok_or_else ( || {
128150 invalid_data_err ( format ! ( "Cannot find registrar symbol in file {path}" ) )
@@ -135,9 +157,12 @@ impl ProcMacroLibrary {
135157 // due to self-referentiality
136158 // But we make sure that we do not drop it before the symbol is dropped
137159 let proc_macros =
138- unsafe { lib. get :: < & ' static & ' static ProcMacros > ( symbol_name. as_bytes ( ) ) } ;
160+ unsafe { lib. get :: < & ' static & ' static ProcMacroClients > ( symbol_name. as_bytes ( ) ) } ;
139161 match proc_macros {
140- Ok ( proc_macros) => Ok ( ProcMacroLibrary { proc_macros : * proc_macros, _lib : lib } ) ,
162+ Ok ( proc_macros) => Ok ( ProcMacroLibrary {
163+ proc_macros : ProcMacros :: new ( * proc_macros, proc_macro_kinds) ,
164+ _lib : lib,
165+ } ) ,
141166 Err ( e) => Err ( e. into ( ) ) ,
142167 }
143168 }
0 commit comments