Navigation Menu

Skip to content

Commit

Permalink
Remove REC, change related tests/docs
Browse files Browse the repository at this point in the history
  • Loading branch information
yjh0502 committed Mar 2, 2013
1 parent 0fd1b58 commit 95bc9ea
Show file tree
Hide file tree
Showing 25 changed files with 74 additions and 335 deletions.
109 changes: 14 additions & 95 deletions doc/rust.md
Expand Up @@ -1285,19 +1285,22 @@ An _implementation_ is an item that implements a [trait](#traits) for a specific
Implementations are defined with the keyword `impl`.

~~~~
# type Point = {x: float, y: float};
# struct Point {x: float, y: float};
# type Surface = int;
# type BoundingBox = {x: float, y: float, width: float, height: float};
# struct BoundingBox {x: float, y: float, width: float, height: float};
# trait Shape { fn draw(Surface); fn bounding_box() -> BoundingBox; }
# fn do_draw_circle(s: Surface, c: Circle) { }
type Circle = {radius: float, center: Point};
struct Circle {
radius: float,
center: Point,
}
impl Shape for Circle {
fn draw(s: Surface) { do_draw_circle(s, self); }
fn bounding_box() -> BoundingBox {
let r = self.radius;
{x: self.center.x - r, y: self.center.y - r,
BoundingBox{x: self.center.x - r, y: self.center.y - r,
width: 2.0 * r, height: 2.0 * r}
}
}
Expand Down Expand Up @@ -1637,38 +1640,6 @@ rec_expr : '{' ident ':' expr
[ ".." expr ] '}'
~~~~~~~~

> **Note:** In future versions of Rust, record expressions and [record types](#record-types) will be removed.
A [_record_](#record-types) _expression_ is one or more comma-separated
name-value pairs enclosed by braces. A fieldname can be any identifier,
and is separated from its value expression by a
colon. To indicate that a field is mutable, the `mut` keyword is
written before its name.

~~~~
{x: 10f, y: 20f};
{name: "Joe", age: 35u, score: 100_000};
{ident: "X", mut count: 0u};
~~~~

The order of the fields in a record expression is significant, and
determines the type of the resulting value. `{a: u8, b: u8}` and `{b:
u8, a: u8}` are two different fields.

A record expression can terminate with the syntax `..` followed by an
expression to denote a functional update. The expression following
`..` (the base) must be of a record type that includes at least all the
fields mentioned in the record expression. A new record will be
created, of the same type as the base expression, with the given
values for the fields that were explicitly specified, and the values
in the base record for all other fields. The ordering of the fields in
such a record expression is not significant.

~~~~
let base = {x: 1, y: 2, z: 3};
{y: 0, z: 10, .. base};
~~~~

### Method-call expressions

~~~~~~~~{.ebnf .gram}
Expand All @@ -1689,7 +1660,7 @@ field_expr : expr '.' ident

A _field expression_ consists of an expression followed by a single dot and an identifier,
when not immediately followed by a parenthesized expression-list (the latter is a [method call expression](#method-call-expressions)).
A field expression denotes a field of a [structure](#structure-types) or [record](#record-types).
A field expression denotes a field of a [structure](#structure-types).

~~~~~~~~ {.field}
myrecord.myfield;
Expand Down Expand Up @@ -1905,8 +1876,10 @@ An example of three different swap expressions:
# let mut x = &mut [0];
# let mut a = &mut [0];
# let i = 0;
# let y = {mut z: 0};
# let b = {mut c: 0};
# struct S1 { z: int };
# struct S2 { c: int };
# let mut y = S1{z: 0};
# let mut b = S2{c: 0};
x <-> a;
x[i] <-> a[i];
Expand Down Expand Up @@ -2328,42 +2301,6 @@ match x {
}
~~~~

Records and structures can also be pattern-matched and their fields bound to variables.
When matching fields of a record,
the fields being matched are specified first,
then a placeholder (`_`) represents the remaining fields.

~~~~
# type options = {choose: bool, size: ~str};
# type player = {player: ~str, stats: (), options: options};
# fn load_stats() { }
# fn choose_player(r: &player) { }
# fn next_player() { }
fn main() {
let r = {
player: ~"ralph",
stats: load_stats(),
options: {
choose: true,
size: ~"small"
}
};
match r {
{options: {choose: true, _}, _} => {
choose_player(&r)
}
{player: ref p, options: {size: ~"small", _}, _} => {
log(info, (copy *p) + ~" is small");
}
_ => {
next_player();
}
}
}
~~~~

Patterns that bind variables default to binding to a copy of the matched value. This can be made
explicit using the ```copy``` keyword, changed to bind to a borrowed pointer by using the ```ref```
keyword, or to a mutable borrowed pointer using ```ref mut```, or the value can be moved into
Expand Down Expand Up @@ -2692,25 +2629,6 @@ let a: List<int> = Cons(7, @Cons(13, @Nil));
~~~~


### Record types

> **Note:** Records are not nominal types, thus do not directly support recursion, visibility control,
> out-of-order field initialization, or coherent trait implementation.
> Records are therefore deprecated and will be removed in future versions of Rust.
> [Structure types](#structure-types) should be used instead.
The record type-constructor forms a new heterogeneous product of values.
Fields of a record type are accessed by name and are arranged in memory in the order specified by the record type.

An example of a record type and its use:

~~~~
type Point = {x: int, y: int};
let p: Point = {x: 10, y: 11};
let px: int = p.x;
~~~~


### Pointer types

All pointers in Rust are explicit first-class values.
Expand Down Expand Up @@ -3040,7 +2958,8 @@ Some operations (such as field selection) implicitly dereference boxes. An
example of an _implicit dereference_ operation performed on box values:

~~~~~~~~
let x = @{y: 10};
struct Foo { y: int }
let x = @Foo{y: 10};
assert x.y == 10;
~~~~~~~~

Expand Down
11 changes: 6 additions & 5 deletions doc/tutorial-borrowed-ptr.md
Expand Up @@ -166,9 +166,9 @@ operator. For example, I could write:
# struct Point {x: float, y: float} // as before
# struct Size {w: float, h: float} // as before
# struct Rectangle {origin: Point, size: Size}
# let rect_stack = &{origin: Point {x: 1f, y: 2f}, size: Size {w: 3f, h: 4f}};
# let rect_managed = @{origin: Point {x: 3f, y: 4f}, size: Size {w: 3f, h: 4f}};
# let rect_unique = ~{origin: Point {x: 5f, y: 6f}, size: Size {w: 3f, h: 4f}};
# let rect_stack = &Rectangle {origin: Point {x: 1f, y: 2f}, size: Size {w: 3f, h: 4f}};
# let rect_managed = @Rectangle {origin: Point {x: 3f, y: 4f}, size: Size {w: 3f, h: 4f}};
# let rect_unique = ~Rectangle {origin: Point {x: 5f, y: 6f}, size: Size {w: 3f, h: 4f}};
# fn compute_distance(p1: &Point, p2: &Point) -> float { 0f }
compute_distance(&rect_stack.origin, &rect_managed.origin);
~~~
Expand Down Expand Up @@ -274,13 +274,14 @@ the following function is legal:

~~~
# fn some_condition() -> bool { true }
# struct Foo { f: int }
fn example3() -> int {
let mut x = ~{f: 3};
let mut x = ~Foo {f: 3};
if some_condition() {
let y = &x.f; // -+ L
return *y; // |
} // -+
x = ~{f: 4};
x = ~Foo {f: 4};
...
# return 0;
}
Expand Down
8 changes: 4 additions & 4 deletions src/libcore/dvec.rs
@@ -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.
//
Expand Down Expand Up @@ -62,17 +62,17 @@ pub struct DVec<A> {

/// Creates a new, empty dvec
pub pure fn DVec<A>() -> DVec<A> {
DVec {mut data: ~[]}
DVec {data: ~[]}
}

/// Creates a new dvec with a single element
pub pure fn from_elem<A>(e: A) -> DVec<A> {
DVec {mut data: ~[e]}
DVec {data: ~[e]}
}

/// Creates a new dvec with the contents of a vector
pub pure fn from_vec<A>(v: ~[A]) -> DVec<A> {
DVec {mut data: v}
DVec {data: v}
}

/// Consumes the vector and returns its contents
Expand Down
18 changes: 11 additions & 7 deletions src/libcore/os.rs
@@ -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.
//
Expand Down Expand Up @@ -322,8 +322,8 @@ pub struct Pipe { mut in: c_int, mut out: c_int }
#[cfg(unix)]
pub fn pipe() -> Pipe {
unsafe {
let mut fds = Pipe {mut in: 0 as c_int,
mut out: 0 as c_int };
let mut fds = Pipe {in: 0 as c_int,
out: 0 as c_int };
assert (libc::pipe(&mut fds.in) == (0 as c_int));
return Pipe {in: fds.in, out: fds.out};
}
Expand All @@ -339,8 +339,8 @@ pub fn pipe() -> Pipe {
// fully understand. Here we explicitly make the pipe non-inheritable,
// which means to pass it to a subprocess they need to be duplicated
// first, as in rust_run_program.
let mut fds = Pipe { mut in: 0 as c_int,
mut out: 0 as c_int };
let mut fds = Pipe {in: 0 as c_int,
out: 0 as c_int };
let res = libc::pipe(&mut fds.in, 1024 as c_uint,
(libc::O_BINARY | libc::O_NOINHERIT) as c_int);
assert (res == 0 as c_int);
Expand Down Expand Up @@ -566,13 +566,17 @@ pub fn path_exists(p: &Path) -> bool {
*
* If the given path is relative, return it prepended with the current working
* directory. If the given path is already an absolute path, return it
* as is. This is a shortcut for calling os::getcwd().unsafe_join(p)
* as is.
*/
// NB: this is here rather than in path because it is a form of environment
// querying; what it does depends on the process working directory, not just
// the input paths.
pub fn make_absolute(p: &Path) -> Path {
getcwd().unsafe_join(p)
if p.is_absolute {
copy *p
} else {
getcwd().push_many(p.components)
}
}


Expand Down
6 changes: 3 additions & 3 deletions src/libcore/ptr.rs
@@ -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.
//
Expand Down Expand Up @@ -300,15 +300,15 @@ impl<T:Ord> Ord for &const T {
pub fn test() {
unsafe {
struct Pair {mut fst: int, mut snd: int};
let mut p = Pair {mut fst: 10, mut snd: 20};
let mut p = Pair {fst: 10, snd: 20};
let pptr: *mut Pair = &mut p;
let iptr: *mut int = cast::reinterpret_cast(&pptr);
assert (*iptr == 10);;
*iptr = 30;
assert (*iptr == 30);
assert (p.fst == 30);;

*pptr = Pair {mut fst: 50, mut snd: 60};
*pptr = Pair {fst: 50, snd: 60};
assert (*iptr == 50);
assert (p.fst == 50);
assert (p.snd == 60);
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/ebml.rs
@@ -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.
//
Expand Down Expand Up @@ -219,7 +219,7 @@ pub mod reader {
}

pub fn Decoder(d: Doc) -> Decoder {
Decoder { mut parent: d, mut pos: d.start }
Decoder { parent: d, pos: d.start }
}

priv impl Decoder {
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/sync.rs
@@ -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.
//
Expand Down Expand Up @@ -87,7 +87,7 @@ enum Sem<Q> = Exclusive<SemInner<Q>>;
#[doc(hidden)]
fn new_sem<Q:Owned>(count: int, q: Q) -> Sem<Q> {
Sem(exclusive(SemInner {
mut count: count, waiters: new_waitqueue(), blocked: q }))
count: count, waiters: new_waitqueue(), blocked: q }))
}
#[doc(hidden)]
fn new_sem_and_signal(count: int, num_condvars: uint)
Expand Down
16 changes: 6 additions & 10 deletions src/libsyntax/parse/parser.rs
@@ -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.
//
Expand Down Expand Up @@ -1093,15 +1093,10 @@ pub impl Parser {
self.mk_expr(lo, hi, expr_tup(es))
}
} else if *self.token == token::LBRACE {
if self.looking_at_record_literal() {
ex = self.parse_record_literal();
hi = self.span.hi;
} else {
self.bump();
let blk = self.parse_block_tail(lo, default_blk);
return self.mk_expr(blk.span.lo, blk.span.hi,
expr_block(blk));
}
self.bump();
let blk = self.parse_block_tail(lo, default_blk);
return self.mk_expr(blk.span.lo, blk.span.hi,
expr_block(blk));
} else if token::is_bar(*self.token) {
return self.parse_lambda_expr();
} else if self.eat_keyword(~"if") {
Expand Down Expand Up @@ -1223,6 +1218,7 @@ pub impl Parser {
self.bump();
let mut fields = ~[];
let mut base = None;

fields.push(self.parse_field(token::COLON));
while *self.token != token::RBRACE {
if self.try_parse_obsolete_with() {
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/print/pprust.rs
Expand Up @@ -1213,7 +1213,7 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) {
print_expr(s, expr);
end(s);
}
_ => word(s.s, ~",")
_ => (word(s.s, ~","))
}
word(s.s, ~"}");
}
Expand Down
17 changes: 11 additions & 6 deletions src/test/compile-fail/autoderef-full-lval.rs
Expand Up @@ -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);
Expand Down

5 comments on commit 95bc9ea

@bors
Copy link
Contributor

@bors bors commented on 95bc9ea Mar 2, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from nikomatsakis
at yjh0502@95bc9ea

@bors
Copy link
Contributor

@bors bors commented on 95bc9ea Mar 2, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging yjh0502/rust/empty_struct = 95bc9ea into auto

@bors
Copy link
Contributor

@bors bors commented on 95bc9ea Mar 2, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yjh0502/rust/empty_struct = 95bc9ea merged ok, testing candidate = 5aca7d6

@bors
Copy link
Contributor

@bors bors commented on 95bc9ea Mar 2, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 95bc9ea Mar 2, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding incoming to auto = 5aca7d6

Please sign in to comment.