From 1e42c9a367aa924963db462aa686324766e260b3 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 7 Apr 2012 17:11:33 -0700 Subject: [PATCH] Do not consider ty_bot to be a "resolved type". Fixes #2149. Fixes #2150. Fixes #2151. --- src/rustc/middle/typeck.rs | 6 ++++-- src/test/compile-fail/issue-2149.rs | 14 ++++++++++++++ src/test/compile-fail/issue-2150.rs | 8 ++++++++ src/test/compile-fail/issue-2151.rs | 6 ++++++ src/test/compile-fail/unreachable-code-1.rs | 14 ++++++++++++++ src/test/pretty/disamb-stmt-expr.rs | 4 +++- src/test/run-pass/early-ret-binop-add.rs | 2 +- src/test/run-pass/unreachable-code.rs | 5 +---- 8 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 src/test/compile-fail/issue-2149.rs create mode 100644 src/test/compile-fail/issue-2150.rs create mode 100644 src/test/compile-fail/issue-2151.rs create mode 100644 src/test/compile-fail/unreachable-code-1.rs diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index c7ccb9e03df..83b07b9e86c 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -232,8 +232,10 @@ fn instantiate_path(fcx: @fn_ctxt, pth: @ast::path, // Type tests fn structurally_resolved_type(fcx: @fn_ctxt, sp: span, tp: ty::t) -> ty::t { alt infer::resolve_type_structure(fcx.infcx, tp) { - result::ok(typ_s) { ret typ_s; } - result::err(_) { + // note: the bot type doesn't count as resolved; it's what we use when + // there is no information about a variable. + result::ok(t_s) if !ty::type_is_bot(t_s) { ret t_s; } + _ { fcx.ccx.tcx.sess.span_fatal (sp, "the type of this value must be known in this context"); } diff --git a/src/test/compile-fail/issue-2149.rs b/src/test/compile-fail/issue-2149.rs new file mode 100644 index 00000000000..8559d78bcdf --- /dev/null +++ b/src/test/compile-fail/issue-2149.rs @@ -0,0 +1,14 @@ +iface monad { + fn bind(fn(A) -> self); +} +impl monad of monad for [A] { + fn bind(f: fn(A) -> [B]) { + let mut r = fail; + for self.each {|elt| r += f(elt); } + //!^ WARNING unreachable expression + //!^^ ERROR the type of this value must be known + } +} +fn main() { + ["hi"].bind {|x| [x] }; +} \ No newline at end of file diff --git a/src/test/compile-fail/issue-2150.rs b/src/test/compile-fail/issue-2150.rs new file mode 100644 index 00000000000..6fc8bf78af6 --- /dev/null +++ b/src/test/compile-fail/issue-2150.rs @@ -0,0 +1,8 @@ +fn fail_len(v: [const int]) -> uint { + let mut i = fail; + for v.each {|x| i += 1u; } + //!^ WARNING unreachable statement + //!^^ ERROR the type of this value must be known + ret i; +} +fn main() {} \ No newline at end of file diff --git a/src/test/compile-fail/issue-2151.rs b/src/test/compile-fail/issue-2151.rs new file mode 100644 index 00000000000..a69b6df1106 --- /dev/null +++ b/src/test/compile-fail/issue-2151.rs @@ -0,0 +1,6 @@ +fn main() { + vec::iter(fail) {|i| + log (debug, i * 2); + //!^ ERROR the type of this value must be known + }; +} \ No newline at end of file diff --git a/src/test/compile-fail/unreachable-code-1.rs b/src/test/compile-fail/unreachable-code-1.rs new file mode 100644 index 00000000000..1dba6f952b5 --- /dev/null +++ b/src/test/compile-fail/unreachable-code-1.rs @@ -0,0 +1,14 @@ +// xfail-pretty + +fn id(x: bool) -> bool { x } + +fn call_id() { + let c <- fail; + id(c); //! WARNING unreachable statement +} + +fn call_id_3() { id(ret) && id(ret); } + //!^ ERROR the type of this value must be known + +fn main() { +} diff --git a/src/test/pretty/disamb-stmt-expr.rs b/src/test/pretty/disamb-stmt-expr.rs index 4f4bf6ff512..b525d0a2da5 100644 --- a/src/test/pretty/disamb-stmt-expr.rs +++ b/src/test/pretty/disamb-stmt-expr.rs @@ -4,5 +4,7 @@ // preserved. They are needed to disambiguate `{ret n+1}; - 0` from // `({ret n+1}-0)`. -fn wsucc(n: int) -> int { ({ ret n + 1 }) - 0; } +fn id(f: fn() -> int) -> int { f() } + +fn wsucc(n: int) -> int { (id {|| 1 }) - 0 } fn main() { } diff --git a/src/test/run-pass/early-ret-binop-add.rs b/src/test/run-pass/early-ret-binop-add.rs index 21eca8fefac..977536cd57c 100644 --- a/src/test/run-pass/early-ret-binop-add.rs +++ b/src/test/run-pass/early-ret-binop-add.rs @@ -1,2 +1,2 @@ -fn wsucc(n: int) -> int { ({ ret n + 1 } + 0); } +fn wsucc(n: int) -> int { 0 + { ret n + 1 } } fn main() { } diff --git a/src/test/run-pass/unreachable-code.rs b/src/test/run-pass/unreachable-code.rs index e7b5ea7070f..c97224144e2 100644 --- a/src/test/run-pass/unreachable-code.rs +++ b/src/test/run-pass/unreachable-code.rs @@ -9,8 +9,6 @@ fn call_id() { fn call_id_2() { id(true) && id(ret); } -fn call_id_3() { id(ret) && id(ret); } - fn call_id_4() { while id(ret) { } } fn bind_id_1() { bind id(fail); } @@ -27,7 +25,7 @@ fn log_break() { loop { log(error, break); } } fn log_cont() { do { log(error, cont); } while false } -fn ret_ret() -> int { ret (ret 2) + 3; } +fn ret_ret() -> int { ret 3 + (ret 2); } fn ret_guard() { alt check 2 { @@ -53,7 +51,6 @@ fn main() { ret_ret(); log_ret(); call_id_2(); - call_id_3(); call_id_4(); bind_id_2(); ret_guard();