You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For most patterns and in safe code, "evaluation"(/matching?) order of subpatterns does not matter, but there is (that I can think of) one instance on stable where pattern evaluation order matters: matching on a struct with a tag and a union field (and similar situations).
The Reference section on unions does mention pattern matching, but does not say anything about pattern evaluation order. It gives an example of pattern-matching on a manual tagged union, though pattern evaluation order does not matter for the example given1. In a slightly different example, however, the field order does matter:
my original example
#[derive(Clone,Copy)]enumTag{A,B,}#[derive(Clone,Copy)]#[repr(C)]unionValue{a:u32,b:u8,// note that b is smaller than a}/// Assume that if tag == Tag::A, then val.a is valid, and if tag == Tag::B, then tag.b is valid.#[derive(Clone,Copy)]structTagged{tag:Tag,val:Value,}unsafefntag_first(v:Tagged) -> bool{match v {// fine under miri with tag == B, sees that `tag != A` and skips the armTagged{tag:Tag::A,val:Value{a:0}} => true,
_ => false,}}unsafefnval_first(v:Tagged) -> bool{match v {// error under miri with tag == B, since it reads the padding bytes after `Value::b`Tagged{val:Value{a:0},tag:Tag::A} => true,
_ => false,}}fnmain(){let v = Tagged{tag:Tag::B,val:Value{b:0},};unsafe{tag_first(v);val_first(v);}}
a simpler but basically the same example
fnmain(){unionUnion{value:u8,_empty:()}structMyOption{tag:u8,value:Union}// assume tag == 1 means value.value is validlet foo = MyOption{tag:0,value:Union{_empty:()}};unsafe{match foo {// currently fine under Miri, since `tag` is mentioned firstMyOption{tag:1,value:Union{value:0}} => true,
_ => false,};match foo {// currently this is UB under Miri if value is `_empty`/uninit, regardless of the tag fieldMyOption{value:Union{value:0},tag:1} => true,
_ => false,};}}
For unstable code, I suppose deref_patterns might also make it important to document pattern evaluation order, or maybe that feature is/will be restricted enough for it not to matter. Depending on the resolution of #412 pattern evaluation order might be important if matching on references-to-references-to-invalid-data (miri example)?
I'm not sure if this is fully the intended behavior2, or if it is intended, how best to document it.
Footnotes
in that example, the union field is fully-initailized either way, or UB happens regardless of pattern evaluation order ↩
Alternately, instead of documenting pattern evaluation order, it could be specified that if any (union) field used in a pattern match is invalid/uninitialized, then the whole arm is UB, regardless of the order the fields were written in the pattern. ↩
The text was updated successfully, but these errors were encountered:
cc rust-lang/reference#1665
For most patterns and in safe code, "evaluation"(/matching?) order of subpatterns does not matter, but there is (that I can think of) one instance on stable where pattern evaluation order matters: matching on a struct with a tag and a
union
field (and similar situations).The Reference section on
union
s does mention pattern matching, but does not say anything about pattern evaluation order. It gives an example of pattern-matching on a manual tagged union, though pattern evaluation order does not matter for the example given1. In a slightly different example, however, the field order does matter:my original example
a simpler but basically the same example
For unstable code, I suppose
deref_patterns
might also make it important to document pattern evaluation order, or maybe that feature is/will be restricted enough for it not to matter. Depending on the resolution of #412 pattern evaluation order might be important if matching on references-to-references-to-invalid-data (miri example)?I'm not sure if this is fully the intended behavior2, or if it is intended, how best to document it.
Footnotes
in that example, the union field is fully-initailized either way, or UB happens regardless of pattern evaluation order ↩
Alternately, instead of documenting pattern evaluation order, it could be specified that if any (union) field used in a pattern match is invalid/uninitialized, then the whole arm is UB, regardless of the order the fields were written in the pattern. ↩
The text was updated successfully, but these errors were encountered: