Skip to content

Commit e3a90f2

Browse files
committed
Auto merge of #5845 - alexcrichton:fix-edition, r=alexcrichton
Rename `--prepare-for` to `--edition`, drop arg This commit tweaks the UI of `cargo fix` for the edition. Previously you'd execute `cargo fix --prepare-for 2018`, but that's a lot of typing! Plus it's some manual data that Cargo can already infer. Instead, after this commit, you now type `cargo fix --edition`, and that's it! The idea is that this'll tell Cargo to fix code for the *next* edition, inferring whatever edition is in use and figuring out what to pass to rustc. Functionality-wise this should be the exact same as `--prepare-for 2018` though If others agree w/ this change I'll send a PR to the edition guide after this merges!
2 parents 748cbea + b2b120e commit e3a90f2

File tree

3 files changed

+97
-30
lines changed

3 files changed

+97
-30
lines changed

src/bin/cargo/commands/fix.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,19 @@ pub fn cli() -> App {
3737
)
3838
.arg(
3939
Arg::with_name("edition")
40+
.long("edition")
41+
.help("Fix in preparation for the next edition"),
42+
)
43+
.arg(
44+
// This is a deprecated argument, we'll want to phase it out
45+
// eventually.
46+
Arg::with_name("prepare-for")
4047
.long("prepare-for")
4148
.help("Fix warnings in preparation of an edition upgrade")
4249
.takes_value(true)
43-
.possible_values(&["2018"]),
50+
.possible_values(&["2018"])
51+
.conflicts_with("edition")
52+
.hidden(true),
4453
)
4554
.arg(
4655
Arg::with_name("allow-no-vcs")
@@ -67,22 +76,16 @@ remaining warnings will be displayed when the check process is finished. For
6776
example if you'd like to prepare for the 2018 edition, you can do so by
6877
executing:
6978
70-
cargo fix --prepare-for 2018
71-
72-
Note that this is not guaranteed to fix all your code as it only fixes code that
73-
`cargo check` would otherwise compile. For example unit tests are left out
74-
from this command, but they can be checked with:
75-
76-
cargo fix --prepare-for 2018 --all-targets
79+
cargo fix --edition
7780
7881
which behaves the same as `cargo check --all-targets`. Similarly if you'd like
7982
to fix code for different platforms you can do:
8083
81-
cargo fix --prepare-for 2018 --target x86_64-pc-windows-gnu
84+
cargo fix --edition --target x86_64-pc-windows-gnu
8285
8386
or if your crate has optional features:
8487
85-
cargo fix --prepare-for 2018 --no-default-features --features foo
88+
cargo fix --edition --no-default-features --features foo
8689
8790
If you encounter any problems with `cargo fix` or otherwise have any questions
8891
or feature requests please don't hesitate to file an issue at
@@ -121,7 +124,8 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
121124
}
122125
}
123126
ops::fix(&ws, &mut ops::FixOptions {
124-
edition: args.value_of("edition"),
127+
edition: args.is_present("edition"),
128+
prepare_for: args.value_of("prepare-for"),
125129
compile_opts: opts,
126130
allow_dirty: args.is_present("allow-dirty"),
127131
allow_no_vcs: args.is_present("allow-no-vcs"),

src/cargo/ops/fix.rs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ use util::paths;
2121

2222
const FIX_ENV: &str = "__CARGO_FIX_PLZ";
2323
const BROKEN_CODE_ENV: &str = "__CARGO_FIX_BROKEN_CODE";
24+
const PREPARE_FOR_ENV: &str = "__CARGO_FIX_PREPARE_FOR";
2425
const EDITION_ENV: &str = "__CARGO_FIX_EDITION";
2526

2627
pub struct FixOptions<'a> {
27-
pub edition: Option<&'a str>,
28+
pub edition: bool,
29+
pub prepare_for: Option<&'a str>,
2830
pub compile_opts: CompileOptions<'a>,
2931
pub allow_dirty: bool,
3032
pub allow_no_vcs: bool,
@@ -48,9 +50,12 @@ pub fn fix(ws: &Workspace, opts: &mut FixOptions) -> CargoResult<()> {
4850
opts.compile_opts.build_config.extra_rustc_env.push((key, "1".to_string()));
4951
}
5052

51-
if let Some(edition) = opts.edition {
53+
if opts.edition {
54+
let key = EDITION_ENV.to_string();
55+
opts.compile_opts.build_config.extra_rustc_env.push((key, "1".to_string()));
56+
} else if let Some(edition) = opts.prepare_for {
5257
opts.compile_opts.build_config.extra_rustc_env.push((
53-
EDITION_ENV.to_string(),
58+
PREPARE_FOR_ENV.to_string(),
5459
edition.to_string(),
5560
));
5661
}
@@ -465,11 +470,23 @@ fn log_failed_fix(stderr: &[u8]) -> Result<(), Error> {
465470
#[derive(Default)]
466471
struct FixArgs {
467472
file: Option<PathBuf>,
468-
prepare_for_edition: Option<String>,
473+
prepare_for_edition: PrepareFor,
469474
enabled_edition: Option<String>,
470475
other: Vec<OsString>,
471476
}
472477

478+
enum PrepareFor {
479+
Next,
480+
Edition(String),
481+
None,
482+
}
483+
484+
impl Default for PrepareFor {
485+
fn default() -> PrepareFor {
486+
PrepareFor::None
487+
}
488+
}
489+
473490
impl FixArgs {
474491
fn get() -> FixArgs {
475492
let mut ret = FixArgs::default();
@@ -490,8 +507,10 @@ impl FixArgs {
490507
}
491508
ret.other.push(path.into());
492509
}
493-
if let Ok(s) = env::var(EDITION_ENV) {
494-
ret.prepare_for_edition = Some(s);
510+
if let Ok(s) = env::var(PREPARE_FOR_ENV) {
511+
ret.prepare_for_edition = PrepareFor::Edition(s);
512+
} else if env::var(EDITION_ENV).is_ok() {
513+
ret.prepare_for_edition = PrepareFor::Next;
495514
}
496515
return ret
497516
}
@@ -505,8 +524,15 @@ impl FixArgs {
505524
if let Some(edition) = &self.enabled_edition {
506525
cmd.arg("--edition").arg(edition);
507526
}
508-
if let Some(prepare_for) = &self.prepare_for_edition {
509-
cmd.arg("-W").arg(format!("rust-{}-compatibility", prepare_for));
527+
match &self.prepare_for_edition {
528+
PrepareFor::Edition(edition) => {
529+
cmd.arg("-W").arg(format!("rust-{}-compatibility", edition));
530+
}
531+
PrepareFor::Next => {
532+
let edition = self.next_edition();
533+
cmd.arg("-W").arg(format!("rust-{}-compatibility", edition));
534+
}
535+
PrepareFor::None => {}
510536
}
511537
}
512538

@@ -519,8 +545,9 @@ impl FixArgs {
519545
/// then yield an error to the user, indicating that this is happening.
520546
fn verify_not_preparing_for_enabled_edition(&self) -> CargoResult<()> {
521547
let edition = match &self.prepare_for_edition {
522-
Some(s) => s,
523-
None => return Ok(()),
548+
PrepareFor::Edition(s) => s,
549+
PrepareFor::Next => self.next_edition(),
550+
PrepareFor::None => return Ok(()),
524551
};
525552
let enabled = match &self.enabled_edition {
526553
Some(s) => s,
@@ -544,8 +571,9 @@ impl FixArgs {
544571

545572
fn warn_if_preparing_probably_inert(&self) -> CargoResult<()> {
546573
let edition = match &self.prepare_for_edition {
547-
Some(s) => s,
548-
None => return Ok(()),
574+
PrepareFor::Edition(s) => s,
575+
PrepareFor::Next => self.next_edition(),
576+
PrepareFor::None => return Ok(()),
549577
};
550578
let path = match &self.file {
551579
Some(s) => s,
@@ -567,4 +595,16 @@ impl FixArgs {
567595

568596
Ok(())
569597
}
598+
599+
fn next_edition(&self) -> &str {
600+
match self.enabled_edition.as_ref().map(|s| &**s) {
601+
// 2015 -> 2018,
602+
None | Some("2015") => "2018",
603+
604+
// This'll probably be wrong in 2020, but that's future Cargo's
605+
// problem. Eventually though we'll just add more editions here as
606+
// necessary.
607+
_ => "2018",
608+
}
609+
}
570610
}

tests/testsuite/fix.rs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ fn prepare_for_2018() {
284284
[FINISHED] [..]
285285
";
286286
assert_that(
287-
p.cargo("fix --prepare-for 2018 --allow-no-vcs"),
287+
p.cargo("fix --edition --allow-no-vcs"),
288288
execs().with_status(0).with_stderr(stderr).with_stdout(""),
289289
);
290290

@@ -324,7 +324,7 @@ fn local_paths() {
324324
";
325325

326326
assert_that(
327-
p.cargo("fix --prepare-for 2018 --allow-no-vcs"),
327+
p.cargo("fix --edition --allow-no-vcs"),
328328
execs().with_status(0).with_stderr(stderr).with_stdout(""),
329329
);
330330

@@ -362,7 +362,7 @@ issues in preparation for the 2018 edition
362362
[FINISHED] [..]
363363
";
364364
assert_that(
365-
p.cargo("fix --prepare-for 2018 --allow-no-vcs"),
365+
p.cargo("fix --edition --allow-no-vcs"),
366366
execs().with_status(0).with_stderr(stderr).with_stdout(""),
367367
);
368368
}
@@ -452,7 +452,7 @@ fn specify_rustflags() {
452452
[FINISHED] [..]
453453
";
454454
assert_that(
455-
p.cargo("fix --prepare-for 2018 --allow-no-vcs")
455+
p.cargo("fix --edition --allow-no-vcs")
456456
.env("RUSTFLAGS", "-C target-cpu=native"),
457457
execs().with_status(0).with_stderr(stderr).with_stdout(""),
458458
);
@@ -882,7 +882,6 @@ fn prepare_for_and_enable() {
882882
.build();
883883

884884
let stderr = "\
885-
[CHECKING] foo v0.1.0 ([..])
886885
error: cannot prepare for the 2018 edition when it is enabled, so cargo cannot
887886
automatically fix errors in `src/lib.rs`
888887
@@ -895,7 +894,7 @@ information about transitioning to the 2018 edition see:
895894
896895
";
897896
assert_that(
898-
p.cargo("fix --prepare-for 2018 --allow-no-vcs")
897+
p.cargo("fix --edition --allow-no-vcs")
899898
.masquerade_as_nightly_cargo(),
900899
execs()
901900
.with_stderr_contains(stderr)
@@ -920,7 +919,7 @@ issues in preparation for the 2018 edition
920919
[FINISHED] [..]
921920
";
922921
assert_that(
923-
p.cargo("fix --prepare-for 2018 --allow-no-vcs")
922+
p.cargo("fix --edition --allow-no-vcs")
924923
.masquerade_as_nightly_cargo(),
925924
execs()
926925
.with_stderr(stderr)
@@ -966,3 +965,27 @@ fn fix_overlapping() {
966965
println!("{}", contents);
967966
assert!(contents.contains("crate::foo::<crate::A>()"));
968967
}
968+
969+
#[test]
970+
fn both_edition_migrate_flags() {
971+
if !is_nightly() {
972+
return
973+
}
974+
let p = project()
975+
.file("src/lib.rs", "")
976+
.build();
977+
978+
let stderr = "\
979+
error: The argument '--edition' cannot be used with '--prepare-for <prepare-for>'
980+
981+
USAGE:
982+
cargo[..] fix --edition --message-format <FMT>
983+
984+
For more information try --help
985+
";
986+
987+
assert_that(
988+
p.cargo("fix --prepare-for 2018 --edition"),
989+
execs().with_status(1).with_stderr(stderr),
990+
);
991+
}

0 commit comments

Comments
 (0)