diff options
| author | Brian Koropoff <bkoropoff@gmail.com> | 2014-09-27 12:17:12 -0700 |
|---|---|---|
| committer | Brian Koropoff <bkoropoff@gmail.com> | 2014-09-28 17:57:34 -0700 |
| commit | ca15637b7ce18975113a8a8b022e97d499ad6689 (patch) | |
| tree | bdccf11ce63bc1d8eb0ac572e63cdae8816d4a1e | |
| parent | 34dfa45718d9d40361dadf0abf9c3dc5cc0b0381 (diff) | |
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
| -rw-r--r-- | src/librustc/middle/typeck/check/mod.rs | 31 |
1 files changed, 31 insertions, 0 deletions
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); |
