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

TAIT: empty match on TAIT confuses typeck #117413

Closed
Nadrieril opened this issue Oct 30, 2023 · 6 comments · Fixed by #117416 or #117418
Closed

TAIT: empty match on TAIT confuses typeck #117413

Nadrieril opened this issue Oct 30, 2023 · 6 comments · Fixed by #117416 or #117418
Assignees
Labels
C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@Nadrieril
Copy link
Member

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.

@Nadrieril Nadrieril added the C-bug Category: This is a bug. label Oct 30, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Oct 30, 2023
@Nadrieril Nadrieril added the F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` label Oct 30, 2023
@oli-obk
Copy link
Contributor

oli-obk commented Oct 30, 2023

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

@Nadrieril
Copy link
Member Author

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
}

@Nadrieril
Copy link
Member Author

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
}

@compiler-errors
Copy link
Member

compiler-errors commented Oct 30, 2023

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)

@Nadrieril
Copy link
Member Author

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

@compiler-errors
Copy link
Member

compiler-errors commented Oct 30, 2023

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.

@compiler-errors compiler-errors self-assigned this Oct 30, 2023
@saethlin saethlin added T-types Relevant to the types team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Oct 30, 2023
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Oct 31, 2023
…r=oli-obk

Also consider TAIT to be uncomputable if the MIR body is tainted

Not totally sure if this is the best solution. We could, alternatively, look at the hir typeck results and try to take a type from there instead of just falling back to type error, inferring `u8` instead of `{type error}`. Not certain it really matters, though.

Happy to iterate on this.

Fixes rust-lang#117413

r? `@oli-obk` cc `@Nadrieril`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Oct 31, 2023
… r=oli-obk

Build a better MIR body when errors are encountered

Doesn't really have much of an effect on its own, but it does lead to a less confusing phony MIR body being generated when an error is detected during THIR/MIR/match building. This was quite confusing when I hacked `-Zunpretty=mir` to emit `mir_built` rather than `instance_mir`.

This coincidentually also fixes rust-lang#117413, but not as generally as rust-lang#117416.

cc `@Nadrieril`
@bors bors closed this as completed in 8daa317 Oct 31, 2023
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Oct 31, 2023
Rollup merge of rust-lang#117416 - compiler-errors:tait-in-bad-body, r=oli-obk

Also consider TAIT to be uncomputable if the MIR body is tainted

Not totally sure if this is the best solution. We could, alternatively, look at the hir typeck results and try to take a type from there instead of just falling back to type error, inferring `u8` instead of `{type error}`. Not certain it really matters, though.

Happy to iterate on this.

Fixes rust-lang#117413

r? ``@oli-obk`` cc ``@Nadrieril``
bors added a commit to rust-lang-ci/rust that referenced this issue Nov 7, 2023
…=oli-obk

Build a better MIR body when errors are encountered

Doesn't really have much of an effect on its own, but it does lead to a less confusing phony MIR body being generated when an error is detected during THIR/MIR/match building. This was quite confusing when I hacked `-Zunpretty=mir` to emit `mir_built` rather than `instance_mir`.

This coincidentually also fixes rust-lang#117413, but not as generally as rust-lang#117416.

cc `@Nadrieril`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
5 participants