@@ -24,7 +24,7 @@ use rustc_middle::bug;
2424use  rustc_middle:: ty:: { TyCtxt ,  TyCtxtFeed } ; 
2525use  rustc_session:: config:: { self ,  CrateType ,  ExternLocation } ; 
2626use  rustc_session:: cstore:: { CrateDepKind ,  CrateSource ,  ExternCrate ,  ExternCrateSource } ; 
27- use  rustc_session:: lint:: { self ,  BuiltinLintDiag } ; 
27+ use  rustc_session:: lint:: { self ,  BuiltinLintDiag ,   LintBuffer } ; 
2828use  rustc_session:: output:: validate_crate_name; 
2929use  rustc_session:: search_paths:: PathKind ; 
3030use  rustc_span:: edition:: Edition ; 
@@ -35,7 +35,9 @@ use tracing::{debug, info, trace};
3535
3636use  crate :: errors; 
3737use  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+ } ; 
3941
4042/// The backend's way to give the crate store access to the metadata in a library. 
4143/// Note that it returns the raw metadata bytes stored in the library file, whether 
@@ -290,6 +292,79 @@ impl CStore {
290292        } 
291293    } 
292294
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+ 
293368    pub  fn  new ( metadata_loader :  Box < MetadataLoaderDyn > )  -> CStore  { 
294369        CStore  { 
295370            metadata_loader, 
@@ -432,6 +507,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
432507        } ; 
433508
434509        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) ?; 
435511
436512        let  raw_proc_macros = if  crate_root. is_proc_macro_crate ( )  { 
437513            let  temp_root; 
@@ -456,6 +532,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
456532            raw_proc_macros, 
457533            cnum, 
458534            cnum_map, 
535+             target_modifiers, 
459536            dep_kind, 
460537            source, 
461538            private_dep, 
@@ -689,6 +766,25 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
689766        Ok ( crate_num_map) 
690767    } 
691768
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+ 
692788    fn  dlsym_proc_macros ( 
693789        & self , 
694790        path :  & Path , 
0 commit comments