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
This commit is contained in:
commit
7cc8c44871
2 changed files with 49 additions and 6 deletions
|
@ -65,6 +65,7 @@ use std::iter;
|
||||||
enum PlaceAncestryRelation {
|
enum PlaceAncestryRelation {
|
||||||
Ancestor,
|
Ancestor,
|
||||||
Descendant,
|
Descendant,
|
||||||
|
SamePlace,
|
||||||
Divergent,
|
Divergent,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,7 +565,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
for possible_ancestor in min_cap_list.iter_mut() {
|
for possible_ancestor in min_cap_list.iter_mut() {
|
||||||
match determine_place_ancestry_relation(&place, &possible_ancestor.place) {
|
match determine_place_ancestry_relation(&place, &possible_ancestor.place) {
|
||||||
// current place is descendant of possible_ancestor
|
// current place is descendant of possible_ancestor
|
||||||
PlaceAncestryRelation::Descendant => {
|
PlaceAncestryRelation::Descendant | PlaceAncestryRelation::SamePlace => {
|
||||||
ancestor_found = true;
|
ancestor_found = true;
|
||||||
let backup_path_expr_id = possible_ancestor.info.path_expr_id;
|
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 projections_b = &place_b.projections;
|
||||||
|
|
||||||
let same_initial_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 {
|
if same_initial_projections {
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
// First min(n, m) projections are the same
|
// First min(n, m) projections are the same
|
||||||
// Select Ancestor/Descendant
|
// Select Ancestor/Descendant
|
||||||
if projections_b.len() >= projections_a.len() {
|
match projections_b.len().cmp(&projections_a.len()) {
|
||||||
PlaceAncestryRelation::Ancestor
|
Ordering::Greater => PlaceAncestryRelation::Ancestor,
|
||||||
} else {
|
Ordering::Equal => PlaceAncestryRelation::SamePlace,
|
||||||
PlaceAncestryRelation::Descendant
|
Ordering::Less => PlaceAncestryRelation::Descendant,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PlaceAncestryRelation::Divergent
|
PlaceAncestryRelation::Divergent
|
||||||
|
|
40
src/test/ui/closures/2229_closure_analysis/issue-89606.rs
Normal file
40
src/test/ui/closures/2229_closure_analysis/issue-89606.rs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// Regression test for #89606. Used to ICE.
|
||||||
|
//
|
||||||
|
// check-pass
|
||||||
|
// revisions: twenty_eighteen twenty_twentyone
|
||||||
|
// [twenty_eighteen]compile-flags: --edition 2018
|
||||||
|
// [twenty_twentyone]compile-flags: --edition 2021
|
||||||
|
|
||||||
|
struct S<'a>(Option<&'a mut i32>);
|
||||||
|
|
||||||
|
fn by_ref(s: &mut S<'_>) {
|
||||||
|
(|| {
|
||||||
|
let S(_o) = s;
|
||||||
|
s.0 = None;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn by_value(s: S<'_>) {
|
||||||
|
(|| {
|
||||||
|
let S(ref _o) = s;
|
||||||
|
let _g = s.0;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct V<'a>((Option<&'a mut i32>,));
|
||||||
|
|
||||||
|
fn nested(v: &mut V<'_>) {
|
||||||
|
(|| {
|
||||||
|
let V((_o,)) = v;
|
||||||
|
v.0 = (None, );
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut s = S(None);
|
||||||
|
by_ref(&mut s);
|
||||||
|
by_value(s);
|
||||||
|
|
||||||
|
let mut v = V((None, ));
|
||||||
|
nested(&mut v);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue