@@ -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,61 @@ 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
+ // 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
+
271
337
fn resolve_crate < ' b > (
272
338
& ' b mut self ,
273
339
root : & ' b Option < CratePaths > ,
@@ -280,53 +346,39 @@ impl<'a> CrateLoader<'a> {
280
346
mut dep_kind : DepKind ,
281
347
) -> Result < ( CrateNum , Lrc < cstore:: CrateMetadata > ) , LoadError < ' b > > {
282
348
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
+
283
370
let result = if let Some ( cnum) = self . existing_match ( name, hash, path_kind) {
284
- LoadResult :: Previous ( cnum)
371
+ ( LoadResult :: Previous ( cnum) , None )
285
372
} else {
286
373
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 ( || {
309
375
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)
325
377
} ) . ok_or_else ( move || LoadError :: LocatorError ( locate_ctxt) ) ?
326
378
} ;
327
379
328
380
match result {
329
- LoadResult :: Previous ( cnum) => {
381
+ ( LoadResult :: Previous ( cnum) , None ) => {
330
382
let data = self . cstore . get_crate_data ( cnum) ;
331
383
if data. root . proc_macro_decls_static . is_some ( ) {
332
384
dep_kind = DepKind :: UnexportedMacrosOnly ;
@@ -336,9 +388,10 @@ impl<'a> CrateLoader<'a> {
336
388
} ) ;
337
389
Ok ( ( cnum, data) )
338
390
}
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) )
341
393
}
394
+ _ => panic ! ( )
342
395
}
343
396
}
344
397
@@ -354,7 +407,7 @@ impl<'a> CrateLoader<'a> {
354
407
// don't want to match a host crate against an equivalent target one
355
408
// already loaded.
356
409
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 {
358
411
let mut result = LoadResult :: Loaded ( library) ;
359
412
self . cstore . iter_crate_data ( |cnum, data| {
360
413
if data. root . name == root. name && root. hash == data. root . hash {
@@ -450,9 +503,9 @@ impl<'a> CrateLoader<'a> {
450
503
fn read_extension_crate ( & mut self , span : Span , orig_name : Symbol , rename : Symbol )
451
504
-> ExtensionCrate {
452
505
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 ( ) ;
454
507
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;
456
509
let mut target_only = false ;
457
510
let mut locate_ctxt = locator:: Context {
458
511
sess : self . sess ,
@@ -463,7 +516,7 @@ impl<'a> CrateLoader<'a> {
463
516
extra_filename : None ,
464
517
filesearch : self . sess . host_filesearch ( PathKind :: Crate ) ,
465
518
target : & self . sess . host ,
466
- triple : & host_triple,
519
+ triple : host_triple,
467
520
root : & None ,
468
521
rejected_via_hash : vec ! [ ] ,
469
522
rejected_via_triple : vec ! [ ] ,
@@ -547,7 +600,7 @@ impl<'a> CrateLoader<'a> {
547
600
* ( sym as * const & [ ProcMacro ] )
548
601
} ;
549
602
550
- let extensions = decls. iter ( ) . map ( |& decl| {
603
+ let mut extensions: Vec < _ > = decls. iter ( ) . map ( |& decl| {
551
604
match decl {
552
605
ProcMacro :: CustomDerive { trait_name, attributes, client } => {
553
606
let attrs = attributes. iter ( ) . cloned ( ) . map ( Symbol :: intern) . collect :: < Vec < _ > > ( ) ;
@@ -574,13 +627,17 @@ impl<'a> CrateLoader<'a> {
574
627
} )
575
628
}
576
629
}
577
- } ) . map ( |( name, ext) | ( Symbol :: intern ( name) , Lrc :: new ( ext) ) ) . collect ( ) ;
630
+ } ) . map ( |( name, ext) | ( name, Lrc :: new ( ext) ) ) . collect ( ) ;
578
631
579
632
// Intentionally leak the dynamic library. We can't ever unload it
580
633
// since the library can make things that will live arbitrarily long.
581
634
mem:: forget ( lib) ;
582
635
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 ( )
584
641
}
585
642
586
643
/// Look for a plugin registrar. Returns library path, crate
0 commit comments