diff --git a/src/cargo/ops/fix.rs b/src/cargo/ops/fix.rs index 743bd486646..398ad46b40f 100644 --- a/src/cargo/ops/fix.rs +++ b/src/cargo/ops/fix.rs @@ -254,9 +254,42 @@ fn migrate_manifests(ws: &Workspace<'_>, pkgs: &[&Package]) -> CargoResult<()> { let mut fixes = 0; let root = document.as_table_mut(); + + if let Some(workspace) = root + .get_mut("workspace") + .and_then(|t| t.as_table_like_mut()) + { + // strictly speaking, the edition doesn't apply to this table but it should be safe + // enough + fixes += rename_dep_fields_2024(workspace, "dependencies"); + } + fixes += add_feature_for_unused_deps(pkg, root); - if rename_table(root, "project", "package") { - fixes += 1; + fixes += rename_table(root, "project", "package"); + if let Some(target) = root.get_mut("lib").and_then(|t| t.as_table_like_mut()) { + fixes += rename_target_fields_2024(target); + } + fixes += rename_array_of_target_fields_2024(root, "bin"); + fixes += rename_array_of_target_fields_2024(root, "example"); + fixes += rename_array_of_target_fields_2024(root, "test"); + fixes += rename_array_of_target_fields_2024(root, "bench"); + fixes += rename_dep_fields_2024(root, "dependencies"); + fixes += rename_table(root, "dev_dependencies", "dev-dependencies"); + fixes += rename_dep_fields_2024(root, "dev-dependencies"); + fixes += rename_table(root, "build_dependencies", "build-dependencies"); + fixes += rename_dep_fields_2024(root, "build-dependencies"); + for target in root + .get_mut("target") + .and_then(|t| t.as_table_like_mut()) + .iter_mut() + .flat_map(|t| t.iter_mut()) + .filter_map(|(_k, t)| t.as_table_like_mut()) + { + fixes += rename_dep_fields_2024(target, "dependencies"); + fixes += rename_table(target, "dev_dependencies", "dev-dependencies"); + fixes += rename_dep_fields_2024(target, "dev-dependencies"); + fixes += rename_table(target, "build_dependencies", "build-dependencies"); + fixes += rename_dep_fields_2024(target, "build-dependencies"); } if 0 < fixes { @@ -274,9 +307,43 @@ fn migrate_manifests(ws: &Workspace<'_>, pkgs: &[&Package]) -> CargoResult<()> { Ok(()) } -fn rename_table(parent: &mut dyn toml_edit::TableLike, old: &str, new: &str) -> bool { +fn rename_dep_fields_2024(parent: &mut dyn toml_edit::TableLike, dep_kind: &str) -> usize { + let mut fixes = 0; + for target in parent + .get_mut(dep_kind) + .and_then(|t| t.as_table_like_mut()) + .iter_mut() + .flat_map(|t| t.iter_mut()) + .filter_map(|(_k, t)| t.as_table_like_mut()) + { + fixes += rename_table(target, "default_features", "default-features"); + } + fixes +} + +fn rename_array_of_target_fields_2024(root: &mut dyn toml_edit::TableLike, kind: &str) -> usize { + let mut fixes = 0; + for target in root + .get_mut(kind) + .and_then(|t| t.as_array_of_tables_mut()) + .iter_mut() + .flat_map(|t| t.iter_mut()) + { + fixes += rename_target_fields_2024(target); + } + fixes +} + +fn rename_target_fields_2024(target: &mut dyn toml_edit::TableLike) -> usize { + let mut fixes = 0; + fixes += rename_table(target, "crate_type", "crate-type"); + fixes += rename_table(target, "proc_macro", "proc-macro"); + fixes +} + +fn rename_table(parent: &mut dyn toml_edit::TableLike, old: &str, new: &str) -> usize { let Some(old_key) = parent.key(old).cloned() else { - return false; + return 0; }; let project = parent.remove(old).expect("returned early"); @@ -286,7 +353,7 @@ fn rename_table(parent: &mut dyn toml_edit::TableLike, old: &str, new: &str) -> *new_key.dotted_decor_mut() = old_key.dotted_decor().clone(); *new_key.leaf_decor_mut() = old_key.leaf_decor().clone(); } - true + 1 } fn add_feature_for_unused_deps(pkg: &Package, parent: &mut dyn toml_edit::TableLike) -> usize { diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 06887da68d9..96720937a92 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -306,6 +306,8 @@ fn resolve_toml( }; if let Some(original_package) = original_toml.package() { + let package_name = &original_package.name; + let resolved_package = resolve_package_toml(original_package, features, package_root, &inherit)?; let edition = resolved_package @@ -341,6 +343,15 @@ fn resolve_toml( package_root, warnings, )?; + deprecated_underscore( + &original_toml.dev_dependencies2, + &original_toml.dev_dependencies, + "dev-dependencies", + package_name, + "package", + edition, + warnings, + )?; resolved_toml.dev_dependencies = resolve_dependencies( gctx, edition, @@ -352,6 +363,15 @@ fn resolve_toml( package_root, warnings, )?; + deprecated_underscore( + &original_toml.build_dependencies2, + &original_toml.build_dependencies, + "build-dependencies", + package_name, + "package", + edition, + warnings, + )?; resolved_toml.build_dependencies = resolve_dependencies( gctx, edition, @@ -376,6 +396,15 @@ fn resolve_toml( package_root, warnings, )?; + deprecated_underscore( + &platform.dev_dependencies2, + &platform.dev_dependencies, + "dev-dependencies", + name, + "platform target", + edition, + warnings, + )?; let resolved_dev_dependencies = resolve_dependencies( gctx, edition, @@ -387,6 +416,15 @@ fn resolve_toml( package_root, warnings, )?; + deprecated_underscore( + &platform.build_dependencies2, + &platform.build_dependencies, + "build-dependencies", + name, + "platform target", + edition, + warnings, + )?; let resolved_build_dependencies = resolve_dependencies( gctx, edition, @@ -617,6 +655,15 @@ fn resolve_dependencies<'a>( let mut resolved = dependency_inherit_with(v.clone(), name_in_toml, inherit, package_root, warnings)?; if let manifest::TomlDependency::Detailed(ref mut d) = resolved { + deprecated_underscore( + &d.default_features2, + &d.default_features, + "default-features", + name_in_toml, + "dependency", + edition, + warnings, + )?; if d.public.is_some() { let public_feature = features.require(Feature::public_dependency()); let with_public_feature = public_feature.is_ok(); @@ -1146,28 +1193,12 @@ fn to_real_manifest( } validate_dependencies(original_toml.dependencies.as_ref(), None, None, warnings)?; - deprecated_underscore( - &original_toml.dev_dependencies2, - &original_toml.dev_dependencies, - "dev-dependencies", - package_name, - "package", - warnings, - ); validate_dependencies( original_toml.dev_dependencies(), None, Some(DepKind::Development), warnings, )?; - deprecated_underscore( - &original_toml.build_dependencies2, - &original_toml.build_dependencies, - "build-dependencies", - package_name, - "package", - warnings, - ); validate_dependencies( original_toml.build_dependencies(), None, @@ -1184,28 +1215,12 @@ fn to_real_manifest( None, warnings, )?; - deprecated_underscore( - &platform.build_dependencies2, - &platform.build_dependencies, - "build-dependencies", - name, - "platform target", - warnings, - ); validate_dependencies( platform.build_dependencies(), platform_kind.as_ref(), Some(DepKind::Build), warnings, )?; - deprecated_underscore( - &platform.dev_dependencies2, - &platform.dev_dependencies, - "dev-dependencies", - name, - "platform target", - warnings, - ); validate_dependencies( platform.dev_dependencies(), platform_kind.as_ref(), @@ -1811,14 +1826,6 @@ fn detailed_dep_to_dependency( let version = orig.version.as_deref(); let mut dep = Dependency::parse(pkg_name, version, new_source_id)?; - deprecated_underscore( - &orig.default_features2, - &orig.default_features, - "default-features", - name_in_toml, - "dependency", - manifest_ctx.warnings, - ); dep.set_features(orig.features.iter().flatten()) .set_default_features(orig.default_features().unwrap_or(true)) .set_optional(orig.optional.unwrap_or(false)) @@ -2321,19 +2328,22 @@ fn deprecated_underscore( new_path: &str, name: &str, kind: &str, + edition: Edition, warnings: &mut Vec, -) { - if old.is_some() && new.is_some() { - let old_path = new_path.replace("-", "_"); +) -> CargoResult<()> { + let old_path = new_path.replace("-", "_"); + if old.is_some() && Edition::Edition2024 <= edition { + anyhow::bail!("`{old_path}` is unsupported as of the 2024 edition; instead use `{new_path}`\n(in the `{name}` {kind})"); + } else if old.is_some() && new.is_some() { warnings.push(format!( "`{old_path}` is redundant with `{new_path}`, preferring `{new_path}` in the `{name}` {kind}" )) } else if old.is_some() { - let old_path = new_path.replace("-", "_"); warnings.push(format!( "`{old_path}` is deprecated in favor of `{new_path}` and will not work in the 2024 edition\n(in the `{name}` {kind})" )) } + Ok(()) } fn warn_on_unused(unused: &BTreeSet, warnings: &mut Vec) { diff --git a/src/cargo/util/toml/targets.rs b/src/cargo/util/toml/targets.rs index 9c1268a39b8..1795cf24752 100644 --- a/src/cargo/util/toml/targets.rs +++ b/src/cargo/util/toml/targets.rs @@ -97,12 +97,7 @@ pub(super) fn to_targets( warnings, errors, )?; - targets.extend(to_example_targets( - &toml_examples, - package_root, - edition, - warnings, - )?); + targets.extend(to_example_targets(&toml_examples, package_root, edition)?); let toml_tests = resolve_tests( resolved_toml.test.as_ref(), @@ -183,6 +178,10 @@ fn resolve_lib( // Check early to improve error messages validate_lib_name(&lib, warnings)?; + // Checking the original lib + validate_proc_macro(&lib, "library", edition, warnings)?; + validate_crate_types(&lib, "library", edition, warnings)?; + if lib.path.is_none() { if let Some(inferred) = inferred { lib.path = Some(PathValue(inferred)); @@ -218,8 +217,6 @@ fn to_lib_target( let Some(lib) = resolved_lib else { return Ok(None); }; - validate_proc_macro(lib, "library", warnings); - validate_crate_types(lib, "library", warnings); let path = lib.path.as_ref().expect("previously resolved"); let path = package_root.join(&path.0); @@ -442,14 +439,12 @@ fn to_example_targets( targets: &[TomlExampleTarget], package_root: &Path, edition: Edition, - warnings: &mut Vec, ) -> CargoResult> { validate_unique_names(&targets, "example")?; let mut result = Vec::new(); for toml in targets { let path = package_root.join(&toml.path.as_ref().expect("previously resolved").0); - validate_crate_types(&toml, "example", warnings); let crate_types = match toml.crate_types() { Some(kinds) => kinds.iter().map(|s| s.into()).collect(), None => Vec::new(), @@ -637,6 +632,8 @@ fn resolve_targets_with_legacy_path( for target in &toml_targets { validate_target_name(target, target_kind_human, target_kind, warnings)?; + validate_proc_macro(target, target_kind_human, edition, warnings)?; + validate_crate_types(target, target_kind_human, edition, warnings)?; } let mut result = Vec::new(); @@ -1101,24 +1098,36 @@ fn name_or_panic(target: &TomlTarget) -> &str { .unwrap_or_else(|| panic!("target name is required")) } -fn validate_proc_macro(target: &TomlTarget, kind: &str, warnings: &mut Vec) { +fn validate_proc_macro( + target: &TomlTarget, + kind: &str, + edition: Edition, + warnings: &mut Vec, +) -> CargoResult<()> { deprecated_underscore( &target.proc_macro2, &target.proc_macro, "proc-macro", name_or_panic(target), format!("{kind} target").as_str(), + edition, warnings, - ); + ) } -fn validate_crate_types(target: &TomlTarget, kind: &str, warnings: &mut Vec) { +fn validate_crate_types( + target: &TomlTarget, + kind: &str, + edition: Edition, + warnings: &mut Vec, +) -> CargoResult<()> { deprecated_underscore( &target.crate_type2, &target.crate_type, "crate-type", name_or_panic(target), format!("{kind} target").as_str(), + edition, warnings, - ); + ) } diff --git a/tests/testsuite/bad_config.rs b/tests/testsuite/bad_config.rs index a45e654b5fa..07ae1d76897 100644 --- a/tests/testsuite/bad_config.rs +++ b/tests/testsuite/bad_config.rs @@ -841,6 +841,50 @@ fn dev_dependencies2() { .run(); } +#[cargo_test(nightly, reason = "edition2024 is not stable")] +fn dev_dependencies2_2024() { + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["edition2024"] + + [package] + name = "foo" + version = "0.1.0" + edition = "2024" + + [dev_dependencies] + a = {path = "a"} + "#, + ) + .file("src/lib.rs", "") + .file( + "a/Cargo.toml", + r#" + [package] + name = "a" + version = "0.0.1" + edition = "2015" + "#, + ) + .file("a/src/lib.rs", "") + .build(); + p.cargo("check") + .masquerade_as_nightly_cargo(&["edition2024"]) + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to parse manifest at `[CWD]/Cargo.toml` + +Caused by: + `dev_dependencies` is unsupported as of the 2024 edition; instead use `dev-dependencies` + (in the `foo` package) +", + ) + .run(); +} + #[cargo_test] fn dev_dependencies2_conflict() { let p = project() @@ -916,6 +960,50 @@ fn build_dependencies2() { .run(); } +#[cargo_test(nightly, reason = "edition2024 is not stable")] +fn build_dependencies2_2024() { + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["edition2024"] + + [package] + name = "foo" + version = "0.1.0" + edition = "2024" + + [build_dependencies] + a = {path = "a"} + "#, + ) + .file("src/lib.rs", "") + .file( + "a/Cargo.toml", + r#" + [package] + name = "a" + version = "0.0.1" + edition = "2015" + "#, + ) + .file("a/src/lib.rs", "") + .build(); + p.cargo("check") + .masquerade_as_nightly_cargo(&["edition2024"]) + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to parse manifest at `[CWD]/Cargo.toml` + +Caused by: + `build_dependencies` is unsupported as of the 2024 edition; instead use `build-dependencies` + (in the `foo` package) +", + ) + .run(); +} + #[cargo_test] fn build_dependencies2_conflict() { let p = project() @@ -983,6 +1071,42 @@ fn lib_crate_type2() { .run(); } +#[cargo_test(nightly, reason = "edition2024 is not stable")] +fn lib_crate_type2_2024() { + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["edition2024"] + + [package] + name = "foo" + version = "0.5.0" + edition = "2024" + authors = ["wycats@example.com"] + + [lib] + name = "foo" + crate_type = ["staticlib", "dylib"] + "#, + ) + .file("src/lib.rs", "pub fn foo() {}") + .build(); + p.cargo("check") + .masquerade_as_nightly_cargo(&["edition2024"]) + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to parse manifest at `[CWD]/Cargo.toml` + +Caused by: + `crate_type` is unsupported as of the 2024 edition; instead use `crate-type` + (in the `foo` library target) +", + ) + .run(); +} + #[cargo_test] fn lib_crate_type2_conflict() { let p = project() @@ -1060,6 +1184,59 @@ fn examples_crate_type2() { .run(); } +#[cargo_test(nightly, reason = "edition2024 is not stable")] +fn examples_crate_type2_2024() { + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["edition2024"] + + [package] + name = "foo" + version = "0.5.0" + edition = "2024" + authors = ["wycats@example.com"] + + [[example]] + name = "ex" + path = "examples/ex.rs" + crate_type = ["proc_macro"] + [[example]] + name = "goodbye" + path = "examples/ex-goodbye.rs" + crate_type = ["rlib", "staticlib"] + "#, + ) + .file("src/lib.rs", "") + .file( + "examples/ex.rs", + r#" + fn main() { println!("ex"); } + "#, + ) + .file( + "examples/ex-goodbye.rs", + r#" + fn main() { println!("goodbye"); } + "#, + ) + .build(); + p.cargo("check") + .masquerade_as_nightly_cargo(&["edition2024"]) + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to parse manifest at `[CWD]/Cargo.toml` + +Caused by: + `crate_type` is unsupported as of the 2024 edition; instead use `crate-type` + (in the `ex` example target) +", + ) + .run(); +} + #[cargo_test] fn examples_crate_type2_conflict() { let p = project() @@ -1148,6 +1325,53 @@ fn cargo_platform_build_dependencies2() { .run(); } +#[cargo_test(nightly, reason = "edition2024 is not stable")] +fn cargo_platform_build_dependencies2_2024() { + let host = rustc_host(); + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + cargo-features = ["edition2024"] + + [package] + name = "foo" + version = "0.5.0" + edition = "2024" + authors = ["wycats@example.com"] + build = "build.rs" + + [target.{host}.build_dependencies] + build = {{ path = "build" }} + "#, + host = host + ), + ) + .file("src/main.rs", "fn main() { }") + .file( + "build.rs", + "extern crate build; fn main() { build::build(); }", + ) + .file("build/Cargo.toml", &basic_manifest("build", "0.5.0")) + .file("build/src/lib.rs", "pub fn build() {}") + .build(); + + p.cargo("check") + .masquerade_as_nightly_cargo(&["edition2024"]) + .with_status(101) + .with_stderr(format!( + "\ +[ERROR] failed to parse manifest at `[CWD]/Cargo.toml` + +Caused by: + `build_dependencies` is unsupported as of the 2024 edition; instead use `build-dependencies` + (in the `{host}` platform target) +" + )) + .run(); +} + #[cargo_test] fn cargo_platform_build_dependencies2_conflict() { let host = rustc_host(); @@ -1228,6 +1452,52 @@ fn cargo_platform_dev_dependencies2() { .run(); } +#[cargo_test(nightly, reason = "edition2024 is not stable")] +fn cargo_platform_dev_dependencies2_2024() { + let host = rustc_host(); + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + cargo-features = ["edition2024"] + + [package] + name = "foo" + version = "0.5.0" + edition = "2024" + authors = ["wycats@example.com"] + + [target.{host}.dev_dependencies] + dev = {{ path = "dev" }} + "#, + host = host + ), + ) + .file("src/main.rs", "fn main() { }") + .file( + "tests/foo.rs", + "extern crate dev; #[test] fn foo() { dev::dev() }", + ) + .file("dev/Cargo.toml", &basic_manifest("dev", "0.5.0")) + .file("dev/src/lib.rs", "pub fn dev() {}") + .build(); + + p.cargo("check") + .masquerade_as_nightly_cargo(&["edition2024"]) + .with_status(101) + .with_stderr(format!( + "\ +[ERROR] failed to parse manifest at `[CWD]/Cargo.toml` + +Caused by: + `dev_dependencies` is unsupported as of the 2024 edition; instead use `dev-dependencies` + (in the `{host}` platform target) +" + )) + .run(); +} + #[cargo_test] fn cargo_platform_dev_dependencies2_conflict() { let host = rustc_host(); @@ -1312,6 +1582,57 @@ fn default_features2() { .run(); } +#[cargo_test(nightly, reason = "edition2024 is not stable")] +fn default_features2_2024() { + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["edition2024"] + + [package] + name = "foo" + version = "0.1.0" + edition = "2024" + authors = [] + + [dependencies] + a = { path = "a", features = ["f1"], default_features = false } + "#, + ) + .file("src/lib.rs", "") + .file( + "a/Cargo.toml", + r#" + [package] + name = "a" + version = "0.1.0" + edition = "2015" + authors = [] + + [features] + default = ["f1"] + f1 = [] + "#, + ) + .file("a/src/lib.rs", "") + .build(); + + p.cargo("check") + .masquerade_as_nightly_cargo(&["edition2024"]) + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to parse manifest at `[CWD]/Cargo.toml` + +Caused by: + `default_features` is unsupported as of the 2024 edition; instead use `default-features` + (in the `a` dependency) +", + ) + .run(); +} + #[cargo_test] fn default_features2_conflict() { let p = project() @@ -1437,6 +1758,99 @@ warning: [CWD]/workspace_only/Cargo.toml: `default_features` is deprecated in fa .run(); } +#[cargo_test(nightly, reason = "edition2024 is not stable")] +fn workspace_default_features2_2024() { + let p = project() + .file( + "Cargo.toml", + r#" + [workspace] + members = ["workspace_only", "dep_workspace_only", "package_only", "dep_package_only"] + + [workspace.dependencies] + dep_workspace_only = { path = "dep_workspace_only", default_features = true } + dep_package_only = { path = "dep_package_only" } + "#, + ) + .file( + "workspace_only/Cargo.toml", + r#" + cargo-features = ["edition2024"] + + [package] + name = "workspace_only" + version = "0.1.0" + edition = "2024" + authors = [] + + [dependencies] + dep_workspace_only.workspace = true + "#, + ) + .file("workspace_only/src/lib.rs", "") + .file( + "dep_workspace_only/Cargo.toml", + r#" + cargo-features = ["edition2024"] + + [package] + name = "dep_workspace_only" + version = "0.1.0" + edition = "2024" + authors = [] + "#, + ) + .file("dep_workspace_only/src/lib.rs", "") + .file( + "package_only/Cargo.toml", + r#" + cargo-features = ["edition2024"] + + [package] + name = "package_only" + version = "0.1.0" + edition = "2024" + authors = [] + + [dependencies] + dep_package_only = { workspace = true, default_features = true } + "#, + ) + .file("package_only/src/lib.rs", "") + .file( + "dep_package_only/Cargo.toml", + r#" + cargo-features = ["edition2024"] + + [package] + name = "dep_package_only" + version = "0.1.0" + edition = "2024" + authors = [] + "#, + ) + .file("dep_package_only/src/lib.rs", "") + .build(); + + p.cargo("check") + .masquerade_as_nightly_cargo(&["edition2024"]) + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to load manifest for workspace member `[CWD]/workspace_only` +referenced by workspace at `[CWD]/Cargo.toml` + +Caused by: + failed to parse manifest at `[CWD]/workspace_only/Cargo.toml` + +Caused by: + `default_features` is unsupported as of the 2024 edition; instead use `default-features` + (in the `dep_workspace_only` dependency) +", + ) + .run(); +} + #[cargo_test] fn proc_macro2() { let foo = project() @@ -1464,6 +1878,40 @@ fn proc_macro2() { .run(); } +#[cargo_test(nightly, reason = "edition2024 is not stable")] +fn proc_macro2_2024() { + let foo = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["edition2024"] + + [package] + name = "foo" + version = "0.1.0" + edition = "2024" + [lib] + proc_macro = true + "#, + ) + .file("src/lib.rs", "") + .build(); + + foo.cargo("check") + .masquerade_as_nightly_cargo(&["edition2024"]) + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to parse manifest at `[CWD]/Cargo.toml` + +Caused by: + `proc_macro` is unsupported as of the 2024 edition; instead use `proc-macro` + (in the `foo` library target) +", + ) + .run(); +} + #[cargo_test] fn proc_macro2_conflict() { let foo = project() diff --git a/tests/testsuite/fix.rs b/tests/testsuite/fix.rs index 7997a68ae62..2eb3c79ae54 100644 --- a/tests/testsuite/fix.rs +++ b/tests/testsuite/fix.rs @@ -2050,6 +2050,149 @@ edition = "2021" ); } +#[cargo_test] +fn migrate_rename_underscore_fields() { + let p = project() + .file( + "Cargo.toml", + r#" +cargo-features = ["edition2024"] + +[workspace.dependencies] +# Before default_features +a = {path = "a", default_features = false} # After default_features value +# After default_features line + +[package] +name = "foo" +edition = "2021" + +[lib] +name = "foo" +# Before crate_type +crate_type = ["staticlib", "dylib"] # After crate_type value +# After crate_type line + +[[example]] +name = "ex" +path = "examples/ex.rs" +# Before crate_type +crate_type = ["proc-macro"] # After crate_type value +# After crate_type line + +# Before dev_dependencies +[ dev_dependencies ] # After dev_dependencies header +# After dev_dependencies line +a = {path = "a", default_features = false} +# After dev_dependencies table + +# Before build_dependencies +[ build_dependencies ] # After build_dependencies header +# After build_dependencies line +a = {path = "a", default_features = false} +# After build_dependencies table + +# Before dev_dependencies +[ target.'cfg(any())'.dev_dependencies ] # After dev_dependencies header +# After dev_dependencies line +a = {path = "a", default_features = false} +# After dev_dependencies table + +# Before build_dependencies +[ target.'cfg(any())'.build_dependencies ] # After build_dependencies header +# After build_dependencies line +a = {path = "a", default_features = false} +# After build_dependencies table +"#, + ) + .file("src/lib.rs", "") + .file( + "examples/ex.rs", + r#" + fn main() { println!("ex"); } + "#, + ) + .file( + "a/Cargo.toml", + r#" + [package] + name = "a" + version = "0.0.1" + edition = "2015" + "#, + ) + .file("a/src/lib.rs", "") + .build(); + + p.cargo("fix --edition --allow-no-vcs") + .masquerade_as_nightly_cargo(&["edition2024"]) + .with_stderr( + "\ +[MIGRATING] Cargo.toml from 2021 edition to 2024 +[FIXED] Cargo.toml (11 fixes) + Locking 2 packages to latest compatible versions + Checking a v0.0.1 ([CWD]/a) +[CHECKING] foo v0.0.0 ([CWD]) +[MIGRATING] src/lib.rs from 2021 edition to 2024 +[MIGRATING] examples/ex.rs from 2021 edition to 2024 +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..]s +", + ) + .run(); + assert_eq!( + p.read_file("Cargo.toml"), + r#" +cargo-features = ["edition2024"] + +[workspace.dependencies] +# Before default_features +a = {path = "a", default-features = false} # After default_features value +# After default_features line + +[package] +name = "foo" +edition = "2021" + +[lib] +name = "foo" +# Before crate_type +crate-type = ["staticlib", "dylib"] # After crate_type value +# After crate_type line + +[[example]] +name = "ex" +path = "examples/ex.rs" +# Before crate_type +crate-type = ["proc-macro"] # After crate_type value +# After crate_type line + +# Before dev_dependencies +[ dev-dependencies ] # After dev_dependencies header +# After dev_dependencies line +a = {path = "a", default-features = false} +# After dev_dependencies table + +# Before build_dependencies +[ build-dependencies ] # After build_dependencies header +# After build_dependencies line +a = {path = "a", default-features = false} +# After build_dependencies table + +# Before dev_dependencies +[ target.'cfg(any())'.dev-dependencies ] # After dev_dependencies header +# After dev_dependencies line +a = {path = "a", default-features = false} +# After dev_dependencies table + +# Before build_dependencies +[ target.'cfg(any())'.build-dependencies ] # After build_dependencies header +# After build_dependencies line +a = {path = "a", default-features = false} +# After build_dependencies table +"#, + ); +} + #[cargo_test] fn add_feature_for_unused_dep() { Package::new("bar", "0.1.0").publish();