@@ -35,7 +35,6 @@ use syntax::ast;
3535use syntax:: abi:: Abi ;
3636use syntax:: attr;
3737use syntax:: ext:: base:: SyntaxExtension ;
38- use syntax:: feature_gate:: { self , emit_feature_err} ;
3938use syntax:: parse:: token:: { InternedString , intern} ;
4039use syntax_pos:: { Span , DUMMY_SP } ;
4140use log;
@@ -285,15 +284,13 @@ impl<'a> CrateLoader<'a> {
285284
286285 let cnum_map = self . resolve_crate_deps ( root, & crate_root, & metadata, cnum, span, dep_kind) ;
287286
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-
293287 let cmeta = Rc :: new ( cstore:: CrateMetadata {
294288 name : name. to_string ( ) ,
295289 extern_crate : Cell :: new ( None ) ,
296290 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+ } ) ,
297294 root : crate_root,
298295 blob : metadata,
299296 cnum_map : RefCell :: new ( cnum_map) ,
@@ -317,34 +314,48 @@ impl<'a> CrateLoader<'a> {
317314 hash : Option < & Svh > ,
318315 span : Span ,
319316 kind : PathKind ,
320- dep_kind : DepKind )
317+ mut dep_kind : DepKind )
321318 -> ( CrateNum , Rc < cstore:: CrateMetadata > ) {
322319 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 ) ,
337349 rejected_via_hash : vec ! [ ] ,
338350 rejected_via_triple : vec ! [ ] ,
339351 rejected_via_kind : vec ! [ ] ,
340352 rejected_via_version : vec ! [ ] ,
341- should_match_name : true ,
353+ is_proc_macro : Some ( true ) ,
354+ ..locate_ctxt
342355 } ;
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 ( ) )
348359 } ;
349360
350361 match result {
@@ -431,6 +442,10 @@ impl<'a> CrateLoader<'a> {
431442 dep_kind : DepKind )
432443 -> cstore:: CrateNumMap {
433444 debug ! ( "resolving deps of external crate" ) ;
445+ if crate_root. macro_derive_registrar . is_some ( ) {
446+ return cstore:: CrateNumMap :: new ( ) ;
447+ }
448+
434449 // The map from crate numbers in the crate we're resolving to local crate
435450 // numbers
436451 let deps = crate_root. crate_deps . decode ( metadata) ;
@@ -479,6 +494,7 @@ impl<'a> CrateLoader<'a> {
479494 rejected_via_kind : vec ! [ ] ,
480495 rejected_via_version : vec ! [ ] ,
481496 should_match_name : true ,
497+ is_proc_macro : None ,
482498 } ;
483499 let library = self . load ( & mut locate_ctxt) . or_else ( || {
484500 if !is_cross {
@@ -525,51 +541,36 @@ impl<'a> CrateLoader<'a> {
525541 /// implemented as dynamic libraries, but we have a possible future where
526542 /// custom derive (and other macro-1.1 style features) are implemented via
527543 /// 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 > ) > {
530546 use std:: { env, mem} ;
531547 use proc_macro:: TokenStream ;
532548 use proc_macro:: __internal:: Registry ;
533549 use rustc_back:: dynamic_lib:: DynamicLibrary ;
534550 use syntax_ext:: deriving:: custom:: CustomDerive ;
535551
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 {
553553 Some ( dylib) => dylib,
554- None => span_bug ! ( item . span, "proc-macro crate not dylib" ) ,
554+ None => span_bug ! ( span, "proc-macro crate not dylib" ) ,
555555 } ;
556556 // Make sure the path contains a / or the linker will search for it.
557557 let path = env:: current_dir ( ) . unwrap ( ) . join ( path) ;
558558 let lib = match DynamicLibrary :: open ( Some ( & path) ) {
559559 Ok ( lib) => lib,
560- Err ( err) => self . sess . span_fatal ( item . span , & err) ,
560+ Err ( err) => self . sess . span_fatal ( span, & err) ,
561561 } ;
562562
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 ( ) ) ;
564565 let registrar = unsafe {
565566 let sym = match lib. symbol ( & sym) {
566567 Ok ( f) => f,
567- Err ( err) => self . sess . span_fatal ( item . span , & err) ,
568+ Err ( err) => self . sess . span_fatal ( span, & err) ,
568569 } ;
569570 mem:: transmute :: < * mut u8 , fn ( & mut Registry ) > ( sym)
570571 } ;
571572
572- struct MyRegistrar ( Vec < ( ast:: Name , SyntaxExtension ) > ) ;
573+ struct MyRegistrar ( Vec < ( ast:: Name , Rc < SyntaxExtension > ) > ) ;
573574
574575 impl Registry for MyRegistrar {
575576 fn register_custom_derive ( & mut self ,
@@ -580,7 +581,7 @@ impl<'a> CrateLoader<'a> {
580581 let derive = SyntaxExtension :: CustomDerive (
581582 Box :: new ( CustomDerive :: new ( expand, attrs) )
582583 ) ;
583- self . 0 . push ( ( intern ( trait_name) , derive) ) ;
584+ self . 0 . push ( ( intern ( trait_name) , Rc :: new ( derive) ) ) ;
584585 }
585586 }
586587
@@ -590,7 +591,7 @@ impl<'a> CrateLoader<'a> {
590591 // Intentionally leak the dynamic library. We can't ever unload it
591592 // since the library can make things that will live arbitrarily long.
592593 mem:: forget ( lib) ;
593- Some ( my_registrar. 0 )
594+ my_registrar. 0
594595 }
595596
596597 /// Look for a plugin registrar. Returns library path, crate
@@ -928,35 +929,14 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
928929 self . register_statically_included_foreign_items ( ) ;
929930 }
930931
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 ) {
933933 match item. node {
934934 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 ,
940937 }
941938
942939 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-
960940 let ( cnum, ..) = self . resolve_crate (
961941 & None , & info. ident , & info. name , None , item. span , PathKind :: Crate , info. dep_kind ,
962942 ) ;
@@ -968,7 +948,5 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
968948 ExternCrate { def_id : def_id, span : item. span , direct : true , path_len : len } ;
969949 self . update_extern_crate ( cnum, extern_crate, & mut FxHashSet ( ) ) ;
970950 self . cstore . add_extern_mod_stmt_cnum ( info. id , cnum) ;
971-
972- Vec :: new ( )
973951 }
974952}
0 commit comments