Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upAny old type of constant can be used in a pattern #20489
Comments
nikomatsakis
added
the
I-nominated
label
Jan 3, 2015
This comment has been minimized.
This comment has been minimized.
|
Surely if you wanted the comparison to use #[deriving(PartialEq)]
struct Foo<T> {
value: T
}
const F: Foo<int> = Foo { value: 2 };
fn main() {
let x = Foo { value: 2 };
match x {
_ if x == F => { println!("Hi"); }
_ => { println!("Ho"); }
}
}Why remove the possibly useful behaviour of using constants as a pattern? |
This comment has been minimized.
This comment has been minimized.
|
I was under the impression that |
nikomatsakis
added a commit
to nikomatsakis/rust
that referenced
this issue
Jan 4, 2015
This comment has been minimized.
This comment has been minimized.
|
So, all I'd like to do for this bug is to ensure that we limit the types of such constants to scalars (and maybe tuples of scalars), which I'm sure we can all agree ought to work. We can hash out our disagreements about what the correct semantics ought to be over an RFC, I imagine. But for the record:
|
This comment has been minimized.
This comment has been minimized.
|
I really can't agree on this. I don't expect pattern matching to run arbitrary code (which is what running the |
nikomatsakis
closed this
in
dbfa054
Jan 6, 2015
This comment has been minimized.
This comment has been minimized.
|
It appears this bug was closed accidentally. I still think this is something we'll have to resolve -- right now, you can match on types that don't implement |
nikomatsakis
reopened this
Jul 17, 2015
nikomatsakis
added
the
T-lang
label
Jul 17, 2015
This comment has been minimized.
This comment has been minimized.
|
I'll note that in the MIR desugaring branch this becomes much easier to handle. |
This comment has been minimized.
This comment has been minimized.
|
triage: P-medium |
rust-highfive
removed
the
I-nominated
label
Jul 31, 2015
nrc
added
P-medium
and removed
I-nominated
labels
Jul 31, 2015
rust-highfive
added
the
P-medium
label
Jul 31, 2015
This comment has been minimized.
This comment has been minimized.
|
Pattern matching is always structural (as I know it from both Rust and other languages), this bug report is very surprising to me. |
This comment has been minimized.
This comment has been minimized.
+1
+1 @nikomatsakis
as
Given that interpretation, in the next example
Should this matching involve |
This comment has been minimized.
This comment has been minimized.
|
I have a hard time imagining how one would even implement |
This comment has been minimized.
This comment has been minimized.
|
@petrochenkov yeah, but I no longer stand by that idea. I think it's a good guiding principle, but there is a definite distinction between an enum variant and a constant like: struct Foo { x: i32 }
const fn make_foo(x: i32) -> Foo { Foo { x: x } }
...
const EXAMPLE: Foo = make_foo(22);
...
match something {
EXAMPLE => ...
}what we currently do now in cases like these is to treat that final match as if you wrote: match something {
Foo { x: 22 } => ...
}This effectively introduces two forms of equality: normal equality ( In particular, there is something about taking a constant that is computed through an arbitrary complex compile-time expression and "boiling it down" to the particular result that feels like a violation of abstraction boundaries. Let me give you another example. Imagine I wrote: mod foo {
pub struct Foo { b: bool }
pub const V1: Foo = Foo { b: true };
pub const V2: Foo = Foo { b: false };
}Note that there is an abstraction boundary here: fn bar(f: x::Foo) {
// rustc knows this is exhaustive because if expanded `V1` into equivalent
// patterns; patterns you could not write by hand!
match f {
x::V1 => { }
x::V2 => { }
}
}This seems bad to me. Now if I add new fields to (On play: http://is.gd/exTrhs) Anyway, it seems clear that this topic is controversial enough that it merits a wider audience. I've been planning for some time (months now!) to write an RFC. Things are coming to a head with the MIR rewrite, which requires us to reimplement pattern matching anyhow, and thus makes a good chance to make sure it is doing what we want it to. |
nikomatsakis
referenced this issue
Oct 26, 2015
Closed
Perf regression in nightly when compiling massive matches #29227
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis |
This comment has been minimized.
This comment has been minimized.
|
+1 for "ban constants that assign a value to a private field". Maybe even make matching against |
This comment has been minimized.
This comment has been minimized.
|
I opened a discussion thread here: https://internals.rust-lang.org/t/how-to-handle-pattern-matching-on-constants/2846 I also tried to lay out the pros/cons as I see them. Please add additional considerations I forgot about! |
This comment has been minimized.
This comment has been minimized.
|
Closing in favor of #31434 |
nikomatsakis commentedJan 3, 2015
Example:
I feel pretty sure that we would want matching to use a
PartialEqimpl. For now constant patterns should be limited to uint/int/&str. I'll throw it into a patch I'm working on.