@@ -35,7 +35,6 @@ use syntax::ast;
35
35
use syntax:: abi:: Abi ;
36
36
use syntax:: attr;
37
37
use syntax:: ext:: base:: SyntaxExtension ;
38
- use syntax:: feature_gate:: { self , emit_feature_err} ;
39
38
use syntax:: parse:: token:: { InternedString , intern} ;
40
39
use syntax_pos:: { Span , DUMMY_SP } ;
41
40
use log;
@@ -285,15 +284,13 @@ impl<'a> CrateLoader<'a> {
285
284
286
285
let cnum_map = self . resolve_crate_deps ( root, & crate_root, & metadata, cnum, span, dep_kind) ;
287
286
288
- if crate_root. macro_derive_registrar . is_some ( ) {
289
- self . sess . span_err ( span, "crates of the `proc-macro` crate type \
290
- cannot be linked at runtime") ;
291
- }
292
-
293
287
let cmeta = Rc :: new ( cstore:: CrateMetadata {
294
288
name : name. to_string ( ) ,
295
289
extern_crate : Cell :: new ( None ) ,
296
290
key_map : metadata. load_key_map ( crate_root. index ) ,
291
+ proc_macros : crate_root. macro_derive_registrar . map ( |_| {
292
+ self . load_derive_macros ( & crate_root, dylib. clone ( ) . map ( |p| p. 0 ) , span)
293
+ } ) ,
297
294
root : crate_root,
298
295
blob : metadata,
299
296
cnum_map : RefCell :: new ( cnum_map) ,
@@ -317,34 +314,48 @@ impl<'a> CrateLoader<'a> {
317
314
hash : Option < & Svh > ,
318
315
span : Span ,
319
316
kind : PathKind ,
320
- dep_kind : DepKind )
317
+ mut dep_kind : DepKind )
321
318
-> ( CrateNum , Rc < cstore:: CrateMetadata > ) {
322
319
info ! ( "resolving crate `extern crate {} as {}`" , name, ident) ;
323
- let result = match self . existing_match ( name, hash, kind) {
324
- Some ( cnum) => LoadResult :: Previous ( cnum) ,
325
- None => {
326
- info ! ( "falling back to a load" ) ;
327
- let mut locate_ctxt = locator:: Context {
328
- sess : self . sess ,
329
- span : span,
330
- ident : ident,
331
- crate_name : name,
332
- hash : hash. map ( |a| & * a) ,
333
- filesearch : self . sess . target_filesearch ( kind) ,
334
- target : & self . sess . target . target ,
335
- triple : & self . sess . opts . target_triple ,
336
- root : root,
320
+ let result = if let Some ( cnum) = self . existing_match ( name, hash, kind) {
321
+ LoadResult :: Previous ( cnum)
322
+ } else {
323
+ info ! ( "falling back to a load" ) ;
324
+ let mut locate_ctxt = locator:: Context {
325
+ sess : self . sess ,
326
+ span : span,
327
+ ident : ident,
328
+ crate_name : name,
329
+ hash : hash. map ( |a| & * a) ,
330
+ filesearch : self . sess . target_filesearch ( kind) ,
331
+ target : & self . sess . target . target ,
332
+ triple : & self . sess . opts . target_triple ,
333
+ root : root,
334
+ rejected_via_hash : vec ! [ ] ,
335
+ rejected_via_triple : vec ! [ ] ,
336
+ rejected_via_kind : vec ! [ ] ,
337
+ rejected_via_version : vec ! [ ] ,
338
+ should_match_name : true ,
339
+ is_proc_macro : Some ( false ) ,
340
+ } ;
341
+
342
+ self . load ( & mut locate_ctxt) . or_else ( || {
343
+ dep_kind = DepKind :: MacrosOnly ;
344
+
345
+ let mut proc_macro_locator = locator:: Context {
346
+ target : & self . sess . host ,
347
+ triple : config:: host_triple ( ) ,
348
+ filesearch : self . sess . host_filesearch ( PathKind :: Crate ) ,
337
349
rejected_via_hash : vec ! [ ] ,
338
350
rejected_via_triple : vec ! [ ] ,
339
351
rejected_via_kind : vec ! [ ] ,
340
352
rejected_via_version : vec ! [ ] ,
341
- should_match_name : true ,
353
+ is_proc_macro : Some ( true ) ,
354
+ ..locate_ctxt
342
355
} ;
343
- match self . load ( & mut locate_ctxt) {
344
- Some ( result) => result,
345
- None => locate_ctxt. report_errs ( ) ,
346
- }
347
- }
356
+
357
+ self . load ( & mut proc_macro_locator)
358
+ } ) . unwrap_or_else ( || locate_ctxt. report_errs ( ) )
348
359
} ;
349
360
350
361
match result {
@@ -431,6 +442,10 @@ impl<'a> CrateLoader<'a> {
431
442
dep_kind : DepKind )
432
443
-> cstore:: CrateNumMap {
433
444
debug ! ( "resolving deps of external crate" ) ;
445
+ if crate_root. macro_derive_registrar . is_some ( ) {
446
+ return cstore:: CrateNumMap :: new ( ) ;
447
+ }
448
+
434
449
// The map from crate numbers in the crate we're resolving to local crate
435
450
// numbers
436
451
let deps = crate_root. crate_deps . decode ( metadata) ;
@@ -479,6 +494,7 @@ impl<'a> CrateLoader<'a> {
479
494
rejected_via_kind : vec ! [ ] ,
480
495
rejected_via_version : vec ! [ ] ,
481
496
should_match_name : true ,
497
+ is_proc_macro : None ,
482
498
} ;
483
499
let library = self . load ( & mut locate_ctxt) . or_else ( || {
484
500
if !is_cross {
@@ -525,51 +541,36 @@ impl<'a> CrateLoader<'a> {
525
541
/// implemented as dynamic libraries, but we have a possible future where
526
542
/// custom derive (and other macro-1.1 style features) are implemented via
527
543
/// executables and custom IPC.
528
- fn load_derive_macros ( & mut self , item : & ast :: Item , ekrate : & ExtensionCrate )
529
- -> Option < Vec < ( ast:: Name , SyntaxExtension ) > > {
544
+ fn load_derive_macros ( & mut self , root : & CrateRoot , dylib : Option < PathBuf > , span : Span )
545
+ -> Vec < ( ast:: Name , Rc < SyntaxExtension > ) > {
530
546
use std:: { env, mem} ;
531
547
use proc_macro:: TokenStream ;
532
548
use proc_macro:: __internal:: Registry ;
533
549
use rustc_back:: dynamic_lib:: DynamicLibrary ;
534
550
use syntax_ext:: deriving:: custom:: CustomDerive ;
535
551
536
- let root = ekrate. metadata . get_root ( ) ;
537
- let index = match root. macro_derive_registrar {
538
- Some ( index) => index,
539
- None => return None ,
540
- } ;
541
- if !self . sess . features . borrow ( ) . proc_macro {
542
- let issue = feature_gate:: GateIssue :: Language ;
543
- let msg = "loading custom derive macro crates is experimentally supported" ;
544
- emit_feature_err ( & self . sess . parse_sess , "proc_macro" , item. span , issue, msg) ;
545
- }
546
-
547
- if ekrate. target_only {
548
- let msg = format ! ( "proc-macro crate is not available for triple `{}` (only found {})" ,
549
- config:: host_triple( ) , self . sess. opts. target_triple) ;
550
- self . sess . span_fatal ( item. span , & msg) ;
551
- }
552
- let path = match ekrate. dylib . clone ( ) {
552
+ let path = match dylib {
553
553
Some ( dylib) => dylib,
554
- None => span_bug ! ( item . span, "proc-macro crate not dylib" ) ,
554
+ None => span_bug ! ( span, "proc-macro crate not dylib" ) ,
555
555
} ;
556
556
// Make sure the path contains a / or the linker will search for it.
557
557
let path = env:: current_dir ( ) . unwrap ( ) . join ( path) ;
558
558
let lib = match DynamicLibrary :: open ( Some ( & path) ) {
559
559
Ok ( lib) => lib,
560
- Err ( err) => self . sess . span_fatal ( item . span , & err) ,
560
+ Err ( err) => self . sess . span_fatal ( span, & err) ,
561
561
} ;
562
562
563
- let sym = self . sess . generate_derive_registrar_symbol ( & root. hash , index) ;
563
+ let sym = self . sess . generate_derive_registrar_symbol ( & root. hash ,
564
+ root. macro_derive_registrar . unwrap ( ) ) ;
564
565
let registrar = unsafe {
565
566
let sym = match lib. symbol ( & sym) {
566
567
Ok ( f) => f,
567
- Err ( err) => self . sess . span_fatal ( item . span , & err) ,
568
+ Err ( err) => self . sess . span_fatal ( span, & err) ,
568
569
} ;
569
570
mem:: transmute :: < * mut u8 , fn ( & mut Registry ) > ( sym)
570
571
} ;
571
572
572
- struct MyRegistrar ( Vec < ( ast:: Name , SyntaxExtension ) > ) ;
573
+ struct MyRegistrar ( Vec < ( ast:: Name , Rc < SyntaxExtension > ) > ) ;
573
574
574
575
impl Registry for MyRegistrar {
575
576
fn register_custom_derive ( & mut self ,
@@ -580,7 +581,7 @@ impl<'a> CrateLoader<'a> {
580
581
let derive = SyntaxExtension :: CustomDerive (
581
582
Box :: new ( CustomDerive :: new ( expand, attrs) )
582
583
) ;
583
- self . 0 . push ( ( intern ( trait_name) , derive) ) ;
584
+ self . 0 . push ( ( intern ( trait_name) , Rc :: new ( derive) ) ) ;
584
585
}
585
586
}
586
587
@@ -590,7 +591,7 @@ impl<'a> CrateLoader<'a> {
590
591
// Intentionally leak the dynamic library. We can't ever unload it
591
592
// since the library can make things that will live arbitrarily long.
592
593
mem:: forget ( lib) ;
593
- Some ( my_registrar. 0 )
594
+ my_registrar. 0
594
595
}
595
596
596
597
/// Look for a plugin registrar. Returns library path, crate
@@ -928,35 +929,14 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
928
929
self . register_statically_included_foreign_items ( ) ;
929
930
}
930
931
931
- fn process_item ( & mut self , item : & ast:: Item , definitions : & Definitions , load_macros : bool )
932
- -> Vec < ( ast:: Name , SyntaxExtension ) > {
932
+ fn process_item ( & mut self , item : & ast:: Item , definitions : & Definitions ) {
933
933
match item. node {
934
934
ast:: ItemKind :: ExternCrate ( _) => { }
935
- ast:: ItemKind :: ForeignMod ( ref fm) => {
936
- self . process_foreign_mod ( item, fm) ;
937
- return Vec :: new ( ) ;
938
- }
939
- _ => return Vec :: new ( ) ,
935
+ ast:: ItemKind :: ForeignMod ( ref fm) => return self . process_foreign_mod ( item, fm) ,
936
+ _ => return ,
940
937
}
941
938
942
939
let info = self . extract_crate_info ( item) . unwrap ( ) ;
943
- if load_macros {
944
- let ekrate = self . read_extension_crate ( item. span , & info) ;
945
-
946
- // If this is a proc-macro crate, return here to avoid registering.
947
- if let Some ( custom_derives) = self . load_derive_macros ( item, & ekrate) {
948
- return custom_derives;
949
- }
950
-
951
- // Register crate now to avoid double-reading metadata
952
- if let PMDSource :: Owned ( lib) = ekrate. metadata {
953
- if ekrate. target_only || config:: host_triple ( ) == self . sess . opts . target_triple {
954
- let ExternCrateInfo { ref ident, ref name, dep_kind, .. } = info;
955
- self . register_crate ( & None , ident, name, item. span , lib, dep_kind) ;
956
- }
957
- }
958
- }
959
-
960
940
let ( cnum, ..) = self . resolve_crate (
961
941
& None , & info. ident , & info. name , None , item. span , PathKind :: Crate , info. dep_kind ,
962
942
) ;
@@ -968,7 +948,5 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
968
948
ExternCrate { def_id : def_id, span : item. span , direct : true , path_len : len } ;
969
949
self . update_extern_crate ( cnum, extern_crate, & mut FxHashSet ( ) ) ;
970
950
self . cstore . add_extern_mod_stmt_cnum ( info. id , cnum) ;
971
-
972
- Vec :: new ( )
973
951
}
974
952
}
0 commit comments