Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify public type aliasing behavior #26953

Closed
jethrogb opened this Issue Jul 10, 2015 · 12 comments

Comments

Projects
None yet
5 participants
@jethrogb
Copy link
Contributor

jethrogb commented Jul 10, 2015

Compile:

// Example #1
mod mod_a {
    mod sub_a {
        pub struct InnerA;
    }
    pub type A = sub_a::InnerA;
}

use mod_a::A;

fn main() {
    let a=A;
}
error[E0425]: unresolved name `A`
  --> test.rs:12:11
   |
12 |     let a=A;
   |           ^ unresolved name

Yet A is quite obviously imported. The same error appears in a different place when compiling:

// Example #2
mod mod_a {
    mod sub_a {
        pub struct InnerA;
    }
    pub type A = sub_a::InnerA;

    pub fn make_a() -> A {
        A
    }
}

use mod_a::{A,make_a};

fn main() {
    let a: A=make_a();
}
error[E0425]: unresolved name `A`
 --> test.rs:9:9
  |
9 |         A
  |         ^ unresolved name

This compiles:

// Example #3
mod mod_a {
    mod sub_a {
        pub struct InnerA;
    }
    pub type A = sub_a::InnerA;

    pub fn make_a() -> A {
        sub_a::InnerA
    }
}

use mod_a::{A,make_a};

fn main() {
    let a: A=make_a();
}

But wait, I thought in example no. 1, we couldn't resolve A from main()?

Using pub use instead makes example no. 1 work:

// Example #4
mod mod_a {
    mod sub_a {
        pub struct InnerA;
    }
    pub use self::sub_a::InnerA as A;
}

use mod_a::A;

fn main() {
    let a=A;
}

For completeness, here is the tuple-struct version:

// Example #5
mod mod_a {
    mod sub_a {
        pub struct InnerA(pub u8);
    }
    pub type A = sub_a::InnerA;
}

use mod_a::A;

fn main() {
    let a=A(0);
}
error[E0425]: unresolved name `A`
  --> test.rs:12:11
   |
12 |     let a=A(0);
   |           ^ unresolved name

And the regular struct version (compiles without errors):

// Example #6
mod mod_a {
    mod sub_a {
        pub struct InnerA {pub i:u8}
    }
    pub type A = sub_a::InnerA;
}

use mod_a::A;

fn main() {
    let a=A{i:0};
}

It seems like structure expressionsconstructors are handled differently from other uses of types with regards to aliases. Also, the phrase pub type does not appear in the Rust Book or the Rust Reference.

I propose the following:

  • Improve the error message in cases 1, 2 and 5 above
  • Improve documentation on public type aliases
  • Improve documentation on structure expressionsconstructors involving type aliases
@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Jul 11, 2015

These (A) are not structure expressions - they are just the (nullary) tuple-struct constructor. Every tuple-struct declaration declares both the struct and the struct's constructor, which have the same name. The struct constructor is pretty much an ordinary constant/function (with type A if the struct is nullary, or type fn(Foo,Bar)->A if the struct contains fields). type aliases only the type, not the constructor.

In fact, real structure expressions (A { foo: bar }) do work with type-aliases - these aren't just calls to a constructor.

@jethrogb

This comment has been minimized.

Copy link
Contributor Author

jethrogb commented Jul 11, 2015

What do I know, I just go by what the reference says.

@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Jul 11, 2015

Then the reference is wrong – TuplePoint(10.0, 20.0) is just a call expression with the function being the path TuplePoint and the arguments being 10.0 and 20.0 - there is no such thing as a tuple structure expression.

@steveklabnik

This comment has been minimized.

Copy link
Member

steveklabnik commented Jul 16, 2015

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jul 18, 2015

I see why the behavior is confusing, but I see no bug here. The missing ingredient is that Rust has two namespaces, a type and a value namespace. Tuple struct inhabit both, as @arielb1 is saying. When you declare a 'pub use', you are reporting both namespaces simultaneously. When you declare a type alias, though, you are creating a name just in the type namespace, which is why your attempts to use 'A' as a value failed.

Niko

-------- Original message --------
From: Steve Klabnik notifications@github.com
Date:07/16/2015 15:30 (GMT-05:00)
To: rust-lang/rust rust@noreply.github.com
Cc: Niko Matsakis niko@alum.mit.edu
Subject: Re: [rust] Clarify public type aliasing behavior (#26953)
/cc @rust-lang/lang


Reply to this email directly or view it on GitHub.

@jethrogb

This comment has been minimized.

Copy link
Contributor Author

jethrogb commented Oct 1, 2015

So this is mostly an error message/documentation bug then.

@steveklabnik

This comment has been minimized.

Copy link
Member

steveklabnik commented Mar 8, 2017

Tagging as docs/diagnostics, in line with the last comment. I'll figure out which of the two it should be at some point, just a quick triage for now.

@jethrogb

This comment has been minimized.

Copy link
Contributor Author

jethrogb commented Mar 8, 2017

I re-ran all the examples with the latest compiler and updated the error messages (which didn't meaningfully change)

@steveklabnik steveklabnik added T-doc and removed T-compiler labels Mar 9, 2017

@steveklabnik steveklabnik removed the A-docs label Mar 24, 2017

@steveklabnik

This comment has been minimized.

Copy link
Member

steveklabnik commented May 24, 2017

tagging as p-medium for now; we need to tease apart all of the different stuff that's going on here today

@petrochenkov

This comment has been minimized.

Copy link
Contributor

petrochenkov commented May 24, 2017

Current error:

// Example #1
rustc 1.19.0-nightly (5b13bff52 2017-05-23)
error[E0423]: expected value, found type alias `A`
  --> <anon>:12:11
   |
12 |     let a=A;
   |           ^ did you mean `A { /* fields */ }`?

// Example #2
rustc 1.19.0-nightly (5b13bff52 2017-05-23)
error[E0423]: expected value, found type alias `A`
 --> <anon>:8:9
  |
8 |         A
  |         ^ did you mean `A { /* fields */ }`?

// Example #5
rustc 1.19.0-nightly (5b13bff52 2017-05-23)
error[E0423]: expected function, found type alias `A`
  --> <anon>:12:11
   |
12 |     let a=A(0);
   |           ^ did you mean `A { /* fields */ }`?

So, diagnostics look good enough.
I remember closing a couple of issues that were duplicates of this one.
Maybe something needs to be done on the doc side, but I'll left this to @steveklabnik to decide.

@steveklabnik

This comment has been minimized.

Copy link
Member

steveklabnik commented May 26, 2017

I'm going to close; if the diagnostics are good, then that's good enough for me. Thanks!

@jethrogb

This comment has been minimized.

Copy link
Contributor Author

jethrogb commented Jul 7, 2017

@steveklabnik is the type/value namespace separation discussed in the book?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.