I believe this patch incorporates all expected syntax changes from extern
function reform (#3678). You can now write things like:
extern "<abi>" fn foo(s: S) -> T { ... }
extern "<abi>" mod { ... }
extern "<abi>" fn(S) -> T
The ABI for foreign functions is taken from this syntax (rather than from an
annotation). We support the full ABI specification I described on the mailing
list. The correct ABI is chosen based on the target architecture.
Calls by pointer to C functions are not yet supported, and the Rust type of
crust fns is still *u8.
For bootstrapping purposes, this commit does not remove all uses of
the keyword "pure" -- doing so would cause the compiler to no longer
bootstrap due to some syntax extensions ("deriving" in particular).
Instead, it makes the compiler ignore "pure". Post-snapshot, we can
remove "pure" from the language.
There are quite a few (~100) borrow check errors that were essentially
all the result of mutable fields or partial borrows of `@mut`. Per
discussions with Niko I think we want to allow partial borrows of
`@mut` but detect obvious footguns. We should also improve the error
message when `@mut` is erroneously reborrowed.
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
}
}
```