summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-03-01 22:57:35 +0000
committerbors <bors@rust-lang.org>2024-03-01 22:57:35 +0000
commitf772ec0224d3755ce52ac5128a80319fb2eb45d0 (patch)
treee79979beb968f8f2849ccd7f19b47c6d37f1b878
parentdb609a5ac8901cea0bc2f369eaf2944fa72739e5 (diff)
parent768c70a744429f678a7cd6e88e9670f833e5e58f (diff)
Auto merge of #13505 - epage:edition-warn, r=weihanglo
feat(toml): Warn on unset Edition ### What does this PR try to resolve? On [Internals](https://internals.rust-lang.org/t/idea-rustc-cargo-should-warn-on-unspecified-edition/20309), the idea came up for warning on unset Edition. Besides helping people who forget to set the Edition, this creates symmetry between `Cargo.toml` and cargo scripts (#12207). While the default is different in each case, we are making the default obvious and guiding people away from it. ### How should we test and review this PR? There are separate commits for adding tests (and refactors) so the changes in behavior will be more obvious ### Additional information This builds on - #13499 - #13504
-rw-r--r--src/cargo/core/features.rs11
-rw-r--r--src/cargo/util/toml/mod.rs81
-rw-r--r--tests/testsuite/bench.rs17
-rw-r--r--tests/testsuite/check_cfg.rs19
-rw-r--r--tests/testsuite/custom_target.rs2
-rw-r--r--tests/testsuite/docscrape.rs20
-rw-r--r--tests/testsuite/edition.rs54
-rw-r--r--tests/testsuite/https.rs3
-rw-r--r--tests/testsuite/profile_trim_paths.rs14
-rw-r--r--tests/testsuite/ssh.rs4
10 files changed, 200 insertions, 25 deletions
diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs
index f0cd9c48d..76ccdadb6 100644
--- a/src/cargo/core/features.rs
+++ b/src/cargo/core/features.rs
@@ -180,9 +180,12 @@ pub type AllowFeatures = BTreeSet<String>;
/// [`is_stable`]: Edition::is_stable
/// [`toml::to_real_manifest`]: crate::util::toml::to_real_manifest
/// [`features!`]: macro.features.html
-#[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, Eq, PartialEq, Serialize, Deserialize)]
+#[derive(
+ Default, Clone, Copy, Debug, Hash, PartialOrd, Ord, Eq, PartialEq, Serialize, Deserialize,
+)]
pub enum Edition {
/// The 2015 edition
+ #[default]
Edition2015,
/// The 2018 edition
Edition2018,
@@ -199,6 +202,12 @@ impl Edition {
pub const LATEST_UNSTABLE: Option<Edition> = Some(Edition::Edition2024);
/// The latest stable edition.
pub const LATEST_STABLE: Edition = Edition::Edition2021;
+ pub const ALL: &'static [Edition] = &[
+ Self::Edition2015,
+ Self::Edition2018,
+ Self::Edition2021,
+ Self::Edition2024,
+ ];
/// Possible values allowed for the `--edition` CLI flag.
///
/// This requires a static value due to the way clap works, otherwise I
diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs
index 8049f538c..1f10d37d3 100644
--- a/src/cargo/util/toml/mod.rs
+++ b/src/cargo/util/toml/mod.rs
@@ -9,6 +9,7 @@ use crate::AlreadyPrintedError;
use anyhow::{anyhow, bail, Context as _};
use cargo_platform::Platform;
use cargo_util::paths;
+use cargo_util_schemas::core::PartialVersion;
use cargo_util_schemas::manifest;
use cargo_util_schemas::manifest::RustVersion;
use itertools::Itertools;
@@ -563,14 +564,69 @@ pub fn to_real_manifest(
source_id,
);
+ let rust_version = if let Some(rust_version) = &package.rust_version {
+ let rust_version = field_inherit_with(rust_version.clone(), "rust_version", || {
+ inherit()?.rust_version()
+ })?;
+ Some(rust_version)
+ } else {
+ None
+ };
+
let edition = if let Some(edition) = package.edition.clone() {
let edition: Edition = field_inherit_with(edition, "edition", || inherit()?.edition())?
.parse()
.with_context(|| "failed to parse the `edition` key")?;
package.edition = Some(manifest::InheritableField::Value(edition.to_string()));
+ if let Some(rust_version) = &rust_version {
+ let req = rust_version.to_caret_req();
+ if let Some(first_version) = edition.first_version() {
+ let unsupported =
+ semver::Version::new(first_version.major, first_version.minor - 1, 9999);
+ if req.matches(&unsupported) {
+ bail!(
+ "rust-version {} is older than first version ({}) required by \
+ the specified edition ({})",
+ rust_version,
+ first_version,
+ edition,
+ )
+ }
+ }
+ }
edition
} else {
- Edition::Edition2015
+ let msrv_edition = if let Some(rust_version) = &rust_version {
+ Edition::ALL
+ .iter()
+ .filter(|e| {
+ e.first_version()
+ .map(|e| {
+ let e = PartialVersion::from(e);
+ e <= **rust_version
+ })
+ .unwrap_or_default()
+ })
+ .max()
+ .copied()
+ } else {
+ None
+ }
+ .unwrap_or_default();
+ let default_edition = Edition::default();
+ let latest_edition = Edition::LATEST_STABLE;
+
+ let tip = if msrv_edition == default_edition {
+ String::new()
+ } else if msrv_edition == latest_edition {
+ format!(" while the latest is {latest_edition}")
+ } else {
+ format!(" while {msrv_edition} is compatible with `rust-version`")
+ };
+ warnings.push(format!(
+ "no edition set: defaulting to the {default_edition} edition{tip}",
+ ));
+ default_edition
};
// Add these lines if start a new unstable edition.
// ```
@@ -588,29 +644,6 @@ pub fn to_real_manifest(
)));
}
- let rust_version = if let Some(rust_version) = &package.rust_version {
- let rust_version = field_inherit_with(rust_version.clone(), "rust_version", || {
- inherit()?.rust_version()
- })?;
- let req = rust_version.to_caret_req();
- if let Some(first_version) = edition.first_version() {
- let unsupported =
- semver::Version::new(first_version.major, first_version.minor - 1, 9999);
- if req.matches(&unsupported) {
- bail!(
- "rust-version {} is older than first version ({}) required by \
- the specified edition ({})",
- rust_version,
- first_version,
- edition,
- )
- }
- }
- Some(rust_version)
- } else {
- None
- };
-
if package.metabuild.is_some() {
features.require(Feature::metabuild())?;
}
diff --git a/tests/testsuite/bench.rs b/tests/testsuite/bench.rs
index 9e5cc1b17..35c78454a 100644
--- a/tests/testsuite/bench.rs
+++ b/tests/testsuite/bench.rs
@@ -331,6 +331,7 @@ fn bench_with_lib_dep() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
[[bin]]
@@ -396,6 +397,7 @@ fn bench_with_deep_lib_dep() {
[package]
name = "bar"
version = "0.0.1"
+ edition = "2015"
authors = []
[dependencies.foo]
@@ -454,6 +456,7 @@ fn external_bench_explicit() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
[[bench]]
@@ -697,6 +700,7 @@ fn lib_bin_same_name() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
[lib]
@@ -796,6 +800,7 @@ fn lib_with_standard_name2() {
[package]
name = "syntax"
version = "0.0.1"
+ edition = "2015"
authors = []
[lib]
@@ -842,6 +847,7 @@ fn bench_dylib() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
[lib]
@@ -883,6 +889,7 @@ fn bench_dylib() {
[package]
name = "bar"
version = "0.0.1"
+ edition = "2015"
authors = []
[lib]
@@ -932,6 +939,7 @@ fn bench_twice_with_build_cmd() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
build = "build.rs"
"#,
@@ -977,6 +985,7 @@ fn bench_with_examples() {
[package]
name = "foo"
version = "6.6.6"
+ edition = "2015"
authors = []
[[example]]
@@ -1061,6 +1070,7 @@ fn test_a_bench() {
name = "foo"
authors = []
version = "0.1.0"
+ edition = "2015"
[lib]
name = "foo"
@@ -1219,6 +1229,7 @@ fn test_bench_multiple_packages() {
name = "foo"
authors = []
version = "0.1.0"
+ edition = "2015"
[dependencies.bar]
path = "../bar"
@@ -1239,6 +1250,7 @@ fn test_bench_multiple_packages() {
name = "bar"
authors = []
version = "0.1.0"
+ edition = "2015"
[[bench]]
name = "bbar"
@@ -1269,6 +1281,7 @@ fn test_bench_multiple_packages() {
name = "baz"
authors = []
version = "0.1.0"
+ edition = "2015"
[[bench]]
name = "bbaz"
@@ -1307,6 +1320,7 @@ fn bench_all_workspace() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[dependencies]
bar = { path = "bar" }
@@ -1360,6 +1374,7 @@ fn bench_all_exclude() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[workspace]
members = ["bar", "baz"]
@@ -1405,6 +1420,7 @@ fn bench_all_exclude_glob() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[workspace]
members = ["bar", "baz"]
@@ -1549,6 +1565,7 @@ fn legacy_bench_name() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[[bench]]
name = "bench"
diff --git a/tests/testsuite/check_cfg.rs b/tests/testsuite/check_cfg.rs
index 3f96451e0..004fc482a 100644
--- a/tests/testsuite/check_cfg.rs
+++ b/tests/testsuite/check_cfg.rs
@@ -38,6 +38,7 @@ fn features() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[features]
f_a = []
@@ -63,6 +64,7 @@ fn features_with_deps() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[dependencies]
bar = { path = "bar/" }
@@ -93,6 +95,7 @@ fn features_with_opt_deps() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[dependencies]
bar = { path = "bar/", optional = true }
@@ -124,6 +127,7 @@ fn features_with_namespaced_features() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[dependencies]
bar = { path = "bar/", optional = true }
@@ -154,6 +158,7 @@ fn features_fingerprint() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[features]
f_a = []
@@ -181,6 +186,7 @@ fn features_fingerprint() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[features]
f_b = []
@@ -199,6 +205,7 @@ fn features_fingerprint() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[features]
f_a = []
@@ -239,6 +246,7 @@ fn features_test() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[features]
f_a = []
@@ -264,6 +272,7 @@ fn features_doctest() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[features]
default = ["f_a"]
@@ -322,6 +331,7 @@ fn features_doc() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[features]
default = ["f_a"]
@@ -348,6 +358,7 @@ fn build_script_feedback() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
build = "build.rs"
"#,
@@ -375,6 +386,7 @@ fn build_script_doc() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
build = "build.rs"
"#,
@@ -415,6 +427,7 @@ fn build_script_override() {
[package]
name = "foo"
version = "0.5.0"
+ edition = "2015"
authors = []
links = "a"
build = "build.rs"
@@ -453,6 +466,7 @@ fn build_script_override_feature_gate() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
links = "a"
"#,
)
@@ -484,6 +498,7 @@ fn build_script_test() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
build = "build.rs"
"#,
@@ -539,6 +554,7 @@ fn build_script_feature_gate() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
build = "build.rs"
"#,
)
@@ -567,6 +583,7 @@ fn config_valid() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[features]
f_a = []
@@ -599,6 +616,7 @@ fn config_invalid() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
"#,
)
.file("src/main.rs", "fn main() {}")
@@ -627,6 +645,7 @@ fn config_feature_gate() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[features]
f_a = []
diff --git a/tests/testsuite/custom_target.rs b/tests/testsuite/custom_target.rs
index 518b19672..191d4cd51 100644
--- a/tests/testsuite/custom_target.rs
+++ b/tests/testsuite/custom_target.rs
@@ -72,6 +72,7 @@ fn custom_target_dependency() {
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = ["author@example.com"]
[dependencies]
@@ -189,6 +190,7 @@ fn changing_spec_relearns_crate_types() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[lib]
crate-type = ["cdylib"]
diff --git a/tests/testsuite/docscrape.rs b/tests/testsuite/docscrape.rs
index 0d96ad718..7398ee0a3 100644
--- a/tests/testsuite/docscrape.rs
+++ b/tests/testsuite/docscrape.rs
@@ -11,6 +11,7 @@ fn basic() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
"#,
)
@@ -83,6 +84,7 @@ fn main() {
[package]
name = "a"
version = "0.0.1"
+ edition = "2015"
authors = []
"#,
)
@@ -136,6 +138,7 @@ fn avoid_build_script_cycle() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
links = "foo"
@@ -155,6 +158,7 @@ fn avoid_build_script_cycle() {
[package]
name = "bar"
version = "0.0.1"
+ edition = "2015"
authors = []
links = "bar"
"#,
@@ -177,6 +181,7 @@ fn complex_reverse_dependencies() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
[dev-dependencies]
@@ -195,6 +200,7 @@ fn complex_reverse_dependencies() {
[package]
name = "a"
version = "0.0.1"
+ edition = "2015"
authors = []
[lib]
@@ -214,6 +220,7 @@ fn complex_reverse_dependencies() {
[package]
name = "b"
version = "0.0.1"
+ edition = "2015"
authors = []
"#,
)
@@ -234,6 +241,7 @@ fn crate_with_dash() {
[package]
name = "da-sh"
version = "0.0.1"
+ edition = "2015"
authors = []
"#,
)
@@ -258,6 +266,7 @@ fn configure_target() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
[lib]
@@ -305,6 +314,7 @@ fn configure_profile_issue_10500() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
[profile.dev]
@@ -379,6 +389,7 @@ fn cache() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
"#,
)
@@ -419,6 +430,7 @@ fn no_fail_bad_lib() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
"#,
)
@@ -463,6 +475,7 @@ fn fail_bad_build_script() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
"#,
)
.file("src/lib.rs", "")
@@ -493,6 +506,7 @@ fn no_fail_bad_example() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
"#,
)
@@ -560,6 +574,7 @@ fn no_scrape_with_dev_deps() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
[dev-dependencies]
@@ -574,6 +589,7 @@ fn no_scrape_with_dev_deps() {
[package]
name = "a"
version = "0.0.1"
+ edition = "2015"
authors = []
"#,
)
@@ -622,6 +638,7 @@ fn use_dev_deps_if_explicitly_enabled() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
[[example]]
@@ -640,6 +657,7 @@ fn use_dev_deps_if_explicitly_enabled() {
[package]
name = "a"
version = "0.0.1"
+ edition = "2015"
authors = []
"#,
)
@@ -673,6 +691,7 @@ fn only_scrape_documented_targets() {
[package]
name = "bar"
version = "0.0.1"
+ edition = "2015"
authors = []
[lib]
@@ -694,6 +713,7 @@ fn only_scrape_documented_targets() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
authors = []
"#,
)
diff --git a/tests/testsuite/edition.rs b/tests/testsuite/edition.rs
index 377a86ec0..6f68233c1 100644
--- a/tests/testsuite/edition.rs
+++ b/tests/testsuite/edition.rs
@@ -122,3 +122,57 @@ fn edition_unstable() {
)
.run();
}
+
+#[cargo_test]
+fn unset_edition_works_with_no_newer_compatible_edition() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = 'foo'
+ version = '0.1.0'
+ rust-version = "1.0"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("check -v")
+ .with_stderr(
+ "\
+[WARNING] no edition set: defaulting to the 2015 edition
+[CHECKING] foo [..]
+[RUNNING] `rustc [..] --edition=2015 [..]`
+[FINISHED] [..]
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn unset_edition_works_on_old_msrv() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = 'foo'
+ version = '0.1.0'
+ rust-version = "1.50" # contains 2018 edition
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("check -v")
+ .with_stderr(
+ "\
+[WARNING] no edition set: defaulting to the 2015 edition while 2018 is compatible with `rust-version`
+[CHECKING] foo [..]
+[RUNNING] `rustc [..] --edition=2015 [..]`
+[FINISHED] [..]
+",
+ )
+ .run();
+}
diff --git a/tests/testsuite/https.rs b/tests/testsuite/https.rs
index c7aec9111..85a894a31 100644
--- a/tests/testsuite/https.rs
+++ b/tests/testsuite/https.rs
@@ -20,6 +20,7 @@ fn self_signed_should_fail() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[dependencies]
bar = {{ git = "{url}" }}
@@ -106,6 +107,7 @@ fn self_signed_with_cacert() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[dependencies]
bar = {{ git = "{url}" }}
@@ -139,6 +141,7 @@ fn github_works() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[dependencies]
bitflags = { git = "https://github.com/rust-lang/bitflags.git", tag="1.3.2" }
diff --git a/tests/testsuite/profile_trim_paths.rs b/tests/testsuite/profile_trim_paths.rs
index 67a7785fe..2cb266bf8 100644
--- a/tests/testsuite/profile_trim_paths.rs
+++ b/tests/testsuite/profile_trim_paths.rs
@@ -15,6 +15,7 @@ fn gated_manifest() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
[profile.dev]
trim-paths = "macro"
@@ -71,6 +72,7 @@ fn release_profile_default_to_object() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
"#,
)
.file("src/lib.rs", "")
@@ -101,6 +103,7 @@ fn one_option() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
[profile.dev]
trim-paths = "{option}"
@@ -143,6 +146,7 @@ fn multiple_options() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
[profile.dev]
trim-paths = ["diagnostics", "macro", "object"]
@@ -174,6 +178,7 @@ fn profile_merge_works() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
[profile.dev]
trim-paths = ["macro"]
@@ -213,6 +218,7 @@ fn registry_dependency() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
[dependencies]
bar = "0.0.1"
@@ -268,6 +274,7 @@ fn git_dependency() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
[dependencies]
bar = {{ git = "{url}" }}
@@ -314,6 +321,7 @@ fn path_dependency() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
[dependencies]
bar = { path = "cocktail-bar" }
@@ -368,6 +376,7 @@ fn path_dependency_outside_workspace() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
[dependencies]
bar = { path = "../bar" }
@@ -413,6 +422,7 @@ fn diagnostics_works() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
[dependencies]
bar = "0.0.1"
@@ -532,6 +542,7 @@ fn object_works_helper(split_debuginfo: &str, run: impl Fn(&std::path::Path) ->
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
[dependencies]
bar = "0.0.1"
@@ -635,6 +646,7 @@ fn custom_build_env_var_trim_paths() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
"#,
)
.file("src/lib.rs", "")
@@ -664,6 +676,7 @@ fn custom_build_env_var_trim_paths() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
[profile.dev]
trim-paths = {opts}
@@ -722,6 +735,7 @@ fn lldb_works_after_trimmed() {
[package]
name = "foo"
version = "0.0.1"
+ edition = "2015"
[profile.dev]
trim-paths = "object"
diff --git a/tests/testsuite/ssh.rs b/tests/testsuite/ssh.rs
index f8c12819b..66ec55d53 100644
--- a/tests/testsuite/ssh.rs
+++ b/tests/testsuite/ssh.rs
@@ -110,6 +110,7 @@ fn foo_bar_project(url: &str) -> Project {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[dependencies]
bar = {{ git = "{url}" }}
@@ -406,6 +407,7 @@ fn invalid_github_key() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[dependencies]
bitflags = { git = "ssh://git@github.com/rust-lang/bitflags.git", tag = "1.3.2" }
@@ -444,6 +446,7 @@ fn bundled_github_works() {
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[dependencies]
bitflags = { git = "ssh://git@github.com/rust-lang/bitflags.git", tag = "1.3.2" }
@@ -552,6 +555,7 @@ Caused by:
[package]
name = "foo"
version = "0.1.0"
+ edition = "2015"
[dependencies]
bitflags = { git = "ssh://git@github.com:22/rust-lang/bitflags.git", tag = "1.3.2" }