Be a bit more constrained in our early check

Do not require the target type to be fully known,
either. This allows code like `let x: *const () = 0 as _` to work
(see regression test).
This commit is contained in:
Niko Matsakis 2016-04-14 09:57:55 -04:00
parent 2c9dfafa57
commit 89bbd2c8b7
3 changed files with 29 additions and 9 deletions

View File

@ -128,15 +128,18 @@ impl<'tcx> CastCheck<'tcx> {
span: span, span: span,
}; };
// For better error messages, we try to check whether the // For better error messages, check for some obviously unsized
// target type is known to be sized now (we will also check // cases now. We do a more thorough check at the end, once
// later, once inference is more complete done). // inference is more completely known.
if !fcx.type_is_known_to_be_sized(cast_ty, span) { match cast_ty.sty {
check.report_cast_to_unsized_type(fcx); ty::TyTrait(..) | ty::TySlice(..) => {
return Err(ErrorReported); check.report_cast_to_unsized_type(fcx);
Err(ErrorReported)
}
_ => {
Ok(check)
}
} }
Ok(check)
} }
fn report_cast_error<'a>(&self, fn report_cast_error<'a>(&self,

View File

@ -3518,7 +3518,7 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// Find the type of `e`. Supply hints based on the type we are casting to, // Find the type of `e`. Supply hints based on the type we are casting to,
// if appropriate. // if appropriate.
let t_cast = fcx.to_ty(t); let t_cast = fcx.to_ty(t);
let t_cast = structurally_resolved_type(fcx, expr.span, t_cast); let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);
check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast)); check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
let t_expr = fcx.expr_ty(e); let t_expr = fcx.expr_ty(e);
let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast); let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);

View File

@ -0,0 +1,17 @@
// Copyright 2012 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Check that we allow a cast to `_` so long as the target type can be
// inferred elsewhere.
pub fn main() {
let i: *const i32 = 0 as _;
assert!(i.is_null());
}