An expression like:
foo(1, fail, 2)
was failing to parse, because the parser was interpreting the comma
as the start of an expression that was an argument to fail, rather
than recognizing that the fail here has no arguments
Fixed this by using can_begin_expr to determine whether the next
token after a fail token suggests that this is a nullary fail or a
unary fail.
In addition, when translating calls, check before translating each
argument that the block still isn't terminated. This has the effect
that if an argument list includes fail, the back-end won't keep trying
to generate code for successive arguments and trip the !*terminated
assertion.
The code for translating a fail (for example) would call
Unreachable(), which terminates the block; if a fail appeared as an
argument, this would cause an LLVM assertion failure. Changed
trans_call to handle this situation correctly.
This is important since we are going to be making functions noncopyable
soon, which means we'll be seeing a lot of boxed functions.
(*f)(...) is really just too heavyweight.
Doing the autodereferencing was a very little bit tricky since
trans_call works with an *lval* of the function whereas existing
autoderef code was not for lvals.
Implement "claim" (issue #14), which is a version of "check" that
doesn't really do the check at runtime. It's an unsafe feature.
The new flag --check-claims turns claims into checks automatically --
but it's off by default, so by default, the assertion in a claim
doesn't execute at runtime.
The meta items within a crate's link attribute are used in linkage:
#[link(name = "std",
vers = "1.0",
custom = "whatever")];
Name and vers are treated specially, and everything else is hashed together
into the crate meta hash.
Issue #487
Resources are now defined like...
resource fd(int n) { close(n); }
Calling fd with an int will then produce a non-copyable value
that, when dropped, will call close on the given int.
Wrote some small test cases that use while loops and moves, to
make sure the poststate for the loop body gets propagated into the
new prestate and deinitialization gets reflected.
Along with that, rewrite the code for intersecting states. I still
find it dodgy, but I guess I'll continue trying to add more tests.
Also, I'll probably feel better about it once I start formalizing
the algorithm.