@@ -146,6 +146,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
146
146
}
147
147
148
148
fn coerce ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> CoerceResult < ' tcx > {
149
+ // First, remove any resolved type variables (at the top level, at least):
149
150
let a = self . shallow_resolve ( a) ;
150
151
let b = self . shallow_resolve ( b) ;
151
152
debug ! ( "Coerce.tys({:?} => {:?})" , a, b) ;
@@ -155,6 +156,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
155
156
return success ( vec ! [ ] , self . fcx . tcx . ty_error ( ) , vec ! [ ] ) ;
156
157
}
157
158
159
+ // Coercing from `!` to any type is allowed:
158
160
if a. is_never ( ) {
159
161
// Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
160
162
// type variable, we want `?T` to fallback to `!` if not
@@ -176,6 +178,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
176
178
} ;
177
179
}
178
180
181
+ // Coercing *from* an unresolved inference variable means that
182
+ // we have no information about the source type. This will always
183
+ // ultimately fall back to some form of subtyping.
184
+ if a. is_ty_var ( ) {
185
+ return self . coerce_from_inference_variable ( a, b) ;
186
+ }
187
+
179
188
// Consider coercing the subtype to a DST
180
189
//
181
190
// NOTE: this is wrapped in a `commit_if_ok` because it creates
@@ -233,6 +242,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
233
242
}
234
243
}
235
244
245
+ /// Coercing *from* an inference variable. In this case, we have no information
246
+ /// about the source type, so we can't really do a true coercion and we always
247
+ /// fall back to subtyping (`unify_and`).
248
+ fn coerce_from_inference_variable ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> CoerceResult < ' tcx > {
249
+ assert ! ( a. is_ty_var( ) && self . infcx. shallow_resolve( a) == a) ;
250
+ assert ! ( self . infcx. shallow_resolve( b) == b) ;
251
+
252
+ self . unify_and ( a, b, identity)
253
+ }
254
+
236
255
/// Reborrows `&mut A` to `&mut B` and `&(mut) A` to `&B`.
237
256
/// To match `A` with `B`, autoderef will be performed,
238
257
/// calling `deref`/`deref_mut` where necessary.
0 commit comments