]> git.lizzy.rs Git - rust.git/commitdiff
erase regions instead of using `builtin_deref`
authorNicholas Matsakis <nmatsakis@psyche.localdomain>
Wed, 11 Dec 2019 18:23:07 +0000 (13:23 -0500)
committerNicholas Matsakis <nmatsakis@psyche.localdomain>
Wed, 11 Dec 2019 18:23:07 +0000 (13:23 -0500)
The reason we were invoking `builtin_deref` was to enable comparisons
when the type was `&T`. For the reasons outlined in the comment, those
comparisons failed because the regions disagreed.

src/librustc/traits/error_reporting.rs

index 84ffb74045eff12f67ff13f58de03554c37ac091..6a111895b5637bd982c4a7eb9e8aad19f60e50e4 100644 (file)
@@ -2260,15 +2260,26 @@ fn maybe_note_obligation_cause_for_async_await(
 
         // Look for a type inside the generator interior that matches the target type to get
         // a span.
+        let target_ty_erased = self.tcx.erase_regions(&target_ty);
         let target_span = tables.generator_interior_types.iter()
             .find(|ty::GeneratorInteriorTypeCause { ty, .. }| {
-                let ty = ty.builtin_deref(false).map(|ty_and_mut| ty_and_mut.ty).unwrap_or(ty);
-                let target_ty = target_ty.builtin_deref(false)
-                    .map(|ty_and_mut| ty_and_mut.ty)
-                    .unwrap_or(target_ty);
-                let eq = ty::TyS::same_type(ty, target_ty);
-                debug!("maybe_note_obligation_cause_for_async_await: ty={:?} \
-                        target_ty={:?} eq={:?}", ty, target_ty, eq);
+                // Careful: the regions for types that appear in the
+                // generator interior are not generally known, so we
+                // want to erase them when comparing (and anyway,
+                // `Send` and other bounds are generally unaffected by
+                // the choice of region).  When erasing regions, we
+                // also have to erase late-bound regions. This is
+                // because the types that appear in the generator
+                // interior generally contain "bound regions" to
+                // represent regions that are part of the suspended
+                // generator frame. Bound regions are preserved by
+                // `erase_regions` and so we must also call
+                // `erase_late_bound_regions`.
+                let ty_erased = self.tcx.erase_late_bound_regions(&ty::Binder::bind(*ty));
+                let ty_erased = self.tcx.erase_regions(&ty_erased);
+                let eq = ty::TyS::same_type(ty_erased, target_ty_erased);
+                debug!("maybe_note_obligation_cause_for_async_await: ty_erased={:?} \
+                        target_ty_erased={:?} eq={:?}", ty_erased, target_ty_erased, eq);
                 eq
             })
             .map(|ty::GeneratorInteriorTypeCause { span, scope_span, .. }|