Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: enforce module directory structure more strictly #63

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions active/0000-sane-module-file-system-hierarchy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
- Start Date: 2014-05-02
- RFC PR #: (leave this empty)
- Rust Issue #: (leave this empty)

# Summary

The rules about the places `mod foo;` can be used are tightened to only permit

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you mean to say: the places where?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

English is funny like that. the places that X is equivalent to the places where X, and that can be elided. (Still clearer with it though)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh okay. It's the first time I see such pattern.

its use in a crate root and in `mod.rs` files, to ensure a more sane
correspondence between module structure and file system hierarchy. Most
notably, this prevents a common newbie error where a module is loaded multiple
times, leading to surprising incompatibility between them. This proposal does
not take away one's ability to shoot oneself in the foot should one really
desire to; it just removes almost all of the rope, leaving only mixed
metaphors.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahhahahahah :D


# Motivation

It is a common newbie mistake to write things like this:

`lib.rs`:

```rust
mod foo;
pub mod bar;
```

`foo.rs`:

```rust
mod baz;

pub fn foo(_baz: baz::Baz) { }
```

`bar.rs`:

```rust
mod baz;
use foo::foo;

pub fn bar(baz: baz::Baz) {
foo(baz)
}
```

`baz.rs`:

```rust
pub struct Baz;
```

This fails to compile because `foo::foo()` wants a `foo::baz::Baz`, while
`bar::bar()` is giving it a `bar::baz::Baz`.

Such a situation, importing one file multiple times, is exceedingly rarely what
the user actually wanted to do, but the present design allows it to occur
without warning the user. The alterations contained herein ensure that there is
no situation where such double loading can occur without deliberate intent via
`#[path = "….rs"]`.

# Drawbacks

None known.

# Detailed design

When a `mod foo;` statement is used, the compiler attempts to find a suitable
file. At present, it just blindly seeks for `foo.rs` or `foo/mod.rs` (relative
to the file under parsing).

The new behaviour will only permit `mod foo;` if at least one of the following
conditions hold:

- The file under parsing is the crate root, or

- The file under parsing is a `mod.rs`, or

- `#[path]` is specified, e.g. `#[path = "foo.rs"] mod foo;`.

In layman's terms, the file under parsing must "own" the directory, so to
speak.

# Alternatives

The rationale is covered in the summary. This is the simplest repair to the
current lack of structure; all alternatives would be more complex and invasive.

One non-invasive alternative is a lint which would detect double loads. This is
less desirable than the solution discussed in this RFC as it doesn't fix the
underlying problem which can, fortunately, be fairly easily fixed.

# Unresolved questions

None.