aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Chevalier <[email protected]>2011-05-02 14:28:35 -0700
committerGraydon Hoare <[email protected]>2011-05-05 11:26:07 -0700
commit3060eadcbabba50fd6a5d633fea710b6b6bed614 (patch)
tree600e724e9e29f38bddd2861c006f4da49e7fa2ee
parentChange checks to asserts in test/bench files (diff)
downloadrust-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.rs14
-rw-r--r--src/comp/middle/typeck.rs29
-rw-r--r--src/test/compile-fail/not-a-pred-3.rs15
-rw-r--r--src/test/compile-fail/not-pred-args.rs11
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);
+}