I see, that would work. Although it would forbid people to use pub to not have to write the long pub(crate) or pub(super) they would otherwise have to write. I’d be a big user of #![internal], I’d add it to all the modules that right now I don’t declare pub, just to make sure they are not exposed, and to make it sure for readers (including future self) that the crate is not exposed. Inside of them, I’d have to write the lengthy pub(crate) for every single item, I’d be literally punished to not expose something in the public API. I think there should be sugar for pub(crate), like cub or something else which is very short (around three characters). That could solve it, and at least make the new system not hugely more inconvenient for me and most other users to use.
To provide you with a personal story, my reasons to split up crates never were around compile times. I have a crate (lewton) whose 90% of uses is together with another crate (ogg) to decode ogg/vorbis files, still I have them separate in order for other things that may be included in the ogg container. I in fact wrote a crate to read ogg metadata from it, which is even used in servo, while lewton, which came from the same project as ogg, is not used (yet xD). And I’m considering splitting up lewton even more, e.g. to put the IMDCT decoder into a separate crate. This would help me writing an opus decoder.
There is this great feature to small crates that you can reuse the code everywhere and in multiple different places.
Another example, minetest. Its an open source minecraft clone written in C++. It has a map like minecraft, and it stores that map in different kinds of databases. Now there are big servers with big maps, and some of them want to provide a top down map to their users. For this use case, mapper tools were designed (some in python, but the most popular one atm is in C++) that get the map database as input and which output the finished map. They had to re-implement parsing of the data format, including the bindings to the database libraries, as well as the deserialisation of the actual chunks (minetest calls them mapblocks). If minetest had been a Rust project, you’d just simply could have put the map format and database interfacing into one crate and the rest of the game into other crates, and published it all on crates.io and the mappers simply could have used the crate and would have gotten the same code that minetest ran on. Of course, you can do this in C++ as well, but again, all the issues with crates downloading.
So I don’t think crates will get much bigger, and I don’t hope it.
I don’t see though how crates getting bigger will mean that you want to expose some module to the entire crate (or world) and not facade it. If it will affect motivations to facade, it will be the reverse.
I think I’m not a big fan of hoisting. I certainly wouldn’t want it to happen. It would make renaming a module very hard and require you to repeat the module name multiple times. And if you really want to find out where an item is reexported, just rg for the name of the item, or change the name and see where it errors. Of course neither is watertight though due to wildcard reexports. Also, looking at workflows, right now you can look at rustdoc output to get a list of items where you can copy each name into a (pub) use list, they are all nicely condensed, if you want to hoist a couple of items, you’d have to scroll through their implementations to set them.