@@ -187,13 +187,15 @@ impl<'a> CrateLoader<'a> {
187
187
} ) ;
188
188
}
189
189
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 > ) {
197
199
let crate_root = lib. metadata . get_root ( ) ;
198
200
info ! ( "register crate `extern crate {} as {}`" , crate_root. name, ident) ;
199
201
self . verify_no_symbol_conflicts ( span, & crate_root) ;
@@ -221,7 +223,16 @@ impl<'a> CrateLoader<'a> {
221
223
let dependencies: Vec < CrateNum > = cnum_map. iter ( ) . cloned ( ) . collect ( ) ;
222
224
223
225
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
+ }
225
236
} ) ;
226
237
227
238
let def_path_table = record_time ( & self . sess . perf_stats . decode_def_path_tables_time , || {
@@ -268,6 +279,58 @@ impl<'a> CrateLoader<'a> {
268
279
( cnum, cmeta)
269
280
}
270
281
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
+ // Use the locate_ctxt when looking for the host proc macro crate, as that is required
305
+ // so we want it to affect the error message
306
+ ( locate_ctxt, result)
307
+ } else {
308
+ ( & mut proc_macro_locator, None )
309
+ } ;
310
+
311
+ // Load the proc macro crate for the host
312
+
313
+ locator. reset ( ) ;
314
+ locator. is_proc_macro = Some ( true ) ;
315
+ locator. target = & self . sess . host ;
316
+ locator. triple = TargetTriple :: from_triple ( config:: host_triple ( ) ) ;
317
+ locator. filesearch = self . sess . host_filesearch ( path_kind) ;
318
+
319
+ let host_result = self . load ( locator) ?;
320
+
321
+ Some ( if self . sess . opts . debugging_opts . dual_proc_macros {
322
+ let host_result = match host_result {
323
+ LoadResult :: Previous ( ..) => {
324
+ panic ! ( "host and target proc macros must be loaded in lock-step" )
325
+ }
326
+ LoadResult :: Loaded ( library) => library
327
+ } ;
328
+ ( target_result. unwrap ( ) , Some ( host_result) )
329
+ } else {
330
+ ( host_result, None )
331
+ } )
332
+ }
333
+
271
334
fn resolve_crate < ' b > (
272
335
& ' b mut self ,
273
336
root : & ' b Option < CratePaths > ,
@@ -280,53 +343,39 @@ impl<'a> CrateLoader<'a> {
280
343
mut dep_kind : DepKind ,
281
344
) -> Result < ( CrateNum , Lrc < cstore:: CrateMetadata > ) , LoadError < ' b > > {
282
345
info ! ( "resolving crate `extern crate {} as {}`" , name, ident) ;
346
+ let mut locate_ctxt = locator:: Context {
347
+ sess : self . sess ,
348
+ span,
349
+ ident,
350
+ crate_name : name,
351
+ hash : hash. map ( |a| & * a) ,
352
+ extra_filename : extra_filename,
353
+ filesearch : self . sess . target_filesearch ( path_kind) ,
354
+ target : & self . sess . target . target ,
355
+ triple : self . sess . opts . target_triple . clone ( ) ,
356
+ root,
357
+ rejected_via_hash : vec ! [ ] ,
358
+ rejected_via_triple : vec ! [ ] ,
359
+ rejected_via_kind : vec ! [ ] ,
360
+ rejected_via_version : vec ! [ ] ,
361
+ rejected_via_filename : vec ! [ ] ,
362
+ should_match_name : true ,
363
+ is_proc_macro : Some ( false ) ,
364
+ metadata_loader : & * self . cstore . metadata_loader ,
365
+ } ;
366
+
283
367
let result = if let Some ( cnum) = self . existing_match ( name, hash, path_kind) {
284
- LoadResult :: Previous ( cnum)
368
+ ( LoadResult :: Previous ( cnum) , None )
285
369
} else {
286
370
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 ( || {
371
+ self . load ( & mut locate_ctxt) . map ( |r| ( r, None ) ) . or_else ( || {
309
372
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)
373
+ self . load_proc_macro ( & mut locate_ctxt, path_kind)
325
374
} ) . ok_or_else ( move || LoadError :: LocatorError ( locate_ctxt) ) ?
326
375
} ;
327
376
328
377
match result {
329
- LoadResult :: Previous ( cnum) => {
378
+ ( LoadResult :: Previous ( cnum) , None ) => {
330
379
let data = self . cstore . get_crate_data ( cnum) ;
331
380
if data. root . proc_macro_decls_static . is_some ( ) {
332
381
dep_kind = DepKind :: UnexportedMacrosOnly ;
@@ -336,9 +385,10 @@ impl<'a> CrateLoader<'a> {
336
385
} ) ;
337
386
Ok ( ( cnum, data) )
338
387
}
339
- LoadResult :: Loaded ( library) => {
340
- Ok ( self . register_crate ( root, ident, span, library, dep_kind) )
388
+ ( LoadResult :: Loaded ( library) , host_library ) => {
389
+ Ok ( self . register_crate ( host_library , root, ident, span, library, dep_kind) )
341
390
}
391
+ _ => panic ! ( )
342
392
}
343
393
}
344
394
@@ -354,7 +404,7 @@ impl<'a> CrateLoader<'a> {
354
404
// don't want to match a host crate against an equivalent target one
355
405
// already loaded.
356
406
let root = library. metadata . get_root ( ) ;
357
- if locate_ctxt. triple == & self . sess . opts . target_triple {
407
+ if locate_ctxt. triple == self . sess . opts . target_triple {
358
408
let mut result = LoadResult :: Loaded ( library) ;
359
409
self . cstore . iter_crate_data ( |cnum, data| {
360
410
if data. root . name == root. name && root. hash == data. root . hash {
@@ -450,9 +500,9 @@ impl<'a> CrateLoader<'a> {
450
500
fn read_extension_crate ( & mut self , span : Span , orig_name : Symbol , rename : Symbol )
451
501
-> ExtensionCrate {
452
502
info ! ( "read extension crate `extern crate {} as {}`" , orig_name, rename) ;
453
- let target_triple = & self . sess . opts . target_triple ;
503
+ let target_triple = self . sess . opts . target_triple . clone ( ) ;
454
504
let host_triple = TargetTriple :: from_triple ( config:: host_triple ( ) ) ;
455
- let is_cross = target_triple != & host_triple;
505
+ let is_cross = target_triple != host_triple;
456
506
let mut target_only = false ;
457
507
let mut locate_ctxt = locator:: Context {
458
508
sess : self . sess ,
@@ -463,7 +513,7 @@ impl<'a> CrateLoader<'a> {
463
513
extra_filename : None ,
464
514
filesearch : self . sess . host_filesearch ( PathKind :: Crate ) ,
465
515
target : & self . sess . host ,
466
- triple : & host_triple,
516
+ triple : host_triple,
467
517
root : & None ,
468
518
rejected_via_hash : vec ! [ ] ,
469
519
rejected_via_triple : vec ! [ ] ,
@@ -547,7 +597,7 @@ impl<'a> CrateLoader<'a> {
547
597
* ( sym as * const & [ ProcMacro ] )
548
598
} ;
549
599
550
- let extensions = decls. iter ( ) . map ( |& decl| {
600
+ let mut extensions: Vec < _ > = decls. iter ( ) . map ( |& decl| {
551
601
match decl {
552
602
ProcMacro :: CustomDerive { trait_name, attributes, client } => {
553
603
let attrs = attributes. iter ( ) . cloned ( ) . map ( Symbol :: intern) . collect :: < Vec < _ > > ( ) ;
@@ -574,13 +624,17 @@ impl<'a> CrateLoader<'a> {
574
624
} )
575
625
}
576
626
}
577
- } ) . map ( |( name, ext) | ( Symbol :: intern ( name) , Lrc :: new ( ext) ) ) . collect ( ) ;
627
+ } ) . map ( |( name, ext) | ( name, Lrc :: new ( ext) ) ) . collect ( ) ;
578
628
579
629
// Intentionally leak the dynamic library. We can't ever unload it
580
630
// since the library can make things that will live arbitrarily long.
581
631
mem:: forget ( lib) ;
582
632
583
- extensions
633
+ // Sort by macro name to ensure this is ordered the same way on
634
+ // both host and target proc macro crates
635
+ extensions. sort_by_key ( |ext| ext. 0 ) ;
636
+
637
+ extensions. into_iter ( ) . map ( |( name, ext) | ( Symbol :: intern ( name) , ext) ) . collect ( )
584
638
}
585
639
586
640
/// Look for a plugin registrar. Returns library path, crate
0 commit comments