src/comp/syntax is currently just a sub-module of rustc, but it will,
in the near future, be its own crate. This includes:
- The AST data structure
- The parser
- The pretty-printer
- Visit, walk, and fold
- The syntax extension system
- Some utility stuff that should be in the stdlib*
*) Stdlib extensions currently require a snapshot before they can be
used, and the win build is very broken right now. This is temporary
and will be cleaned up when one of those problems goes away.
A lot of code was moved by this patch, mostly towards a more organized
layout. Some package paths did get longer, and I guess the new layout
will take some getting used to. Sorry about that!
Please try not to re-introduce any dependencies in syntax/ on any of
the other src/comp/ subdirs.
Modify typestate to check for unused variables and emit warnings
where relevant. This exposed a (previously harmless) bug in
collect_locals where outer functions had bit-vector entries
for init constraints for variables declared in their inner
nested functions. Fixing that required changing collect_locals to
use visit instead of walk -- probably a good thing anyway.
Modified typestate to throw away any constraints mentioning a
variable on the LHS of an assignment, recv, assign_op, or on
either side of a swap.
Some code cleanup as well.
typestate now drops constraints correctly in the post-state of
a move expression or a declaration whose op is a move. It doesn't
yet drop constraints mentioning variables that get updated.
To do this, I had to change typestate to use trit-vectors instead
of bit-vectors, because for every constraint, there are three
possible values: known-to-be-false (e.g. after x <- y, init(y) is
known-to-be-false), known-to-be-true, and unknown. Before, we
conflated known-to-be-false with unknown. But move requires them
to be treated differently. Consider:
(program a)
(a1) x = 1;
(a2) y <- x;
(a3) log x;
(program b)
(b1) x = 1;
(b2) y <- z;
(b3) log x;
With only two values, the postcondition of statement a2 for
constraint init(x) is the same as that of b2: 0. But in (a2)'s
postcondition, init(x) *must* be false, but in (b2)'s condition,
it's just whatever it was in the postcondition of the preceding statement.
This involved, in part, changing the ast::def type so that a def_fn
has a "purity" field. This lets the typechecker determine whether
functions defined in other crates are pure.
It also required updating some error messages in tests. As a test
for cross-crate constrained functions, I added a safe_slice function
to std::str (slice(), with one of the asserts replaced with a
function precondition) and some test cases (various versions of
fn-constraint.rs) that call it. Also, I changed "fn" to "pred" for
some of the boolean functions in std::uint.
This reduces some redundancy in the AST data structures and cruft in
the code that works with them. To get a def_id from a node_id, apply
ast::local_def, which adds the local crate_num to the given node_id.
Most code only deals with crate-local node_ids, and won't have to
create def_ids at all.
Revert "rustc: Export only what's needed from middle::ty"
This reverts commit 4255d58aa5.
Revert "rustc: Make name resolution errors less fatal"
This reverts commit b8ab9ea89c.
Revert "rustc: Make import resolution errors less fatal"
This reverts commit 92a8ae94b9.
Revert "rustc: Export only what's used from middle::resolve"
This reverts commit 4539a2cf7a.
Revert "rustc: Re-introduce session.span_err, session.err"
This reverts commit 7fe9a88e31.
Revert "rustc: Rename session.span_err -> span_fatal, err -> fatal"
This reverts commit c394a7f49a.
I noticed that typestate was being lazier than it should be,
because it was only checking typestate for statements and
top-level expression (that is, the expression in a stmt_expr, but
not any subexpressions). So I rewrote the checks in tstate/ck.rs
to use walk, which exposed a few bugs in typestate that I fixed.
Also added some more test cases for if-check.
I added a "resolved" version of the ast::constr type -- ty::constr_def
-- that has a def_id field instead of an ann_field. This is more
consistent with other types and eliminates some checking.
Incidentally, I removed the def_map argument to the top-level function
in middle::alias, since the ty::ctxt already has a def_map field.
Generate appropriate constraints for calls to functions with
preconditions, and reject calls where those constraints don't
hold true in the prestate.
...by which I mean that it works for one test case :-)
Changed function types to include a list of constraints. Added
code for parsing and pretty-printing constraints. This necessitated
splitting pprust into two files (pprust and ppaux) to break a
circulate dependency, as ty_to_str now needs to print out constraints,
which may include literals, but pprust depended on ty.
Change ty_fn to have a controlflow field. A 'controlflow' is
essentially a bit of data that says whether or not this function
never returns to the caller (if it never returns, that means it calls
"fail" or another "never-returns" function on every control path).
Also add syntax for annotating functions that never return:
fn foo() -> ! {
fail;
}
for example. Functions marked with ! implicitly have a result type of
ty_bot, which is a new type that this commit also adds.