@@ -24,7 +24,7 @@ use rustc_middle::bug;
24
24
use rustc_middle:: ty:: { TyCtxt , TyCtxtFeed } ;
25
25
use rustc_session:: config:: { self , CrateType , ExternLocation } ;
26
26
use rustc_session:: cstore:: { CrateDepKind , CrateSource , ExternCrate , ExternCrateSource } ;
27
- use rustc_session:: lint:: { self , BuiltinLintDiag } ;
27
+ use rustc_session:: lint:: { self , BuiltinLintDiag , LintBuffer } ;
28
28
use rustc_session:: output:: validate_crate_name;
29
29
use rustc_session:: search_paths:: PathKind ;
30
30
use rustc_span:: edition:: Edition ;
@@ -35,7 +35,9 @@ use tracing::{debug, info, trace};
35
35
36
36
use crate :: errors;
37
37
use crate :: locator:: { CrateError , CrateLocator , CratePaths } ;
38
- use crate :: rmeta:: { CrateDep , CrateMetadata , CrateNumMap , CrateRoot , MetadataBlob } ;
38
+ use crate :: rmeta:: {
39
+ CrateDep , CrateMetadata , CrateNumMap , CrateRoot , MetadataBlob , TargetModifiers ,
40
+ } ;
39
41
40
42
/// The backend's way to give the crate store access to the metadata in a library.
41
43
/// Note that it returns the raw metadata bytes stored in the library file, whether
@@ -290,6 +292,79 @@ impl CStore {
290
292
}
291
293
}
292
294
295
+ pub fn report_incompatible_target_modifiers (
296
+ & self ,
297
+ tcx : TyCtxt < ' _ > ,
298
+ krate : & Crate ,
299
+ lints : & mut LintBuffer ,
300
+ ) {
301
+ if tcx. crate_types ( ) . contains ( & CrateType :: ProcMacro ) {
302
+ return ;
303
+ }
304
+ let sess = tcx. sess ;
305
+ let span = krate. spans . inner_span . shrink_to_lo ( ) ;
306
+
307
+ let splitter = |v : & String | {
308
+ let splitted: Vec < _ > = v. split ( "=" ) . collect ( ) ;
309
+ ( splitted[ 0 ] . to_string ( ) , splitted[ 1 ] . to_string ( ) )
310
+ } ;
311
+ let name = tcx. crate_name ( LOCAL_CRATE ) ;
312
+ let mods = sess. opts . gather_target_modifiers ( ) ;
313
+ for ( _cnum, data) in self . iter_crate_data ( ) {
314
+ if data. is_proc_macro_crate ( ) {
315
+ continue ;
316
+ }
317
+ let mut report_diff = |tmod : String | {
318
+ lints. buffer_lint (
319
+ lint:: builtin:: INCOMPATIBLE_TARGET_MODIFIERS ,
320
+ ast:: CRATE_NODE_ID ,
321
+ span,
322
+ BuiltinLintDiag :: IncompatibleTargetModifiers {
323
+ extern_crate : data. name ( ) ,
324
+ local_crate : name,
325
+ tmod,
326
+ } ,
327
+ ) ;
328
+ } ;
329
+ let mut it1 = mods. iter ( ) . map ( splitter) ;
330
+ let mut it2 = data. target_modifiers ( ) . map ( splitter) ;
331
+ let mut left_name_val: Option < ( String , String ) > = None ;
332
+ let mut right_name_val: Option < ( String , String ) > = None ;
333
+ loop {
334
+ left_name_val = left_name_val. or_else ( || it1. next ( ) ) ;
335
+ right_name_val = right_name_val. or_else ( || it2. next ( ) ) ;
336
+ match ( & left_name_val, & right_name_val) {
337
+ ( Some ( l) , Some ( r) ) => match l. 0 . cmp ( & r. 0 ) {
338
+ cmp:: Ordering :: Equal => {
339
+ if l. 1 != r. 1 {
340
+ report_diff ( format ! ( "{} = ( {} | {} )" , l. 0 , l. 1 , r. 1 ) ) ;
341
+ }
342
+ left_name_val = None ;
343
+ right_name_val = None ;
344
+ }
345
+ cmp:: Ordering :: Greater => {
346
+ report_diff ( format ! ( "{} = ( * | {} )" , r. 0 , r. 1 ) ) ;
347
+ right_name_val = None ;
348
+ }
349
+ cmp:: Ordering :: Less => {
350
+ report_diff ( format ! ( "{} = ( {} | * )" , l. 0 , l. 1 ) ) ;
351
+ left_name_val = None ;
352
+ }
353
+ } ,
354
+ ( Some ( l) , None ) => {
355
+ report_diff ( format ! ( "{} = ( {} | * )" , l. 0 , l. 1 ) ) ;
356
+ left_name_val = None ;
357
+ }
358
+ ( None , Some ( r) ) => {
359
+ report_diff ( format ! ( "{} = ( * | {} )" , r. 0 , r. 1 ) ) ;
360
+ right_name_val = None ;
361
+ }
362
+ ( None , None ) => break ,
363
+ }
364
+ }
365
+ }
366
+ }
367
+
293
368
pub fn new ( metadata_loader : Box < MetadataLoaderDyn > ) -> CStore {
294
369
CStore {
295
370
metadata_loader,
@@ -432,6 +507,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
432
507
} ;
433
508
434
509
let cnum_map = self . resolve_crate_deps ( root, & crate_root, & metadata, cnum, dep_kind) ?;
510
+ let target_modifiers = self . resolve_target_modifiers ( & crate_root, & metadata, cnum) ?;
435
511
436
512
let raw_proc_macros = if crate_root. is_proc_macro_crate ( ) {
437
513
let temp_root;
@@ -456,6 +532,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
456
532
raw_proc_macros,
457
533
cnum,
458
534
cnum_map,
535
+ target_modifiers,
459
536
dep_kind,
460
537
source,
461
538
private_dep,
@@ -689,6 +766,25 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
689
766
Ok ( crate_num_map)
690
767
}
691
768
769
+ fn resolve_target_modifiers (
770
+ & mut self ,
771
+ crate_root : & CrateRoot ,
772
+ metadata : & MetadataBlob ,
773
+ krate : CrateNum ,
774
+ ) -> Result < TargetModifiers , CrateError > {
775
+ debug ! ( "resolving target modifiers of external crate" ) ;
776
+ if crate_root. is_proc_macro_crate ( ) {
777
+ return Ok ( TargetModifiers :: new ( ) ) ;
778
+ }
779
+ let mods = crate_root. decode_target_modifiers ( metadata) ;
780
+ let mut target_modifiers = TargetModifiers :: with_capacity ( mods. len ( ) ) ;
781
+ for modifier in mods {
782
+ target_modifiers. push ( modifier) ;
783
+ }
784
+ debug ! ( "resolve_target_modifiers: target mods for {:?} is {:?}" , krate, target_modifiers) ;
785
+ Ok ( target_modifiers)
786
+ }
787
+
692
788
fn dlsym_proc_macros (
693
789
& self ,
694
790
path : & Path ,
0 commit comments