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

Cannot call static methods on type aliases, "module wasn't actually a module!" #11047

Closed
bstrie opened this issue Dec 18, 2013 · 18 comments
Closed
Labels
A-resolve Area: Name resolution E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. P-medium Medium priority

Comments

@bstrie
Copy link
Contributor

bstrie commented Dec 18, 2013

Compile this:

pub mod foo {
    pub mod bar {
        pub mod baz {
            struct Qux;

            impl Qux {
                pub fn new() {}
            }
        }
    }
}

fn main() {
    type Ham = foo::bar::baz::Qux;
    let Foo = foo::bar::baz::Qux::new();  // works fine
    let Bar = Ham::new();  // oops!
}
$ rustc ty.rs
!!! (resolving module in lexical scope) module wasn't actually a module!
ty.rs:16:14: 16:22 error: unresolved name
ty.rs:16     let Bar = Ham::new();
                       ^~~~~~~~
ty.rs:16:14: 16:22 error: use of undeclared module `Ham`
ty.rs:16     let Bar = Ham::new();
                       ^~~~~~~~
!!! (resolving module in lexical scope) module wasn't actually a module!
ty.rs:16:14: 16:22 error: unresolved name `Ham::new`.
ty.rs:16     let Bar = Ham::new();
                       ^~~~~~~~
error: aborting due to 3 previous errors
task 'rustc' failed at 'explicit failure', /root/catacombs/scrap/rust/src/libsyntax/diagnostic.rs:102
task '<main>' failed at 'explicit failure', /root/catacombs/scrap/rust/src/librustc/lib.rs:392

I can't imagine that this is intentional, as it greatly limits the utility of type aliases.

@emberian
Copy link
Member

cc @pcwalton @alexcrichton

@jdm
Copy link
Contributor

jdm commented Dec 18, 2013

#4508 seems related.

@alexcrichton
Copy link
Member

The problem here is calling a static method through a typedef. The error messages getting printed is another unrelated bug (but easy to fix). To the best of my knowledge, this has never worked, and I was under the impression that was intentional.

@pcwalton, is it intended to be able to call methods through a typedef?

@nmsmith
Copy link

nmsmith commented Jan 17, 2014

I've noticed this issue as well. It's definitely inconvenient that this doesn't work. Also, it took me a while to realise the error message was complete rubbish.

@nmsmith
Copy link

nmsmith commented Jan 17, 2014

Exhibit A:

use std::sync::mpmc_bounded_queue;

mod work;

void main() {
    let work_queue = mpmc_bounded_queue::Queue::<work::Work>::with_capacity(8);
}

This badly needs a typedef - Queue is not descriptive enough, but mpmc_bounded_queue::Queue is far too verbose!

@zslayton
Copy link
Contributor

zslayton commented May 4, 2014

cc me

@huonw
Copy link
Member

huonw commented May 24, 2014

This now prints sane error messages:

11047.rs:16:15: 16:23 error: unresolved name
11047.rs:16     let Bar = Ham::new();  // oops!
                          ^~~~~~~~
11047.rs:16:15: 16:23 error: use of undeclared module `Ham`
11047.rs:16     let Bar = Ham::new();  // oops!
                          ^~~~~~~~
11047.rs:16:15: 16:23 error: unresolved name `Ham::new`.
11047.rs:16     let Bar = Ham::new();  // oops!
                          ^~~~~~~~
error: aborting due to 3 previous errors

@matthieu-m
Copy link
Contributor

I accidentally triggered this and indeed the diagnosis is better.

Unfortunately, it also means that aliases are second-class citizens and seriously hampers their usefulness...

@ben0x539
Copy link
Contributor

@huonw That doesn't really seem like a reasonable error message to me. Coming from other languages where there's something like functions in a type, that types sort of incidentally also create a module of the same name into which subsequent impls then inject methods is pretty unintuitive, that in contrast type aliases then don't do that, even more so.

(Also surprised that #3884 wasn't linked in here yet.)

@huonw
Copy link
Member

huonw commented May 29, 2014

@ben0x539 I meant to say saner error messages, since it no longer has the "lexical" error junk.

@gavinb
Copy link
Contributor

gavinb commented Jan 17, 2015

I keep bumping into #19130 and this issue, and keep referring to the docs assuming it's a mistake.

It would seem that one of the most common reasons to use a type alias would be for generics, however due to this issue, the type feature is of rather limited use.

The official docs on type alias only show an example of a tuple type alias, and no mention is made of traits or generic types. The Rust by Example docs on type alias only alias ordinal types, but it does mention aliasing generic types in passing at the end.

It seems very natural to want to write:

type StringVec = Vec<String>;
// ...
let mut sv = StringVec::new();

but you get the rather ambiguous error:

error: failed to resolve. Use of undeclared type or module `StringVec`

when the type declaration is right there, and then have to write this instead, which rather defeats the purpose:

type StringVec = Vec<String>;
// ...
let mut sv: StringVec = Vec::new();

Anyway, I guess this is a big +1 for this issue.

@vadimcn
Copy link
Contributor

vadimcn commented Feb 18, 2015

@pcwalton, @alexcrichton, @pnkfelix : Was this bug ever triaged? I think this should be considered for 1.0 nomination.

@alexcrichton
Copy link
Member

I'll renominate to make sure we see this. My personal recommendation though is that if the only bug is generating more errors than we should then this isn't a 1.0 issue.

@pnkfelix
Copy link
Member

This is a nice-to-have, not a 1.0 blocker. Marking as P-high.

@pnkfelix pnkfelix added P-medium Medium priority and removed I-nominated labels Feb 19, 2015
@LukasKalbertodt
Copy link
Member

I would agree that type aliases are pretty useless when you can't use them as first class types. If I can do Foo::stuff() I want to be able to do type Bar = Foo; Bar::stuff().
I think it's important.

@matthieu-m
Copy link
Contributor

@LukasKalbertodt I believe we all agree on this; however 1.0 does not mean "finished" but "backward compatible" and calling static methods on type aliases is not necessary for backward compatibility since all programs without will continue to compile once it is implemented (the converse would not be true). Therefore, while I personally value this improvement, I understand that it is not necessary for 1.0.

@arielb1 arielb1 added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Sep 27, 2015
@arielb1
Copy link
Contributor

arielb1 commented Sep 27, 2015

This seems to work on 1.3+.

@gavinb
Copy link
Contributor

gavinb commented Sep 28, 2015

Verified this works on 1.3. I created a test for this issue. https://github.com/rust-lang/rust/pull/28703/files

bors added a commit that referenced this issue Sep 28, 2015
Tests invoking a static method using a type alias.

Closes #11047
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-resolve Area: Name resolution E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. P-medium Medium priority
Projects
None yet
Development

No branches or pull requests