Skip to content

Commit 6fc6023

Browse files
pvdrznyurik
andcommitted
Add support for edition 2024
Co-authored-by: Yuri Astrakhan <[email protected]>
1 parent f417b88 commit 6fc6023

File tree

1 file changed

+104
-3
lines changed

1 file changed

+104
-3
lines changed

bindgen/features.rs

Lines changed: 104 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,93 @@ impl fmt::Display for InvalidRustTarget {
7979
}
8080
}
8181

82+
/// This macro defines the Rust editions supported by bindgen.
83+
macro_rules! define_rust_editions {
84+
($($variant:ident($value:literal) => $minor:literal,)*) => {
85+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
86+
pub enum RustEdition {
87+
$(
88+
#[doc = concat!("The ", stringify!($value), " edition of Rust.")]
89+
$variant,
90+
)*
91+
}
92+
93+
impl FromStr for RustEdition {
94+
type Err = InvalidRustEdition;
95+
96+
fn from_str(s: &str) -> Result<Self, Self::Err> {
97+
match s {
98+
$(stringify!($value) => Ok(Self::$variant),)*
99+
_ => Err(InvalidRustEdition(s.to_owned())),
100+
}
101+
}
102+
}
103+
104+
impl fmt::Display for RustEdition {
105+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106+
match self {
107+
$(Self::$variant => stringify!($value).fmt(f),)*
108+
}
109+
}
110+
}
111+
112+
impl RustEdition {
113+
pub(crate) const ALL: [Self; [$($value,)*].len()] = [$(Self::$variant,)*];
114+
115+
pub(crate) fn is_available(self, target: RustTarget) -> bool {
116+
let Some(minor) = target.minor() else {
117+
return true;
118+
};
119+
120+
match self {
121+
$(Self::$variant => $minor <= minor,)*
122+
}
123+
}
124+
}
125+
}
126+
}
127+
128+
#[derive(Debug)]
129+
pub struct InvalidRustEdition(String);
130+
131+
impl fmt::Display for InvalidRustEdition {
132+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133+
write!(f, "\"{}\" is not a valid Rust edition", self.0)
134+
}
135+
}
136+
137+
impl std::error::Error for InvalidRustEdition {}
138+
139+
define_rust_editions! {
140+
Edition2018(2018) => 31,
141+
Edition2021(2021) => 56,
142+
+ Edition2024(2024) => 85,
143+
}
144+
145+
impl RustTarget {
146+
/// Returns the latest edition supported by this target.
147+
pub(crate) fn latest_edition(self) -> RustEdition {
148+
RustEdition::ALL
149+
.iter()
150+
.rev()
151+
.find(|edition| edition.is_available(self))
152+
.copied()
153+
.expect("bindgen should always support at least one edition")
154+
}
155+
}
156+
157+
impl Default for RustEdition {
158+
fn default() -> Self {
159+
RustTarget::default().latest_edition()
160+
}
161+
}
162+
82163
/// This macro defines the [`RustTarget`] and [`RustFeatures`] types.
83164
macro_rules! define_rust_targets {
84165
(
85-
Nightly => {$($nightly_feature:ident $(: #$issue:literal)?),* $(,)?} $(,)?
166+
Nightly => {$($nightly_feature:ident $(($nightly_edition:literal))|* $(: #$issue:literal)?),* $(,)?} $(,)?
86167
$(
87-
$variant:ident($minor:literal) => {$($feature:ident $(: #$pull:literal)?),* $(,)?},
168+
$variant:ident($minor:literal) => {$($feature:ident $(($edition:literal))|* $(: #$pull:literal)?),* $(,)?},
88169
)*
89170
$(,)?
90171
) => {
@@ -163,7 +244,7 @@ define_rust_targets! {
163244
},
164245
Stable_1_77(77) => {
165246
offset_of: #106655,
166-
literal_cstr: #117472,
247+
literal_cstr(2021)|(2024): #117472,
167248
},
168249
Stable_1_73(73) => { thiscall_abi: #42202 },
169250
Stable_1_71(71) => { c_unwind_abi: #106075 },
@@ -306,6 +387,26 @@ impl Default for RustFeatures {
306387
mod test {
307388
use super::*;
308389

390+
#[test]
391+
fn release_versions_for_editions() {
392+
assert_eq!(
393+
"1.33".parse::<RustTarget>().unwrap().latest_edition(),
394+
RustEdition::Edition2018
395+
);
396+
assert_eq!(
397+
"1.56".parse::<RustTarget>().unwrap().latest_edition(),
398+
RustEdition::Edition2021
399+
);
400+
assert_eq!(
401+
"1.85".parse::<RustTarget>().unwrap().latest_edition(),
402+
RustEdition::Edition2024
403+
);
404+
assert_eq!(
405+
"nightly".parse::<RustTarget>().unwrap().latest_edition(),
406+
RustEdition::Edition2024
407+
);
408+
}
409+
309410
#[test]
310411
fn target_features() {
311412
let features = RustFeatures::from(RustTarget::Stable_1_71);

0 commit comments

Comments
 (0)