diff --git a/AUTHORS.txt b/AUTHORS.txt index 92903a26093f9..33ac21e6db9d8 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -93,6 +93,7 @@ Josh Matthews Joshua Clark Joshua Wise Jyun-Yan You +Kang Seonghoon Kelly Wilson Kevin Atkinson Kevin Cantu diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c6e9478713d58..d934e38c35d24 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ You're not off the hook even if you just stick to documentation; code examples i Pull requests will be treated as "review requests", and we will give feedback we expect to see corrected on [style](https://github.com/mozilla/rust/wiki/Note-style-guide) and substance before pulling. Changes contributed via pull request should focus on a single issue at a time, like any other. -We will not look accept pull-requests that try to "sneak" unrelated changes in. +We will not accept pull-requests that try to "sneak" unrelated changes in. Normally, all pull requests must include regression tests (see [Note-testsuite](https://github.com/mozilla/rust/wiki/Note-testsuite)) that test your change. Occasionally, a change will be very difficult to test for. diff --git a/configure b/configure index d9f2db8e11099..3576e43468dd7 100755 --- a/configure +++ b/configure @@ -678,7 +678,7 @@ do LLVM_BUILD_DIR=${CFG_BUILD_DIR}llvm/$t if [ ! -z "$CFG_DISABLE_OPTIMIZE_LLVM" ] then - LLVM_DBG_OPTS="" + LLVM_DBG_OPTS="--enable-debug-symbols --disable-optimized" # Just use LLVM straight from its build directory to # avoid 'make install' time LLVM_INST_DIR=$LLVM_BUILD_DIR/Debug+Asserts diff --git a/doc/rust.md b/doc/rust.md index 975e4bbb8a209..2b9ed6d2d5143 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -297,7 +297,7 @@ the following forms: num_lit : nonzero_dec [ dec_digit | '_' ] * num_suffix ? | '0' [ [ dec_digit | '_' ] + num_suffix ? | 'b' [ '1' | '0' | '_' ] + int_suffix ? - | 'x' [ hex_digit | '-' ] + int_suffix ? ] ; + | 'x' [ hex_digit | '_' ] + int_suffix ? ] ; num_suffix : int_suffix | float_suffix ; @@ -908,6 +908,11 @@ function defined above on `[1, 2]` will instantiate type parameter `T` with `int`, and require the closure parameter to have type `fn(int)`. +The type parameters can also be explicitly supplied in a trailing +[path](#paths) component after the function name. This might be necessary +if there is not sufficient context to determine the type parameters. For +example, `sys::size_of::() == 4`. + Since a parameter type is opaque to the generic function, the set of operations that can be performed on it is limited. Values of parameter type can always be moved, but they can only be copied when the @@ -1085,6 +1090,15 @@ let p = Point(10, 11); let px: int = match p { Point(x, _) => x }; ~~~~ +A _unit-like struct_ is a structure without any fields, defined by leaving off the fields list entirely. +Such types will have a single value, just like the [unit value `()`](#unit-and-boolean-literals) of the unit type. +For example: + +~~~~ +struct Cookie; +let c = [Cookie, Cookie, Cookie, Cookie]; +~~~~ + ### Enumerations An _enumeration_ is a simultaneous definition of a nominal [enumerated type](#enumerated-types) as well as a set of *constructors*, @@ -1590,7 +1604,8 @@ struct_expr : expr_path '{' ident ':' expr [ ',' ident ':' expr ] * [ ".." expr ] '}' | expr_path '(' expr - [ ',' expr ] * ')' + [ ',' expr ] * ')' | + expr_path ~~~~~~~~ There are several forms of structure expressions. @@ -1600,24 +1615,28 @@ providing the field values of a new instance of the structure. A field name 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. -A _tuple structure expression_ constists of the [path](#paths) of a [structure item](#structures), +A _tuple structure expression_ consists of the [path](#paths) of a [structure item](#structures), followed by a parenthesized list of one or more comma-separated expressions (in other words, the path of a structured item followed by a tuple expression). The structure item must be a tuple structure item. +A _unit-like structure expression_ consists only of the [path](#paths) of a [structure item](#structures). + The following are examples of structure expressions: ~~~~ # struct Point { x: float, y: float } # struct TuplePoint(float, float); -# mod game { pub struct User { name: &str, age: uint, mut score: uint } } -# use game; +# mod game { pub struct User { name: &str, age: uint, score: uint } } +# struct Cookie; fn some_fn(t: T) {} Point {x: 10f, y: 20f}; TuplePoint(10f, 20f); -let u = game::User {name: "Joe", age: 35u, mut score: 100_000}; +let u = game::User {name: "Joe", age: 35u, score: 100_000}; +some_fn::(Cookie); ~~~~ A structure expression forms a new value of the named structure type. +Note that for a given *unit-like* structure type, this will always be the same value. A structure expression can terminate with the syntax `..` followed by an expression to denote a functional update. The expression following `..` (the base) must be of the same structure type as the new structure type being formed. @@ -2041,12 +2060,14 @@ an optional reference slot to serve as the function's output, bound to the `lval` on the right hand side of the call. If the function eventually returns, then the expression completes. -An example of a call expression: +Some examples of call expressions: ~~~~ # fn add(x: int, y: int) -> int { 0 } +# use core::from_str::FromStr::from_str; let x: int = add(1, 2); +let pi = from_str::("3.14"); ~~~~ ### Lambda expressions @@ -2644,7 +2665,10 @@ the resulting `struct` value will always be laid out in memory in the order spec The fields of a `struct` may be qualified by [visibility modifiers](#visibility-modifiers), to restrict access to implementation-private data in a structure. -A `tuple struct` type is just like a structure type, except that the fields are anonymous. +A _tuple struct_ type is just like a structure type, except that the fields are anonymous. + +A _unit-like struct_ type is like a structure type, except that it has no fields. +The one value constructed by the associated [structure expression](#structure-expression) is the only value that inhabits such a type. ### Enumerated types diff --git a/doc/tutorial-borrowed-ptr.md b/doc/tutorial-borrowed-ptr.md index c13b2528598c1..0c1624706bfeb 100644 --- a/doc/tutorial-borrowed-ptr.md +++ b/doc/tutorial-borrowed-ptr.md @@ -348,12 +348,12 @@ mutations: ~~~ {.xfail-test} fn example3() -> int { struct R { g: int } - struct S { mut f: ~R } + struct S { f: ~R } - let mut x = ~S {mut f: ~R {g: 3}}; + let mut x = ~S {f: ~R {g: 3}}; let y = &x.f.g; - x = ~S {mut f: ~R {g: 4}}; // Error reported here. - x.f = ~R {g: 5}; // Error reported here. + x = ~S {f: ~R {g: 4}}; // Error reported here. + x.f = ~R {g: 5}; // Error reported here. *y } ~~~ @@ -362,91 +362,6 @@ In this case, two errors are reported, one when the variable `x` is modified and another when `x.f` is modified. Either modification would invalidate the pointer `y`. -Things get trickier when the unique box is not uniquely owned by the -stack frame, or when there is no way for the compiler to determine the -box's owner. Consider a program like this: - -~~~ {.xfail-test} -struct R { g: int } -struct S { mut f: ~R } -fn example5a(x: @S, callback: @fn()) -> int { - let y = &x.f.g; // Error reported here. - ... - callback(); - ... -# return 0; -} -~~~ - -Here the heap looks something like: - -~~~ {.notrust} - Stack Managed Heap Exchange Heap - - x +------+ +-------------+ +------+ - | @... | ----> | mut f: ~... | --+-> | g: 3 | - y +------+ +-------------+ | +------+ - | &int | -------------------------+ - +------+ -~~~ - -In this case, the owning reference to the value being borrowed is -`x.f`. Moreover, `x.f` is both mutable and *aliasable*. Aliasable -means that there may be other pointers to that same managed box, so -even if the compiler were to prove an absence of mutations to `x.f`, -code could mutate `x.f` indirectly by changing an alias of -`x`. Therefore, to be safe, the compiler only accepts *pure* actions -during the lifetime of `y`. We define what "pure" means in the section -on [purity](#purity). - -Besides ensuring purity, the only way to borrow the interior of a -unique found in aliasable memory is to ensure that the borrowed field -itself is also unique, as in the following example: - -~~~ -struct R { g: int } -struct S { f: ~R } -fn example5b(x: @S) -> int { - let y = &x.f.g; - ... -# return 0; -} -~~~ - -Here, the field `f` is not declared as mutable. But that is enough for -the compiler to know that, even if aliases to `x` exist, the field `f` -cannot be changed and hence the unique box `g` will remain valid. - -If you do have a unique box in a mutable field, and you wish to borrow -it, one option is to use the swap operator to move that unique box -onto your stack: - -~~~ -struct R { g: int } -struct S { mut f: ~R } -fn example5c(x: @S) -> int { - let mut v = ~R {g: 0}; - v <-> x.f; // Swap v and x.f - { // Block constrains the scope of `y`: - let y = &v.g; - ... - } - x.f = v; // Replace x.f - ... -# return 0; -} -~~~ - -Of course, this has the side effect of modifying your managed box for -the duration of the borrow, so it only works when you know that you -won't be accessing that same box for the duration of the loan. Also, -it is sometimes necessary to introduce additional blocks to constrain -the scope of the loan. In this example, the borrowed pointer `y` -would still be in scope when you moved the value `v` back into `x.f`, -and hence moving `v` would be considered illegal. You cannot move -values if they are the targets of valid outstanding loans. Introducing -the block restricts the scope of `y`, making the move legal. - # Borrowing and enums The previous example showed that the type system forbids any borrowing @@ -558,11 +473,6 @@ permit `ref` bindings into data owned by the stack frame even if the data are mutable, but otherwise it requires that the data reside in immutable memory. -> ***Note:*** Right now, pattern bindings not explicitly annotated -> with `ref` or `copy` use a special mode of "implicit by reference". -> This is changing as soon as we finish updating all the existing code -> in the compiler that relies on the current settings. - # Returning borrowed pointers So far, all of the examples we've looked at use borrowed pointers in a @@ -745,69 +655,6 @@ fn select(shape: &Shape, threshold: float, This is equivalent to the previous definition. -# Purity - -As mentioned before, the Rust compiler offers a kind of escape hatch -that permits borrowing of any data, as long as the actions that occur -during the lifetime of the borrow are pure. Pure actions are those -that only modify data owned by the current stack frame. The compiler -can therefore permit arbitrary pointers into the heap, secure in the -knowledge that no pure action will ever cause them to become -invalidated (the compiler must still track data on the stack which is -borrowed and enforce those rules normally, of course). A pure function -in Rust is referentially transparent: it returns the same results -given the same (observably equivalent) inputs. That is because while -pure functions are allowed to modify data, they may only modify -*stack-local* data, which cannot be observed outside the scope of the -function itself. (Using an `unsafe` block invalidates this guarantee.) - -Let’s revisit a previous example and show how purity can affect -typechecking. Here is `example5a()`, which borrows the interior of a -unique box found in an aliasable, mutable location, only now we’ve -replaced the `...` with some specific code: - -~~~ -struct R { g: int } -struct S { mut f: ~R } -fn example5a(x: @S ...) -> int { - let y = &x.f.g; // Unsafe - *y + 1 -} -~~~ - -The new code simply returns an incremented version of `y`. This code -clearly doesn't mutate the heap, so the compiler is satisfied. - -But suppose we wanted to pull the increment code into a helper, like -this: - -~~~ -fn add_one(x: &int) -> int { *x + 1 } -~~~ - -We can now update `example5a()` to use `add_one()`: - -~~~ -# struct R { g: int } -# struct S { mut f: ~R } -# pure fn add_one(x: &int) -> int { *x + 1 } -fn example5a(x: @S ...) -> int { - let y = &x.f.g; - add_one(y) // Error reported here -} -~~~ - -But now the compiler will report an error again. The reason is that it -only considers one function at a time (like most typecheckers), and -so it does not know that `add_one()` consists of pure code. We can -help the compiler by labeling `add_one()` as pure: - -~~~ -pure fn add_one(x: &int) -> int { *x + 1 } -~~~ - -With this change, the modified version of `example5a()` will again compile. - # Conclusion So there you have it: a (relatively) brief tour of the borrowed pointer diff --git a/doc/tutorial-ffi.md b/doc/tutorial-ffi.md index c3def1f4b27c4..b7659376ed65c 100644 --- a/doc/tutorial-ffi.md +++ b/doc/tutorial-ffi.md @@ -220,21 +220,21 @@ extern mod std; use libc::c_ulonglong; struct timeval { - mut tv_sec: c_ulonglong, - mut tv_usec: c_ulonglong + tv_sec: c_ulonglong, + tv_usec: c_ulonglong } #[nolink] extern mod lib_c { - fn gettimeofday(tv: *timeval, tz: *()) -> i32; + fn gettimeofday(tv: *mut timeval, tz: *()) -> i32; } fn unix_time_in_microseconds() -> u64 { unsafe { - let x = timeval { - mut tv_sec: 0 as c_ulonglong, - mut tv_usec: 0 as c_ulonglong + let mut x = timeval { + tv_sec: 0 as c_ulonglong, + tv_usec: 0 as c_ulonglong }; - lib_c::gettimeofday(ptr::addr_of(&x), ptr::null()); + lib_c::gettimeofday(&mut x, ptr::null()); return (x.tv_sec as u64) * 1000_000_u64 + (x.tv_usec as u64); } } diff --git a/doc/tutorial-tasks.md b/doc/tutorial-tasks.md index c0f9a37627065..22d0ff8bf78a2 100644 --- a/doc/tutorial-tasks.md +++ b/doc/tutorial-tasks.md @@ -468,7 +468,6 @@ Here is the function that implements the child task: ~~~~ # use std::comm::DuplexStream; -# use comm::{Port, Chan}; fn stringifier(channel: &DuplexStream<~str, uint>) { let mut value: uint; loop { @@ -491,7 +490,6 @@ Here is the code for the parent task: ~~~~ # use std::comm::DuplexStream; -# use comm::{Port, Chan}; # use task::spawn; # fn stringifier(channel: &DuplexStream<~str, uint>) { # let mut value: uint; diff --git a/doc/tutorial.md b/doc/tutorial.md index 41895ebed7c59..d31fbbb0c07a1 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -556,7 +556,7 @@ let mut x = 5; loop { x += x - 3; if x % 5 == 0 { break; } - io::println(int::str(x)); + io::println(int::to_str(x)); } ~~~~ @@ -583,19 +583,16 @@ Inherited mutability means that any field of a struct may be mutable, if the struct is in a mutable slot (or a field of a struct in a mutable slot, and so forth). -A struct that is not mutable due to inherited mutability may declare some -of its fields nevertheless mutable, using the `mut` keyword. - ~~~~ struct Stack { content: ~[int], - mut head: uint + head: uint } ~~~~ -With a value of such a type, you can do `mystack.head += 1`. If `mut` were -omitted from the type, such an assignment to a struct without inherited -mutability would result in a type error. +With a value (say, `mystack`) of such a type in a mutable location, you can do +`mystack.head += 1`. But in an immutable location, such an assignment to a +struct without inherited mutability would result in a type error. `match` patterns destructure structs. The basic syntax is `Name { fieldname: pattern, ... }`: @@ -938,19 +935,19 @@ type that contains managed boxes or other managed types. ~~~ // A linked list node struct Node { - mut next: MaybeNode, - mut prev: MaybeNode, + next: MaybeNode, + prev: MaybeNode, payload: int } enum MaybeNode { - SomeNode(@Node), + SomeNode(@mut Node), NoNode } -let node1 = @Node { next: NoNode, prev: NoNode, payload: 1 }; -let node2 = @Node { next: NoNode, prev: NoNode, payload: 2 }; -let node3 = @Node { next: NoNode, prev: NoNode, payload: 3 }; +let node1 = @mut Node { next: NoNode, prev: NoNode, payload: 1 }; +let node2 = @mut Node { next: NoNode, prev: NoNode, payload: 2 }; +let node3 = @mut Node { next: NoNode, prev: NoNode, payload: 3 }; // Link the three list nodes together node1.next = SomeNode(node2); @@ -1129,7 +1126,7 @@ points to. ~~~ let managed = @mut 10; -let owned = ~mut 20; +let mut owned = ~20; let mut value = 30; let borrowed = &mut value; @@ -2273,7 +2270,9 @@ fn chicken_farmer() { // The same, but name it `my_chicken` use my_chicken = farm::chicken; ... +# my_chicken(); } +# chicken(); # } ~~~ @@ -2300,16 +2299,15 @@ mod farm { # impl Human { fn rest(&self) { } } # pub fn make_me_a_farm() -> farm::Farm { farm::Farm { chickens: ~[], cows: ~[], farmer: Human(0) } } pub struct Farm { - priv mut chickens: ~[Chicken], - priv mut cows: ~[Cow], + priv chickens: ~[Chicken], + priv cows: ~[Cow], farmer: Human } - // Note - visibility modifiers on impls currently have no effect impl Farm { priv fn feed_chickens(&self) { ... } priv fn feed_cows(&self) { ... } - fn add_chicken(&self, c: Chicken) { ... } + pub fn add_chicken(&self, c: Chicken) { ... } } pub fn feed_animals(farm: &Farm) { diff --git a/src/etc/emacs/rust-mode.el b/src/etc/emacs/rust-mode.el index 5fbd2ab67c29d..5a6acbaddda0a 100644 --- a/src/etc/emacs/rust-mode.el +++ b/src/etc/emacs/rust-mode.el @@ -66,22 +66,17 @@ "trait" "struct" "fn" "enum" "impl")) (puthash word 'def table)) - (dolist (word '("again" "assert" - "break" - "copy" - "do" "drop" - "else" "export" "extern" - "fail" "for" - "if" "use" - "let" "log" "loop" - "move" "new" - "pure" "pub" "priv" - "ref" "return" "static" - "unchecked" "unsafe" - "while")) + (dolist (word '("as" "break" + "copy" "do" "drop" "else" + "extern" "for" "if" "let" "log" + "loop" "once" "priv" "pub" "pure" + "ref" "return" "static" "unsafe" "use" + "while" "while" + "assert" + "mut")) (puthash word t table)) (puthash "match" 'alt table) - (dolist (word '("true" "false")) (puthash word 'atom table)) + (dolist (word '("self" "true" "false")) (puthash word 'atom table)) table)) ;; FIXME type-context keywords diff --git a/src/etc/gedit/readme.txt b/src/etc/gedit/readme.txt new file mode 100644 index 0000000000000..735b023627662 --- /dev/null +++ b/src/etc/gedit/readme.txt @@ -0,0 +1,11 @@ +Add syntax highlighting for Mozilla Rust in GtkSourceView (used by GEdit). + + +Instructions for Ubuntu Linux 12.04+ + +1) Close all instances of GEdit + +2) Copy the included "share" folder into "~/.local/" + +3) Open a shell in "~/.local/share/" and run "update-mime-database mime" + diff --git a/src/etc/gedit/share/gtksourceview-3.0/language-specs/rust.lang b/src/etc/gedit/share/gtksourceview-3.0/language-specs/rust.lang new file mode 100644 index 0000000000000..0b23808b76524 --- /dev/null +++ b/src/etc/gedit/share/gtksourceview-3.0/language-specs/rust.lang @@ -0,0 +1,264 @@ + + + + + + + text/x-rust + *.rs;*.rc + // + /* + */ + + + +