about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-10-11 21:39:11 +0000
committerbors <bors@rust-lang.org>2021-10-11 21:39:11 +0000
commit7cc8c44871b6e789d29fc0d42dacad9804c3a41c (patch)
treeea56ac3a075e8aa22a5aeb712e6834ffdf15ed04 /compiler
parent5b210643ebf2485aafdf2494de8cf41941a64e95 (diff)
parent7275cfa47cf3fdbf41c2ad859ac937bffe5923a4 (diff)
downloadrust-7cc8c44871b6e789d29fc0d42dacad9804c3a41c.tar.gz
rust-7cc8c44871b6e789d29fc0d42dacad9804c3a41c.zip
Auto merge of #89648 - nbdd0121:issue-89606, r=nikomatsakis
Ignore type of projections for upvar capturing

Fix #89606

Ignore type of projections for upvar capturing. Originally HashMap is used, and the hash/eq implementation of Place takes the type of projections into account. These types may differ by lifetime which causes #89606 to ICE.

I originally considered erasing regions but `place.ty()` is used when creating upvar tuple type, more than just serving as a key type, so I switched to a linear comparison with custom eq (`compare_place_ignore_ty`) instead.

r? `@wesleywiser`

`@rustbot` label +T-compiler
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_typeck/src/check/upvar.rs15
1 files changed, 9 insertions, 6 deletions
diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index b7c042a08cf..3a10988bba0 100644
--- a/compiler/rustc_typeck/src/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
@@ -65,6 +65,7 @@ use std::iter;
 enum PlaceAncestryRelation {
     Ancestor,
     Descendant,
+    SamePlace,
     Divergent,
 }
 
@@ -564,7 +565,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 for possible_ancestor in min_cap_list.iter_mut() {
                     match determine_place_ancestry_relation(&place, &possible_ancestor.place) {
                         // current place is descendant of possible_ancestor
-                        PlaceAncestryRelation::Descendant => {
+                        PlaceAncestryRelation::Descendant | PlaceAncestryRelation::SamePlace => {
                             ancestor_found = true;
                             let backup_path_expr_id = possible_ancestor.info.path_expr_id;
 
@@ -2278,15 +2279,17 @@ fn determine_place_ancestry_relation(
     let projections_b = &place_b.projections;
 
     let same_initial_projections =
-        iter::zip(projections_a, projections_b).all(|(proj_a, proj_b)| proj_a == proj_b);
+        iter::zip(projections_a, projections_b).all(|(proj_a, proj_b)| proj_a.kind == proj_b.kind);
 
     if same_initial_projections {
+        use std::cmp::Ordering;
+
         // First min(n, m) projections are the same
         // Select Ancestor/Descendant
-        if projections_b.len() >= projections_a.len() {
-            PlaceAncestryRelation::Ancestor
-        } else {
-            PlaceAncestryRelation::Descendant
+        match projections_b.len().cmp(&projections_a.len()) {
+            Ordering::Greater => PlaceAncestryRelation::Ancestor,
+            Ordering::Equal => PlaceAncestryRelation::SamePlace,
+            Ordering::Less => PlaceAncestryRelation::Descendant,
         }
     } else {
         PlaceAncestryRelation::Divergent