|
1 | 1 | # Stability - rustfmt
|
2 | 2 |
|
3 |
| -WIP |
| 3 | +This document enumerates areas where backwards compatibility could be a concern |
| 4 | +and some possible quality measures for Rustfmt. For background on what stability |
| 5 | +means for tools in general see [README.md](README.md). |
4 | 6 |
|
5 |
| -## Backwards compatability |
| 7 | +## Backwards compatibility |
6 | 8 |
|
7 | 9 | * Output of formatting
|
8 |
| - - expected major changes soon due to style RFC process |
| 10 | + |
| 11 | +I don't think we can promise 'no changes' without it preventing us fixing bugs. |
| 12 | +I think we can promise that there will be no changes which violate the RFC/spec. |
| 13 | +That would leave us some wriggle room in the ambiguities. It raises the question |
| 14 | +of what happens if we change the spec. I hope we finish the spec before Rustfmt |
| 15 | +1.0 and any changes after that (beyond 'bug fixes') are a breaking change for |
| 16 | +Rustfmt. |
| 17 | + |
| 18 | +I think we should only make promises for the default options. No promises at all |
| 19 | +if you're using any non-default options. |
| 20 | + |
9 | 21 | * Command line args (`rustfmt` and `cargo fmt`)
|
10 |
| -* Accepted options in rustfmt.toml and their defaults |
| 22 | + |
| 23 | +I think we need a notion of stable vs unstable arguments with the obvious back |
| 24 | +compat guarantees. Presumably, unstable arguments should only be usable on the |
| 25 | +nightly channel. |
| 26 | + |
| 27 | +An important argument is the `write-mode` that Rustfmt operates in - this |
| 28 | +controls the output and what is done with it (overwrite files with or without |
| 29 | +backup, pipe to stdout, etc.). We should extend stability to these and promise |
| 30 | +that stable modes will not be removed, nor their operation changed. |
| 31 | + |
| 32 | +The current default write mode is `replace` which leaves a backup, however, |
| 33 | +before stabilisation we should change to `overwrite`, which does not. We should |
| 34 | +then promise not to change the default again. |
| 35 | + |
| 36 | +* exit codes |
| 37 | + |
| 38 | +For stable modes, any change to the possible exit codes must be a breaking |
| 39 | +change. The same code should continue to give the same exit code. |
| 40 | + |
| 41 | +* Configuration options in rustfmt.toml and their defaults |
| 42 | + |
| 43 | +We promise not to remove options, but we can change their effect, including |
| 44 | +making them have no effect at all. We can deprecate options which means we stop |
| 45 | +documenting them and warn on use. Alternatively we could also allow removing |
| 46 | +options and not warn/error if using an unknown option. |
| 47 | + |
11 | 48 | * Library API
|
12 | 49 |
|
| 50 | +I would like to stabilise the public API of the Rustfmt crate with the usual |
| 51 | +meaning for a library. I'm not happy enough with the current API to do it right |
| 52 | +now though. |
| 53 | + |
| 54 | +* skip attributes |
| 55 | + |
| 56 | +Rustfmt can be made to skip sections using an attribute. I would prefer not to |
| 57 | +stabilise the attribute we use before we settle how custom attributes work |
| 58 | +(https://github.com/rust-lang/rfcs/pull/1755). However, I don't want to block |
| 59 | +stabilisation on this. If we get to 1.0 before the custom attributes RFC is |
| 60 | +decided, then we'll just support all supported attributes forever. |
| 61 | + |
| 62 | +* warnings |
| 63 | + |
| 64 | +Rustfmt gives warnings on overlong lines and trailing whitespace it can't fix, |
| 65 | +and could add other warnings. These trigger a failing exit code in some modes. I |
| 66 | +think we must promise not to add or remove warnings without opt-in of some kind. |
| 67 | + |
13 | 68 |
|
14 | 69 | ## Quality
|
15 | 70 |
|
16 | 71 | ### Bugs vs formatting errors
|
17 | 72 |
|
18 |
| -Classify a bug as crashing rustfmt or producing code which fails to compile, or compiles but has different semantics from the source. |
| 73 | +We classify a bug as crashing Rustfmt or producing code which fails to compile, |
| 74 | +or compiles but has different semantics from the source. |
| 75 | + |
| 76 | +Formatting errors are where Rustfmt succeeds, but produces code which does not |
| 77 | +match the RFC style guide or exceeds the width guide (with the exception of |
| 78 | +comments or string literals, or exceptional situations such as very long |
| 79 | +identifier names). |
| 80 | + |
| 81 | + |
| 82 | +#### Comments and multi-line strings |
| 83 | + |
| 84 | +Currently, comments and string literals are only formatted when some non-default |
| 85 | +options are set. Ideally we would format these things, but in practice there is |
| 86 | +often semantic info in their formatting and Rustfmt screws it up. It's not clear |
| 87 | +if there is a better compromise than the current 'do as little as possible' |
| 88 | +approach. |
| 89 | + |
| 90 | +A second issue is that due to the nature of the AST (and architecture of |
| 91 | +Rustfmt) we sometimes miss and thus erase comments in certain positions. Fixing |
| 92 | +this will take either a rewrite of Rustfmt, a rewrite of libsyntax, or using a |
| 93 | +different parser and AST (which would effectively mean a rewrite of both). I |
| 94 | +don't think this is going to happen, and yet this is a major flaw in Rustfmt |
| 95 | +right now. |
| 96 | + |
| 97 | +I think we can make no promises about which comments we preserve since that |
| 98 | +depends on libsyntax which is perma-unstable. |
19 | 99 |
|
20 |
| -Formatting errors are where Rustfmt succeeds, but produces code which does not match the RFC style guide or exceeds the width guide (with the exception of comments or string literals, or exceptional situation such as very long identifier names). |
21 | 100 |
|
22 | 101 | ### Performance
|
23 | 102 |
|
24 |
| -How long does Rustfmt take to run on large codebases |
| 103 | +How long does Rustfmt take to run on large code bases? It is currently a bit |
| 104 | +slow. I don't think this is a problem for users except on very large projects |
| 105 | +(Servo or rustc scale). |
| 106 | + |
| 107 | +I don't think this should block any milestone, but we should keep an eye on it |
| 108 | +and collect some data. |
| 109 | + |
25 | 110 |
|
26 | 111 | ### Testing
|
27 | 112 |
|
28 |
| -run on large test projects, e.g., the Rust repo |
| 113 | +I've found running on large projects (e.g., Rust) to be a good stress test. I |
| 114 | +haven't done this for a while and doing this again should probably block a 1.0 |
| 115 | +announcement. |
| 116 | + |
| 117 | +Rustfmt's test suite is fairly comprehensive, but is not well-organised. I don't |
| 118 | +think there are any blocking issues there. |
29 | 119 |
|
30 |
| -Rustfmt's test suite |
31 | 120 |
|
32 | 121 | ### Customisability
|
33 | 122 |
|
34 |
| -For which options do we apply the quality measures |
| 123 | +For which options do we apply the quality measures? I'm inclined to only care |
| 124 | +about the defaults and to be explicit about this. I think we need to ensure that |
| 125 | +we are offering the right set of options and none of them are too buggy. I don't |
| 126 | +think there is any hope of ensuring quality for all combinations of options. |
| 127 | + |
| 128 | + |
| 129 | +### Unicode wide char support |
| 130 | + |
| 131 | +Rustfmt is currently not great with unicode - we use `byte`s in a bunch of |
| 132 | +places we should use `char`s. I believe this won't cause us to crash anywhere, |
| 133 | +but it will mean sub-optimal formatting and perhaps incorrect line-length |
| 134 | +checks. |
| 135 | + |
| 136 | + |
| 137 | +### Other important issues |
| 138 | + |
| 139 | +* range support (important for IDEs, not so much for command line editors) |
| 140 | +* warnings for skipped sections (i.e., if a section is skipped, should we warn |
| 141 | + on over-long lines, etc.?) |
35 | 142 |
|
36 | 143 |
|
37 | 144 | ## milestones
|
| 145 | + |
| 146 | +### Inclusion with 'Rust product' |
| 147 | + |
| 148 | +* agree on stability criteria |
| 149 | + |
| 150 | + |
| 151 | +### stable channel |
| 152 | + |
| 153 | +* tests running and passing on CI |
| 154 | +* overwrite mode by default |
| 155 | +* implement stable/unstable command line arguments |
| 156 | +* resolve 'warnings for skipped sections' |
| 157 | + |
| 158 | + |
| 159 | +### stable |
| 160 | + |
| 161 | +* audit command line options |
| 162 | +* audit config options |
| 163 | +* RFC style fully implemented |
| 164 | +* audit exit codes |
| 165 | +* TBD - bugs, performance (at least collect data), skip attributes |
| 166 | +* Library API is stablised |
| 167 | + |
| 168 | + |
| 169 | +## Appendix - Rustfmt options and exit codes |
| 170 | + |
| 171 | +``` |
| 172 | +Options: |
| 173 | + -h, --help show this message |
| 174 | + -V, --version show version information |
| 175 | + -v, --verbose print verbose output |
| 176 | + --write-mode [replace|overwrite|display|diff|coverage|checkstyle] |
| 177 | + mode to write in (not usable when piping from stdin) |
| 178 | + --skip-children |
| 179 | + don't reformat child modules |
| 180 | + --config-help show details of rustfmt configuration options |
| 181 | + --dump-default-config PATH |
| 182 | + Dumps the default configuration to a file and exits. |
| 183 | + --dump-minimal-config PATH |
| 184 | + Dumps configuration options that were checked during |
| 185 | + formatting to a file. |
| 186 | + --config-path [Path for the configuration file] |
| 187 | + Recursively searches the given path for the |
| 188 | + rustfmt.toml config file. If not found reverts to the |
| 189 | + input file path |
| 190 | + --file-lines JSON |
| 191 | + Format specified line ranges. See README for more |
| 192 | + detail on the JSON format. |
| 193 | +
|
| 194 | +Exit Codes: |
| 195 | + 0 = No errors |
| 196 | + 1 = Encountered operational errors e.g. an IO error |
| 197 | + 2 = Failed to reformat code because of parsing errors |
| 198 | + 3 = Code is valid, but it is impossible to format it properly |
| 199 | + 4 = Formatted code differs from existing code (write-mode diff only) |
| 200 | +``` |
0 commit comments