1
1
//! Validates all used crates and extern libraries and loads their metadata
2
2
3
- use crate :: locator:: { CrateLocator , CratePaths } ;
3
+ use crate :: dynamic_lib:: DynamicLibrary ;
4
+ use crate :: locator:: { CrateError , CrateLocator , CratePaths } ;
4
5
use crate :: rmeta:: { CrateDep , CrateMetadata , CrateNumMap , CrateRoot , MetadataBlob } ;
5
6
6
7
use rustc_ast:: expand:: allocator:: { global_allocator_spans, AllocatorKind } ;
7
8
use rustc_ast:: { ast, attr} ;
8
9
use rustc_data_structures:: fx:: FxHashSet ;
9
10
use rustc_data_structures:: svh:: Svh ;
10
11
use rustc_data_structures:: sync:: Lrc ;
11
- use rustc_errors:: struct_span_err;
12
12
use rustc_expand:: base:: SyntaxExtension ;
13
13
use rustc_hir:: def_id:: { CrateNum , LocalDefId , LOCAL_CRATE } ;
14
14
use rustc_hir:: definitions:: Definitions ;
15
15
use 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 } ;
20
18
use rustc_middle:: ty:: TyCtxt ;
21
19
use rustc_session:: config:: { self , CrateType , ExternLocation } ;
22
20
use rustc_session:: lint;
@@ -31,7 +29,7 @@ use rustc_target::spec::{PanicStrategy, TargetTriple};
31
29
use log:: { debug, info, log_enabled} ;
32
30
use proc_macro:: bridge:: client:: ProcMacro ;
33
31
use std:: path:: Path ;
34
- use std:: { cmp, fs} ;
32
+ use std:: { cmp, env , fs} ;
35
33
36
34
#[ derive( Clone ) ]
37
35
pub struct CStore {
@@ -69,18 +67,6 @@ enum LoadResult {
69
67
Loaded ( Library ) ,
70
68
}
71
69
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
-
84
70
/// A reference to `CrateMetadata` that can also give access to whole crate store when necessary.
85
71
#[ derive( Clone , Copy ) ]
86
72
crate struct CrateMetadataRef < ' a > {
@@ -280,60 +266,43 @@ impl<'a> CrateLoader<'a> {
280
266
ret
281
267
}
282
268
283
- fn verify_no_symbol_conflicts ( & self , span : Span , root : & CrateRoot < ' _ > ) {
269
+ fn verify_no_symbol_conflicts ( & self , root : & CrateRoot < ' _ > ) -> Result < ( ) , CrateError > {
284
270
// Check for (potential) conflicts with the local crate
285
271
if self . local_crate_name == root. name ( )
286
272
&& self . sess . local_crate_disambiguator ( ) == root. disambiguator ( )
287
273
{
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 ( ) ) ) ;
299
275
}
300
276
301
277
// Check for conflicts with any crate loaded so far
278
+ let mut res = Ok ( ( ) ) ;
302
279
self . cstore . iter_crate_data ( |_, other| {
303
280
if other. name ( ) == root. name ( ) && // same crate-name
304
- other. disambiguator ( ) == root. disambiguator ( ) && // same crate-disambiguator
281
+ other. disambiguator ( ) == root. disambiguator ( ) && // same crate-disambiguator
305
282
other. hash ( ) != root. hash ( )
306
283
{
307
284
// 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 ( ) ) ) ;
318
286
}
319
287
} ) ;
288
+
289
+ res
320
290
}
321
291
322
292
fn register_crate (
323
293
& mut self ,
324
294
host_lib : Option < Library > ,
325
295
root : Option < & CratePaths > ,
326
- span : Span ,
327
296
lib : Library ,
328
297
dep_kind : DepKind ,
329
298
name : Symbol ,
330
- ) -> CrateNum {
299
+ ) -> Result < CrateNum , CrateError > {
331
300
let _prof_timer = self . sess . prof . generic_activity ( "metadata_register_crate" ) ;
332
301
333
302
let Library { source, metadata } = lib;
334
303
let crate_root = metadata. get_root ( ) ;
335
304
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) ? ;
337
306
338
307
let private_dep =
339
308
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> {
353
322
& crate_paths
354
323
} ;
355
324
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) ? ;
357
326
358
327
let raw_proc_macros = if crate_root. is_proc_macro_crate ( ) {
359
328
let temp_root;
@@ -365,7 +334,7 @@ impl<'a> CrateLoader<'a> {
365
334
None => ( & source, & crate_root) ,
366
335
} ;
367
336
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 ( ) ) ? )
369
338
} else {
370
339
None
371
340
} ;
@@ -386,14 +355,14 @@ impl<'a> CrateLoader<'a> {
386
355
) ,
387
356
) ;
388
357
389
- cnum
358
+ Ok ( cnum)
390
359
}
391
360
392
361
fn load_proc_macro < ' b > (
393
362
& self ,
394
363
locator : & mut CrateLocator < ' b > ,
395
364
path_kind : PathKind ,
396
- ) -> Option < ( LoadResult , Option < Library > ) >
365
+ ) -> Result < Option < ( LoadResult , Option < Library > ) > , CrateError >
397
366
where
398
367
' a : ' b ,
399
368
{
@@ -408,8 +377,11 @@ impl<'a> CrateLoader<'a> {
408
377
let ( locator, target_result) = if self . sess . opts . debugging_opts . dual_proc_macros {
409
378
proc_macro_locator. reset ( ) ;
410
379
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 ) ,
413
385
} ;
414
386
locator. hash = locator. host_hash ;
415
387
// Use the locator when looking for the host proc macro crate, as that is required
@@ -427,9 +399,12 @@ impl<'a> CrateLoader<'a> {
427
399
locator. triple = TargetTriple :: from_triple ( config:: host_triple ( ) ) ;
428
400
locator. filesearch = self . sess . host_filesearch ( path_kind) ;
429
401
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
+ } ;
431
406
432
- Some ( if self . sess . opts . debugging_opts . dual_proc_macros {
407
+ Ok ( Some ( if self . sess . opts . debugging_opts . dual_proc_macros {
433
408
let host_result = match host_result {
434
409
LoadResult :: Previous ( ..) => {
435
410
panic ! ( "host and target proc macros must be loaded in lock-step" )
@@ -439,7 +414,7 @@ impl<'a> CrateLoader<'a> {
439
414
( target_result. unwrap ( ) , Some ( host_result) )
440
415
} else {
441
416
( host_result, None )
442
- } )
417
+ } ) )
443
418
}
444
419
445
420
fn resolve_crate < ' b > (
@@ -452,25 +427,20 @@ impl<'a> CrateLoader<'a> {
452
427
if dep. is_none ( ) {
453
428
self . used_extern_options . insert ( name) ;
454
429
}
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) )
464
432
}
465
433
466
434
fn maybe_resolve_crate < ' b > (
467
435
& ' b mut self ,
468
436
name : Symbol ,
469
- span : Span ,
470
437
mut dep_kind : DepKind ,
471
438
dep : Option < ( & ' b CratePaths , & ' b CrateDep ) > ,
472
- ) -> Result < CrateNum , LoadError < ' b > > {
439
+ ) -> Result < CrateNum , CrateError > {
473
440
info ! ( "resolving crate `{}`" , name) ;
441
+ if !name. as_str ( ) . is_ascii ( ) {
442
+ return Err ( CrateError :: NonAsciiName ( name) ) ;
443
+ }
474
444
let ( root, hash, host_hash, extra_filename, path_kind) = match dep {
475
445
Some ( ( root, dep) ) => (
476
446
Some ( root) ,
@@ -494,18 +464,20 @@ impl<'a> CrateLoader<'a> {
494
464
extra_filename,
495
465
false , // is_host
496
466
path_kind,
497
- span,
498
467
root,
499
468
Some ( false ) , // is_proc_macro
500
469
) ;
501
470
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 => {
505
474
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
+ }
509
481
} ;
510
482
511
483
match result {
@@ -518,14 +490,17 @@ impl<'a> CrateLoader<'a> {
518
490
Ok ( cnum)
519
491
}
520
492
( 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)
522
494
}
523
495
_ => panic ! ( ) ,
524
496
}
525
497
}
526
498
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
+ } ;
529
504
530
505
// In the case that we're loading a crate, but not matching
531
506
// against a hash, we could load a crate which has the same hash
@@ -536,7 +511,7 @@ impl<'a> CrateLoader<'a> {
536
511
// don't want to match a host crate against an equivalent target one
537
512
// already loaded.
538
513
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 {
540
515
let mut result = LoadResult :: Loaded ( library) ;
541
516
self . cstore . iter_crate_data ( |cnum, data| {
542
517
if data. name ( ) == root. name ( ) && root. hash ( ) == data. hash ( ) {
@@ -545,10 +520,10 @@ impl<'a> CrateLoader<'a> {
545
520
result = LoadResult :: Previous ( cnum) ;
546
521
}
547
522
} ) ;
548
- Some ( result)
523
+ result
549
524
} else {
550
- Some ( LoadResult :: Loaded ( library) )
551
- }
525
+ LoadResult :: Loaded ( library)
526
+ } ) )
552
527
}
553
528
554
529
fn update_extern_crate ( & self , cnum : CrateNum , extern_crate : ExternCrate ) {
@@ -569,53 +544,51 @@ impl<'a> CrateLoader<'a> {
569
544
crate_root : & CrateRoot < ' _ > ,
570
545
metadata : & MetadataBlob ,
571
546
krate : CrateNum ,
572
- span : Span ,
573
547
dep_kind : DepKind ,
574
- ) -> CrateNumMap {
548
+ ) -> Result < CrateNumMap , CrateError > {
575
549
debug ! ( "resolving deps of external crate" ) ;
576
550
if crate_root. is_proc_macro_crate ( ) {
577
- return CrateNumMap :: new ( ) ;
551
+ return Ok ( CrateNumMap :: new ( ) ) ;
578
552
}
579
553
580
554
// The map from crate numbers in the crate we're resolving to local crate numbers.
581
555
// We map 0 and all other holes in the map to our parent crate. The "additional"
582
556
// 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)
596
573
}
597
574
598
575
fn dlsym_proc_macros (
599
576
& self ,
600
577
path : & Path ,
601
578
disambiguator : CrateDisambiguator ,
602
- span : Span ,
603
- ) -> & ' static [ ProcMacro ] {
604
- use crate :: dynamic_lib:: DynamicLibrary ;
605
- use std:: env;
606
-
579
+ ) -> Result < & ' static [ ProcMacro ] , CrateError > {
607
580
// Make sure the path contains a / or the linker will search for it.
608
581
let path = env:: current_dir ( ) . unwrap ( ) . join ( path) ;
609
582
let lib = match DynamicLibrary :: open ( & path) {
610
583
Ok ( lib) => lib,
611
- Err ( err ) => self . sess . span_fatal ( span , & err ) ,
584
+ Err ( s ) => return Err ( CrateError :: DlOpen ( s ) ) ,
612
585
} ;
613
586
614
587
let sym = self . sess . generate_proc_macro_decls_symbol ( disambiguator) ;
615
588
let decls = unsafe {
616
589
let sym = match lib. symbol ( & sym) {
617
590
Ok ( f) => f,
618
- Err ( err ) => self . sess . span_fatal ( span , & err ) ,
591
+ Err ( s ) => return Err ( CrateError :: DlSym ( s ) ) ,
619
592
} ;
620
593
* ( sym as * const & [ ProcMacro ] )
621
594
} ;
@@ -624,7 +597,7 @@ impl<'a> CrateLoader<'a> {
624
597
// since the library can make things that will live arbitrarily long.
625
598
std:: mem:: forget ( lib) ;
626
599
627
- decls
600
+ Ok ( decls)
628
601
}
629
602
630
603
fn inject_panic_runtime ( & mut self , krate : & ast:: Crate ) {
@@ -952,7 +925,7 @@ impl<'a> CrateLoader<'a> {
952
925
cnum
953
926
}
954
927
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 ( )
957
930
}
958
931
}
0 commit comments