11//! Validates all used crates and extern libraries and loads their metadata
22
3- use crate :: locator:: { CrateLocator , CratePaths } ;
3+ use crate :: dynamic_lib:: DynamicLibrary ;
4+ use crate :: locator:: { CrateError , CrateLocator , CratePaths } ;
45use crate :: rmeta:: { CrateDep , CrateMetadata , CrateNumMap , CrateRoot , MetadataBlob } ;
56
67use rustc_ast:: expand:: allocator:: { global_allocator_spans, AllocatorKind } ;
78use rustc_ast:: { ast, attr} ;
89use rustc_data_structures:: fx:: FxHashSet ;
910use rustc_data_structures:: svh:: Svh ;
1011use rustc_data_structures:: sync:: Lrc ;
11- use rustc_errors:: struct_span_err;
1212use rustc_expand:: base:: SyntaxExtension ;
1313use rustc_hir:: def_id:: { CrateNum , LocalDefId , LOCAL_CRATE } ;
1414use rustc_hir:: definitions:: Definitions ;
1515use rustc_index:: vec:: IndexVec ;
16- use rustc_middle:: middle:: cstore:: DepKind ;
17- use rustc_middle:: middle:: cstore:: {
18- CrateSource , ExternCrate , ExternCrateSource , MetadataLoaderDyn ,
19- } ;
16+ use rustc_middle:: middle:: cstore:: { CrateSource , DepKind , ExternCrate } ;
17+ use rustc_middle:: middle:: cstore:: { ExternCrateSource , MetadataLoaderDyn } ;
2018use rustc_middle:: ty:: TyCtxt ;
2119use rustc_session:: config:: { self , CrateType , ExternLocation } ;
2220use rustc_session:: lint;
@@ -31,7 +29,7 @@ use rustc_target::spec::{PanicStrategy, TargetTriple};
3129use log:: { debug, info, log_enabled} ;
3230use proc_macro:: bridge:: client:: ProcMacro ;
3331use std:: path:: Path ;
34- use std:: { cmp, fs} ;
32+ use std:: { cmp, env , fs} ;
3533
3634#[ derive( Clone ) ]
3735pub struct CStore {
@@ -69,18 +67,6 @@ enum LoadResult {
6967 Loaded ( Library ) ,
7068}
7169
72- enum LoadError < ' a > {
73- LocatorError ( CrateLocator < ' a > ) ,
74- }
75-
76- impl < ' a > LoadError < ' a > {
77- fn report ( self ) -> ! {
78- match self {
79- LoadError :: LocatorError ( locator) => locator. report_errs ( ) ,
80- }
81- }
82- }
83-
8470/// A reference to `CrateMetadata` that can also give access to whole crate store when necessary.
8571#[ derive( Clone , Copy ) ]
8672crate struct CrateMetadataRef < ' a > {
@@ -280,60 +266,43 @@ impl<'a> CrateLoader<'a> {
280266 ret
281267 }
282268
283- fn verify_no_symbol_conflicts ( & self , span : Span , root : & CrateRoot < ' _ > ) {
269+ fn verify_no_symbol_conflicts ( & self , root : & CrateRoot < ' _ > ) -> Result < ( ) , CrateError > {
284270 // Check for (potential) conflicts with the local crate
285271 if self . local_crate_name == root. name ( )
286272 && self . sess . local_crate_disambiguator ( ) == root. disambiguator ( )
287273 {
288- struct_span_err ! (
289- self . sess,
290- span,
291- E0519 ,
292- "the current crate is indistinguishable from one of its \
293- dependencies: it has the same crate-name `{}` and was \
294- compiled with the same `-C metadata` arguments. This \
295- will result in symbol conflicts between the two.",
296- root. name( )
297- )
298- . emit ( )
274+ return Err ( CrateError :: SymbolConflictsCurrent ( root. name ( ) ) ) ;
299275 }
300276
301277 // Check for conflicts with any crate loaded so far
278+ let mut res = Ok ( ( ) ) ;
302279 self . cstore . iter_crate_data ( |_, other| {
303280 if other. name ( ) == root. name ( ) && // same crate-name
304- other. disambiguator ( ) == root. disambiguator ( ) && // same crate-disambiguator
281+ other. disambiguator ( ) == root. disambiguator ( ) && // same crate-disambiguator
305282 other. hash ( ) != root. hash ( )
306283 {
307284 // but different SVH
308- struct_span_err ! (
309- self . sess,
310- span,
311- E0523 ,
312- "found two different crates with name `{}` that are \
313- not distinguished by differing `-C metadata`. This \
314- will result in symbol conflicts between the two.",
315- root. name( )
316- )
317- . emit ( ) ;
285+ res = Err ( CrateError :: SymbolConflictsOthers ( root. name ( ) ) ) ;
318286 }
319287 } ) ;
288+
289+ res
320290 }
321291
322292 fn register_crate (
323293 & mut self ,
324294 host_lib : Option < Library > ,
325295 root : Option < & CratePaths > ,
326- span : Span ,
327296 lib : Library ,
328297 dep_kind : DepKind ,
329298 name : Symbol ,
330- ) -> CrateNum {
299+ ) -> Result < CrateNum , CrateError > {
331300 let _prof_timer = self . sess . prof . generic_activity ( "metadata_register_crate" ) ;
332301
333302 let Library { source, metadata } = lib;
334303 let crate_root = metadata. get_root ( ) ;
335304 let host_hash = host_lib. as_ref ( ) . map ( |lib| lib. metadata . get_root ( ) . hash ( ) ) ;
336- self . verify_no_symbol_conflicts ( span , & crate_root) ;
305+ self . verify_no_symbol_conflicts ( & crate_root) ? ;
337306
338307 let private_dep =
339308 self . sess . opts . externs . get ( & name. as_str ( ) ) . map ( |e| e. is_private_dep ) . unwrap_or ( false ) ;
@@ -353,7 +322,7 @@ impl<'a> CrateLoader<'a> {
353322 & crate_paths
354323 } ;
355324
356- let cnum_map = self . resolve_crate_deps ( root, & crate_root, & metadata, cnum, span , dep_kind) ;
325+ let cnum_map = self . resolve_crate_deps ( root, & crate_root, & metadata, cnum, dep_kind) ? ;
357326
358327 let raw_proc_macros = if crate_root. is_proc_macro_crate ( ) {
359328 let temp_root;
@@ -365,7 +334,7 @@ impl<'a> CrateLoader<'a> {
365334 None => ( & source, & crate_root) ,
366335 } ;
367336 let dlsym_dylib = dlsym_source. dylib . as_ref ( ) . expect ( "no dylib for a proc-macro crate" ) ;
368- Some ( self . dlsym_proc_macros ( & dlsym_dylib. 0 , dlsym_root. disambiguator ( ) , span ) )
337+ Some ( self . dlsym_proc_macros ( & dlsym_dylib. 0 , dlsym_root. disambiguator ( ) ) ? )
369338 } else {
370339 None
371340 } ;
@@ -386,14 +355,14 @@ impl<'a> CrateLoader<'a> {
386355 ) ,
387356 ) ;
388357
389- cnum
358+ Ok ( cnum)
390359 }
391360
392361 fn load_proc_macro < ' b > (
393362 & self ,
394363 locator : & mut CrateLocator < ' b > ,
395364 path_kind : PathKind ,
396- ) -> Option < ( LoadResult , Option < Library > ) >
365+ ) -> Result < Option < ( LoadResult , Option < Library > ) > , CrateError >
397366 where
398367 ' a : ' b ,
399368 {
@@ -408,8 +377,11 @@ impl<'a> CrateLoader<'a> {
408377 let ( locator, target_result) = if self . sess . opts . debugging_opts . dual_proc_macros {
409378 proc_macro_locator. reset ( ) ;
410379 let result = match self . load ( & mut proc_macro_locator) ? {
411- LoadResult :: Previous ( cnum) => return Some ( ( LoadResult :: Previous ( cnum) , None ) ) ,
412- LoadResult :: Loaded ( library) => Some ( LoadResult :: Loaded ( library) ) ,
380+ Some ( LoadResult :: Previous ( cnum) ) => {
381+ return Ok ( Some ( ( LoadResult :: Previous ( cnum) , None ) ) ) ;
382+ }
383+ Some ( LoadResult :: Loaded ( library) ) => Some ( LoadResult :: Loaded ( library) ) ,
384+ None => return Ok ( None ) ,
413385 } ;
414386 locator. hash = locator. host_hash ;
415387 // Use the locator when looking for the host proc macro crate, as that is required
@@ -427,9 +399,12 @@ impl<'a> CrateLoader<'a> {
427399 locator. triple = TargetTriple :: from_triple ( config:: host_triple ( ) ) ;
428400 locator. filesearch = self . sess . host_filesearch ( path_kind) ;
429401
430- let host_result = self . load ( locator) ?;
402+ let host_result = match self . load ( locator) ? {
403+ Some ( host_result) => host_result,
404+ None => return Ok ( None ) ,
405+ } ;
431406
432- Some ( if self . sess . opts . debugging_opts . dual_proc_macros {
407+ Ok ( Some ( if self . sess . opts . debugging_opts . dual_proc_macros {
433408 let host_result = match host_result {
434409 LoadResult :: Previous ( ..) => {
435410 panic ! ( "host and target proc macros must be loaded in lock-step" )
@@ -439,7 +414,7 @@ impl<'a> CrateLoader<'a> {
439414 ( target_result. unwrap ( ) , Some ( host_result) )
440415 } else {
441416 ( host_result, None )
442- } )
417+ } ) )
443418 }
444419
445420 fn resolve_crate < ' b > (
@@ -452,25 +427,20 @@ impl<'a> CrateLoader<'a> {
452427 if dep. is_none ( ) {
453428 self . used_extern_options . insert ( name) ;
454429 }
455- if !name. as_str ( ) . is_ascii ( ) {
456- self . sess
457- . struct_span_err (
458- span,
459- & format ! ( "cannot load a crate with a non-ascii name `{}`" , name, ) ,
460- )
461- . emit ( ) ;
462- }
463- self . maybe_resolve_crate ( name, span, dep_kind, dep) . unwrap_or_else ( |err| err. report ( ) )
430+ self . maybe_resolve_crate ( name, dep_kind, dep)
431+ . unwrap_or_else ( |err| err. report ( self . sess , span) )
464432 }
465433
466434 fn maybe_resolve_crate < ' b > (
467435 & ' b mut self ,
468436 name : Symbol ,
469- span : Span ,
470437 mut dep_kind : DepKind ,
471438 dep : Option < ( & ' b CratePaths , & ' b CrateDep ) > ,
472- ) -> Result < CrateNum , LoadError < ' b > > {
439+ ) -> Result < CrateNum , CrateError > {
473440 info ! ( "resolving crate `{}`" , name) ;
441+ if !name. as_str ( ) . is_ascii ( ) {
442+ return Err ( CrateError :: NonAsciiName ( name) ) ;
443+ }
474444 let ( root, hash, host_hash, extra_filename, path_kind) = match dep {
475445 Some ( ( root, dep) ) => (
476446 Some ( root) ,
@@ -494,18 +464,20 @@ impl<'a> CrateLoader<'a> {
494464 extra_filename,
495465 false , // is_host
496466 path_kind,
497- span,
498467 root,
499468 Some ( false ) , // is_proc_macro
500469 ) ;
501470
502- self . load ( & mut locator)
503- . map ( |r| ( r , None ) )
504- . or_else ( || {
471+ match self . load ( & mut locator) ? {
472+ Some ( res ) => ( res , None ) ,
473+ None => {
505474 dep_kind = DepKind :: MacrosOnly ;
506- self . load_proc_macro ( & mut locator, path_kind)
507- } )
508- . ok_or_else ( move || LoadError :: LocatorError ( locator) ) ?
475+ match self . load_proc_macro ( & mut locator, path_kind) ? {
476+ Some ( res) => res,
477+ None => return Err ( locator. into_error ( ) ) ,
478+ }
479+ }
480+ }
509481 } ;
510482
511483 match result {
@@ -518,14 +490,17 @@ impl<'a> CrateLoader<'a> {
518490 Ok ( cnum)
519491 }
520492 ( LoadResult :: Loaded ( library) , host_library) => {
521- Ok ( self . register_crate ( host_library, root, span , library, dep_kind, name) )
493+ self . register_crate ( host_library, root, library, dep_kind, name)
522494 }
523495 _ => panic ! ( ) ,
524496 }
525497 }
526498
527- fn load ( & self , locator : & mut CrateLocator < ' _ > ) -> Option < LoadResult > {
528- let library = locator. maybe_load_library_crate ( ) ?;
499+ fn load ( & self , locator : & mut CrateLocator < ' _ > ) -> Result < Option < LoadResult > , CrateError > {
500+ let library = match locator. maybe_load_library_crate ( ) ? {
501+ Some ( library) => library,
502+ None => return Ok ( None ) ,
503+ } ;
529504
530505 // In the case that we're loading a crate, but not matching
531506 // against a hash, we could load a crate which has the same hash
@@ -536,7 +511,7 @@ impl<'a> CrateLoader<'a> {
536511 // don't want to match a host crate against an equivalent target one
537512 // already loaded.
538513 let root = library. metadata . get_root ( ) ;
539- if locator. triple == self . sess . opts . target_triple {
514+ Ok ( Some ( if locator. triple == self . sess . opts . target_triple {
540515 let mut result = LoadResult :: Loaded ( library) ;
541516 self . cstore . iter_crate_data ( |cnum, data| {
542517 if data. name ( ) == root. name ( ) && root. hash ( ) == data. hash ( ) {
@@ -545,10 +520,10 @@ impl<'a> CrateLoader<'a> {
545520 result = LoadResult :: Previous ( cnum) ;
546521 }
547522 } ) ;
548- Some ( result)
523+ result
549524 } else {
550- Some ( LoadResult :: Loaded ( library) )
551- }
525+ LoadResult :: Loaded ( library)
526+ } ) )
552527 }
553528
554529 fn update_extern_crate ( & self , cnum : CrateNum , extern_crate : ExternCrate ) {
@@ -569,53 +544,51 @@ impl<'a> CrateLoader<'a> {
569544 crate_root : & CrateRoot < ' _ > ,
570545 metadata : & MetadataBlob ,
571546 krate : CrateNum ,
572- span : Span ,
573547 dep_kind : DepKind ,
574- ) -> CrateNumMap {
548+ ) -> Result < CrateNumMap , CrateError > {
575549 debug ! ( "resolving deps of external crate" ) ;
576550 if crate_root. is_proc_macro_crate ( ) {
577- return CrateNumMap :: new ( ) ;
551+ return Ok ( CrateNumMap :: new ( ) ) ;
578552 }
579553
580554 // The map from crate numbers in the crate we're resolving to local crate numbers.
581555 // We map 0 and all other holes in the map to our parent crate. The "additional"
582556 // self-dependencies should be harmless.
583- std:: iter:: once ( krate)
584- . chain ( crate_root. decode_crate_deps ( metadata) . map ( |dep| {
585- info ! (
586- "resolving dep crate {} hash: `{}` extra filename: `{}`" ,
587- dep. name, dep. hash, dep. extra_filename
588- ) ;
589- let dep_kind = match dep_kind {
590- DepKind :: MacrosOnly => DepKind :: MacrosOnly ,
591- _ => dep. kind ,
592- } ;
593- self . resolve_crate ( dep. name , span, dep_kind, Some ( ( root, & dep) ) )
594- } ) )
595- . collect ( )
557+ let deps = crate_root. decode_crate_deps ( metadata) ;
558+ let mut crate_num_map = CrateNumMap :: with_capacity ( 1 + deps. len ( ) ) ;
559+ crate_num_map. push ( krate) ;
560+ for dep in deps {
561+ info ! (
562+ "resolving dep crate {} hash: `{}` extra filename: `{}`" ,
563+ dep. name, dep. hash, dep. extra_filename
564+ ) ;
565+ let dep_kind = match dep_kind {
566+ DepKind :: MacrosOnly => DepKind :: MacrosOnly ,
567+ _ => dep. kind ,
568+ } ;
569+ let cnum = self . maybe_resolve_crate ( dep. name , dep_kind, Some ( ( root, & dep) ) ) ?;
570+ crate_num_map. push ( cnum) ;
571+ }
572+ Ok ( crate_num_map)
596573 }
597574
598575 fn dlsym_proc_macros (
599576 & self ,
600577 path : & Path ,
601578 disambiguator : CrateDisambiguator ,
602- span : Span ,
603- ) -> & ' static [ ProcMacro ] {
604- use crate :: dynamic_lib:: DynamicLibrary ;
605- use std:: env;
606-
579+ ) -> Result < & ' static [ ProcMacro ] , CrateError > {
607580 // Make sure the path contains a / or the linker will search for it.
608581 let path = env:: current_dir ( ) . unwrap ( ) . join ( path) ;
609582 let lib = match DynamicLibrary :: open ( & path) {
610583 Ok ( lib) => lib,
611- Err ( err ) => self . sess . span_fatal ( span , & err ) ,
584+ Err ( s ) => return Err ( CrateError :: DlOpen ( s ) ) ,
612585 } ;
613586
614587 let sym = self . sess . generate_proc_macro_decls_symbol ( disambiguator) ;
615588 let decls = unsafe {
616589 let sym = match lib. symbol ( & sym) {
617590 Ok ( f) => f,
618- Err ( err ) => self . sess . span_fatal ( span , & err ) ,
591+ Err ( s ) => return Err ( CrateError :: DlSym ( s ) ) ,
619592 } ;
620593 * ( sym as * const & [ ProcMacro ] )
621594 } ;
@@ -624,7 +597,7 @@ impl<'a> CrateLoader<'a> {
624597 // since the library can make things that will live arbitrarily long.
625598 std:: mem:: forget ( lib) ;
626599
627- decls
600+ Ok ( decls)
628601 }
629602
630603 fn inject_panic_runtime ( & mut self , krate : & ast:: Crate ) {
@@ -952,7 +925,7 @@ impl<'a> CrateLoader<'a> {
952925 cnum
953926 }
954927
955- pub fn maybe_process_path_extern ( & mut self , name : Symbol , span : Span ) -> Option < CrateNum > {
956- self . maybe_resolve_crate ( name, span , DepKind :: Explicit , None ) . ok ( )
928+ pub fn maybe_process_path_extern ( & mut self , name : Symbol ) -> Option < CrateNum > {
929+ self . maybe_resolve_crate ( name, DepKind :: Explicit , None ) . ok ( )
957930 }
958931}
0 commit comments