UI for the 2018 edition release #64
Comments
I'm also not entirely sure where a |
One thing I want to note is that I'm currently maintaining a breakage vs idiom distinction for epoch lints. Breakage lints are the bare minimum you must fix to upgrade. A good feature of this is that they're backwards compatible changes; if you fix these you can still work on the old edition (great for testing). Idiom lints contain changes that may be more expansive but not required (but highly recommended). It would be nice if we had a |
Sounds like a very solid plan to me, @alexcrichton! I've previously tried to rely on cargo to give us all the JSON output we desire (i.e., just call I like the idea to pass cargo-like flags to I'm a bit unsure if we need the "find out if this is a file we care about" step, though. If our wrapper gets called by cargo, we should get Also, do we actually need the user to add |
@killercup oh hm interesting! Using I'm not actually sure if there's a benefit to shadowing I think that's something we'll want to talk through today about whether users need to add the attribute to their code, I don't personally have too many thoughts but would be fine either way! |
cf. #66 |
Ok with #66 landed now I'm going to close this and we can continue to iterate in-tree and on future issues |
My naive expectation was that if my crate is currently on Rust 2015, |
The
rustfix
tool is going to be a banner feature of the 2018 edition coming up later this year, so I think we'll want to UI to be as good as we can get it to ensure that everyone's got a smooth experience with applying the tool and updating code.How does
rustfix
work today?I've been reading the code as-is to better understand how it works today, and I'll try to summarize it here for the unfamiliar but please correct me if I'm wrong! Today you can either execute
rustfix
orcargo fix
and they'll do the same thing. The CLI takes no arguments and has a few flags that change its operation. Just executingrustfix
means that it'll instead runcargo rustc -- --message-format json
.Once Cargo/rustc is executed rustfix slurps up all the output of rustc. The stderr stream is then parsed into a list of suggestions and replacements. All suggestions are then iterated over and by default presented to the user to ask whether the fix should be applied or not. If accepted then it's queued up to be applied later. This then happens for all suggestions found, and there's a flag as well to say "don't query me, just apply everything".
Finally after all this the suggestions will be applied one-by-one, updating the files on the filesystem.
What do we want the UI for the edition to feel like?
I think we're largely undecided on this in the sense that we haven't concretely nailed this down (although I may have missed it!). I'll put forth a strawman though for how I could see this working.
First off before we release the edition we'll want to test out lints, language features, and rustfix. To do that you'll first add
#![warn(rust_2018_migration)]
to the crate you'd like to update. This will includesrc/lib.rs
,src/main.rs
,tests/*.rs
,examples/*.rs
, etc. They'll all need this annotation. After that's applied you'll executecargo fix
. This'll then apply as many fixes as it can (no user interaction), but also continue to emit normal compiler warnings about things that couldn't be fixed.The second scenario is when we've actually released the edition itself. The only difference here is that instead of
#![warn(..)]
all over the place you'll instead just sayrust = '2018'
in yourCargo.toml
.How to implement this?
Rustfix is shaping up to be a pretty simple tool (yay!). It's largely just taking suggestions from the compiler and actually applying them on the filesystem, assuming the compiler is correctly informing rustfix of changes that need to be made.
The actual integration though is going to be pretty tricky. For a the best-quality experience we'll want to make sure that rustfix gracefully handles things like workspaces, multiple crates/targets in a workspace, cross-compilation, etc. I think that we can get all this done with a "hack" which has worked out quite well for rustbuild historically, override
rustc
.A new CLI
I'm envisioning a CLI that looks like this for rustfix:
The general idea is that
cargo fix
is the main entry point, and it otherwise mirrors Cargo's normal invocations. It will operate "as if" some other cargo command is executing, only a bunch of warnings are fixed along the way.If a subcommand to
fix
isn't specified it's assumed to becheck
. If nothing is passed it's the special casecheck --all-targets
to fix as much as possible. Otherwise flags are all forwarded tocargo
subcommands as usual to execute various compilations.This should have the benefit of working on workspaces, working on all targets, and hopefully even being future compatible with future Cargo features!
Overriding
rustc
To actually implement the above interface I think we'll want to execute
cargo
(the CLI) with theRUSTC
environment variable set to rustfix's binary itself. That way it'll get reexecuted and have control over the compilation.In this way we've now provided a hook to all rustc compilations, allowing us to intercept error messages and such to see what's going on. I think the logic of the script will look like:
--emit metadata
mode (injected if not already present). All output is slurped up with--error-format=json
as well.And I think that's enough to basically get the feeling of "automatically fix all the code" while also assuming as little as possible about Cargo itself.
Some possible caveats are:
cargo fix
actually run over code that may need fixing.If we were to do this it's a pretty major rewrite/rethinking of the current CLI, so I'd like to get others' opinions on this! I'm curious if we can improve various aspects or otherwise make us better suited for the edition release!
The text was updated successfully, but these errors were encountered: