Skip to content

Commit 56ccd1f

Browse files
committed
Auto merge of #10316 - hi-rustin:rustin-patch-proc_macro, r=weihanglo
Warning on conflicting keys Signed-off-by: hi-rustin <[email protected]> ### What does this PR try to resolve? close #10299 and close #10317 ### How should we test and review this PR? - Warning on conflicting proc_macro and crate_types keys. - Warning on conflicting dev-dependencies, build-dependencies, and default-features keys.
2 parents a77ed9b + 8b895cc commit 56ccd1f

File tree

5 files changed

+343
-0
lines changed

5 files changed

+343
-0
lines changed

src/cargo/util/toml/mod.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,15 @@ pub fn parse_document(
180180
.map_err(|e| anyhow::Error::from(e).context("could not parse input as TOML"))
181181
}
182182

183+
/// Warn about paths that have been deprecated and may conflict.
184+
fn warn_on_deprecated(new_path: &str, name: &str, kind: &str, warnings: &mut Vec<String>) {
185+
let old_path = new_path.replace("-", "_");
186+
warnings.push(format!(
187+
"conflicting between `{new_path}` and `{old_path}` in the `{name}` {kind}.\n
188+
`{old_path}` is ignored and not recommended for use in the future"
189+
))
190+
}
191+
183192
type TomlLibTarget = TomlTarget;
184193
type TomlBinTarget = TomlTarget;
185194
type TomlExampleTarget = TomlTarget;
@@ -1264,11 +1273,17 @@ impl TomlManifest {
12641273

12651274
// Collect the dependencies.
12661275
process_dependencies(&mut cx, me.dependencies.as_ref(), None)?;
1276+
if me.dev_dependencies.is_some() && me.dev_dependencies2.is_some() {
1277+
warn_on_deprecated("dev-dependencies", package_name, "package", cx.warnings);
1278+
}
12671279
let dev_deps = me
12681280
.dev_dependencies
12691281
.as_ref()
12701282
.or_else(|| me.dev_dependencies2.as_ref());
12711283
process_dependencies(&mut cx, dev_deps, Some(DepKind::Development))?;
1284+
if me.build_dependencies.is_some() && me.build_dependencies2.is_some() {
1285+
warn_on_deprecated("build-dependencies", package_name, "package", cx.warnings);
1286+
}
12721287
let build_deps = me
12731288
.build_dependencies
12741289
.as_ref()
@@ -1282,11 +1297,17 @@ impl TomlManifest {
12821297
Some(platform)
12831298
};
12841299
process_dependencies(&mut cx, platform.dependencies.as_ref(), None)?;
1300+
if platform.build_dependencies.is_some() && platform.build_dependencies2.is_some() {
1301+
warn_on_deprecated("build-dependencies", name, "platform target", cx.warnings);
1302+
}
12851303
let build_deps = platform
12861304
.build_dependencies
12871305
.as_ref()
12881306
.or_else(|| platform.build_dependencies2.as_ref());
12891307
process_dependencies(&mut cx, build_deps, Some(DepKind::Build))?;
1308+
if platform.dev_dependencies.is_some() && platform.dev_dependencies2.is_some() {
1309+
warn_on_deprecated("dev-dependencies", name, "platform target", cx.warnings);
1310+
}
12901311
let dev_deps = platform
12911312
.dev_dependencies
12921313
.as_ref()
@@ -1908,6 +1929,9 @@ impl<P: ResolveToPath> DetailedTomlDependency<P> {
19081929

19091930
let version = self.version.as_deref();
19101931
let mut dep = Dependency::parse(pkg_name, version, new_source_id)?;
1932+
if self.default_features.is_some() && self.default_features2.is_some() {
1933+
warn_on_deprecated("default-features", name_in_toml, "dependency", cx.warnings);
1934+
}
19111935
dep.set_features(self.features.iter().flatten())
19121936
.set_default_features(
19131937
self.default_features
@@ -2057,6 +2081,17 @@ impl TomlTarget {
20572081
}
20582082
}
20592083

2084+
fn validate_proc_macro(&self, warnings: &mut Vec<String>) {
2085+
if self.proc_macro_raw.is_some() && self.proc_macro_raw2.is_some() {
2086+
warn_on_deprecated(
2087+
"proc-macro",
2088+
self.name().as_str(),
2089+
"library target",
2090+
warnings,
2091+
);
2092+
}
2093+
}
2094+
20602095
fn proc_macro(&self) -> Option<bool> {
20612096
self.proc_macro_raw.or(self.proc_macro_raw2).or_else(|| {
20622097
if let Some(types) = self.crate_types() {
@@ -2068,6 +2103,17 @@ impl TomlTarget {
20682103
})
20692104
}
20702105

2106+
fn validate_crate_types(&self, target_kind_human: &str, warnings: &mut Vec<String>) {
2107+
if self.crate_type.is_some() && self.crate_type2.is_some() {
2108+
warn_on_deprecated(
2109+
"crate-type",
2110+
self.name().as_str(),
2111+
format!("{target_kind_human} target").as_str(),
2112+
warnings,
2113+
);
2114+
}
2115+
}
2116+
20712117
fn crate_types(&self) -> Option<&Vec<String>> {
20722118
self.crate_type
20732119
.as_ref()

src/cargo/util/toml/targets.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ fn clean_lib(
174174
Some(ref lib) => lib,
175175
None => return Ok(None),
176176
};
177+
lib.validate_proc_macro(warnings);
178+
lib.validate_crate_types("library", warnings);
177179

178180
validate_target_name(lib, "library", "lib", warnings)?;
179181

@@ -398,6 +400,7 @@ fn clean_examples(
398400

399401
let mut result = Vec::new();
400402
for (path, toml) in targets {
403+
toml.validate_crate_types("example", warnings);
401404
let crate_types = match toml.crate_types() {
402405
Some(kinds) => kinds.iter().map(|s| s.into()).collect(),
403406
None => Vec::new(),

tests/testsuite/build.rs

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,6 +1676,153 @@ Caused by:
16761676
.run();
16771677
}
16781678

1679+
#[cargo_test]
1680+
fn dev_dependencies_conflicting_warning() {
1681+
let p = project()
1682+
.file(
1683+
"Cargo.toml",
1684+
r#"
1685+
[package]
1686+
name = "foo"
1687+
version = "0.1.0"
1688+
edition = "2018"
1689+
1690+
[dev-dependencies]
1691+
a = {path = "a"}
1692+
[dev_dependencies]
1693+
a = {path = "a"}
1694+
"#,
1695+
)
1696+
.file("src/lib.rs", "")
1697+
.file(
1698+
"a/Cargo.toml",
1699+
r#"
1700+
[package]
1701+
name = "a"
1702+
version = "0.0.1"
1703+
"#,
1704+
)
1705+
.file("a/src/lib.rs", "")
1706+
.build();
1707+
p.cargo("build")
1708+
.with_stderr_contains(
1709+
"[WARNING] conflicting between `dev-dependencies` and `dev_dependencies` in the `foo` package.\n
1710+
`dev_dependencies` is ignored and not recommended for use in the future"
1711+
)
1712+
.run();
1713+
}
1714+
1715+
#[cargo_test]
1716+
fn build_dependencies_conflicting_warning() {
1717+
let p = project()
1718+
.file(
1719+
"Cargo.toml",
1720+
r#"
1721+
[package]
1722+
name = "foo"
1723+
version = "0.1.0"
1724+
edition = "2018"
1725+
1726+
[build-dependencies]
1727+
a = {path = "a"}
1728+
[build_dependencies]
1729+
a = {path = "a"}
1730+
"#,
1731+
)
1732+
.file("src/lib.rs", "")
1733+
.file(
1734+
"a/Cargo.toml",
1735+
r#"
1736+
[package]
1737+
name = "a"
1738+
version = "0.0.1"
1739+
"#,
1740+
)
1741+
.file("a/src/lib.rs", "")
1742+
.build();
1743+
p.cargo("build")
1744+
.with_stderr_contains(
1745+
"[WARNING] conflicting between `build-dependencies` and `build_dependencies` in the `foo` package.\n
1746+
`build_dependencies` is ignored and not recommended for use in the future"
1747+
)
1748+
.run();
1749+
}
1750+
1751+
#[cargo_test]
1752+
fn lib_crate_types_conflicting_warning() {
1753+
let p = project()
1754+
.file(
1755+
"Cargo.toml",
1756+
r#"
1757+
[project]
1758+
name = "foo"
1759+
version = "0.5.0"
1760+
authors = ["[email protected]"]
1761+
1762+
[lib]
1763+
name = "foo"
1764+
crate-type = ["rlib", "dylib"]
1765+
crate_type = ["staticlib", "dylib"]
1766+
"#,
1767+
)
1768+
.file("src/lib.rs", "pub fn foo() {}")
1769+
.build();
1770+
p.cargo("build")
1771+
.with_stderr_contains(
1772+
"[WARNING] conflicting between `crate-type` and `crate_type` in the `foo` library target.\n
1773+
`crate_type` is ignored and not recommended for use in the future",
1774+
)
1775+
.run();
1776+
}
1777+
1778+
#[cargo_test]
1779+
fn examples_crate_types_conflicting_warning() {
1780+
let p = project()
1781+
.file(
1782+
"Cargo.toml",
1783+
r#"
1784+
[project]
1785+
name = "foo"
1786+
version = "0.5.0"
1787+
authors = ["[email protected]"]
1788+
1789+
[[example]]
1790+
name = "ex"
1791+
path = "examples/ex.rs"
1792+
crate-type = ["rlib", "dylib"]
1793+
crate_type = ["proc_macro"]
1794+
[[example]]
1795+
name = "goodbye"
1796+
path = "examples/ex-goodbye.rs"
1797+
crate-type = ["rlib", "dylib"]
1798+
crate_type = ["rlib", "staticlib"]
1799+
"#,
1800+
)
1801+
.file("src/lib.rs", "")
1802+
.file(
1803+
"examples/ex.rs",
1804+
r#"
1805+
fn main() { println!("ex"); }
1806+
"#,
1807+
)
1808+
.file(
1809+
"examples/ex-goodbye.rs",
1810+
r#"
1811+
fn main() { println!("goodbye"); }
1812+
"#,
1813+
)
1814+
.build();
1815+
p.cargo("build")
1816+
.with_stderr_contains(
1817+
"\
1818+
[WARNING] conflicting between `crate-type` and `crate_type` in the `ex` example target.\n
1819+
`crate_type` is ignored and not recommended for use in the future
1820+
[WARNING] conflicting between `crate-type` and `crate_type` in the `goodbye` example target.\n
1821+
`crate_type` is ignored and not recommended for use in the future",
1822+
)
1823+
.run();
1824+
}
1825+
16791826
#[cargo_test]
16801827
fn self_dependency() {
16811828
let p = project()
@@ -2841,6 +2988,88 @@ fn cargo_platform_specific_dependency() {
28412988
p.cargo("test").run();
28422989
}
28432990

2991+
#[cargo_test]
2992+
fn cargo_platform_specific_dependency_build_dependencies_conflicting_warning() {
2993+
let host = rustc_host();
2994+
let p = project()
2995+
.file(
2996+
"Cargo.toml",
2997+
&format!(
2998+
r#"
2999+
[project]
3000+
name = "foo"
3001+
version = "0.5.0"
3002+
authors = ["[email protected]"]
3003+
build = "build.rs"
3004+
3005+
[target.{host}.build-dependencies]
3006+
build = {{ path = "build" }}
3007+
[target.{host}.build_dependencies]
3008+
build = {{ path = "build" }}
3009+
"#,
3010+
host = host
3011+
),
3012+
)
3013+
.file("src/main.rs", "fn main() { }")
3014+
.file(
3015+
"build.rs",
3016+
"extern crate build; fn main() { build::build(); }",
3017+
)
3018+
.file("build/Cargo.toml", &basic_manifest("build", "0.5.0"))
3019+
.file("build/src/lib.rs", "pub fn build() {}")
3020+
.build();
3021+
3022+
p.cargo("build")
3023+
.with_stderr_contains(
3024+
format!("[WARNING] conflicting between `build-dependencies` and `build_dependencies` in the `{}` platform target.\n
3025+
`build_dependencies` is ignored and not recommended for use in the future", host)
3026+
)
3027+
.run();
3028+
3029+
assert!(p.bin("foo").is_file());
3030+
}
3031+
3032+
#[cargo_test]
3033+
fn cargo_platform_specific_dependency_dev_dependencies_conflicting_warning() {
3034+
let host = rustc_host();
3035+
let p = project()
3036+
.file(
3037+
"Cargo.toml",
3038+
&format!(
3039+
r#"
3040+
[project]
3041+
name = "foo"
3042+
version = "0.5.0"
3043+
authors = ["[email protected]"]
3044+
3045+
[target.{host}.dev-dependencies]
3046+
dev = {{ path = "dev" }}
3047+
[target.{host}.dev_dependencies]
3048+
dev = {{ path = "dev" }}
3049+
"#,
3050+
host = host
3051+
),
3052+
)
3053+
.file("src/main.rs", "fn main() { }")
3054+
.file(
3055+
"tests/foo.rs",
3056+
"extern crate dev; #[test] fn foo() { dev::dev() }",
3057+
)
3058+
.file("dev/Cargo.toml", &basic_manifest("dev", "0.5.0"))
3059+
.file("dev/src/lib.rs", "pub fn dev() {}")
3060+
.build();
3061+
3062+
p.cargo("build")
3063+
.with_stderr_contains(
3064+
format!("[WARNING] conflicting between `dev-dependencies` and `dev_dependencies` in the `{}` platform target.\n
3065+
`dev_dependencies` is ignored and not recommended for use in the future", host)
3066+
)
3067+
.run();
3068+
3069+
assert!(p.bin("foo").is_file());
3070+
p.cargo("test").run();
3071+
}
3072+
28443073
#[cargo_test]
28453074
fn bad_platform_specific_dependency() {
28463075
let p = project()

0 commit comments

Comments
 (0)