From c011f131446d3e2cbbb9266bfefc9fd9637f9bd0 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 23 Aug 2011 15:58:53 -0700 Subject: [PATCH] Add kind-checking for assign-op, copy, ret, be, fail exprs. Fix caught kinding-violations in rustc and libstd. --- src/comp/driver/rustc.rs | 2 +- src/comp/front/attr.rs | 2 +- src/comp/front/test.rs | 2 +- src/comp/middle/kind.rs | 14 ++++++++++++++ src/comp/syntax/ast_util.rs | 2 +- src/comp/syntax/parse/parser.rs | 2 +- src/comp/syntax/util/interner.rs | 2 +- src/lib/task.rs | 6 +----- src/lib/unsafe.rs | 2 +- src/lib/util.rs | 2 +- src/test/compile-fail/block-copy.rs | 2 +- src/test/compiletest/procsrv.rs | 2 +- src/test/run-pass/auto-instantiate.rs | 2 +- src/test/run-pass/autobind.rs | 2 +- src/test/run-pass/box-unbox.rs | 2 +- src/test/run-pass/fixed-point-bind-box.rs | 4 ++-- src/test/run-pass/generic-alias-box.rs | 2 +- src/test/run-pass/generic-bind-2.rs | 2 +- src/test/run-pass/generic-bind.rs | 2 +- src/test/run-pass/generic-derived-type.rs | 4 ++-- src/test/run-pass/generic-fn-infer.rs | 2 +- src/test/run-pass/generic-fn.rs | 2 +- src/test/run-pass/generic-obj-with-derived-type.rs | 2 +- src/test/run-pass/generic-obj.rs | 2 +- src/test/run-pass/generic-tup.rs | 2 +- src/test/run-pass/issue-333.rs | 4 ++-- src/test/run-pass/newtype-polymorphic.rs | 4 ++-- src/test/run-pass/ret-none.rs | 2 +- 28 files changed, 45 insertions(+), 35 deletions(-) diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index a1981e1d283..ded36db2cf8 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -108,7 +108,7 @@ fn parse_input_src(sess: session::session, cfg: &ast::crate_cfg, infile: str) ret {crate: crate, src: src}; } -fn time(do_it: bool, what: str, thunk: fn() -> T) -> T { +fn time<@T>(do_it: bool, what: str, thunk: fn() -> T) -> T { if !do_it { ret thunk(); } let start = std::time::precise_time_s(); let rv = thunk(); diff --git a/src/comp/front/attr.rs b/src/comp/front/attr.rs index e199d10fbd1..5701ff33f97 100644 --- a/src/comp/front/attr.rs +++ b/src/comp/front/attr.rs @@ -189,7 +189,7 @@ fn require_unique_names(sess: &session::session, metas: &[@ast::meta_item]) { } } -fn span(item: &T) -> ast::spanned { +fn span<@T>(item: &T) -> ast::spanned { ret {node: item, span: ast_util::dummy_sp()}; } diff --git a/src/comp/front/test.rs b/src/comp/front/test.rs index d9cda6e601a..8e0b71caf84 100644 --- a/src/comp/front/test.rs +++ b/src/comp/front/test.rs @@ -170,7 +170,7 @@ fn mk_test_module(cx: &test_ctxt) -> @ast::item { ret @item; } -fn nospan(t: &T) -> ast::spanned { +fn nospan<@T>(t: &T) -> ast::spanned { ret {node: t, span: dummy_sp()}; } diff --git a/src/comp/middle/kind.rs b/src/comp/middle/kind.rs index 4ffdcc95ff3..9a0d251e44e 100644 --- a/src/comp/middle/kind.rs +++ b/src/comp/middle/kind.rs @@ -76,6 +76,7 @@ import syntax::ast_util; import syntax::visit; import std::vec; +import std::option; import ast::kind; import ast::kind_unique; @@ -135,7 +136,20 @@ fn check_expr(tcx: &ty::ctxt, e: &@ast::expr) { alt e.node { ast::expr_move(a, b) { need_shared_lhs_rhs(tcx, a, b, "<-"); } ast::expr_assign(a, b) { need_shared_lhs_rhs(tcx, a, b, "="); } + ast::expr_assign_op(_, a, b) { need_shared_lhs_rhs(tcx, a, b, "op="); } ast::expr_swap(a, b) { need_shared_lhs_rhs(tcx, a, b, "<->"); } + ast::expr_copy(a) { + need_expr_kind(tcx, a, ast::kind_shared, "'copy' operand"); + } + ast::expr_ret(option::some(a)) { + need_expr_kind(tcx, a, ast::kind_shared, "'ret' operand"); + } + ast::expr_be(a) { + need_expr_kind(tcx, a, ast::kind_shared, "'be' operand"); + } + ast::expr_fail(option::some(a)) { + need_expr_kind(tcx, a, ast::kind_shared, "'fail' operand"); + } ast::expr_call(callee, _) { let tpt = ty::expr_ty_params_and_ty(tcx, callee); diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs index e3b16702b76..e89889fa027 100644 --- a/src/comp/syntax/ast_util.rs +++ b/src/comp/syntax/ast_util.rs @@ -3,7 +3,7 @@ import std::option; import codemap::span; import ast::*; -fn respan(sp: &span, t: &T) -> spanned { ret {node: t, span: sp}; } +fn respan<@T>(sp: &span, t: &T) -> spanned { ret {node: t, span: sp}; } /* assuming that we're not in macro expansion */ fn mk_sp(lo: uint, hi: uint) -> span { diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index 495d1372d79..aa553e32e39 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -222,7 +222,7 @@ fn expect_gt(p: &parser) { } } -fn spanned(lo: uint, hi: uint, node: &T) -> spanned { +fn spanned<@T>(lo: uint, hi: uint, node: &T) -> spanned { ret {node: node, span: ast_util::mk_sp(lo, hi)}; } diff --git a/src/comp/syntax/util/interner.rs b/src/comp/syntax/util/interner.rs index 31656886a45..3d1a495fb2e 100644 --- a/src/comp/syntax/util/interner.rs +++ b/src/comp/syntax/util/interner.rs @@ -33,7 +33,7 @@ fn intern<@T>(itr: &interner, val: &T) -> uint { } } -fn get(itr: &interner, idx: uint) -> T { ret itr.vect[idx]; } +fn get<@T>(itr: &interner, idx: uint) -> T { ret itr.vect[idx]; } fn len(itr: &interner) -> uint { ret vec::len(itr.vect); } diff --git a/src/lib/task.rs b/src/lib/task.rs index 2e88f12f6c0..52181528b4f 100644 --- a/src/lib/task.rs +++ b/src/lib/task.rs @@ -38,10 +38,6 @@ type task_context = {regs: x86_registers, next: *u8}; resource rust_task_ptr(task: *rust_task) { rustrt::drop_task(task); } -fn get_task_ptr(id: task) -> rust_task_ptr { - ret rust_task_ptr(rustrt::get_task_pointer(id)); -} - type task = int; type task_id = task; @@ -107,7 +103,7 @@ fn spawn_inner(thunk: -fn(), notify: option>) -> // stack. // set up the task pointer - let task_ptr = get_task_ptr(id); + let task_ptr = rust_task_ptr(rustrt::get_task_pointer(id)); let regs = ptr::addr_of((**task_ptr).ctx.regs); (*regs).edx = cast(*task_ptr);; (*regs).esp = cast((**task_ptr).stack_ptr); diff --git a/src/lib/unsafe.rs b/src/lib/unsafe.rs index 6e1b4b3b7c3..0d382655b41 100644 --- a/src/lib/unsafe.rs +++ b/src/lib/unsafe.rs @@ -9,7 +9,7 @@ native "rust" mod rustrt { } // Casts the value at `src` to U. The two types must have the same length. -fn reinterpret_cast(src: &T) -> U { ret rusti::cast(src); } +fn reinterpret_cast(src: &T) -> U { ret rusti::cast(src); } fn leak<@T>(thing: -T) { rustrt::leak(thing); diff --git a/src/lib/util.rs b/src/lib/util.rs index 24a14b1fa92..6041da4d0d0 100644 --- a/src/lib/util.rs +++ b/src/lib/util.rs @@ -1,6 +1,6 @@ -fn id(x: &T) -> T { ret x; } +fn id<@T>(x: &T) -> T { ret x; } /* FIXME (issue #141): See test/run-pass/constrained-type.rs. Uncomment diff --git a/src/test/compile-fail/block-copy.rs b/src/test/compile-fail/block-copy.rs index 6a6c708cf88..76b05792f2f 100644 --- a/src/test/compile-fail/block-copy.rs +++ b/src/test/compile-fail/block-copy.rs @@ -1,4 +1,4 @@ -// error-pattern: non-copyable +// error-pattern: mismatched kinds fn lol(f: &block()) -> block() { ret f; } fn main() { let i = 8; let f = lol(block () { log_err i; }); f(); } diff --git a/src/test/compiletest/procsrv.rs b/src/test/compiletest/procsrv.rs index 6e464038b18..efbc26f669a 100644 --- a/src/test/compiletest/procsrv.rs +++ b/src/test/compiletest/procsrv.rs @@ -150,7 +150,7 @@ fn worker(p: port) { } } -fn with_lib_path(path: &str, f: fn() -> T) -> T { +fn with_lib_path<@T>(path: &str, f: fn() -> T) -> T { let maybe_oldpath = getenv(util::lib_path_env_var()); append_lib_path(path); let res = f(); diff --git a/src/test/run-pass/auto-instantiate.rs b/src/test/run-pass/auto-instantiate.rs index f8d9ebbb587..e06da60789c 100644 --- a/src/test/run-pass/auto-instantiate.rs +++ b/src/test/run-pass/auto-instantiate.rs @@ -2,6 +2,6 @@ // -*- rust -*- -fn f(x: &T, y: &U) -> {a: T, b: U} { ret {a: x, b: y}; } +fn f<@T, @U>(x: &T, y: &U) -> {a: T, b: U} { ret {a: x, b: y}; } fn main() { log f({x: 3, y: 4, z: 5}, 4).a.x; log f(5, 6).a; } diff --git a/src/test/run-pass/autobind.rs b/src/test/run-pass/autobind.rs index 536db525d5c..ebf2bd432d4 100644 --- a/src/test/run-pass/autobind.rs +++ b/src/test/run-pass/autobind.rs @@ -1,4 +1,4 @@ -fn f(x: &[T]) -> T { ret x[0]; } +fn f<@T>(x: &[T]) -> T { ret x[0]; } fn g(act: fn(&[int]) -> int) -> int { ret act([1, 2, 3]); } diff --git a/src/test/run-pass/box-unbox.rs b/src/test/run-pass/box-unbox.rs index e27954d4d65..08633a572a3 100644 --- a/src/test/run-pass/box-unbox.rs +++ b/src/test/run-pass/box-unbox.rs @@ -2,7 +2,7 @@ type box = {c: @T}; -fn unbox(b: &box) -> T { ret *b.c; } +fn unbox<@T>(b: &box) -> T { ret *b.c; } fn main() { let foo: int = 17; diff --git a/src/test/run-pass/fixed-point-bind-box.rs b/src/test/run-pass/fixed-point-bind-box.rs index 4ca1cdb34c9..57dcc98b2a8 100644 --- a/src/test/run-pass/fixed-point-bind-box.rs +++ b/src/test/run-pass/fixed-point-bind-box.rs @@ -1,8 +1,8 @@ -fn fix_help(f: @fn(@fn(&A) -> B, &A) -> B, x: &A) -> B { +fn fix_help(f: @fn(@fn(&A) -> B, &A) -> B, x: &A) -> B { ret f(@bind fix_help(f, _), x); } -fn fix(f: @fn(@fn(&A) -> B, &A) -> B) -> @fn(&A) -> B { +fn fix(f: @fn(@fn(&A) -> B, &A) -> B) -> @fn(&A) -> B { ret @bind fix_help(f, _); } diff --git a/src/test/run-pass/generic-alias-box.rs b/src/test/run-pass/generic-alias-box.rs index 8d58c580fba..3250b88ab82 100644 --- a/src/test/run-pass/generic-alias-box.rs +++ b/src/test/run-pass/generic-alias-box.rs @@ -1,6 +1,6 @@ -fn id(t: &T) -> T { ret t; } +fn id<@T>(t: &T) -> T { ret t; } fn main() { let expected = @100; diff --git a/src/test/run-pass/generic-bind-2.rs b/src/test/run-pass/generic-bind-2.rs index 499bc2a25d1..5c149ad5936 100644 --- a/src/test/run-pass/generic-bind-2.rs +++ b/src/test/run-pass/generic-bind-2.rs @@ -1,6 +1,6 @@ -fn id(t: &T) -> T { ret t; } +fn id<@T>(t: &T) -> T { ret t; } fn main() { let t = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}; diff --git a/src/test/run-pass/generic-bind.rs b/src/test/run-pass/generic-bind.rs index 97b000ee1b5..01156f57900 100644 --- a/src/test/run-pass/generic-bind.rs +++ b/src/test/run-pass/generic-bind.rs @@ -1,6 +1,6 @@ -fn id(t: &T) -> T { ret t; } +fn id<@T>(t: &T) -> T { ret t; } fn main() { let t = {_0: 1, _1: 2, _2: 3, _3: 4, _4: 5, _5: 6, _6: 7}; diff --git a/src/test/run-pass/generic-derived-type.rs b/src/test/run-pass/generic-derived-type.rs index d0b98b1068e..c11dce2ac7b 100644 --- a/src/test/run-pass/generic-derived-type.rs +++ b/src/test/run-pass/generic-derived-type.rs @@ -1,8 +1,8 @@ -fn g(x: &X) -> X { ret x; } +fn g<@X>(x: &X) -> X { ret x; } -fn f(t: &T) -> {a: T, b: T} { +fn f<@T>(t: &T) -> {a: T, b: T} { type pair = {a: T, b: T}; let x: pair = {a: t, b: t}; diff --git a/src/test/run-pass/generic-fn-infer.rs b/src/test/run-pass/generic-fn-infer.rs index 4c6597e97d7..559fa4d0446 100644 --- a/src/test/run-pass/generic-fn-infer.rs +++ b/src/test/run-pass/generic-fn-infer.rs @@ -4,6 +4,6 @@ // -*- rust -*- // Issue #45: infer type parameters in function applications -fn id(x: &T) -> T { ret x; } +fn id<@T>(x: &T) -> T { ret x; } fn main() { let x: int = 42; let y: int = id(x); assert (x == y); } diff --git a/src/test/run-pass/generic-fn.rs b/src/test/run-pass/generic-fn.rs index 5eb4e0aae32..940e0fe5aed 100644 --- a/src/test/run-pass/generic-fn.rs +++ b/src/test/run-pass/generic-fn.rs @@ -2,7 +2,7 @@ // -*- rust -*- -fn id(x: &T) -> T { ret x; } +fn id<@T>(x: &T) -> T { ret x; } type triple = {x: int, y: int, z: int}; diff --git a/src/test/run-pass/generic-obj-with-derived-type.rs b/src/test/run-pass/generic-obj-with-derived-type.rs index 05552db04ff..0bc1fafa495 100644 --- a/src/test/run-pass/generic-obj-with-derived-type.rs +++ b/src/test/run-pass/generic-obj-with-derived-type.rs @@ -1,6 +1,6 @@ -obj handle(data: T) { +obj handle<@T>(data: T) { fn get() -> T { ret data; } } diff --git a/src/test/run-pass/generic-obj.rs b/src/test/run-pass/generic-obj.rs index f22addc8b51..6653014b024 100644 --- a/src/test/run-pass/generic-obj.rs +++ b/src/test/run-pass/generic-obj.rs @@ -1,6 +1,6 @@ -obj buf(data: {_0: T, _1: T, _2: T}) { +obj buf<@T>(data: {_0: T, _1: T, _2: T}) { fn get(i: int) -> T { if i == 0 { ret data._0; diff --git a/src/test/run-pass/generic-tup.rs b/src/test/run-pass/generic-tup.rs index 8cacf51e9b5..ac15998c1cc 100644 --- a/src/test/run-pass/generic-tup.rs +++ b/src/test/run-pass/generic-tup.rs @@ -1,4 +1,4 @@ -fn get_third(t: &(T, T, T)) -> T { let (_, _, x) = t; ret x; } +fn get_third<@T>(t: &(T, T, T)) -> T { let (_, _, x) = t; ret x; } fn main() { log get_third((1, 2, 3)); diff --git a/src/test/run-pass/issue-333.rs b/src/test/run-pass/issue-333.rs index 12afefe57b1..b5304234b98 100644 --- a/src/test/run-pass/issue-333.rs +++ b/src/test/run-pass/issue-333.rs @@ -1,5 +1,5 @@ -fn quux(x: &T) -> T { let f = id::; ret f(x); } +fn quux<@T>(x: &T) -> T { let f = id::; ret f(x); } -fn id(x: &T) -> T { ret x; } +fn id<@T>(x: &T) -> T { ret x; } fn main() { assert (quux(10) == 10); } diff --git a/src/test/run-pass/newtype-polymorphic.rs b/src/test/run-pass/newtype-polymorphic.rs index fc3002ba662..27fbaee6a77 100644 --- a/src/test/run-pass/newtype-polymorphic.rs +++ b/src/test/run-pass/newtype-polymorphic.rs @@ -1,8 +1,8 @@ tag myvec = [X]; -fn myvec_deref(mv: &myvec) -> [X] { ret *mv; } +fn myvec_deref<@X>(mv: &myvec) -> [X] { ret *mv; } -fn myvec_elt(mv: &myvec) -> X { ret mv[0]; } +fn myvec_elt<@X>(mv: &myvec) -> X { ret mv[0]; } fn main() { let mv = myvec([1, 2, 3]); diff --git a/src/test/run-pass/ret-none.rs b/src/test/run-pass/ret-none.rs index b56db9f9c70..841753d7ad1 100644 --- a/src/test/run-pass/ret-none.rs +++ b/src/test/run-pass/ret-none.rs @@ -2,6 +2,6 @@ tag option { none; some(T); } -fn f() -> option { ret none; } +fn f<@T>() -> option { ret none; } fn main() { f::(); }