From 31f6d45a181859e10595ee1de43dfaee9f16963d Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Fri, 19 Sep 2014 21:09:59 -0700 Subject: [PATCH 1/5] Do not attempt to autoderef `!` This prevents error spam when attempting to look up overload traits. --- src/librustc/middle/typeck/check/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index c8728d375f6a3..8d67c04f687bf 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 => {} From c48faaff64fe5acce68e72cc77fc6e7599a784c3 Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Fri, 19 Sep 2014 23:46:55 -0700 Subject: [PATCH 2/5] 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 --- src/librustc/middle/typeck/check/mod.rs | 43 +++++++++++++++---------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 8d67c04f687bf..5c19110a71e5c 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); + } } } } From a92c3fb3eda104685d012c3e99677b931f22ff9a Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Sat, 20 Sep 2014 00:14:22 -0700 Subject: [PATCH 3/5] Disallow index of `!` This avoids ICEs in later passes that cannot cope with this construct --- src/librustc/middle/typeck/check/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 5c19110a71e5c..f26a1387bb64a 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -4394,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, From fc3bd12a790b35b94b90c9646084418a6fb23960 Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Fri, 19 Sep 2014 19:52:44 -0700 Subject: [PATCH 4/5] Add regression test for issue #17373 --- src/test/compile-fail/issue-17373.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/compile-fail/issue-17373.rs 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 +} From 6035222d21480c30614048538556d6a615810304 Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Sat, 20 Sep 2014 00:25:05 -0700 Subject: [PATCH 5/5] Add test that `!` cannot be indexed --- src/test/compile-fail/index-bot.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/compile-fail/index-bot.rs 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 `!` +}