Skip to content

Commit a78bd0b

Browse files
committed
Merge remote-tracking branch 'cm/sane-module-file-system-hierarchy'
2 parents 62bfca4 + 6158a86 commit a78bd0b

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
- Start Date: 2014-05-02
2+
- RFC PR #: (leave this empty)
3+
- Rust Issue #: (leave this empty)
4+
5+
# Summary
6+
7+
The rules about the places `mod foo;` can be used are tightened to only permit
8+
its use in a crate root and in `mod.rs` files, to ensure a more sane
9+
correspondence between module structure and file system hierarchy. Most
10+
notably, this prevents a common newbie error where a module is loaded multiple
11+
times, leading to surprising incompatibility between them. This proposal does
12+
not take away one's ability to shoot oneself in the foot should one really
13+
desire to; it just removes almost all of the rope, leaving only mixed
14+
metaphors.
15+
16+
# Motivation
17+
18+
It is a common newbie mistake to write things like this:
19+
20+
`lib.rs`:
21+
22+
```rust
23+
mod foo;
24+
pub mod bar;
25+
```
26+
27+
`foo.rs`:
28+
29+
```rust
30+
mod baz;
31+
32+
pub fn foo(_baz: baz::Baz) { }
33+
```
34+
35+
`bar.rs`:
36+
37+
```rust
38+
mod baz;
39+
use foo::foo;
40+
41+
pub fn bar(baz: baz::Baz) {
42+
foo(baz)
43+
}
44+
```
45+
46+
`baz.rs`:
47+
48+
```rust
49+
pub struct Baz;
50+
```
51+
52+
This fails to compile because `foo::foo()` wants a `foo::baz::Baz`, while
53+
`bar::bar()` is giving it a `bar::baz::Baz`.
54+
55+
Such a situation, importing one file multiple times, is exceedingly rarely what
56+
the user actually wanted to do, but the present design allows it to occur
57+
without warning the user. The alterations contained herein ensure that there is
58+
no situation where such double loading can occur without deliberate intent via
59+
`#[path = "….rs"]`.
60+
61+
# Drawbacks
62+
63+
None known.
64+
65+
# Detailed design
66+
67+
When a `mod foo;` statement is used, the compiler attempts to find a suitable
68+
file. At present, it just blindly seeks for `foo.rs` or `foo/mod.rs` (relative
69+
to the file under parsing).
70+
71+
The new behaviour will only permit `mod foo;` if at least one of the following
72+
conditions hold:
73+
74+
- The file under parsing is the crate root, or
75+
76+
- The file under parsing is a `mod.rs`, or
77+
78+
- `#[path]` is specified, e.g. `#[path = "foo.rs"] mod foo;`.
79+
80+
In layman's terms, the file under parsing must "own" the directory, so to
81+
speak.
82+
83+
# Alternatives
84+
85+
The rationale is covered in the summary. This is the simplest repair to the
86+
current lack of structure; all alternatives would be more complex and invasive.
87+
88+
One non-invasive alternative is a lint which would detect double loads. This is
89+
less desirable than the solution discussed in this RFC as it doesn't fix the
90+
underlying problem which can, fortunately, be fairly easily fixed.
91+
92+
# Unresolved questions
93+
94+
None.

0 commit comments

Comments
 (0)