Curly brace support for mod

To keep in line with use statements, would a multi-line pub mod be a good idea?

pub mod {
   bread,
   lettuce,
   bacon, 
   tomato, 
};
4 Likes

I've also thought that it's a slight inconsistency that you can group uses but not mods.

3 Likes

mod { ... } looks like an anonymous inline module to me.

15 Likes

Maybe this is better:

// sandwich.rs
mod self::{
   bread,
   lettuce,
   bacon, 
   tomato, 
};

Or:

mod [ a, b, c]; 

Agreed. But in theory we could do this:

pub mod mod1, mod2, mod3, mod4;
14 Likes

I thought kornel's post was a good observation:

3 Likes

Fair distinction.

Honestly, if we touch this area, what I'd much rather do is eliminate the need for mod statements entirely. :slight_smile:

6 Likes

eliminate the need for mod statements entirely

Still implacably opposed to this! ^_^

7 Likes

I like this so much, I am new around here, how so?

Still happy for it to have an opt-out for projects that need it (e.g. projects with .rs files sitting around that they don't want to use, or projects making heavy use of path).

(And I wouldn't be surprised if initially that starts out as an opt-in; making it the default would likely require an edition.)

2 Likes

Automatic module discovery, so after creating mymod/submod.rs, you don't have to add mod submod; anywhere.

1 Like

Personally, I think what I I'd most like to see is some way to smooth the "look, I'm only making separate files for organization purposes, not because I wanted them exposed in different namespaces" problem.

Imagine, say, a folder mod foo; that pulled in all the .rs files from that folder, treated each as a hygenic private namespace, and used all the pub things from each into the foo namespace. (And maybe a folder mod foo in {file1, file2}; if you want to list exactly the files in source.)

So you can just have, say, pub folder mod iter; that automatically pulls in iter/map.rs and iter/enumerate.rs and ... so you have iter::Map and iter::Enumerate and such, rather than needing multiple mods and multiple uses and such. Notably, no need for iter.rs or iter/mod.rs either!

And thus you'd not run into the "I have to name so many modules that it's annoying to have them on separate lines" problem at all.

6 Likes

How do I specify the visibility in this scheme? Do I for example put a single pub mod; in the submodule?

1 Like

Important to remember is that r-a has an assist for creating a new file when a mod statement is selected where the file hasn't been created. So adding a module this way is faster that creating a new file.

That could be done by pub use mod; or similar, if one desires to export the submodule or introduce a module-level attribute like #![public].

This could be opt in. Usually it works like nowadays, but we could specify a mod to recursively add its children. And if the top level recursively adds itself, then you don't need to add mod whatsoever.

Something like mod rec something; if I just want to have something pulls recursively, or mod rec crate; at the top level to add everything.

I don't think an attribute works as pub(in …) is also possible. Not to mention cfg() to conditionally export a module. A full statement feels better to me.

I'll note again that git will create .rs files during a merge conflict resolution, so "projects with .rs files sitting around" only really involves projects that never have manual merge conflict resolutions. I would not be a fan of not supporting building while resolving conflicts and instead have to finish with git mergetool before being "allowed" to touch cargo in any meaningful way (potentially including suppressing rust-analyzer and/or any other LSP-like support in the editor).

4 Likes

I think that the best immediate course of action would be to implement that logic as a lint first, one for detecting stray .rs files that are not being modded anywhere, and one for trying to access a module that hasn't being modded but where the file exists. The logic is the same that would be needed for the actual implementation, but for now (and for <=ed2024) we can make that a warning to help newcomers.

7 Likes

I think automatic module discovery could work, but it should be opt-in initially. For example, we could add #![auto_mod] to crate/module to tell the compiler to mount all .rs files as modules. By default the mounted modules would be private and to re-export a module you would have to use pub use mod_name;.

Then in the next edition we could make it the default and add something like #![no_auto_mod] to return the old behavior for projects which require finer-grained control over mounting of modules.

3 Likes

@Josh: Agreed. But in theory we could do this:

pub mod mod1, mod2, mod3, mod4;

I still like this and it is a separate discussion from the auto-mod one.