about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Koropoff <bkoropoff@gmail.com>2014-09-19 23:46:55 -0700
committerBrian Koropoff <bkoropoff@gmail.com>2014-09-20 00:18:54 -0700
commitc48faaff64fe5acce68e72cc77fc6e7599a784c3 (patch)
tree5e4820828de0870b4b61ca85f36127164dd2b772 /src
parent31f6d45a181859e10595ee1de43dfaee9f16963d (diff)
downloadrust-c48faaff64fe5acce68e72cc77fc6e7599a784c3.tar.gz
rust-c48faaff64fe5acce68e72cc77fc6e7599a784c3.zip
Disallow dereference of `!`
Later compiler passes are not prepared to deal with deref of
`ty_bot` and will generate various ICEs, so disallow it outright for now.

Closes issue #17373
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/typeck/check/mod.rs43
1 files changed, 26 insertions, 17 deletions
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 8d67c04f687..5c19110a71e 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -3869,13 +3869,18 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
         check_expr_with_expectation_and_lvalue_pref(
             fcx, &**oprnd, expected_inner, lvalue_pref);
         let mut oprnd_t = fcx.expr_ty(&**oprnd);
-        if !ty::type_is_error(oprnd_t) && !ty::type_is_bot(oprnd_t) {
+
+        if !ty::type_is_error(oprnd_t) {
             match unop {
                 ast::UnBox => {
-                    oprnd_t = ty::mk_box(tcx, oprnd_t)
+                    if !ty::type_is_bot(oprnd_t) {
+                        oprnd_t = ty::mk_box(tcx, oprnd_t)
+                    }
                 }
                 ast::UnUniq => {
-                    oprnd_t = ty::mk_uniq(tcx, oprnd_t);
+                    if !ty::type_is_bot(oprnd_t) {
+                        oprnd_t = ty::mk_uniq(tcx, oprnd_t);
+                    }
                 }
                 ast::UnDeref => {
                     oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
@@ -3912,23 +3917,27 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
                     };
                 }
                 ast::UnNot => {
-                    oprnd_t = structurally_resolved_type(fcx, oprnd.span,
-                                                         oprnd_t);
-                    if !(ty::type_is_integral(oprnd_t) ||
-                         ty::get(oprnd_t).sty == ty::ty_bool) {
-                        oprnd_t = check_user_unop(fcx, "!", "not",
-                                                  tcx.lang_items.not_trait(),
-                                                  expr, &**oprnd, oprnd_t);
+                    if !ty::type_is_bot(oprnd_t) {
+                        oprnd_t = structurally_resolved_type(fcx, oprnd.span,
+                                                             oprnd_t);
+                        if !(ty::type_is_integral(oprnd_t) ||
+                             ty::get(oprnd_t).sty == ty::ty_bool) {
+                            oprnd_t = check_user_unop(fcx, "!", "not",
+                                                      tcx.lang_items.not_trait(),
+                                                      expr, &**oprnd, oprnd_t);
+                        }
                     }
                 }
                 ast::UnNeg => {
-                    oprnd_t = structurally_resolved_type(fcx, oprnd.span,
-                                                         oprnd_t);
-                    if !(ty::type_is_integral(oprnd_t) ||
-                         ty::type_is_fp(oprnd_t)) {
-                        oprnd_t = check_user_unop(fcx, "-", "neg",
-                                                  tcx.lang_items.neg_trait(),
-                                                  expr, &**oprnd, oprnd_t);
+                    if !ty::type_is_bot(oprnd_t) {
+                        oprnd_t = structurally_resolved_type(fcx, oprnd.span,
+                                                             oprnd_t);
+                        if !(ty::type_is_integral(oprnd_t) ||
+                             ty::type_is_fp(oprnd_t)) {
+                            oprnd_t = check_user_unop(fcx, "-", "neg",
+                                                      tcx.lang_items.neg_trait(),
+                                                      expr, &**oprnd, oprnd_t);
+                        }
                     }
                 }
             }