You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/0000-hyphens-considered-harmful.md
+31-64Lines changed: 31 additions & 64 deletions
Original file line number
Diff line number
Diff line change
@@ -5,110 +5,77 @@
5
5
6
6
# Summary
7
7
8
-
Disallow hyphens in package and crate names. Propose a clear transition path for existing packages.
8
+
Disallow hyphens in Rust crate names, but continue allowing them in Cargo packages.
9
9
10
10
# Motivation
11
11
12
-
Currently, Cargo packages and Rust crates both allow hyphens in their names. This is not good, for two reasons:
12
+
This RFC aims to reconcile two conflicting points of view.
13
13
14
-
1.**Usability**: Since hyphens are not allowed in identifiers, anyone who uses such a crate must rename it on import:
14
+
First: hyphens in crate names are awkward to use, and inconsistent with the rest of the language. Anyone who uses such a crate must rename it on import:
However, asofJanuary2015thereare589packageswithhyphensoncrates.io.Itisunlikelythatsimplyremovinghyphensfromthesyntaxwillwork, givenallthecodethatdependsonthem.Inparticular, weneedaplanthat:
16
+
```rust
17
+
externcrate "rustc-serialize" as rustc_serialize;
18
+
```
27
19
28
-
*Iseasytoimplementandunderstand;
20
+
An earlier version of this RFC aimed to solve this issue by removing hyphens entirely.
29
21
30
-
*Accountsfortheexistingpackagesoncrates.io; and
22
+
However, there is a large amount of precedent for keeping `-` in package names. Systems as varied as GitHub, npm, RubyGems and Debian all have an established convention of using hyphens. Disallowing them would go against this precedent, causing friction with the wider community.
31
23
32
-
*Givesasmuchtimeaspossibleforuserstofixtheircode.
24
+
Fortunately, Cargo presents us with a solution. It already separates the concepts of *package name* (used by Cargo and crates.io) and *crate name* (used by rustc and `extern crate`). We can disallow hyphens in the crate name only, while still accepting them in the outer package. This solves the usability problem, while keeping with the broader convention.
In **Cargo**, continue allowing hyphens in package names. But unless the `Cargo.toml` says otherwise, the inner crate name will have all hyphens replaced with underscores.
For example, if I had a package named `apple-fritter`, its crate will be named `apple_fritter` instead.
47
33
48
-
3.In**rustc**:
34
+
In **rustc**, enforce that all crate names are valid identifiers. With the changes in Cargo, existing hyphenated packages should continue to build unchanged.
49
35
50
-
+AswithCargo, continueallowinghyphensin `externcrate`, but rewrite them to underscores in the parser. Warn the user when this happens.
36
+
## Identify `-` and `_` on crates.io
51
37
52
-
+ Do *not* allow hyphens in other contexts, such as the `#[crate_name]` attribute or `--crate-name` and `--extern` options.
38
+
Right now, crates.io compares package names case-insensitively. This means, for example, you cannot upload a new package named `RUSTC-SERIALIZE` because `rustc-serialize` already exists.
53
39
54
-
> Rationale: These options are usually provided by external tools, which would breakin strange ways if rustc chooses a different name.
40
+
Under this proposal, we will extend this logic to identify `-` and `_` as well.
55
41
56
-
4. Announce the change on the users forum and /r/rust. Tell users to update to the latest Cargo and rustc, and to begin transitioning their packages to the new system. Party.
42
+
## Remove the quotes from `extern crate`
57
43
58
-
5. Some time between the beta and 1.0 release, remove support for hyphens from Cargo and rustc.
44
+
Change the syntax of `extern crate` so that the crate name is no longer in quotes (e.g. `extern crate photo_finish as photo;`). This is viable now that all crate names are valid identifiers.
59
45
60
-
## C dependency (`*-sys`) packages
61
-
62
-
[RFC 403] introduced a `*-sys` convention for wrappers around C libraries. Under this proposal, we will use `*_sys` instead.
To ease the transition, keep the old `extern crate` syntax around, transparently mapping any hyphens to underscores. For example, `extern crate "silver-spoon" as spoon;` will be desugared to `extern crate silver_spoon as spoon;`. This syntax will be deprecated, and removed before 1.0.
65
47
66
48
# Drawbacks
67
49
68
-
## Code churn
50
+
## Inconsistency between packages and crates
69
51
70
-
While most code should not break from these changes, there will be much churn as maintainers fix their packages. However, the work should not amount to more than a simple find/replace. Also, because old packages are migrated automatically, maintainers can delay fixing their code until they need to publish a new version.
52
+
This proposal makes package and crate names inconsistent: the former will accept hyphens while the latter will not.
71
53
72
-
## Loss of hyphens
54
+
However, this drawback may not be an issue in practice. As hinted in the motivation, most other platforms have different syntaxes for packages and crates/modules anyway. Since the package system is orthogonal to the language itself, there is no need for consistency between the two.
73
55
74
-
There are two advantages to keeping hyphens around:
56
+
## Inconsistency between `-` and `_`
75
57
76
-
* Aesthetics: Hyphens do look nicer than underscores.
58
+
Quoth @P1start:
77
59
78
-
* Namespacing: Hyphens are often used for pseudo-namespaces. For example in Python, the Django web framework has a wealth of addon packages, all prefixed with `django-`.
60
+
> ... it's also annoying to have to choose between `-` and `_` when choosing a crate name, and to remember which of `-` and `_` a particular crate uses.
79
61
80
-
The author believes the disadvantages of hyphens outweigh these benefits.
62
+
I believe, like other naming issues, this problem can be addressed by conventions.
81
63
82
64
# Alternatives
83
65
84
66
## Do nothing
85
67
86
68
As with any proposal, we can choose to do nothing. But given the reasons outlined above, the author believes it is important that we address the problem before the beta release.
87
69
88
-
## Disallow hyphens in crates, but allow them in packages
89
-
90
-
What we often call "crate name" is actually two separate concepts: the *package name*as seen by Cargo and crates.io, and the *crate name* used by rustc and `externcrate`. While the two names are usually equal, Cargo lets us set them separately.
91
-
92
-
For example, if we have a package named `lily-valley`, we can rename the inner crate to `lily_valley` as follows:
93
-
94
-
```toml
95
-
[package]
96
-
name = "lily-valley" # Package name
97
-
# ...
98
-
99
-
[lib]
100
-
name = "lily_valley" # Crate name
101
-
```
102
-
103
-
This will let us import the crateas `externcrate lily_valley` while keeping the hyphenated name in Cargo.
70
+
## Disallow hyphens in package names as well
104
71
105
-
But while this solution solves the usability problem, it still leaves the package and crate names inconsistent. Given the few use cases for hyphens, it is unclear whether this solution is better than just disallowing them altogether.
72
+
An earlier version of this RFC proposed to disallow hyphens in packages as well. The drawbacks of this idea are covered in the motivation.
106
73
107
74
## Make `extern crate` match fuzzily
108
75
109
-
Alternatively, we can have the compiler consider hyphens and underscores as equal while looking up a crate. In other words, the crate `flim-flam` would match both `externcrate flim_flam` and `externcrate "flim-flam" as flim_flam`. This will let us keep the hyphenated names, without having to rename them on import.
76
+
Alternatively, we can have the compiler consider hyphens and underscores as equal while looking up a crate. In other words, the crate `flim-flam` would match both `extern crate flim_flam` and `extern crate "flim-flam" as flim_flam`.
110
77
111
-
The drawback to this solution is complexity. We will need to add this special case to the compiler, guard against conflicting packages on crates.io, and explain this behavior to newcomers. That's too much work to support a marginal use case.
78
+
This involves much more magic than the original proposal, and it is not clear what advantages it has over it.
112
79
113
80
## Repurpose hyphens as namespace separators
114
81
@@ -131,7 +98,7 @@ mod hoity {
131
98
}
132
99
```
133
100
134
-
However, on prototyping this proposal, the author found it too complex and fraught with edge cases. Banning hyphens outright would be much easier to implement and understand.
101
+
However, on prototyping this proposal, the author found it too complex and fraught with edge cases. For these reasons the author chose not to push this solution.
0 commit comments