Entry tags:
TMI: Exhausting all the possibilities
I closed #2735, which had to do with how
and
can have different semantics in Rust. As you might guess, "_" effectively means "I'm never going to use this, so just give it a name I can't refer to." (Left-hand sides of let decls, by the way, can be any irrefutable pattern.) So why would they be different?
e might have a struct type (structs are the new classes) that has a destructor. So in the first case, the code generator looks at the decl and says "we're binding e to something, so run the destructor when that something goes out of scope". So if you actually had:
e's destructor would run, presumably having observable effects, after "Hello" got printed out. On the other hand, with just e; the code generator sees that you're not doing anything with the result of e;, and runs the destructor immediately after evaluating e.
I changed it by adding a special case that checks the pattern on the left-hand side for "_"-ness. It feels a little odd to have this special case, but weirder to have these two forms behave differently.
Mainly, though, I'm still working on removing non-exhaustive matches from the Rust codebase. I started compiling a list of all the non-exhaustive matches I removed, and classifying them roughly. The hope is that this will be evidence that we can actually use to figure what, if any, language features to add to make it easier and safer to express the knowledge that's in your head (but not communicated to the compiler) when you wrote a match check before. (match is the new alt. Oh, syntax changes.)
let _ = e;
and
e;
can have different semantics in Rust. As you might guess, "_" effectively means "I'm never going to use this, so just give it a name I can't refer to." (Left-hand sides of let decls, by the way, can be any irrefutable pattern.) So why would they be different?
e might have a struct type (structs are the new classes) that has a destructor. So in the first case, the code generator looks at the decl and says "we're binding e to something, so run the destructor when that something goes out of scope". So if you actually had:
let _ = e;
error!("Hello");
e's destructor would run, presumably having observable effects, after "Hello" got printed out. On the other hand, with just e; the code generator sees that you're not doing anything with the result of e;, and runs the destructor immediately after evaluating e.
I changed it by adding a special case that checks the pattern on the left-hand side for "_"-ness. It feels a little odd to have this special case, but weirder to have these two forms behave differently.
Mainly, though, I'm still working on removing non-exhaustive matches from the Rust codebase. I started compiling a list of all the non-exhaustive matches I removed, and classifying them roughly. The hope is that this will be evidence that we can actually use to figure what, if any, language features to add to make it easier and safer to express the knowledge that's in your head (but not communicated to the compiler) when you wrote a match check before. (match is the new alt. Oh, syntax changes.)