Are module declarations allowed inside functions?

Consider the following code.

fn foo() {
    mod m;
}

fn bar() {
    mod m;
}

It compiles if you have m.rs, but it works strange: the m module is essentially duplicated.

Is this intentional that non inline modules are allowed inside functions?

Well, you're allowed to put items into functions, and there's no real reason why modules should be specifically excluded. Also, "non inline" modules are just syntax sugar for "inline" modules; the compiler doesn't distinguish between the two AFAIK. It does the same thing as if you'd copy+pasted the contents of m.rs twice.

So sure, why not.

Hah, that's strange and most likely accidental. I filed #29765 about making an explicit decision.

A similar strange piece of code is

mod foo;

#[path = "foo.rs"]
mod bar;

Oh, you haven't seen anything until you've tried:

#[path = "/dev/stdin"]
mod foo;

fn main() {
    foo::hello();
}
$ rustc stdin.rs
pub fn hello() {
    println!("Hi!");
}
$ ./stdin
Hi!
3 Likes

Windows also has this cool feature:

mod Foo;
mod foo;
fn main() {
    foo::hello();
    Foo::hello();
}
// foo.rs
fn hello() { println!("hello"); }
2 Likes

Oh, that's fun too, but it one isn't quite so strange IMO: having the attribute is explicitly opting-in to importing the same file twice. (Maybe there could be a lint against it? Although, I imagine most cases where one does it accidentally will result in a compilation error earlier.)

At least you'll get a warning about snake case names for Foo. But yes, case-insensitivity is ugly. If your file was called Foo.rs and you wrote mod foo; then it would only work on Windows.