]> git.lizzy.rs Git - rust.git/commitdiff
permit coercions if `[error]` is found in either type
authorNiko Matsakis <niko@alum.mit.edu>
Sat, 9 Jan 2016 01:16:30 +0000 (20:16 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Sat, 9 Jan 2016 01:20:02 +0000 (20:20 -0500)
src/librustc_typeck/check/coercion.rs
src/test/compile-fail/issue-19692.rs
src/test/compile-fail/issue-3973.rs

index 85f0aa3bbd3c3c7fcad4020eadc89c38ed54aef6..f91f13f586c41b6ea00c24b82fadbb3f94ce14c7 100644 (file)
@@ -68,7 +68,7 @@
 use middle::ty::adjustment::{AutoAdjustment, AutoDerefRef, AdjustDerefRef};
 use middle::ty::adjustment::{AutoPtr, AutoUnsafe, AdjustReifyFnPointer};
 use middle::ty::adjustment::{AdjustUnsafeFnPointer};
-use middle::ty::{self, LvaluePreference, TypeAndMut, Ty};
+use middle::ty::{self, LvaluePreference, TypeAndMut, Ty, HasTypeFlags};
 use middle::ty::error::TypeError;
 use middle::ty::relate::RelateResult;
 use util::common::indent;
@@ -110,10 +110,15 @@ fn coerce(&self,
                a,
                b);
 
+        let a = self.fcx.infcx().shallow_resolve(a);
+
+        // Just ignore error types.
+        if a.references_error() || b.references_error() {
+            return Ok(None);
+        }
+
         // Consider coercing the subtype to a DST
-        let unsize = self.unpack_actual_value(a, |a| {
-            self.coerce_unsized(a, b)
-        });
+        let unsize = self.coerce_unsized(a, b);
         if unsize.is_ok() {
             return unsize;
         }
@@ -124,39 +129,33 @@ fn coerce(&self,
         // See above for details.
         match b.sty {
             ty::TyRawPtr(mt_b) => {
-                return self.unpack_actual_value(a, |a| {
-                    self.coerce_unsafe_ptr(a, b, mt_b.mutbl)
-                });
+                return self.coerce_unsafe_ptr(a, b, mt_b.mutbl);
             }
 
             ty::TyRef(_, mt_b) => {
-                return self.unpack_actual_value(a, |a| {
-                    self.coerce_borrowed_pointer(expr_a, a, b, mt_b.mutbl)
-                });
+                return self.coerce_borrowed_pointer(expr_a, a, b, mt_b.mutbl);
             }
 
             _ => {}
         }
 
-        self.unpack_actual_value(a, |a| {
-            match a.sty {
-                ty::TyBareFn(Some(_), a_f) => {
-                    // Function items are coercible to any closure
-                    // type; function pointers are not (that would
-                    // require double indirection).
-                    self.coerce_from_fn_item(a, a_f, b)
-                }
-                ty::TyBareFn(None, a_f) => {
-                    // We permit coercion of fn pointers to drop the
-                    // unsafe qualifier.
-                    self.coerce_from_fn_pointer(a, a_f, b)
-                }
-                _ => {
-                    // Otherwise, just use subtyping rules.
-                    self.subtype(a, b)
-                }
+        match a.sty {
+            ty::TyBareFn(Some(_), a_f) => {
+                // Function items are coercible to any closure
+                // type; function pointers are not (that would
+                // require double indirection).
+                self.coerce_from_fn_item(a, a_f, b)
             }
-        })
+            ty::TyBareFn(None, a_f) => {
+                // We permit coercion of fn pointers to drop the
+                // unsafe qualifier.
+                self.coerce_from_fn_pointer(a, a_f, b)
+            }
+            _ => {
+                // Otherwise, just use subtyping rules.
+                self.subtype(a, b)
+            }
+        }
     }
 
     /// Reborrows `&mut A` to `&mut B` and `&(mut) A` to `&B`.
index ca1715445e526e976f3c8f10b67c09bc7e483b4f..53ad2416878942e4e6d6a8261f14cab53c5117a3 100644 (file)
@@ -12,7 +12,7 @@
 
 fn akemi(homura: Homura) {
     let Some(ref madoka) = Some(homura.kaname()); //~ ERROR no method named `kaname` found
-    madoka.clone();
+    madoka.clone(); //~ ERROR the type of this value must be known
 }
 
 fn main() { }
index 92456760b0508971bef2f5cde9506564b39b7f89..54eb2a908295568ce1d49356b954d4cd959f02b2 100644 (file)
@@ -31,5 +31,5 @@ fn to_string(&self) -> String {
 fn main() {
     let p = Point::new(0.0, 0.0);
     //~^ ERROR no associated item named `new` found for type `Point` in the current scope
-    println!("{}", p.to_string());
+    println!("{}", p.to_string()); //~ ERROR type of this value must be known
 }