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

match variant with fields unresolved when enum type in scope #14221

Closed
pnkfelix opened this issue May 15, 2014 · 8 comments
Closed

match variant with fields unresolved when enum type in scope #14221

pnkfelix opened this issue May 15, 2014 · 8 comments
Labels
A-resolve Area: Name resolution
Milestone

Comments

@pnkfelix
Copy link
Member

Here is some code (derived from something I actually saw recently in rustc):

pub mod a {
    pub enum E {
                         A,
                         B,
        #[cfg(show_bug)] C(int),
    }
    pub mod b {
        pub fn key(e: ::a::E) -> StrBuf {
            match e {
                                 A => "A",
                                 B => "B",
                #[cfg(show_bug)] C(_) => "C",

            }.to_strbuf()
        }
    }
}

fn main() {
    println!("Hello World {}", a::b::key(a::A));
}

Now the bug:

% rustc /tmp/e.rs && ./e
Hello World A
% rustc --cfg show_bug /tmp/e.rs && ./e
/tmp/e.rs:12:34: 12:35 error: unresolved enum variant, struct or const `C`
/tmp/e.rs:12                 #[cfg(show_bug)] C(_) => "C",
                                              ^
error: aborting due to previous error

(The workaround is to explicitly import the enum variant with the field. It does not suffice to just do use a::EnumType; see comments below.)

@pnkfelix pnkfelix changed the title resolve fails to find enum variant with fields via the type alone resolve fails to pat-match enum variant with fields via the type alone May 15, 2014
@alexcrichton
Copy link
Member

This looks like a serious resolve bug, neither the name A or B is in scope for mod b. Nominating.

@pnkfelix pnkfelix changed the title resolve fails to pat-match enum variant with fields via the type alone pat-match enum variant with fields via the type alone fails to resolve May 15, 2014
@pnkfelix pnkfelix changed the title pat-match enum variant with fields via the type alone fails to resolve match variant with fields fails to resolve via abspath-to-type May 15, 2014
@pnkfelix
Copy link
Member Author

wow I think this bug is actually much more serious than I had realized. Even doing a use a::Enum; in the inner module does not suffice to pull C into scope, though it does pull A and B into scope.

pub mod a {
    pub enum En { A,
                  B,
    #[cfg(field)] C(int) }

    pub fn key(e: En) -> StrBuf {
        match e { A => "A",
                  B => "B",
    #[cfg(field)] C(_) => "C",
        }.to_strbuf()
    }

    #[cfg(inner)]
    pub mod b {
        use a::En;
        pub fn key(e: En) -> StrBuf {
            match e { A => "A",
                      B => "B",
        #[cfg(field)] C(_) => "C",
            }.to_strbuf()
        }
    }
}

#[cfg(inner)]
fn main() {
    println!("Hello World {}", a::b::key(a::A));
}

#[cfg(not(inner))]
fn main() {
    println!("Hello World {}", a::key(a::A));
}

If you have both inner and field, things break:

% rustc /tmp/e.rs && ./e
Hello World A
% rustc --cfg inner /tmp/e.rs && ./e
Hello World A
% rustc --cfg field /tmp/e.rs && ./e
Hello World A
% rustc --cfg inner --cfg field /tmp/e.rs && ./e
/tmp/e.rs:19:23: 19:24 error: unresolved enum variant, struct or const `C`
/tmp/e.rs:19         #[cfg(field)] C(_) => "C",
                                   ^
error: aborting due to previous error
% 

@pnkfelix pnkfelix changed the title match variant with fields fails to resolve via abspath-to-type match variant with fields fails to resolve when type in scope May 15, 2014
@pnkfelix pnkfelix changed the title match variant with fields fails to resolve when type in scope match variant with fields fails to resolve when enum type in scope May 15, 2014
@pnkfelix pnkfelix changed the title match variant with fields fails to resolve when enum type in scope match variant with fields unresolved when enum type in scope May 15, 2014
@pnkfelix
Copy link
Member Author

@alexcrichton I thought it was by design that when you import an enum type, you were supposed to automatically get its variants without having to import them explicitly?

@alexcrichton
Copy link
Member

I was unaware of such a design! If so, then this seems like just a bug, if not though, we may have some other issues...

@sfackler
Copy link
Member

Variants definitely do not auto-import in my experience.

@pnkfelix
Copy link
Member Author

admittedly, I do not recall where I got the impression that enum import worked this way. (and on a test case i just hacked up, none of the variants get auto-imported into a sibling module. so perhaps this is an artifact of some interaction between the parent and child modules.)

But etiher way, we should resolve what the appropriate semantics are here. I have no problem

@emberian
Copy link
Member

This is scary.

@pnkfelix
Copy link
Member Author

@alexcrichton is right. (I still don't know how I got the impression I had, but then again, clearly someone working on resolve had the same impression I guess...)

P-backcompat-lang, 1.0. (And I need to change the test better illustrate that the matches of A and B are matching variants, not binding.)

@pnkfelix pnkfelix added this to the 1.0 milestone May 15, 2014
bors added a commit that referenced this issue May 17, 2014
This plugs a leak where resolve was treating enums defined in parent modules as
in-scope for all children modules when resolving a pattern identifier. This
eliminates the code path in resolve entirely.

If this breaks any existing code, then it indicates that the variants need to be
explicitly imported into the module.

Closes #14221
lnicola pushed a commit to lnicola/rust that referenced this issue Mar 13, 2023
…Veykril

fix: show diagnostic for } token followed by else in let else statement

fix rust-lang#14221

My thinking is to check if the `expr` after `=` is block like when parse `let ... lese` , and if so, emit error.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-resolve Area: Name resolution
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants