libsyntax: Disallow struct literals after if
, while
, match
, and
`for...in`. Closes #14803. If you used a structure literal after one of these keywords, surround it in parentheses. [breaking-change]
This commit is contained in:
parent
575710f6ce
commit
654d6444fe
22 changed files with 147 additions and 37 deletions
|
@ -3004,7 +3004,7 @@ ten_times(|j| println!("hello, {}", j));
|
||||||
### While loops
|
### While loops
|
||||||
|
|
||||||
~~~~ {.ebnf .gram}
|
~~~~ {.ebnf .gram}
|
||||||
while_expr : "while" expr '{' block '}' ;
|
while_expr : "while" no_struct_literal_expr '{' block '}' ;
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
A `while` loop begins by evaluating the boolean loop conditional expression.
|
A `while` loop begins by evaluating the boolean loop conditional expression.
|
||||||
|
@ -3071,7 +3071,7 @@ A `continue` expression is only permitted in the body of a loop.
|
||||||
### For expressions
|
### For expressions
|
||||||
|
|
||||||
~~~~ {.ebnf .gram}
|
~~~~ {.ebnf .gram}
|
||||||
for_expr : "for" pat "in" expr '{' block '}' ;
|
for_expr : "for" pat "in" no_struct_literal_expr '{' block '}' ;
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
A `for` expression is a syntactic construct for looping over elements
|
A `for` expression is a syntactic construct for looping over elements
|
||||||
|
@ -3105,7 +3105,7 @@ for i in range(0u, 256) {
|
||||||
### If expressions
|
### If expressions
|
||||||
|
|
||||||
~~~~ {.ebnf .gram}
|
~~~~ {.ebnf .gram}
|
||||||
if_expr : "if" expr '{' block '}'
|
if_expr : "if" no_struct_literal_expr '{' block '}'
|
||||||
else_tail ? ;
|
else_tail ? ;
|
||||||
|
|
||||||
else_tail : "else" [ if_expr
|
else_tail : "else" [ if_expr
|
||||||
|
@ -3126,7 +3126,7 @@ then any `else` block is executed.
|
||||||
### Match expressions
|
### Match expressions
|
||||||
|
|
||||||
~~~~ {.ebnf .gram}
|
~~~~ {.ebnf .gram}
|
||||||
match_expr : "match" expr '{' match_arm * '}' ;
|
match_expr : "match" no_struct_literal_expr '{' match_arm * '}' ;
|
||||||
|
|
||||||
match_arm : attribute * match_pat "=>" [ expr "," | '{' block '}' ] ;
|
match_arm : attribute * match_pat "=>" [ expr "," | '{' block '}' ] ;
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ pub enum restriction {
|
||||||
RESTRICT_STMT_EXPR,
|
RESTRICT_STMT_EXPR,
|
||||||
RESTRICT_NO_BAR_OP,
|
RESTRICT_NO_BAR_OP,
|
||||||
RESTRICT_NO_BAR_OR_DOUBLEBAR_OP,
|
RESTRICT_NO_BAR_OR_DOUBLEBAR_OP,
|
||||||
|
RESTRICT_NO_STRUCT_LITERAL,
|
||||||
}
|
}
|
||||||
|
|
||||||
type ItemInfo = (Ident, Item_, Option<Vec<Attribute> >);
|
type ItemInfo = (Ident, Item_, Option<Vec<Attribute> >);
|
||||||
|
@ -2024,8 +2025,9 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
return self.mk_mac_expr(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT));
|
return self.mk_mac_expr(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT));
|
||||||
} else if self.token == token::LBRACE {
|
} else if self.token == token::LBRACE {
|
||||||
// This might be a struct literal.
|
// This is a struct literal, unless we're prohibited from
|
||||||
if self.looking_at_struct_literal() {
|
// parsing struct literals here.
|
||||||
|
if self.restriction != RESTRICT_NO_STRUCT_LITERAL {
|
||||||
// It's a struct literal.
|
// It's a struct literal.
|
||||||
self.bump();
|
self.bump();
|
||||||
let mut fields = Vec::new();
|
let mut fields = Vec::new();
|
||||||
|
@ -2042,6 +2044,14 @@ impl<'a> Parser<'a> {
|
||||||
&[token::COMMA], &[token::RBRACE]);
|
&[token::COMMA], &[token::RBRACE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if fields.len() == 0 && base.is_none() {
|
||||||
|
let last_span = self.last_span;
|
||||||
|
self.span_err(last_span,
|
||||||
|
"structure literal must either have at \
|
||||||
|
least one field or use functional \
|
||||||
|
structure update syntax");
|
||||||
|
}
|
||||||
|
|
||||||
hi = self.span.hi;
|
hi = self.span.hi;
|
||||||
self.expect(&token::RBRACE);
|
self.expect(&token::RBRACE);
|
||||||
ex = ExprStruct(pth, fields, base);
|
ex = ExprStruct(pth, fields, base);
|
||||||
|
@ -2548,7 +2558,7 @@ impl<'a> Parser<'a> {
|
||||||
// parse an 'if' expression ('if' token already eaten)
|
// parse an 'if' expression ('if' token already eaten)
|
||||||
pub fn parse_if_expr(&mut self) -> Gc<Expr> {
|
pub fn parse_if_expr(&mut self) -> Gc<Expr> {
|
||||||
let lo = self.last_span.lo;
|
let lo = self.last_span.lo;
|
||||||
let cond = self.parse_expr();
|
let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
|
||||||
let thn = self.parse_block();
|
let thn = self.parse_block();
|
||||||
let mut els: Option<Gc<Expr>> = None;
|
let mut els: Option<Gc<Expr>> = None;
|
||||||
let mut hi = thn.span.hi;
|
let mut hi = thn.span.hi;
|
||||||
|
@ -2633,7 +2643,7 @@ impl<'a> Parser<'a> {
|
||||||
let lo = self.last_span.lo;
|
let lo = self.last_span.lo;
|
||||||
let pat = self.parse_pat();
|
let pat = self.parse_pat();
|
||||||
self.expect_keyword(keywords::In);
|
self.expect_keyword(keywords::In);
|
||||||
let expr = self.parse_expr();
|
let expr = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
|
||||||
let loop_block = self.parse_block();
|
let loop_block = self.parse_block();
|
||||||
let hi = self.span.hi;
|
let hi = self.span.hi;
|
||||||
|
|
||||||
|
@ -2642,7 +2652,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
pub fn parse_while_expr(&mut self) -> Gc<Expr> {
|
pub fn parse_while_expr(&mut self) -> Gc<Expr> {
|
||||||
let lo = self.last_span.lo;
|
let lo = self.last_span.lo;
|
||||||
let cond = self.parse_expr();
|
let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
|
||||||
let body = self.parse_block();
|
let body = self.parse_block();
|
||||||
let hi = body.span.hi;
|
let hi = body.span.hi;
|
||||||
return self.mk_expr(lo, hi, ExprWhile(cond, body));
|
return self.mk_expr(lo, hi, ExprWhile(cond, body));
|
||||||
|
@ -2655,17 +2665,9 @@ impl<'a> Parser<'a> {
|
||||||
self.mk_expr(lo, hi, ExprLoop(body, opt_ident))
|
self.mk_expr(lo, hi, ExprLoop(body, opt_ident))
|
||||||
}
|
}
|
||||||
|
|
||||||
// For distinguishing between struct literals and blocks
|
|
||||||
fn looking_at_struct_literal(&mut self) -> bool {
|
|
||||||
self.token == token::LBRACE &&
|
|
||||||
((self.look_ahead(1, |t| token::is_plain_ident(t)) &&
|
|
||||||
self.look_ahead(2, |t| *t == token::COLON))
|
|
||||||
|| self.look_ahead(1, |t| *t == token::DOTDOT))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_match_expr(&mut self) -> Gc<Expr> {
|
fn parse_match_expr(&mut self) -> Gc<Expr> {
|
||||||
let lo = self.last_span.lo;
|
let lo = self.last_span.lo;
|
||||||
let discriminant = self.parse_expr();
|
let discriminant = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
|
||||||
self.commit_expr_expecting(discriminant, token::LBRACE);
|
self.commit_expr_expecting(discriminant, token::LBRACE);
|
||||||
let mut arms: Vec<Arm> = Vec::new();
|
let mut arms: Vec<Arm> = Vec::new();
|
||||||
while self.token != token::RBRACE {
|
while self.token != token::RBRACE {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
struct Foo { x: int }
|
struct Foo { x: int }
|
||||||
match Foo { x: 10 } {
|
match (Foo { x: 10 }) {
|
||||||
Foo { ref x: ref x } => {}, //~ ERROR unexpected `:`
|
Foo { ref x: ref x } => {}, //~ ERROR unexpected `:`
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match S { bar: 1 } {
|
match (S { bar: 1 }) {
|
||||||
S { bar: x } => {
|
S { bar: x } => {
|
||||||
x += 1; //~ ERROR re-assignment of immutable variable `x`
|
x += 1; //~ ERROR re-assignment of immutable variable `x`
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ impl Drop for S {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_in_match() {
|
fn move_in_match() {
|
||||||
match S {f: "foo".to_string(), g: "bar".to_string()} {
|
match (S {f: "foo".to_string(), g: "bar".to_string()}) {
|
||||||
S { //~ ERROR cannot move out of type `S`, which defines the `Drop` trait
|
S { //~ ERROR cannot move out of type `S`, which defines the `Drop` trait
|
||||||
f: _s, //~ NOTE attempting to move value to here
|
f: _s, //~ NOTE attempting to move value to here
|
||||||
g: _t //~ NOTE and here
|
g: _t //~ NOTE and here
|
||||||
|
|
|
@ -14,7 +14,7 @@ impl Drop for S {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_in_match() {
|
fn move_in_match() {
|
||||||
match S {f:"foo".to_string()} {
|
match (S {f:"foo".to_string()}) {
|
||||||
S {f:_s} => {}
|
S {f:_s} => {}
|
||||||
//~^ ERROR cannot move out of type `S`, which defines the `Drop` trait
|
//~^ ERROR cannot move out of type `S`, which defines the `Drop` trait
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ struct S { a: int }
|
||||||
enum E { C(int) }
|
enum E { C(int) }
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
match S { a: 1 } {
|
match (S { a: 1 }) {
|
||||||
C(_) => (), //~ ERROR mismatched types: expected `S` but found `E`
|
C(_) => (), //~ ERROR mismatched types: expected `S` but found `E`
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ enum Color {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn struct_with_a_nested_enum_and_vector() {
|
fn struct_with_a_nested_enum_and_vector() {
|
||||||
match Foo { first: true, second: None } {
|
match (Foo { first: true, second: None }) {
|
||||||
//~^ ERROR non-exhaustive patterns: `Foo{first: false, second: Some([_, _, _, _])}` not covered
|
//~^ ERROR non-exhaustive patterns: `Foo{first: false, second: Some([_, _, _, _])}` not covered
|
||||||
Foo { first: true, second: None } => (),
|
Foo { first: true, second: None } => (),
|
||||||
Foo { first: true, second: Some(_) } => (),
|
Foo { first: true, second: Some(_) } => (),
|
||||||
|
@ -71,4 +71,4 @@ fn main() {
|
||||||
struct_with_a_nested_enum_and_vector();
|
struct_with_a_nested_enum_and_vector();
|
||||||
enum_with_multiple_missing_variants();
|
enum_with_multiple_missing_variants();
|
||||||
enum_struct_variant();
|
enum_struct_variant();
|
||||||
}
|
}
|
||||||
|
|
28
src/test/compile-fail/struct-literal-in-for.rs
Normal file
28
src/test/compile-fail/struct-literal-in-for.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
struct Foo {
|
||||||
|
x: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
fn hi(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
for x in Foo {
|
||||||
|
x: 3 //~ ERROR expected one of `;`, `}`
|
||||||
|
}.hi() {
|
||||||
|
println!("yo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
28
src/test/compile-fail/struct-literal-in-if.rs
Normal file
28
src/test/compile-fail/struct-literal-in-if.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
struct Foo {
|
||||||
|
x: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
fn hi(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if Foo {
|
||||||
|
x: 3 //~ ERROR expected one of `;`, `}`
|
||||||
|
}.hi() {
|
||||||
|
println!("yo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
struct Foo {
|
||||||
|
x: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
match Foo {
|
||||||
|
x: 3 //~ ERROR expected `=>`
|
||||||
|
} {
|
||||||
|
Foo {
|
||||||
|
x: x
|
||||||
|
} => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
28
src/test/compile-fail/struct-literal-in-while.rs
Normal file
28
src/test/compile-fail/struct-literal-in-while.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
struct Foo {
|
||||||
|
x: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
fn hi(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
while Foo {
|
||||||
|
x: 3 //~ ERROR expected one of `;`, `}`
|
||||||
|
}.hi() {
|
||||||
|
println!("yo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct Foo;
|
||||||
|
|
||||||
fn f2() {
|
fn f2() {
|
||||||
let _end_stmt = Foo { };
|
let _end_stmt = Foo { };
|
||||||
//~^ ERROR: unit-like struct construction is written with no trailing `{ }`
|
//~^ ERROR: structure literal must either have at least one field
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct Foo;
|
||||||
|
|
||||||
fn g3() {
|
fn g3() {
|
||||||
let _mid_tuple = (Foo { }, 2);
|
let _mid_tuple = (Foo { }, 2);
|
||||||
//~^ ERROR: unit-like struct construction is written with no trailing `{ }`
|
//~^ ERROR: structure literal must either have at least one field
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct Foo;
|
||||||
|
|
||||||
fn h4() {
|
fn h4() {
|
||||||
let _end_of_tuple = (3, Foo { });
|
let _end_of_tuple = (3, Foo { });
|
||||||
//~^ ERROR: unit-like struct construction is written with no trailing `{ }`
|
//~^ ERROR: structure literal must either have at least one field
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct Foo;
|
||||||
|
|
||||||
fn i5() {
|
fn i5() {
|
||||||
let _end_of_block = { Foo { } };
|
let _end_of_block = { Foo { } };
|
||||||
//~^ ERROR: unit-like struct construction is written with no trailing `{ }`
|
//~^ ERROR: structure literal must either have at least one field
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -105,7 +105,7 @@ fn main() {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
match Struct { x: 237, y: 238 } {
|
match (Struct { x: 237, y: 238 }) {
|
||||||
Struct { x: shadowed, y: local_to_arm } => {
|
Struct { x: shadowed, y: local_to_arm } => {
|
||||||
|
|
||||||
zzz();
|
zzz();
|
||||||
|
@ -113,7 +113,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match Struct { x: 239, y: 240 } {
|
match (Struct { x: 239, y: 240 }) {
|
||||||
// ignored field
|
// ignored field
|
||||||
Struct { x: shadowed, .. } => {
|
Struct { x: shadowed, .. } => {
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match Struct { x: 241, y: 242 } {
|
match (Struct { x: 241, y: 242 }) {
|
||||||
// with literal
|
// with literal
|
||||||
Struct { x: shadowed, y: 242 } => {
|
Struct { x: shadowed, y: 242 } => {
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub fn main() {
|
||||||
assert_eq!(a, 2);
|
assert_eq!(a, 2);
|
||||||
|
|
||||||
let b =
|
let b =
|
||||||
match Pair {x: 10, y: 20} {
|
match (Pair {x: 10, y: 20}) {
|
||||||
x if x.x < 5 && x.y < 5 => { 1 }
|
x if x.x < 5 && x.y < 5 => { 1 }
|
||||||
Pair {x: x, y: y} if x == 10 && y == 20 => { 2 }
|
Pair {x: x, y: y} if x == 10 && y == 20 => { 2 }
|
||||||
Pair {x: _x, y: _y} => { 3 }
|
Pair {x: _x, y: _y} => { 3 }
|
||||||
|
|
|
@ -16,7 +16,7 @@ enum Foo {
|
||||||
|
|
||||||
macro_rules! match_inside_expansion(
|
macro_rules! match_inside_expansion(
|
||||||
() => (
|
() => (
|
||||||
match B { b1:29 , bb1: 100} {
|
match (B { b1:29 , bb1: 100}) {
|
||||||
B { b1:b2 , bb1:bb2 } => b2+bb2
|
B { b1:b2 , bb1:bb2 } => b2+bb2
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
struct Foo { foo: bool, bar: Option<int>, baz: int }
|
struct Foo { foo: bool, bar: Option<int>, baz: int }
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
match Foo{foo: true, bar: Some(10), baz: 20} {
|
match (Foo{foo: true, bar: Some(10), baz: 20}) {
|
||||||
Foo{foo: true, bar: Some(_), ..} => {}
|
Foo{foo: true, bar: Some(_), ..} => {}
|
||||||
Foo{foo: false, bar: None, ..} => {}
|
Foo{foo: false, bar: None, ..} => {}
|
||||||
Foo{foo: true, bar: None, ..} => {}
|
Foo{foo: true, bar: None, ..} => {}
|
||||||
|
|
|
@ -14,7 +14,7 @@ struct D { a: int, d: C }
|
||||||
struct C { c: int }
|
struct C { c: int }
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
match A {a: 10, b: 20} {
|
match (A {a: 10, b: 20}) {
|
||||||
x@A {a, b: 20} => { assert!(x.a == 10); assert!(a == 10); }
|
x@A {a, b: 20} => { assert!(x.a == 10); assert!(a == 10); }
|
||||||
A {b: _b, ..} => { fail!(); }
|
A {b: _b, ..} => { fail!(); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ extern crate struct_variant_xc_aux;
|
||||||
use struct_variant_xc_aux::{StructVariant, Variant};
|
use struct_variant_xc_aux::{StructVariant, Variant};
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let arg = match StructVariant { arg: 42 } {
|
let arg = match (StructVariant { arg: 42 }) {
|
||||||
Variant(_) => unreachable!(),
|
Variant(_) => unreachable!(),
|
||||||
StructVariant { arg } => arg
|
StructVariant { arg } => arg
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue