@@ -146,6 +146,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
146146 }
147147
148148 fn coerce ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> CoerceResult < ' tcx > {
149+ // First, remove any resolved type variables (at the top level, at least):
149150 let a = self . shallow_resolve ( a) ;
150151 let b = self . shallow_resolve ( b) ;
151152 debug ! ( "Coerce.tys({:?} => {:?})" , a, b) ;
@@ -155,6 +156,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
155156 return success ( vec ! [ ] , self . fcx . tcx . ty_error ( ) , vec ! [ ] ) ;
156157 }
157158
159+ // Coercing from `!` to any type is allowed:
158160 if a. is_never ( ) {
159161 // Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
160162 // type variable, we want `?T` to fallback to `!` if not
@@ -176,6 +178,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
176178 } ;
177179 }
178180
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+
179188 // Consider coercing the subtype to a DST
180189 //
181190 // NOTE: this is wrapped in a `commit_if_ok` because it creates
@@ -233,6 +242,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
233242 }
234243 }
235244
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+
236255 /// Reborrows `&mut A` to `&mut B` and `&(mut) A` to `&B`.
237256 /// To match `A` with `B`, autoderef will be performed,
238257 /// calling `deref`/`deref_mut` where necessary.
0 commit comments