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

Constants in patterns can contain equality-less types #34784

Closed
petrochenkov opened this issue Jul 12, 2016 · 10 comments
Closed

Constants in patterns can contain equality-less types #34784

petrochenkov opened this issue Jul 12, 2016 · 10 comments
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@petrochenkov
Copy link
Contributor

petrochenkov commented Jul 12, 2016

Code:

const C: *const str = "abcd";

fn main() {
    match C {
        C => {}
        _ => {}
    }
}

Diagnostics:

warning: broken MIR (Terminator { source_info: SourceInfo { span: <anon>:5:9: 5:10, scope: scope0 }, kind: tmp1 = <str as std::cmp::PartialEq>::eq(tmp0, const "abcd") -> bb3 }): bad arg #0 (&str <- *const str): Sorts(ExpectedFound { expected: &str, found: *const str })
 --> <anon>:4:11
  |>
4 |>     match C {
  |>           ^

Reproduces on stable/beta/nightly.

@eddyb eddyb added the A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html label Jul 12, 2016
@eddyb
Copy link
Member

eddyb commented Jul 12, 2016

This is a pointer pattern, it shouldn't compile AFAIK. cc @arielb1

@arielb1
Copy link
Contributor

arielb1 commented Jul 13, 2016

This should be a constant pattern. Why it is destructuring through the pointer?

@arielb1 arielb1 added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Jul 13, 2016
@nagisa
Copy link
Member

nagisa commented Jul 14, 2016

As far as I remember, the constant-evaluated initializer expression gets used as a pattern, i.e. the code below and in the report are equivalent for MIR builder:

const C: *const str = "abcd";

fn main() {
    match C {
        "abcd" => {}
        _ => {}
    }
}

Which is caught by the proper-typeck and is why the mir-typeck is complaining.

@arielb1 arielb1 added I-nominated T-lang Relevant to the language team, which will review and decide on the PR/issue. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html labels Jul 17, 2016
@arielb1 arielb1 changed the title warning: broken MIR: expected: &str, found: *const str Constants in patterns can contain equality-less types Jul 17, 2016
@arielb1
Copy link
Contributor

arielb1 commented Jul 17, 2016

This is more general than raw pointers

const C: fn() = main;

fn foo(x: fn()) {
    match x {
        C => {}
        _ => {}
    }
}

fn main() {}

However, other cases result in a const-eval error:

const C: *const u8 = &0; //~ ERROR error: constant evaluation error: unimplemented constant expression: address operator [E0471]

fn foo(x: *const u8) {
    match x {
        C => {}
        _ => {}
    }
}

fn main() {}

I think this is the right solution.

@arielb1 arielb1 removed I-nominated T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Jul 17, 2016
@arielb1
Copy link
Contributor

arielb1 commented Jul 17, 2016

@petrochenkov
Copy link
Contributor Author

@arielb1 changed the title from warning: broken MIR: expected: &str, found: *const str to Constants in patterns can contain equality-less types

Since you generalized this issue, #34782 can probably be closed as a duplicate.

@arielb1
Copy link
Contributor

arielb1 commented Jul 17, 2016

cc @oli-obk

@petrochenkov
Copy link
Contributor Author

petrochenkov commented Jul 17, 2016

One more test, for thin pointers:

const C: *const [u8; 4] = b"abcd";

fn main() {
    match C {
        C => {}
        _ => {}
    }
}

Gives internal compiler error: ../src/librustc_trans/collector.rs:983: find_vtable_types_for_unsizing: invalid coercion *const [u8; 4] -> &[u8] currently.

@oli-obk
Copy link
Contributor

oli-obk commented Jul 18, 2016

The issue is that the mir-building process calls eval_const_expr (

PatternKind::Constant { value: value }
) while the old trans calls consts::const_expr (
let expr = consts::const_expr(ccx, &lit_expr, bcx.fcx.param_substs, None, Yes);
). The latter does things like unsizing and other coercion stuff.

It should work if instead of calling eval_const_expr we'd build a MIR for that expression and used the MIR-const evaluator on that MIR.

@arielb1
Copy link
Contributor

arielb1 commented Jul 21, 2016

@oli-obk

The problem is that the code compiles. We should not be doing *const T -> &T coercions, obviously.

@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
wesleywiser added a commit to wesleywiser/rust that referenced this issue Jul 20, 2018
wesleywiser added a commit to wesleywiser/rust that referenced this issue Jul 20, 2018
@bors bors closed this as completed in 5363911 Jul 26, 2018
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. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants