-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Structure instantiation doesn't handle structure typedefs #4508
Comments
I think this is behaving as intended. |
non-critical for 0.6, de-milestoning |
It's somewhat misleading if you can only use the alias in certain places. Need a verdict on this. Nominating for Maturity 3. |
I don't think it's misleading. You can use an alias declared by |
I don't think that's obvious. Haskell works that way, because in Haskell type and data constructors are declared separately. But for Rust's structs a single declared name is used for both. I don't think it's unreasonable to expect that if you introduce an alias for that one name, you can use it in the same places as the original name, IOW that the constructor has the same name as the type. That's what C++ does. E.g. this is valid:
I think the logical thing would be for it to work the Haskell way for enums (where there are separate names) and the C++ way for structs (where there's a single name), but at the very least I don't think the opposite is self-evident. |
@pcwalton is under the impression that this should be fixed. Reopening for clarification. |
Without the possibility to instantiate struct with them, the aliases would be somewhat useless. Combined with parameters, like for example in:
The use of the alias would allow to not having to carry around the type of the parameter everywhere. The client code does not even have to have knowledge of the aliased struct. But if one has to use the original name to instantiate it, the purpose of aliasing is defeated. |
The relevant code sits under the ExprStruct arm of resolve_pattern in resolve.rs. Assuming that DefTy is a |
You probably meant to link to this code |
The code being matched is a Removing the guard leads to |
This presents a backwards compatibility hazard. The meaning of the following program will change when this bug is fixed: #[deriving(Show)]
struct Foo(int);
fn Bar(a: int) -> int { a }
type Bar = Foo;
fn main() {
println!("{}", Bar(1));
} |
(Nominating) |
Actually, it would probably be rejected. |
Another example that doesn't involve defining the same name twice in a single namespace: use foo::Bar;
struct Foo(int);
type Bar = Foo;
fn main() { Bar(1); } |
Assigning P-backcompat-lang, 1.0 milestone. |
I don't think this will ever work for tuple structs. If typedefs could inject names into the value namespace, then resolve would become quite difficult. I don't think this was P-backcompat-lang, but I just finished the patch so let's get it in anyway. |
structure patterns. Closes rust-lang#4508.
@pcwalton Why is the tuple struct case different from the structural struct one? |
Tuple struct constructors are first-class functions, like variant constructors. So the declaration of a tuple struct injects a value into the value namespace. The variable in an expression like |
Nominating for not P-backcompat-lang per above, although I think this will be closed before the next triage meeting. |
This, and the thing where you can't call static methods of a type through a type alias, is going to keep biting people coming from C++, and probably places like Ruby as well. :( |
@huonw Oh, well, if that includes the tuple/unit-like struct case I'll happily take my complaining to the issue for calling static methods. ;) |
@pcwalton Thanks for explaining. Am I right to suspect that would no longer hold if structural enum variants enter the picture? |
This is from a build of Rust from around Christmas, so it would bear retesting on master.
The text was updated successfully, but these errors were encountered: