diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index c8728d375f6a3..f26a1387bb64a 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2156,6 +2156,10 @@ pub fn autoderef(fcx: &FnCtxt, sp: Span, base_ty: ty::t, for autoderefs in range(0, fcx.tcx().sess.recursion_limit.get()) { let resolved_t = structurally_resolved_type(fcx, sp, t); + if ty::type_is_bot(resolved_t) { + return (resolved_t, autoderefs, None); + } + match should_stop(resolved_t, autoderefs) { Some(x) => return (resolved_t, autoderefs, Some(x)), None => {} @@ -3865,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); @@ -3908,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); + } } } } @@ -4381,21 +4394,21 @@ fn check_expr_with_unifier(fcx: &FnCtxt, check_expr(fcx, &**idx); let raw_base_t = fcx.expr_ty(&**base); let idx_t = fcx.expr_ty(&**idx); - if ty::type_is_error(raw_base_t) || ty::type_is_bot(raw_base_t) { + if ty::type_is_error(raw_base_t) { fcx.write_ty(id, raw_base_t); - } else if ty::type_is_error(idx_t) || ty::type_is_bot(idx_t) { + } else if ty::type_is_error(idx_t) { fcx.write_ty(id, idx_t); } else { let (_, autoderefs, field_ty) = autoderef(fcx, expr.span, raw_base_t, Some(base.id), lvalue_pref, |base_t, _| ty::index(base_t)); match field_ty { - Some(ty) => { + Some(ty) if !ty::type_is_bot(ty) => { check_expr_has_type(fcx, &**idx, ty::mk_uint()); fcx.write_ty(id, ty); fcx.write_autoderef_adjustment(base.id, base.span, autoderefs); } - None => { + _ => { // This is an overloaded method. let base_t = structurally_resolved_type(fcx, expr.span, diff --git a/src/test/compile-fail/index-bot.rs b/src/test/compile-fail/index-bot.rs new file mode 100644 index 0000000000000..cf05cf51640e9 --- /dev/null +++ b/src/test/compile-fail/index-bot.rs @@ -0,0 +1,13 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + (return)[0u]; //~ ERROR cannot index a value of type `!` +} diff --git a/src/test/compile-fail/issue-17373.rs b/src/test/compile-fail/issue-17373.rs new file mode 100644 index 0000000000000..9cfae2662ac00 --- /dev/null +++ b/src/test/compile-fail/issue-17373.rs @@ -0,0 +1,13 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + *return; //~ ERROR type `!` cannot be dereferenced +}