about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2016-04-14 09:57:55 -0400
committerNiko Matsakis <niko@alum.mit.edu>2016-04-14 10:05:51 -0400
commit89bbd2c8b75f31f06496158e8e309557cfeaeed5 (patch)
tree2af1ec22d0feb907b8f2fe8a57179c7413374ea0
parent2c9dfafa572272a758357d6bd5d51c0b22a9fdd3 (diff)
downloadrust-89bbd2c8b75f31f06496158e8e309557cfeaeed5.tar.gz
rust-89bbd2c8b75f31f06496158e8e309557cfeaeed5.zip
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).
-rw-r--r--src/librustc_typeck/check/cast.rs19
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/test/run-pass/cast-to-infer-ty.rs17
3 files changed, 29 insertions, 9 deletions
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 1765f5dc2f2..922c411ce8c 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -128,15 +128,18 @@ impl<'tcx> CastCheck<'tcx> {
             span: span,
         };
 
-        // For better error messages, we try to check whether the
-        // target type is known to be sized now (we will also check
-        // later, once inference is more complete done).
-        if !fcx.type_is_known_to_be_sized(cast_ty, span) {
-            check.report_cast_to_unsized_type(fcx);
-            return Err(ErrorReported);
+        // For better error messages, check for some obviously unsized
+        // cases now. We do a more thorough check at the end, once
+        // inference is more completely known.
+        match cast_ty.sty {
+            ty::TyTrait(..) | ty::TySlice(..) => {
+                check.report_cast_to_unsized_type(fcx);
+                Err(ErrorReported)
+            }
+            _ => {
+                Ok(check)
+            }
         }
-
-        Ok(check)
     }
 
     fn report_cast_error<'a>(&self,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 16d6aca07b5..74ccd44891d 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -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,
         // if appropriate.
         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));
         let t_expr = fcx.expr_ty(e);
         let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);
diff --git a/src/test/run-pass/cast-to-infer-ty.rs b/src/test/run-pass/cast-to-infer-ty.rs
new file mode 100644
index 00000000000..2aa0d9c62fb
--- /dev/null
+++ b/src/test/run-pass/cast-to-infer-ty.rs
@@ -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());
+}