@@ -2,6 +2,7 @@ use std::borrow::Cow;
22use std:: collections:: BTreeMap ;
33use std:: str:: FromStr ;
44
5+ use rustc_abi:: { AbiFromJsonErr , AbiFromStrErr } ;
56use serde_json:: Value ;
67
78use super :: { Target , TargetKind , TargetOptions , TargetWarnings } ;
@@ -56,6 +57,47 @@ impl Target {
5657 }
5758
5859 let mut incorrect_type = vec ! [ ] ;
60+ let mut unused_fields = vec ! [ ] ;
61+ let mut bad_kv = vec ! [ ] ;
62+
63+ match obj. remove ( "abi-map" ) {
64+ Some ( Json :: Object ( object) ) => match rustc_abi:: AbiMap :: from_json_object ( object) {
65+ Ok ( abi_map) => base. options . abi_map = abi_map,
66+ Err ( error_map) => {
67+ for ( key, error) in error_map {
68+ match error {
69+ AbiFromJsonErr :: InvalidType => {
70+ incorrect_type. push ( [ "abi-map" , & key] . join ( "." ) )
71+ }
72+ AbiFromJsonErr :: UnusedKey => {
73+ unused_fields. push ( [ "abi-map" , & key] . join ( "." ) )
74+ }
75+ AbiFromJsonErr :: Parse { kind, value } => bad_kv. push ( (
76+ [ "abi-map" , & key] . join ( "." ) ,
77+ match kind {
78+ AbiFromStrErr :: Unknown => {
79+ format ! ( "{value} is not a valid CanonAbi" )
80+ }
81+ AbiFromStrErr :: NoUnwind => {
82+ format ! ( "{value} must not be -unwind" )
83+ }
84+ } ,
85+ ) ) ,
86+ }
87+ }
88+ }
89+ } ,
90+ Some ( _) => incorrect_type. push ( "abi-map" . to_owned ( ) ) ,
91+ None => ( ) ,
92+ } ;
93+
94+ if bad_kv. len ( ) > 0 {
95+ let err = bad_kv
96+ . into_iter ( )
97+ . map ( |( key, err) | format ! ( "invalid {key}: {err}\n " ) )
98+ . collect :: < String > ( ) ;
99+ return Err ( err) ;
100+ }
59101
60102 macro_rules! key {
61103 ( $key_name: ident) => ( {
@@ -546,7 +588,6 @@ impl Target {
546588 incorrect_type. push ( "frame-pointer" . into ( ) )
547589 }
548590 }
549-
550591 key ! ( c_int_width = "target-c-int-width" ) ;
551592 key ! ( c_enum_min_bits, Option <u64 >) ; // if None, matches c_int_width
552593 key ! ( os) ;
@@ -667,11 +708,9 @@ impl Target {
667708 base. check_consistency ( TargetKind :: Json ) ?;
668709
669710 // Each field should have been read using `Json::remove` so any keys remaining are unused.
670- let remaining_keys = obj. keys ( ) ;
671- Ok ( (
672- base,
673- TargetWarnings { unused_fields : remaining_keys. cloned ( ) . collect ( ) , incorrect_type } ,
674- ) )
711+ unused_fields. extend ( obj. keys ( ) . cloned ( ) ) ;
712+
713+ Ok ( ( base, TargetWarnings { unused_fields, incorrect_type } ) )
675714 }
676715}
677716
0 commit comments