Ask questionsmake `pub type foo = bar` and `pub use bar as foo` interchangable in next edition

Right now renaming a type and re-exporting it via a type alias can be a breaking change whereas re exporting it under the new name is not a breaking change. As far as I know the only difference between the two is how they interact with tuple-struct constructors:

pub struct MyStruct(u32);

pub use self::MyStruct as PubUse;
pub type PubType = MyStruct;

fn main() {
    let _ = PubUse(5); // OK
    // let _ = PubType(5); // Doesn't work

This happens because tuple struct constructors are just free functions with the same ident as the type they're constructing. use statements bring in items from all 3 namespaces that match the given ident but type items only alias the type itself.

This can be fixed by making it so that the compiler generates a constructor for the alias when it sees that the RHS of the type alias is a tuple-struct. This would be a breaking change because users can already define a free function with the same name as the type alias, which people do currently do to add the necessary constructor to work around this very issue.

To resolve this @joshtriplett has recommended the following steps:

  • [ ] implement the alias constructor fix as a feature gated PR
  • [ ] add an allow by default lint to detect free functions that would conflict with the newly generated constructors
    • [ ] do a crater run with the above lint set to deny to measure the impact of this change
    • [ ] add this lint to the future-compatibility lint group

Answer questions scottmcm

It it possible there's anyone relying on this for the opposite, exporting a type while intentionally not exporting the constructor? (And not providing a function of the same name.)

I guess it doesn't hide PubType { 0: 5 }, though...


Related questions

Spurious NaNs produced by trig functions with valid inputs on Windows GNU toolchains hot 3
using 'cargo install xsv' on windows 10 triggers rustc internal error hot 2
under latest MinGW, cannot link with C code using stdout hot 2
Archive all nightlies hot 2
chain() make collect very slow hot 1
if/while Some(n) = &mut foo sugar will leak a temporary mutable borrow to current scope in particular situation hot 1
build an empty project failed (undefined reference to `__onexitbegin') hot 1
Invalid collision with TryFrom implementation? hot 1
Crater runs for Rust 1.38.0 hot 1
Spurious NaNs produced by trig functions with valid inputs on Windows GNU toolchains hot 1
Building LLVM with Clang fails hot 1
Internal compiler error: can't buffer lints after HIR lowering hot 1
E0373 help suggests `move async` but the correct syntax is `async move` hot 1
Tracking issue for `Option::contains` and `Result::contains` hot 1
async fn + rustfmt don't "just work" inside of RLS hot 1
Github User Rank List