Skip to content

Commit 92faa22

Browse files
bors[bot]flodiebold
andcommitted
Merge #815
815: Fix another crash r=matklad a=flodiebold Found while typechecking rustc with better name resolution... `walk_mut` doing a preorder walk can lead to an infinite recursion when substituting type parameters; postorder is actually what we want. Co-authored-by: Florian Diebold <[email protected]>
2 parents 61324a8 + e5f9d54 commit 92faa22

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

crates/ra_hir/src/ty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,6 @@ impl Ty {
450450
}
451451

452452
pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
453-
f(self);
454453
match self {
455454
Ty::Slice(t) | Ty::Array(t) => t.walk(f),
456455
Ty::RawPtr(t, _) => t.walk(f),
@@ -490,10 +489,10 @@ impl Ty {
490489
| Ty::Infer(_)
491490
| Ty::Unknown => {}
492491
}
492+
f(self);
493493
}
494494

495495
fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
496-
f(self);
497496
match self {
498497
Ty::Slice(t) | Ty::Array(t) => Arc::make_mut(t).walk_mut(f),
499498
Ty::RawPtr(t, _) => Arc::make_mut(t).walk_mut(f),
@@ -544,6 +543,7 @@ impl Ty {
544543
| Ty::Infer(_)
545544
| Ty::Unknown => {}
546545
}
546+
f(self);
547547
}
548548

549549
fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Ty {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
created: "2019-02-11T21:59:04.302375838Z"
3+
creator: insta@0.6.1
4+
source: crates/ra_hir/src/ty/tests.rs
5+
expression: "&result"
6+
---
7+
[92; 106) 'query_response': Canonical<QueryResponse<R>>
8+
[137; 167) '{ ...lue; }': ()
9+
[143; 164) '&query....value': &QueryResponse<R>
10+
[144; 158) 'query_response': Canonical<QueryResponse<R>>
11+
[144; 164) 'query_....value': QueryResponse<R>
12+

crates/ra_hir/src/ty/tests.rs

+19
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,25 @@ fn extra_compiler_flags() {
719719
);
720720
}
721721

722+
#[test]
723+
fn infer_nested_generics_crash() {
724+
// another crash found typechecking rustc
725+
check_inference(
726+
"infer_nested_generics_crash",
727+
r#"
728+
struct Canonical<V> {
729+
value: V,
730+
}
731+
struct QueryResponse<V> {
732+
value: V,
733+
}
734+
fn test<R>(query_response: Canonical<QueryResponse<R>>) {
735+
&query_response.value;
736+
}
737+
"#,
738+
);
739+
}
740+
722741
fn infer(content: &str) -> String {
723742
let (db, _, file_id) = MockDatabase::with_single_file(content);
724743
let source_file = db.parse(file_id);

0 commit comments

Comments
 (0)