diff options
| author | Tim Chevalier <[email protected]> | 2011-05-02 14:28:35 -0700 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2011-05-05 11:26:07 -0700 |
| commit | 3060eadcbabba50fd6a5d633fea710b6b6bed614 (patch) | |
| tree | 600e724e9e29f38bddd2861c006f4da49e7fa2ee | |
| parent | Change checks to asserts in test/bench files (diff) | |
| download | rust-3060eadcbabba50fd6a5d633fea710b6b6bed614.tar.xz rust-3060eadcbabba50fd6a5d633fea710b6b6bed614.zip | |
Check well-formedness of constraints
Check that the operand in a constraint is an explicit name,
and that the operands are all local variables or literals. Still need
to check that the name refers to a pure function.
| -rw-r--r-- | src/comp/front/ast.rs | 14 | ||||
| -rw-r--r-- | src/comp/middle/typeck.rs | 29 | ||||
| -rw-r--r-- | src/test/compile-fail/not-a-pred-3.rs | 15 | ||||
| -rw-r--r-- | src/test/compile-fail/not-pred-args.rs | 11 |
4 files changed, 63 insertions, 6 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index 1f123f74..cc7569e1 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -563,6 +563,20 @@ fn is_call_expr(@expr e) -> bool { } } +fn is_constraint_arg(@expr e) -> bool { + alt (e.node) { + case (expr_lit(_,_)) { + ret true; + } + case (expr_path(_, option.some[def](def_local(_)), _)) { + ret true; + } + case (_) { + ret false; + } + } +} + // // Local Variables: // mode: rust diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index fd915108..e693fdf7 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1964,12 +1964,29 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr { literals or slots */ alt (e.node) { case (ast.expr_call(?operator, ?operands, _)) { - /* operator must be a pure function */ - /* FIXME: need more checking */ - ret @fold.respan[ast.expr_] - (expr.span, ast.expr_check(expr_t, - plain_ann(fcx.ccx.tcx))); - + alt (operator.node) { + case (ast.expr_path(?oper_name, ?d_id, _)) { + + for (@ast.expr operand in operands) { + if (! ast.is_constraint_arg(operand)) { + fcx.ccx.sess.span_err(expr.span, + "Constraint args must be " + + "slot variables or literals"); + } + } + + /* operator must be a pure function */ + /* FIXME: need more checking */ + ret @fold.respan[ast.expr_] + (expr.span, ast.expr_check(expr_t, + plain_ann(fcx.ccx.tcx))); + } + case (_) { + fcx.ccx.sess.span_err(expr.span, + "In a constraint, expected the constraint name " + + "to be an explicit name"); + } + } } case (_) { fcx.ccx.sess.span_err(expr.span, diff --git a/src/test/compile-fail/not-a-pred-3.rs b/src/test/compile-fail/not-a-pred-3.rs new file mode 100644 index 00000000..ea1b6cc0 --- /dev/null +++ b/src/test/compile-fail/not-a-pred-3.rs @@ -0,0 +1,15 @@ +// -*- rust -*- +// xfail-boot + +// error-pattern: expected the constraint name + +obj f () { + fn g (int q) -> bool { + ret true; + } +} + +fn main() { + auto z = f (); + check (z.g)(42); // should fail to typecheck, as z.g isn't an explicit name +} diff --git a/src/test/compile-fail/not-pred-args.rs b/src/test/compile-fail/not-pred-args.rs new file mode 100644 index 00000000..c92b4ff9 --- /dev/null +++ b/src/test/compile-fail/not-pred-args.rs @@ -0,0 +1,11 @@ +// -*- rust -*- +// xfail-boot + +// error-pattern: Constraint args must be + +fn f(int q) -> bool { ret true; } + +fn main() { +// should fail to typecheck, as pred args must be slot variables or literals + check f(42 * 17); +} |