From ca15637b7ce18975113a8a8b022e97d499ad6689 Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Sat, 27 Sep 2014 12:17:12 -0700 Subject: [PATCH 1/2] Reject casts to unsized types and suggest use of reference or box This prevents ICEs or less helpful diagnostics if typeck proceeds further. Closes issue #17441 --- src/librustc/middle/typeck/check/mod.rs | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index c7be2430cc9..d4c38d48a8c 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1405,6 +1405,37 @@ fn check_cast(fcx: &FnCtxt, return } + if !ty::type_is_sized(fcx.tcx(), t_1) { + let tstr = fcx.infcx().ty_to_string(t_1); + fcx.type_error_message(span, |actual| { + format!("cast to unsized type: `{}` as `{}`", actual, tstr) + }, t_e, None); + match ty::get(t_e).sty { + ty::ty_rptr(_, ty::mt { mutbl: mt, .. }) => { + let mtstr = match mt { + ast::MutMutable => "mut ", + ast::MutImmutable => "" + }; + if ty::type_is_trait(t_1) { + span_note!(fcx.tcx().sess, t.span, "did you mean `&{}{}`?", mtstr, tstr); + } else { + span_note!(fcx.tcx().sess, span, + "consider using an implicit coercion to `&{}{}` instead", + mtstr, tstr); + } + } + ty::ty_uniq(..) => { + span_note!(fcx.tcx().sess, t.span, "did you mean `Box<{}>`?", tstr); + } + _ => { + span_note!(fcx.tcx().sess, e.span, + "consider using a box or reference as appropriate"); + } + } + fcx.write_error(id); + return + } + if ty::type_is_trait(t_1) { // This will be looked up later on. vtable2::check_object_cast(fcx, cast_expr, e, t_1); From 69d570fbec565a565e0e79b5ce3bfc638d4b83c1 Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Sat, 27 Sep 2014 12:22:32 -0700 Subject: [PATCH 2/2] Add regression test for issue #17441 --- src/test/compile-fail/issue-17441.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/test/compile-fail/issue-17441.rs diff --git a/src/test/compile-fail/issue-17441.rs b/src/test/compile-fail/issue-17441.rs new file mode 100644 index 00000000000..da548ca5ffe --- /dev/null +++ b/src/test/compile-fail/issue-17441.rs @@ -0,0 +1,24 @@ +// 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() { + let _foo = &[1u, 2] as [uint]; + //~^ ERROR cast to unsized type: `&[uint, .. 2]` as `[uint]` + //~^^ NOTE consider using an implicit coercion to `&[uint]` instead + let _bar = box 1u as std::fmt::Show; + //~^ ERROR cast to unsized type: `Box` as `core::fmt::Show` + //~^^ NOTE did you mean `Box`? + let _baz = 1u as std::fmt::Show; + //~^ ERROR cast to unsized type: `uint` as `core::fmt::Show` + //~^^ NOTE consider using a box or reference as appropriate + let _quux = [1u, 2] as [uint]; + //~^ ERROR cast to unsized type: `[uint, .. 2]` as `[uint]` + //~^^ NOTE consider using a box or reference as appropriate +}