@@ -187,13 +187,15 @@ impl<'a> CrateLoader<'a> {
187187 } ) ;
188188 }
189189
190- fn register_crate ( & mut self ,
191- root : & Option < CratePaths > ,
192- ident : Symbol ,
193- span : Span ,
194- lib : Library ,
195- dep_kind : DepKind )
196- -> ( CrateNum , Lrc < cstore:: CrateMetadata > ) {
190+ fn register_crate (
191+ & mut self ,
192+ host_lib : Option < Library > ,
193+ root : & Option < CratePaths > ,
194+ ident : Symbol ,
195+ span : Span ,
196+ lib : Library ,
197+ dep_kind : DepKind
198+ ) -> ( CrateNum , Lrc < cstore:: CrateMetadata > ) {
197199 let crate_root = lib. metadata . get_root ( ) ;
198200 info ! ( "register crate `extern crate {} as {}`" , crate_root. name, ident) ;
199201 self . verify_no_symbol_conflicts ( span, & crate_root) ;
@@ -221,7 +223,16 @@ impl<'a> CrateLoader<'a> {
221223 let dependencies: Vec < CrateNum > = cnum_map. iter ( ) . cloned ( ) . collect ( ) ;
222224
223225 let proc_macros = crate_root. proc_macro_decls_static . map ( |_| {
224- self . load_derive_macros ( & crate_root, dylib. clone ( ) . map ( |p| p. 0 ) , span)
226+ if self . sess . opts . debugging_opts . dual_proc_macros {
227+ let host_lib = host_lib. unwrap ( ) ;
228+ self . load_derive_macros (
229+ & host_lib. metadata . get_root ( ) ,
230+ host_lib. dylib . clone ( ) . map ( |p| p. 0 ) ,
231+ span
232+ )
233+ } else {
234+ self . load_derive_macros ( & crate_root, dylib. clone ( ) . map ( |p| p. 0 ) , span)
235+ }
225236 } ) ;
226237
227238 let def_path_table = record_time ( & self . sess . perf_stats . decode_def_path_tables_time , || {
@@ -268,6 +279,61 @@ impl<'a> CrateLoader<'a> {
268279 ( cnum, cmeta)
269280 }
270281
282+ fn load_proc_macro < ' b > (
283+ & mut self ,
284+ locate_ctxt : & mut locator:: Context < ' b > ,
285+ path_kind : PathKind ,
286+ ) -> Option < ( LoadResult , Option < Library > ) >
287+ where
288+ ' a : ' b
289+ {
290+ // Use a new locator Context so trying to load a proc macro doesn't affect the error
291+ // message we emit
292+ let mut proc_macro_locator = locate_ctxt. clone ( ) ;
293+
294+ // Try to load a proc macro
295+ proc_macro_locator. is_proc_macro = Some ( true ) ;
296+
297+ // Load the proc macro crate for the target
298+ let ( locator, target_result) = if self . sess . opts . debugging_opts . dual_proc_macros {
299+ proc_macro_locator. reset ( ) ;
300+ let result = match self . load ( & mut proc_macro_locator) ? {
301+ LoadResult :: Previous ( cnum) => return Some ( ( LoadResult :: Previous ( cnum) , None ) ) ,
302+ LoadResult :: Loaded ( library) => Some ( LoadResult :: Loaded ( library) )
303+ } ;
304+ // Don't look for a matching hash when looking for the host crate.
305+ // It won't be the same as the target crate hash
306+ locate_ctxt. hash = None ;
307+ // Use the locate_ctxt when looking for the host proc macro crate, as that is required
308+ // so we want it to affect the error message
309+ ( locate_ctxt, result)
310+ } else {
311+ ( & mut proc_macro_locator, None )
312+ } ;
313+
314+ // Load the proc macro crate for the host
315+
316+ locator. reset ( ) ;
317+ locator. is_proc_macro = Some ( true ) ;
318+ locator. target = & self . sess . host ;
319+ locator. triple = TargetTriple :: from_triple ( config:: host_triple ( ) ) ;
320+ locator. filesearch = self . sess . host_filesearch ( path_kind) ;
321+
322+ let host_result = self . load ( locator) ?;
323+
324+ Some ( if self . sess . opts . debugging_opts . dual_proc_macros {
325+ let host_result = match host_result {
326+ LoadResult :: Previous ( ..) => {
327+ panic ! ( "host and target proc macros must be loaded in lock-step" )
328+ }
329+ LoadResult :: Loaded ( library) => library
330+ } ;
331+ ( target_result. unwrap ( ) , Some ( host_result) )
332+ } else {
333+ ( host_result, None )
334+ } )
335+ }
336+
271337 fn resolve_crate < ' b > (
272338 & ' b mut self ,
273339 root : & ' b Option < CratePaths > ,
@@ -280,53 +346,39 @@ impl<'a> CrateLoader<'a> {
280346 mut dep_kind : DepKind ,
281347 ) -> Result < ( CrateNum , Lrc < cstore:: CrateMetadata > ) , LoadError < ' b > > {
282348 info ! ( "resolving crate `extern crate {} as {}`" , name, ident) ;
349+ let mut locate_ctxt = locator:: Context {
350+ sess : self . sess ,
351+ span,
352+ ident,
353+ crate_name : name,
354+ hash : hash. map ( |a| & * a) ,
355+ extra_filename : extra_filename,
356+ filesearch : self . sess . target_filesearch ( path_kind) ,
357+ target : & self . sess . target . target ,
358+ triple : self . sess . opts . target_triple . clone ( ) ,
359+ root,
360+ rejected_via_hash : vec ! [ ] ,
361+ rejected_via_triple : vec ! [ ] ,
362+ rejected_via_kind : vec ! [ ] ,
363+ rejected_via_version : vec ! [ ] ,
364+ rejected_via_filename : vec ! [ ] ,
365+ should_match_name : true ,
366+ is_proc_macro : Some ( false ) ,
367+ metadata_loader : & * self . cstore . metadata_loader ,
368+ } ;
369+
283370 let result = if let Some ( cnum) = self . existing_match ( name, hash, path_kind) {
284- LoadResult :: Previous ( cnum)
371+ ( LoadResult :: Previous ( cnum) , None )
285372 } else {
286373 info ! ( "falling back to a load" ) ;
287- let mut locate_ctxt = locator:: Context {
288- sess : self . sess ,
289- span,
290- ident,
291- crate_name : name,
292- hash : hash. map ( |a| & * a) ,
293- extra_filename : extra_filename,
294- filesearch : self . sess . target_filesearch ( path_kind) ,
295- target : & self . sess . target . target ,
296- triple : & self . sess . opts . target_triple ,
297- root,
298- rejected_via_hash : vec ! [ ] ,
299- rejected_via_triple : vec ! [ ] ,
300- rejected_via_kind : vec ! [ ] ,
301- rejected_via_version : vec ! [ ] ,
302- rejected_via_filename : vec ! [ ] ,
303- should_match_name : true ,
304- is_proc_macro : Some ( false ) ,
305- metadata_loader : & * self . cstore . metadata_loader ,
306- } ;
307-
308- self . load ( & mut locate_ctxt) . or_else ( || {
374+ self . load ( & mut locate_ctxt) . map ( |r| ( r, None ) ) . or_else ( || {
309375 dep_kind = DepKind :: UnexportedMacrosOnly ;
310-
311- let mut proc_macro_locator = locator:: Context {
312- target : & self . sess . host ,
313- triple : & TargetTriple :: from_triple ( config:: host_triple ( ) ) ,
314- filesearch : self . sess . host_filesearch ( path_kind) ,
315- rejected_via_hash : vec ! [ ] ,
316- rejected_via_triple : vec ! [ ] ,
317- rejected_via_kind : vec ! [ ] ,
318- rejected_via_version : vec ! [ ] ,
319- rejected_via_filename : vec ! [ ] ,
320- is_proc_macro : Some ( true ) ,
321- ..locate_ctxt
322- } ;
323-
324- self . load ( & mut proc_macro_locator)
376+ self . load_proc_macro ( & mut locate_ctxt, path_kind)
325377 } ) . ok_or_else ( move || LoadError :: LocatorError ( locate_ctxt) ) ?
326378 } ;
327379
328380 match result {
329- LoadResult :: Previous ( cnum) => {
381+ ( LoadResult :: Previous ( cnum) , None ) => {
330382 let data = self . cstore . get_crate_data ( cnum) ;
331383 if data. root . proc_macro_decls_static . is_some ( ) {
332384 dep_kind = DepKind :: UnexportedMacrosOnly ;
@@ -336,9 +388,10 @@ impl<'a> CrateLoader<'a> {
336388 } ) ;
337389 Ok ( ( cnum, data) )
338390 }
339- LoadResult :: Loaded ( library) => {
340- Ok ( self . register_crate ( root, ident, span, library, dep_kind) )
391+ ( LoadResult :: Loaded ( library) , host_library ) => {
392+ Ok ( self . register_crate ( host_library , root, ident, span, library, dep_kind) )
341393 }
394+ _ => panic ! ( )
342395 }
343396 }
344397
@@ -354,7 +407,7 @@ impl<'a> CrateLoader<'a> {
354407 // don't want to match a host crate against an equivalent target one
355408 // already loaded.
356409 let root = library. metadata . get_root ( ) ;
357- if locate_ctxt. triple == & self . sess . opts . target_triple {
410+ if locate_ctxt. triple == self . sess . opts . target_triple {
358411 let mut result = LoadResult :: Loaded ( library) ;
359412 self . cstore . iter_crate_data ( |cnum, data| {
360413 if data. root . name == root. name && root. hash == data. root . hash {
@@ -450,9 +503,9 @@ impl<'a> CrateLoader<'a> {
450503 fn read_extension_crate ( & mut self , span : Span , orig_name : Symbol , rename : Symbol )
451504 -> ExtensionCrate {
452505 info ! ( "read extension crate `extern crate {} as {}`" , orig_name, rename) ;
453- let target_triple = & self . sess . opts . target_triple ;
506+ let target_triple = self . sess . opts . target_triple . clone ( ) ;
454507 let host_triple = TargetTriple :: from_triple ( config:: host_triple ( ) ) ;
455- let is_cross = target_triple != & host_triple;
508+ let is_cross = target_triple != host_triple;
456509 let mut target_only = false ;
457510 let mut locate_ctxt = locator:: Context {
458511 sess : self . sess ,
@@ -463,7 +516,7 @@ impl<'a> CrateLoader<'a> {
463516 extra_filename : None ,
464517 filesearch : self . sess . host_filesearch ( PathKind :: Crate ) ,
465518 target : & self . sess . host ,
466- triple : & host_triple,
519+ triple : host_triple,
467520 root : & None ,
468521 rejected_via_hash : vec ! [ ] ,
469522 rejected_via_triple : vec ! [ ] ,
@@ -547,7 +600,7 @@ impl<'a> CrateLoader<'a> {
547600 * ( sym as * const & [ ProcMacro ] )
548601 } ;
549602
550- let extensions = decls. iter ( ) . map ( |& decl| {
603+ let mut extensions: Vec < _ > = decls. iter ( ) . map ( |& decl| {
551604 match decl {
552605 ProcMacro :: CustomDerive { trait_name, attributes, client } => {
553606 let attrs = attributes. iter ( ) . cloned ( ) . map ( Symbol :: intern) . collect :: < Vec < _ > > ( ) ;
@@ -574,13 +627,17 @@ impl<'a> CrateLoader<'a> {
574627 } )
575628 }
576629 }
577- } ) . map ( |( name, ext) | ( Symbol :: intern ( name) , Lrc :: new ( ext) ) ) . collect ( ) ;
630+ } ) . map ( |( name, ext) | ( name, Lrc :: new ( ext) ) ) . collect ( ) ;
578631
579632 // Intentionally leak the dynamic library. We can't ever unload it
580633 // since the library can make things that will live arbitrarily long.
581634 mem:: forget ( lib) ;
582635
583- extensions
636+ // Sort by macro name to ensure this is ordered the same way on
637+ // both host and target proc macro crates
638+ extensions. sort_by_key ( |ext| ext. 0 ) ;
639+
640+ extensions. into_iter ( ) . map ( |( name, ext) | ( Symbol :: intern ( name) , ext) ) . collect ( )
584641 }
585642
586643 /// Look for a plugin registrar. Returns library path, crate
0 commit comments