auto merge of #5137 : yjh0502/rust/empty_struct, r=nikomatsakis
The fix is straight-forward, but there are several changes
while fixing the issue.
1) disallow `mut` keyword when making a new struct
In code base, there are following code,
```rust
struct Foo { mut a: int };
let a = Foo { mut a: 1 };
```
This is because of structural record, which is
deprecated corrently (see issue #3089) In structural
record, `mut` keyword should be allowd to control
mutability. But without structural record, we don't
need to allow `mut` keyword while constructing struct.
2) disallow structural records in parser level
This is related to 1). With structural records, there
is an ambiguity between empty block and empty struct
To solve the problem, I change parser to stop parsing
structural records. I think this is not a problem,
because structural records are not compiled already.
Misc. issues
There is an ambiguity between empty struct vs. empty match stmt.
with following code,
```rust
match x{} {}
```
Two interpretation is possible, which is listed blow
```rust
match (x{}) {} // matching with newly-constructed empty struct
(match x{}) {} // matching with empty enum(or struct) x
// and then empty block
```
It seems that there is no such code in rust code base, but
there is one test which uses empty match statement:
https://github.com/mozilla/rust/blob/incoming/src/test/run-pass/issue-3037.rs
All other cases could be distinguished with look-ahead,
but this can't be. One possible solution is wrapping with
parentheses when matching with an uninhabited type.
```rust
enum what { }
fn match_with_empty(x: what) -> ~str {
match (x) { //use parentheses to remove the ambiguity
}
}
```
This commit is contained in:
commit
5aca7d6aef
25 changed files with 75 additions and 336 deletions
|
|
@ -9,18 +9,23 @@
|
|||
// except according to those terms.
|
||||
|
||||
// error-pattern: mismatched types
|
||||
type clam = {x: @int, y: @int};
|
||||
struct clam {
|
||||
x: @int,
|
||||
y: @int,
|
||||
}
|
||||
|
||||
type fish = {a: @int};
|
||||
struct fish {
|
||||
a: @int,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a: clam = {x: @1, y: @2};
|
||||
let b: clam = {x: @10, y: @20};
|
||||
let a: clam = clam{x: @1, y: @2};
|
||||
let b: clam = clam{x: @10, y: @20};
|
||||
let z: int = a.x + b.y;
|
||||
log(debug, z);
|
||||
assert (z == 21);
|
||||
let forty: fish = {a: @40};
|
||||
let two: fish = {a: @2};
|
||||
let forty: fish = fish{a: @40};
|
||||
let two: fish = fish{a: @2};
|
||||
let answer: int = forty.a + two.a;
|
||||
log(debug, answer);
|
||||
assert (answer == 42);
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// error-pattern:did not expect a record with a field `q`
|
||||
|
||||
fn main() { match {x: 1, y: 2} { {x: x, q: q} => { } } }
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// error-pattern:expected a record with 2 fields, found one with 1
|
||||
|
||||
fn main() { match {x: 1, y: 2} { {x: x} => { } } }
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// error-pattern:+ cannot be applied to type `{x: bool}`
|
||||
|
||||
fn main() { let x = {x: true}; x += {x: false}; }
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// error-pattern:+ cannot be applied to type `{x: bool}`
|
||||
|
||||
fn main() { let x = {x: true} + {x: false}; }
|
||||
|
|
@ -9,9 +9,14 @@
|
|||
// except according to those terms.
|
||||
|
||||
// error-pattern:`break` outside of loop
|
||||
|
||||
struct Foo {
|
||||
t: ~str
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let pth = break;
|
||||
|
||||
let rs: {t: ~str} = {t: pth};
|
||||
let rs: Foo = Foo{t: pth};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
// -*- rust -*-
|
||||
// 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.
|
||||
|
||||
|
||||
// error-pattern: record
|
||||
|
||||
type point = {x: int, y: int};
|
||||
|
||||
fn main() {
|
||||
let origin: point = {x: 0, y: 0};
|
||||
|
||||
let origin3d: point = {z: 0,.. origin};
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// error-pattern:refutable pattern
|
||||
// error-pattern:refutable pattern
|
||||
|
||||
enum xx { xx(int), yy, }
|
||||
|
||||
fn main() {
|
||||
let @{x: xx(x), y: y} = @{x: xx(10), y: 20};
|
||||
assert (x + y == 30);
|
||||
|
||||
let [a, b] = ~[1, 2];
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -10,6 +10,10 @@
|
|||
|
||||
// error-pattern:non-scalar cast
|
||||
|
||||
fn main() {
|
||||
log(debug, { x: 1 } as int);
|
||||
struct foo {
|
||||
x:int
|
||||
}
|
||||
|
||||
fn main() {
|
||||
log(debug, foo{ x: 1 } as int);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
// 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.
|
||||
|
||||
type foo = {a: int};
|
||||
type bar = {b: int};
|
||||
|
||||
fn want_foo(f: foo) {}
|
||||
fn have_bar(b: bar) {
|
||||
want_foo(b); //~ ERROR expected a record with field `a`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// error-pattern:expected `int` but found `bool`
|
||||
|
||||
fn main() {
|
||||
|
||||
let a = {foo: 0i};
|
||||
|
||||
let b = {foo: true,.. a};
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// -*- rust -*-
|
||||
// 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.
|
||||
|
||||
|
||||
// error-pattern: mismatched types
|
||||
|
||||
// Issue #51.
|
||||
|
||||
type point = {x: int, y: int};
|
||||
|
||||
fn main() { let p: point = {x: 10}; log(debug, p.y); }
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// -*- rust -*-
|
||||
// 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.
|
||||
|
||||
|
||||
// error-pattern:assigning to immutable field
|
||||
|
||||
type point = {x: int, y: int, z: int};
|
||||
|
||||
fn f(p: point) { p.x = 13; }
|
||||
|
||||
fn main() { let x: point = {x: 10, y: 11, z: 12}; f(x); }
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// error-pattern: assigning to immutable field
|
||||
fn main() { let r: {x: int} = {x: 1}; r.x = 6; }
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
// 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.
|
||||
|
||||
#[warn(structural_records)];
|
||||
pub fn main() {
|
||||
let _foo = {x:5};
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -24,7 +24,7 @@ fn make_uniq_closure<A:Owned + Copy>(a: A) -> fn~() -> uint {
|
|||
|
||||
fn empty_pointy() -> @mut Pointy {
|
||||
return @mut Pointy {
|
||||
mut a : none,
|
||||
a : none,
|
||||
d : make_uniq_closure(~"hi")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue