Skip to content

Commit 6ab5d6a

Browse files
compiler: implement AbiMap errors
1 parent 411d014 commit 6ab5d6a

File tree

4 files changed

+55
-11
lines changed

4 files changed

+55
-11
lines changed

compiler/rustc_abi/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,17 +1899,17 @@ pub enum StructKind {
18991899
Prefixed(Size, Align),
19001900
}
19011901

1902-
#[derive(Clone, Debug)]
1902+
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
19031903
pub enum AbiFromStrErr {
19041904
/// not a known ABI
19051905
Unknown,
19061906
/// no "-unwind" variant
19071907
NoUnwind,
19081908
}
19091909

1910-
#[derive(Clone, Debug)]
1910+
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
19111911
pub enum AbiFromJsonErr {
19121912
InvalidType,
19131913
UnusedKey,
1914-
Parse(AbiFromStrErr),
1914+
Parse { kind: AbiFromStrErr, value: String },
19151915
}

compiler/rustc_abi/src/map.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,9 @@ fn extract_abi_str(
215215
json.remove_entry(s)
216216
.map(|(key_string, abi_str)| {
217217
if let JsonValue::String(abi_str) = abi_str {
218-
abi_str.parse().map_err(|err| (key_string, AbiFromJsonErr::Parse(err)))
218+
abi_str.parse().map_err(|err| {
219+
(key_string, AbiFromJsonErr::Parse { kind: err, value: abi_str })
220+
})
219221
} else {
220222
Err((key_string, AbiFromJsonErr::InvalidType))
221223
}

compiler/rustc_target/src/spec/json.rs

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::borrow::Cow;
22
use std::collections::BTreeMap;
33
use std::str::FromStr;
44

5+
use rustc_abi::{AbiFromJsonErr, AbiFromStrErr};
56
use serde_json::Value;
67

78
use 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

compiler/rustc_target/src/spec/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use std::str::FromStr;
4343
use std::{fmt, io};
4444

4545
use rustc_abi::{
46-
Align, Endian, ExternAbi, Integer, Size, TargetDataLayout, TargetDataLayoutErrors,
46+
AbiMap, Align, Endian, ExternAbi, Integer, Size, TargetDataLayout, TargetDataLayoutErrors,
4747
};
4848
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
4949
use rustc_fs_util::try_canonicalize;
@@ -2274,6 +2274,8 @@ type StaticCow<T> = Cow<'static, T>;
22742274
/// through `Deref` impls.
22752275
#[derive(PartialEq, Clone, Debug)]
22762276
pub struct TargetOptions {
2277+
/// map of ABIs that are supported and mapped
2278+
pub abi_map: AbiMap,
22772279
/// Used as the `target_endian` `cfg` variable. Defaults to little endian.
22782280
pub endian: Endian,
22792281
/// Width of c_int type. Defaults to "32".
@@ -2773,6 +2775,7 @@ impl Default for TargetOptions {
27732775
/// incomplete, and if used for compilation, will certainly not work.
27742776
fn default() -> TargetOptions {
27752777
TargetOptions {
2778+
abi_map: AbiMap::default(),
27762779
endian: Endian::Little,
27772780
c_int_width: "32".into(),
27782781
os: "none".into(),

0 commit comments

Comments
 (0)