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

Tuple struct/variant patterns don't work with type aliases #31659

Closed
petrochenkov opened this issue Feb 14, 2016 · 5 comments
Closed

Tuple struct/variant patterns don't work with type aliases #31659

petrochenkov opened this issue Feb 14, 2016 · 5 comments
Labels
T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@petrochenkov
Copy link
Contributor

struct S(u8);
type Z = S;

fn main() {
    match S(80) {
        S(x) => {} // ok
    }
    match S(90) {
        Z(x) => {} // error: unresolved enum variant, struct or const `Z` [E0419]
    }
}

For some reason names of tuple struct/variant patterns are searched for in the value namespace and not in the type namespace.
This is strange, because S here is a name of the type, not constructor function, and S(x) is not a function call.
S and Z should probably be searched in the type namespace, like names of struct patterns S{..}.
Theoretically such change can break code, but only in highly contrived cases.

@jseyfried @nrc what do you think?

@jseyfried
Copy link
Contributor

I agree with the current behavior. The way I see it, tuple struct constructors live in the value namespace and these constructors can be used as functions or as patterns.

I think it would be confusing to have S in S(x) mean one thing as an expression and another thing as a pattern, which could happen if we split constructor functions and patterns into different namespaces; for example,

fn Some(x: i32) -> Option<i32> { Some(1) }

fn main() {
    let x = 0;
    match Some(x) {
        Some(x) => println!("{}", x), // This would print "1"
        _ => {}
    }
}

@nrc
Copy link
Member

nrc commented Feb 15, 2016

There is a philosophy in Rust that deconstruction by patterns matches construction. I think that supports the notion that the pattern is the constructor function 'in reverse' rather than the type.

Can we contrive an example with structs where the struct name is hidden in the type namespace but not the value namespace, and then what happens to the pattern? Does it still work? As long as we are consistent, then I think it is better to leave things as they are, rather than change the rules.

@jseyfried
Copy link
Contributor

Can we contrive an example with structs where the struct name is hidden in the type namespace but not the value namespace

Yeah, and the pattern still works:

mod foo {
    mod bar {
        pub struct Bar(pub i32);
    }
    pub use self::bar::Bar;
}

use foo::*;
struct Bar { u: () }

fn main() {
    match Bar(0) {
        Bar(x) => println!("{}", x), // prints "0"
    }
}

@nodakai
Copy link
Contributor

nodakai commented Feb 16, 2016

Probably related to #26264

@petrochenkov
Copy link
Contributor Author

Given the drawbacks/interpretations given above I'm not sure this change would be better than status quo anymore.
I'll keep this open for a few days in case someone has more comments.

@steveklabnik steveklabnik added the T-lang Relevant to the language team, which will review and decide on the PR/issue. label Mar 24, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants