]> git.lizzy.rs Git - rust.git/commitdiff
shallow resolve target type in coercion
authorNiko Matsakis <niko@alum.mit.edu>
Fri, 20 Nov 2020 10:52:27 +0000 (05:52 -0500)
committerMark Rousskov <mark.simulacrum@gmail.com>
Thu, 19 Aug 2021 21:28:24 +0000 (17:28 -0400)
We used to avoid doing this because we didn't want to make coercion depend on
the state of inference. For better or worse, we have moved away from this
position over time. Therefore, I am going to go ahead and resolve the `b`
target type early on so that it is done uniformly.

(The older technique for managing this was always something of a hack
regardless; if we really wanted to avoid integrating coercion and inference we
needed to be more disciplined about it.)

compiler/rustc_typeck/src/check/coercion.rs

index 208eb27c84406f7ebdf67a13b414d1e1a3444de5..0f39d2819ab4e8be12ed3913994946e1709db659 100644 (file)
@@ -147,6 +147,7 @@ fn unify_and<F>(&self, a: Ty<'tcx>, b: Ty<'tcx>, f: F) -> CoerceResult<'tcx>
 
     fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
         let a = self.shallow_resolve(a);
+        let b = self.shallow_resolve(b);
         debug!("Coerce.tys({:?} => {:?})", a, b);
 
         // Just ignore error types.
@@ -162,8 +163,7 @@ fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
             //     let _: Option<?T> = Some({ return; });
             //
             // here, we would coerce from `!` to `?T`.
-            let b = self.shallow_resolve(b);
-            return if self.shallow_resolve(b).is_ty_var() {
+            return if b.is_ty_var() {
                 // Micro-optimization: no need for this if `b` is
                 // already resolved in some way.
                 let diverging_ty = self.next_diverging_ty_var(TypeVariableOrigin {
@@ -196,9 +196,6 @@ fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
         debug!("coerce: unsize failed");
 
         // Examine the supertype and consider auto-borrowing.
-        //
-        // Note: does not attempt to resolve type variables we encounter.
-        // See above for details.
         match *b.kind() {
             ty::RawPtr(mt_b) => {
                 return self.coerce_unsafe_ptr(a, b, mt_b.mutbl);