Skip to content

Commit 4b5f456

Browse files
committed
auto merge of #17408 : bkoropoff/rust/bot-ice, r=alexcrichton
- Don't attempt to autoderef `!`. The `Deref`/`DerefMut` trait lookup would generate a bunch of unhelpful error spew. - Don't allow explicit deref of `!`, since later passes just ICE. This closes issue #17373 - Don't allow explicit index of `!`, since later passes just ICE. There does not seem to be an issue associated with this
2 parents 437179e + 6035222 commit 4b5f456

File tree

3 files changed

+60
-21
lines changed

3 files changed

+60
-21
lines changed

src/librustc/middle/typeck/check/mod.rs

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,6 +2154,10 @@ pub fn autoderef<T>(fcx: &FnCtxt, sp: Span, base_ty: ty::t,
21542154
for autoderefs in range(0, fcx.tcx().sess.recursion_limit.get()) {
21552155
let resolved_t = structurally_resolved_type(fcx, sp, t);
21562156

2157+
if ty::type_is_bot(resolved_t) {
2158+
return (resolved_t, autoderefs, None);
2159+
}
2160+
21572161
match should_stop(resolved_t, autoderefs) {
21582162
Some(x) => return (resolved_t, autoderefs, Some(x)),
21592163
None => {}
@@ -3951,13 +3955,18 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
39513955
check_expr_with_expectation_and_lvalue_pref(
39523956
fcx, &**oprnd, expected_inner, lvalue_pref);
39533957
let mut oprnd_t = fcx.expr_ty(&**oprnd);
3954-
if !ty::type_is_error(oprnd_t) && !ty::type_is_bot(oprnd_t) {
3958+
3959+
if !ty::type_is_error(oprnd_t) {
39553960
match unop {
39563961
ast::UnBox => {
3957-
oprnd_t = ty::mk_box(tcx, oprnd_t)
3962+
if !ty::type_is_bot(oprnd_t) {
3963+
oprnd_t = ty::mk_box(tcx, oprnd_t)
3964+
}
39583965
}
39593966
ast::UnUniq => {
3960-
oprnd_t = ty::mk_uniq(tcx, oprnd_t);
3967+
if !ty::type_is_bot(oprnd_t) {
3968+
oprnd_t = ty::mk_uniq(tcx, oprnd_t);
3969+
}
39613970
}
39623971
ast::UnDeref => {
39633972
oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t);
@@ -3994,23 +4003,27 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
39944003
};
39954004
}
39964005
ast::UnNot => {
3997-
oprnd_t = structurally_resolved_type(fcx, oprnd.span,
3998-
oprnd_t);
3999-
if !(ty::type_is_integral(oprnd_t) ||
4000-
ty::get(oprnd_t).sty == ty::ty_bool) {
4001-
oprnd_t = check_user_unop(fcx, "!", "not",
4002-
tcx.lang_items.not_trait(),
4003-
expr, &**oprnd, oprnd_t);
4006+
if !ty::type_is_bot(oprnd_t) {
4007+
oprnd_t = structurally_resolved_type(fcx, oprnd.span,
4008+
oprnd_t);
4009+
if !(ty::type_is_integral(oprnd_t) ||
4010+
ty::get(oprnd_t).sty == ty::ty_bool) {
4011+
oprnd_t = check_user_unop(fcx, "!", "not",
4012+
tcx.lang_items.not_trait(),
4013+
expr, &**oprnd, oprnd_t);
4014+
}
40044015
}
40054016
}
40064017
ast::UnNeg => {
4007-
oprnd_t = structurally_resolved_type(fcx, oprnd.span,
4008-
oprnd_t);
4009-
if !(ty::type_is_integral(oprnd_t) ||
4010-
ty::type_is_fp(oprnd_t)) {
4011-
oprnd_t = check_user_unop(fcx, "-", "neg",
4012-
tcx.lang_items.neg_trait(),
4013-
expr, &**oprnd, oprnd_t);
4018+
if !ty::type_is_bot(oprnd_t) {
4019+
oprnd_t = structurally_resolved_type(fcx, oprnd.span,
4020+
oprnd_t);
4021+
if !(ty::type_is_integral(oprnd_t) ||
4022+
ty::type_is_fp(oprnd_t)) {
4023+
oprnd_t = check_user_unop(fcx, "-", "neg",
4024+
tcx.lang_items.neg_trait(),
4025+
expr, &**oprnd, oprnd_t);
4026+
}
40144027
}
40154028
}
40164029
}
@@ -4468,21 +4481,21 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
44684481
check_expr(fcx, &**idx);
44694482
let raw_base_t = fcx.expr_ty(&**base);
44704483
let idx_t = fcx.expr_ty(&**idx);
4471-
if ty::type_is_error(raw_base_t) || ty::type_is_bot(raw_base_t) {
4484+
if ty::type_is_error(raw_base_t) {
44724485
fcx.write_ty(id, raw_base_t);
4473-
} else if ty::type_is_error(idx_t) || ty::type_is_bot(idx_t) {
4486+
} else if ty::type_is_error(idx_t) {
44744487
fcx.write_ty(id, idx_t);
44754488
} else {
44764489
let (_, autoderefs, field_ty) =
44774490
autoderef(fcx, expr.span, raw_base_t, Some(base.id),
44784491
lvalue_pref, |base_t, _| ty::index(base_t));
44794492
match field_ty {
4480-
Some(ty) => {
4493+
Some(ty) if !ty::type_is_bot(ty) => {
44814494
check_expr_has_type(fcx, &**idx, ty::mk_uint());
44824495
fcx.write_ty(id, ty);
44834496
fcx.write_autoderef_adjustment(base.id, base.span, autoderefs);
44844497
}
4485-
None => {
4498+
_ => {
44864499
// This is an overloaded method.
44874500
let base_t = structurally_resolved_type(fcx,
44884501
expr.span,

src/test/compile-fail/index-bot.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
(return)[0u]; //~ ERROR cannot index a value of type `!`
13+
}

src/test/compile-fail/issue-17373.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
*return; //~ ERROR type `!` cannot be dereferenced
13+
}

0 commit comments

Comments
 (0)