diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2016-01-08 20:16:30 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2016-01-08 20:20:02 -0500 |
| commit | 83710b44716cb078fde8992acc4f28839eefbe51 (patch) | |
| tree | b5db47793063bd16387885e3a32de5bc57659078 | |
| parent | a3cbfa58be12a3ae0c4efd71c3e8c39554924e08 (diff) | |
| download | rust-83710b44716cb078fde8992acc4f28839eefbe51.tar.gz rust-83710b44716cb078fde8992acc4f28839eefbe51.zip | |
permit coercions if `[error]` is found in either type
| -rw-r--r-- | src/librustc_typeck/check/coercion.rs | 55 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-19692.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-3973.rs | 2 |
3 files changed, 29 insertions, 30 deletions
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 85f0aa3bbd3..f91f13f586c 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -68,7 +68,7 @@ use middle::traits::{predicate_for_trait_def, report_selection_error}; 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 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { 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 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // 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`. diff --git a/src/test/compile-fail/issue-19692.rs b/src/test/compile-fail/issue-19692.rs index ca1715445e5..53ad2416878 100644 --- a/src/test/compile-fail/issue-19692.rs +++ b/src/test/compile-fail/issue-19692.rs @@ -12,7 +12,7 @@ struct Homura; 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() { } diff --git a/src/test/compile-fail/issue-3973.rs b/src/test/compile-fail/issue-3973.rs index 92456760b05..54eb2a90829 100644 --- a/src/test/compile-fail/issue-3973.rs +++ b/src/test/compile-fail/issue-3973.rs @@ -31,5 +31,5 @@ impl ToString_ for Point { 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 } |
