Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # 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