Skip to content

Non-inline module is allowed inside other items #29765

@huonw

Description

@huonw
Member

These are all legal, and somewhat strange, since they're not really following the file-system analogy that modules are typically explained with. I expect this behaviour is just whatever happens to fall out of the current implementation strategy, so let's make a more explicit decision one way or another.

static X: u8 = { mod foo; 0 };
fn foo() {
    mod foo;
}
fn main() {
    mod foo;
}

As one might expect, each of these is a distinct instance of foo (which can be verified by placing log_syntax(hello) in foo.rs: the compiler will greet you 3 times).

Noticed in https://users.rust-lang.org/t/are-module-declarations-allowed-inside-functions/3583 .

Activity

added
A-parserArea: The lexing & parsing of Rust source code to an AST
T-langRelevant to the language team
on Nov 11, 2015
nikomatsakis

nikomatsakis commented on Nov 12, 2015

@nikomatsakis
Contributor

This seems weird to me. I think the intention is that the out-of-line syntax (mod foo;) should only work at the top-level.

aturon

aturon commented on Nov 12, 2015

@aturon
Member

I'd vote for allowing non-inline modules only at the top-level, to retain a clear mapping to the file system.

nikomatsakis

nikomatsakis commented on Nov 12, 2015

@nikomatsakis
Contributor

(Or nested inside modules.)

nikomatsakis

nikomatsakis commented on Nov 12, 2015

@nikomatsakis
Contributor

triage: P-medium

Backwards incompatible, but ... kind of a curiousity.

matklad

matklad commented on Nov 14, 2015

@matklad
Member

Found one more mod aliasing scenario. It involves several files, and is semi officially allowed by the reference.

The layout

src/
├─ bar.rs
├─ foo.rs
├─ inner
│  └── copy.rs
└─ main.rs

The files

//main.rs
mod foo;
mod bar;
fn main() {}

//foo.rs
mod inner { mod copy; }

//bar.rs
mod inner { mod copy; }

The copy module will be aliased. The problem is that although foo and bar are not directory owners, their inner modules are.

added a commit that references this issue on Nov 14, 2015

2 remaining items

matklad

matklad commented on Nov 16, 2015

@matklad
Member

What happens if you don't have the mod inner, but just place mod copy in foo?

It is forbidden because foo is not a directory owner.

matklad

matklad commented on Nov 16, 2015

@matklad
Member

Just in case here is a repository with the example: https://github.com/matklad/nested-mod

I tend to believe it is fine to have aliasing if you write the #[path] yourself (you asked for it...)

I don't see a reason to allow user to shoot himself in the leg. What if you accidentelly have identical path attributes (copy paste problem)?

My main concern though is that non injective file to module mapping may complicate the implementation of some rust tools. Here is another hypothetical example of this. Suppose you implement incremental compilation for rustc. You will need a mapping from files to modules. If mod aliasing is alowed, then you will need a multimapping. So you end up with more complex code which is used only in a tiny fraction of projects and because of this probably contains some bugs.

nikomatsakis

nikomatsakis commented on Dec 1, 2015

@nikomatsakis
Contributor

@matklad

It is forbidden because foo is not a directory owner.

Ah, I see. So it seems to me that the problem is that mod inner { mod copy; } should not be allowed in contexts where mod copy; would be illegal. In other words, an inline module should only be considered a "directory owner" if it is located within a directory owner.

I don't see a reason to allow user to shoot himself in the leg. What if you accidentelly have identical path attributes (copy paste problem)?

A compromise might be Yet Another Lint Warning. ;) I agree with you about preventing people from shooting themselves in the leg, but I guess I think people don't use #[path] lightly or frequently, so this seems unlikely to be a major source of confusion.

matklad

matklad commented on Dec 1, 2015

@matklad
Member

so this seems unlikely to be a major source of confusion.

I totally agree that this curiosity is insignificant for users. But I still worry more about the implementation side of the issue, and a lint warning does not help here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-parserArea: The lexing & parsing of Rust source code to an ASTP-mediumMedium priorityT-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Participants

      @nikomatsakis@aturon@huonw@matklad@rust-highfive

      Issue actions

        Non-inline module is allowed inside other items · Issue #29765 · rust-lang/rust