Skip to content

Commit 83710b4

Browse files
committed
permit coercions if [error] is found in either type
1 parent a3cbfa5 commit 83710b4

File tree

3 files changed

+29
-30
lines changed

3 files changed

+29
-30
lines changed

src/librustc_typeck/check/coercion.rs

+27-28
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ use middle::traits::{predicate_for_trait_def, report_selection_error};
6868
use middle::ty::adjustment::{AutoAdjustment, AutoDerefRef, AdjustDerefRef};
6969
use middle::ty::adjustment::{AutoPtr, AutoUnsafe, AdjustReifyFnPointer};
7070
use middle::ty::adjustment::{AdjustUnsafeFnPointer};
71-
use middle::ty::{self, LvaluePreference, TypeAndMut, Ty};
71+
use middle::ty::{self, LvaluePreference, TypeAndMut, Ty, HasTypeFlags};
7272
use middle::ty::error::TypeError;
7373
use middle::ty::relate::RelateResult;
7474
use util::common::indent;
@@ -110,10 +110,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
110110
a,
111111
b);
112112

113+
let a = self.fcx.infcx().shallow_resolve(a);
114+
115+
// Just ignore error types.
116+
if a.references_error() || b.references_error() {
117+
return Ok(None);
118+
}
119+
113120
// Consider coercing the subtype to a DST
114-
let unsize = self.unpack_actual_value(a, |a| {
115-
self.coerce_unsized(a, b)
116-
});
121+
let unsize = self.coerce_unsized(a, b);
117122
if unsize.is_ok() {
118123
return unsize;
119124
}
@@ -124,39 +129,33 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
124129
// See above for details.
125130
match b.sty {
126131
ty::TyRawPtr(mt_b) => {
127-
return self.unpack_actual_value(a, |a| {
128-
self.coerce_unsafe_ptr(a, b, mt_b.mutbl)
129-
});
132+
return self.coerce_unsafe_ptr(a, b, mt_b.mutbl);
130133
}
131134

132135
ty::TyRef(_, mt_b) => {
133-
return self.unpack_actual_value(a, |a| {
134-
self.coerce_borrowed_pointer(expr_a, a, b, mt_b.mutbl)
135-
});
136+
return self.coerce_borrowed_pointer(expr_a, a, b, mt_b.mutbl);
136137
}
137138

138139
_ => {}
139140
}
140141

141-
self.unpack_actual_value(a, |a| {
142-
match a.sty {
143-
ty::TyBareFn(Some(_), a_f) => {
144-
// Function items are coercible to any closure
145-
// type; function pointers are not (that would
146-
// require double indirection).
147-
self.coerce_from_fn_item(a, a_f, b)
148-
}
149-
ty::TyBareFn(None, a_f) => {
150-
// We permit coercion of fn pointers to drop the
151-
// unsafe qualifier.
152-
self.coerce_from_fn_pointer(a, a_f, b)
153-
}
154-
_ => {
155-
// Otherwise, just use subtyping rules.
156-
self.subtype(a, b)
157-
}
142+
match a.sty {
143+
ty::TyBareFn(Some(_), a_f) => {
144+
// Function items are coercible to any closure
145+
// type; function pointers are not (that would
146+
// require double indirection).
147+
self.coerce_from_fn_item(a, a_f, b)
158148
}
159-
})
149+
ty::TyBareFn(None, a_f) => {
150+
// We permit coercion of fn pointers to drop the
151+
// unsafe qualifier.
152+
self.coerce_from_fn_pointer(a, a_f, b)
153+
}
154+
_ => {
155+
// Otherwise, just use subtyping rules.
156+
self.subtype(a, b)
157+
}
158+
}
160159
}
161160

162161
/// Reborrows `&mut A` to `&mut B` and `&(mut) A` to `&B`.

src/test/compile-fail/issue-19692.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct Homura;
1212

1313
fn akemi(homura: Homura) {
1414
let Some(ref madoka) = Some(homura.kaname()); //~ ERROR no method named `kaname` found
15-
madoka.clone();
15+
madoka.clone(); //~ ERROR the type of this value must be known
1616
}
1717

1818
fn main() { }

src/test/compile-fail/issue-3973.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ impl ToString_ for Point {
3131
fn main() {
3232
let p = Point::new(0.0, 0.0);
3333
//~^ ERROR no associated item named `new` found for type `Point` in the current scope
34-
println!("{}", p.to_string());
34+
println!("{}", p.to_string()); //~ ERROR type of this value must be known
3535
}

0 commit comments

Comments
 (0)