about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/cast.rs4
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/test/run-pass/cast.rs5
-rw-r--r--src/test/ui/order-dependent-cast-inference.rs18
-rw-r--r--src/test/ui/order-dependent-cast-inference.stderr13
5 files changed, 39 insertions, 3 deletions
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 31f418df902..7ebacc92bab 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -389,8 +389,8 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
     }
 
     pub fn check(mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
-        self.expr_ty = fcx.resolve_type_vars_if_possible(&self.expr_ty);
-        self.cast_ty = fcx.resolve_type_vars_if_possible(&self.cast_ty);
+        self.expr_ty = fcx.structurally_resolved_type(self.span, self.expr_ty);
+        self.cast_ty = fcx.structurally_resolved_type(self.span, self.cast_ty);
 
         debug!("check_cast({}, {:?} as {:?})",
                self.expr.id,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index e5d3e84e840..69879bbe85d 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3639,7 +3639,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                                                                needs);
 
             if !oprnd_t.references_error() {
-                oprnd_t = self.resolve_type_vars_with_obligations(&oprnd_t);
+                oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
                 match unop {
                     hir::UnDeref => {
                         if let Some(mt) = oprnd_t.builtin_deref(true) {
diff --git a/src/test/run-pass/cast.rs b/src/test/run-pass/cast.rs
index bb60626a4bf..80fa5362a8b 100644
--- a/src/test/run-pass/cast.rs
+++ b/src/test/run-pass/cast.rs
@@ -19,4 +19,9 @@ pub fn main() {
     assert_eq!(i as u8 as i8, 'Q' as u8 as i8);
     assert_eq!(0x51 as char, 'Q');
     assert_eq!(0 as u32, false as u32);
+
+    // Test that `_` is correctly inferred.
+    let x = &"hello";
+    let mut y = x as *const _;
+    y = 0 as *const _;
 }
diff --git a/src/test/ui/order-dependent-cast-inference.rs b/src/test/ui/order-dependent-cast-inference.rs
new file mode 100644
index 00000000000..afcd402343b
--- /dev/null
+++ b/src/test/ui/order-dependent-cast-inference.rs
@@ -0,0 +1,18 @@
+// Copyright 2018 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.
+
+fn main() {
+    // Tests case where inference fails due to the order in which casts are checked.
+    // Ideally this would compile, see #48270.
+    let x = &"hello";
+    let mut y = 0 as *const _;
+    //~^ ERROR cannot cast to a pointer of an unknown kind
+    y = x as *const _;
+}
diff --git a/src/test/ui/order-dependent-cast-inference.stderr b/src/test/ui/order-dependent-cast-inference.stderr
new file mode 100644
index 00000000000..556acc87cff
--- /dev/null
+++ b/src/test/ui/order-dependent-cast-inference.stderr
@@ -0,0 +1,13 @@
+error[E0641]: cannot cast to a pointer of an unknown kind
+  --> $DIR/order-dependent-cast-inference.rs:15:17
+   |
+LL |     let mut y = 0 as *const _;
+   |                 ^^^^^--------
+   |                      |
+   |                      help: consider giving more type information
+   |
+   = note: The type information given here is insufficient to check whether the pointer cast is valid
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0641`.