@@ -188,13 +188,15 @@ impl<'a> CrateLoader<'a> {
188188 } ) ;
189189 }
190190
191- fn register_crate ( & mut self ,
192- root : & Option < CratePaths > ,
193- ident : Symbol ,
194- span : Span ,
195- lib : Library ,
196- dep_kind : DepKind )
197- -> ( CrateNum , Lrc < cstore:: CrateMetadata > ) {
191+ fn register_crate (
192+ & mut self ,
193+ host_lib : Option < Library > ,
194+ root : & Option < CratePaths > ,
195+ ident : Symbol ,
196+ span : Span ,
197+ lib : Library ,
198+ dep_kind : DepKind
199+ ) -> ( CrateNum , Lrc < cstore:: CrateMetadata > ) {
198200 let crate_root = lib. metadata . get_root ( ) ;
199201 info ! ( "register crate `extern crate {} as {}`" , crate_root. name, ident) ;
200202 self . verify_no_symbol_conflicts ( span, & crate_root) ;
@@ -222,7 +224,16 @@ impl<'a> CrateLoader<'a> {
222224 let dependencies: Vec < CrateNum > = cnum_map. iter ( ) . cloned ( ) . collect ( ) ;
223225
224226 let proc_macros = crate_root. proc_macro_decls_static . map ( |_| {
225- self . load_derive_macros ( & crate_root, dylib. clone ( ) . map ( |p| p. 0 ) , span)
227+ if self . sess . opts . debugging_opts . dual_proc_macros {
228+ let host_lib = host_lib. unwrap ( ) ;
229+ self . load_derive_macros (
230+ & host_lib. metadata . get_root ( ) ,
231+ host_lib. dylib . clone ( ) . map ( |p| p. 0 ) ,
232+ span
233+ )
234+ } else {
235+ self . load_derive_macros ( & crate_root, dylib. clone ( ) . map ( |p| p. 0 ) , span)
236+ }
226237 } ) ;
227238
228239 let def_path_table = record_time ( & self . sess . perf_stats . decode_def_path_tables_time , || {
@@ -269,6 +280,61 @@ impl<'a> CrateLoader<'a> {
269280 ( cnum, cmeta)
270281 }
271282
283+ fn load_proc_macro < ' b > (
284+ & mut self ,
285+ locate_ctxt : & mut locator:: Context < ' b > ,
286+ path_kind : PathKind ,
287+ ) -> Option < ( LoadResult , Option < Library > ) >
288+ where
289+ ' a : ' b
290+ {
291+ // Use a new locator Context so trying to load a proc macro doesn't affect the error
292+ // message we emit
293+ let mut proc_macro_locator = locate_ctxt. clone ( ) ;
294+
295+ // Try to load a proc macro
296+ proc_macro_locator. is_proc_macro = Some ( true ) ;
297+
298+ // Load the proc macro crate for the target
299+ let ( locator, target_result) = if self . sess . opts . debugging_opts . dual_proc_macros {
300+ proc_macro_locator. reset ( ) ;
301+ let result = match self . load ( & mut proc_macro_locator) ? {
302+ LoadResult :: Previous ( cnum) => return Some ( ( LoadResult :: Previous ( cnum) , None ) ) ,
303+ LoadResult :: Loaded ( library) => Some ( LoadResult :: Loaded ( library) )
304+ } ;
305+ // Don't look for a matching hash when looking for the host crate.
306+ // It won't be the same as the target crate hash
307+ locate_ctxt. hash = None ;
308+ // Use the locate_ctxt when looking for the host proc macro crate, as that is required
309+ // so we want it to affect the error message
310+ ( locate_ctxt, result)
311+ } else {
312+ ( & mut proc_macro_locator, None )
313+ } ;
314+
315+ // Load the proc macro crate for the host
316+
317+ locator. reset ( ) ;
318+ locator. is_proc_macro = Some ( true ) ;
319+ locator. target = & self . sess . host ;
320+ locator. triple = TargetTriple :: from_triple ( config:: host_triple ( ) ) ;
321+ locator. filesearch = self . sess . host_filesearch ( path_kind) ;
322+
323+ let host_result = self . load ( locator) ?;
324+
325+ Some ( if self . sess . opts . debugging_opts . dual_proc_macros {
326+ let host_result = match host_result {
327+ LoadResult :: Previous ( ..) => {
328+ panic ! ( "host and target proc macros must be loaded in lock-step" )
329+ }
330+ LoadResult :: Loaded ( library) => library
331+ } ;
332+ ( target_result. unwrap ( ) , Some ( host_result) )
333+ } else {
334+ ( host_result, None )
335+ } )
336+ }
337+
272338 fn resolve_crate < ' b > (
273339 & ' b mut self ,
274340 root : & ' b Option < CratePaths > ,
@@ -281,53 +347,39 @@ impl<'a> CrateLoader<'a> {
281347 mut dep_kind : DepKind ,
282348 ) -> Result < ( CrateNum , Lrc < cstore:: CrateMetadata > ) , LoadError < ' b > > {
283349 info ! ( "resolving crate `extern crate {} as {}`" , name, ident) ;
350+ let mut locate_ctxt = locator:: Context {
351+ sess : self . sess ,
352+ span,
353+ ident,
354+ crate_name : name,
355+ hash : hash. map ( |a| & * a) ,
356+ extra_filename : extra_filename,
357+ filesearch : self . sess . target_filesearch ( path_kind) ,
358+ target : & self . sess . target . target ,
359+ triple : self . sess . opts . target_triple . clone ( ) ,
360+ root,
361+ rejected_via_hash : vec ! [ ] ,
362+ rejected_via_triple : vec ! [ ] ,
363+ rejected_via_kind : vec ! [ ] ,
364+ rejected_via_version : vec ! [ ] ,
365+ rejected_via_filename : vec ! [ ] ,
366+ should_match_name : true ,
367+ is_proc_macro : Some ( false ) ,
368+ metadata_loader : & * self . cstore . metadata_loader ,
369+ } ;
370+
284371 let result = if let Some ( cnum) = self . existing_match ( name, hash, path_kind) {
285- LoadResult :: Previous ( cnum)
372+ ( LoadResult :: Previous ( cnum) , None )
286373 } else {
287374 info ! ( "falling back to a load" ) ;
288- let mut locate_ctxt = locator:: Context {
289- sess : self . sess ,
290- span,
291- ident,
292- crate_name : name,
293- hash : hash. map ( |a| & * a) ,
294- extra_filename : extra_filename,
295- filesearch : self . sess . target_filesearch ( path_kind) ,
296- target : & self . sess . target . target ,
297- triple : & self . sess . opts . target_triple ,
298- root,
299- rejected_via_hash : vec ! [ ] ,
300- rejected_via_triple : vec ! [ ] ,
301- rejected_via_kind : vec ! [ ] ,
302- rejected_via_version : vec ! [ ] ,
303- rejected_via_filename : vec ! [ ] ,
304- should_match_name : true ,
305- is_proc_macro : Some ( false ) ,
306- metadata_loader : & * self . cstore . metadata_loader ,
307- } ;
308-
309- self . load ( & mut locate_ctxt) . or_else ( || {
375+ self . load ( & mut locate_ctxt) . map ( |r| ( r, None ) ) . or_else ( || {
310376 dep_kind = DepKind :: UnexportedMacrosOnly ;
311-
312- let mut proc_macro_locator = locator:: Context {
313- target : & self . sess . host ,
314- triple : & TargetTriple :: from_triple ( config:: host_triple ( ) ) ,
315- filesearch : self . sess . host_filesearch ( path_kind) ,
316- rejected_via_hash : vec ! [ ] ,
317- rejected_via_triple : vec ! [ ] ,
318- rejected_via_kind : vec ! [ ] ,
319- rejected_via_version : vec ! [ ] ,
320- rejected_via_filename : vec ! [ ] ,
321- is_proc_macro : Some ( true ) ,
322- ..locate_ctxt
323- } ;
324-
325- self . load ( & mut proc_macro_locator)
377+ self . load_proc_macro ( & mut locate_ctxt, path_kind)
326378 } ) . ok_or_else ( move || LoadError :: LocatorError ( locate_ctxt) ) ?
327379 } ;
328380
329381 match result {
330- LoadResult :: Previous ( cnum) => {
382+ ( LoadResult :: Previous ( cnum) , None ) => {
331383 let data = self . cstore . get_crate_data ( cnum) ;
332384 if data. root . proc_macro_decls_static . is_some ( ) {
333385 dep_kind = DepKind :: UnexportedMacrosOnly ;
@@ -337,9 +389,10 @@ impl<'a> CrateLoader<'a> {
337389 } ) ;
338390 Ok ( ( cnum, data) )
339391 }
340- LoadResult :: Loaded ( library) => {
341- Ok ( self . register_crate ( root, ident, span, library, dep_kind) )
392+ ( LoadResult :: Loaded ( library) , host_library ) => {
393+ Ok ( self . register_crate ( host_library , root, ident, span, library, dep_kind) )
342394 }
395+ _ => panic ! ( )
343396 }
344397 }
345398
@@ -355,7 +408,7 @@ impl<'a> CrateLoader<'a> {
355408 // don't want to match a host crate against an equivalent target one
356409 // already loaded.
357410 let root = library. metadata . get_root ( ) ;
358- if locate_ctxt. triple == & self . sess . opts . target_triple {
411+ if locate_ctxt. triple == self . sess . opts . target_triple {
359412 let mut result = LoadResult :: Loaded ( library) ;
360413 self . cstore . iter_crate_data ( |cnum, data| {
361414 if data. root . name == root. name && root. hash == data. root . hash {
@@ -451,9 +504,9 @@ impl<'a> CrateLoader<'a> {
451504 fn read_extension_crate ( & mut self , span : Span , orig_name : Symbol , rename : Symbol )
452505 -> ExtensionCrate {
453506 info ! ( "read extension crate `extern crate {} as {}`" , orig_name, rename) ;
454- let target_triple = & self . sess . opts . target_triple ;
507+ let target_triple = self . sess . opts . target_triple . clone ( ) ;
455508 let host_triple = TargetTriple :: from_triple ( config:: host_triple ( ) ) ;
456- let is_cross = target_triple != & host_triple;
509+ let is_cross = target_triple != host_triple;
457510 let mut target_only = false ;
458511 let mut locate_ctxt = locator:: Context {
459512 sess : self . sess ,
@@ -464,7 +517,7 @@ impl<'a> CrateLoader<'a> {
464517 extra_filename : None ,
465518 filesearch : self . sess . host_filesearch ( PathKind :: Crate ) ,
466519 target : & self . sess . host ,
467- triple : & host_triple,
520+ triple : host_triple,
468521 root : & None ,
469522 rejected_via_hash : vec ! [ ] ,
470523 rejected_via_triple : vec ! [ ] ,
0 commit comments