Skip to content

TAIT: empty match on TAIT confuses typeck #117413

Description

@Nadrieril

I tried this code (playground):

#![feature(type_alias_impl_trait)]
#![allow(unconditional_recursion)]

#[derive(Copy, Clone)]
enum Void {}

mod match_wildcard {
    type X = impl Copy; // ok
    fn empty_opaque(x: super::Void) -> X {
        match empty_opaque(x) {
            _ => {}
        }
        x
    }
}

mod empty_match {
    type X = impl Copy;
    //~^ ERROR unconstrained opaque type
    fn empty_opaque(x: super::Void) -> X {
        match empty_opaque(x) {}
        x
    }
}

Somehow in the second case we think that X is unconstrained even though it doesn't seem to contain more or less type information than the first case. Note also that this does not error if I use RPIT instead.

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Oct 30, 2023
  2. oli-obk commented on Oct 30, 2023

    @oli-obk
    Contributor

    I think in the second example mir building doesn't generate code for the trailing expression because it's statically known as dead code. But I thought we were keeping around the typeck types nowadays, and typeck should be the same for both functions

  3. Nadrieril commented on Oct 30, 2023

    @Nadrieril
    MemberAuthor

    I don't think that's it, same error if I put the match in a branch (updated playground link with more variations):

    type X = impl Copy;
    //~^ ERROR unconstrained opaque type
    fn empty_opaque(x: super::Void) -> X {
        if false {
            match empty_opaque(x) {}
            //~^ ERROR non-empty
        }
        x
    }
  4. Nadrieril commented on Oct 30, 2023

    @Nadrieril
    MemberAuthor

    In fact this doesn't need an empty type at all:

    type X = impl Copy;
    //~^ ERROR unconstrained opaque type
    fn empty_opaque() -> X {
        if false {
            match empty_opaque() {}
            //~^ ERROR non-empty
        }
        0u8
    }
  5. compiler-errors commented on Oct 30, 2023

    @compiler-errors
    Contributor

    I think we're generating bogus MIR or THIR because of that empty match --

    fn empty_opaque() -> {type error} {
        let mut _0: {type error};
    
        bb0: {
            unreachable;
        }
    }
    

    Are you sure the bug doesn't exist on the THIR/MIR building side, @Nadrieril?

    (hacked -Zunpretty=mir to dump the mir_built instead of instance_mir)

  6. Nadrieril commented on Oct 30, 2023

    @Nadrieril
    MemberAuthor

    Oh I'm sure of nothing 😄 I just assumed an unreachable in a if false branch would not affect anything else

  7. compiler-errors commented on Oct 30, 2023

    @compiler-errors
    Contributor

    So:

    if let Err(e) = tcx.check_match(def) {
    return construct_error(tcx, def, e);
    }

    If there's a match error, we end up constructing a failure MIR body. This will prevent us from inferring the opaque later on. This is because nothing in HIR actually constrains the TAIT either. edit: that last sentence was a lie

    Let me see if I can cook up a quick fix.

  8. added
    T-typesRelevant to the types team, which will review and decide on the PR/issue.
    and removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Oct 30, 2023
  9. added 3 commits that reference this issue on Oct 31, 2023
    b7acdff
    8715479
    8daa317
  10. added a commit that references this issue on Oct 31, 2023
    7ebf659
  11. added a commit that references this issue on Nov 7, 2023
    504f63e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

C-bugCategory: This is a bug.F-type_alias_impl_trait`#[feature(type_alias_impl_trait)]`T-typesRelevant to the types team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions