Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ pub struct AutoCfg {
rustc_version: Version,
target: Option<OsString>,
no_std: bool,
edition: Option<String>,
rustflags: Vec<String>,
uuid: u64,
}
Expand Down Expand Up @@ -203,6 +204,7 @@ impl AutoCfg {
rustc_version: rustc_version,
target: target,
no_std: false,
edition: None,
uuid: new_uuid(),
};

Expand Down Expand Up @@ -246,6 +248,36 @@ impl AutoCfg {
self.no_std = no_std;
}

/// Returns the `--edition` string that is currently being passed to `rustc`, if any,
/// as configured by the [`set_edition`][Self::set_edition] method.
pub fn edition(&self) -> Option<&str> {
match self.edition {
Some(ref edition) => Some(&**edition),
None => None,
}
}

/// Sets the `--edition` string that will be passed to `rustc`,
/// or `None` to leave the compiler at its default edition.
///
/// See also [The Rust Edition Guide](https://doc.rust-lang.org/edition-guide/).
///
/// **Warning:** Setting an unsupported edition will likely cause **all** subsequent probes to
/// fail! As of this writing, the known editions and their minimum Rust versions are:
///
/// | Edition | Version |
/// | ------- | ---------- |
/// | 2015 | 1.27.0[^1] |
/// | 2018 | 1.31.0 |
/// | 2021 | 1.56.0 |
/// | 2024 | 1.85.0 |
///
/// [^1]: Prior to 1.27.0, Rust was effectively 2015 Edition by default, but the concept hadn't
/// been established yet, so the explicit `--edition` flag wasn't supported either.
pub fn set_edition(&mut self, edition: Option<String>) {
self.edition = edition;
}

/// Tests whether the current `rustc` reports a version greater than
/// or equal to "`major`.`minor`".
pub fn probe_rustc_version(&self, major: usize, minor: usize) -> bool {
Expand Down Expand Up @@ -282,6 +314,10 @@ impl AutoCfg {
.arg(&self.out_dir)
.arg("--emit=llvm-ir");

if let Some(edition) = self.edition.as_ref() {
command.arg("--edition").arg(edition);
}

if let Some(target) = self.target.as_ref() {
command.arg("--target").arg(target);
}
Expand Down
38 changes: 38 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,41 @@ fn probe_cleanup() {
// is empty -- i.e. the probe should have removed any output files.
std::fs::remove_dir(&dir).unwrap();
}

#[test]
fn editions() {
let mut ac = autocfg_for_test();
assert!(ac.edition().is_none());
assert!(ac.probe_raw("").is_ok());

for (edition, minor) in vec![(2015, 27), (2018, 31), (2021, 56), (2024, 85)] {
let edition = edition.to_string();
ac.set_edition(Some(edition.clone()));
assert_eq!(ac.edition(), Some(&*edition));
assert_min(&ac, 1, minor, ac.probe_raw("").is_ok());
}

ac.set_edition(Some("invalid".into()));
assert_eq!(ac.edition(), Some("invalid"));
assert!(ac.probe_raw("").is_err());

ac.set_edition(None);
assert!(ac.edition().is_none());
assert!(ac.probe_raw("").is_ok());
}

#[test]
fn edition_keyword_try() {
let mut ac = autocfg_for_test();

if ac.probe_rustc_version(1, 27) {
ac.set_edition(Some(2015.to_string()));
}
assert!(ac.probe_expression("{ let try = 0; try }"));

if ac.probe_rustc_version(1, 31) {
ac.set_edition(Some(2018.to_string()));
assert!(!ac.probe_expression("{ let try = 0; try }"));
assert!(ac.probe_expression("{ let r#try = 0; r#try }"));
}
}