aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-02-12 21:05:09 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-02-12 21:05:09 +0000
commit92faa2225ae2c508c605b8d6f53381a2cc330d32 (patch)
tree5f9237fe67c6a5fd8e3f17eddfc3ee9b5a7a35a8 /crates/ra_hir
parent61324a845bde0959c1f9ac86ce31d022812f4c21 (diff)
parente5f9d54661a46c3e37130716264f8c5ea7540af9 (diff)
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]>
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/ty.rs4
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_nested_generics_crash.snap12
-rw-r--r--crates/ra_hir/src/ty/tests.rs19
3 files changed, 33 insertions, 2 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index 2dc1de41a..f28a7e731 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -450,7 +450,6 @@ impl Ty {
450 } 450 }
451 451
452 pub fn walk(&self, f: &mut impl FnMut(&Ty)) { 452 pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
453 f(self);
454 match self { 453 match self {
455 Ty::Slice(t) | Ty::Array(t) => t.walk(f), 454 Ty::Slice(t) | Ty::Array(t) => t.walk(f),
456 Ty::RawPtr(t, _) => t.walk(f), 455 Ty::RawPtr(t, _) => t.walk(f),
@@ -490,10 +489,10 @@ impl Ty {
490 | Ty::Infer(_) 489 | Ty::Infer(_)
491 | Ty::Unknown => {} 490 | Ty::Unknown => {}
492 } 491 }
492 f(self);
493 } 493 }
494 494
495 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { 495 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
496 f(self);
497 match self { 496 match self {
498 Ty::Slice(t) | Ty::Array(t) => Arc::make_mut(t).walk_mut(f), 497 Ty::Slice(t) | Ty::Array(t) => Arc::make_mut(t).walk_mut(f),
499 Ty::RawPtr(t, _) => Arc::make_mut(t).walk_mut(f), 498 Ty::RawPtr(t, _) => Arc::make_mut(t).walk_mut(f),
@@ -544,6 +543,7 @@ impl Ty {
544 | Ty::Infer(_) 543 | Ty::Infer(_)
545 | Ty::Unknown => {} 544 | Ty::Unknown => {}
546 } 545 }
546 f(self);
547 } 547 }
548 548
549 fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Ty { 549 fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Ty {
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_nested_generics_crash.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_nested_generics_crash.snap
new file mode 100644
index 000000000..209454a91
--- /dev/null
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_nested_generics_crash.snap
@@ -0,0 +1,12 @@
1---
2created: "2019-02-11T21:59:04.302375838Z"
3creator: [email protected]
4source: crates/ra_hir/src/ty/tests.rs
5expression: "&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
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index e64fd2749..203f1fe4d 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -719,6 +719,25 @@ fn extra_compiler_flags() {
719 ); 719 );
720} 720}
721 721
722#[test]
723fn infer_nested_generics_crash() {
724 // another crash found typechecking rustc
725 check_inference(
726 "infer_nested_generics_crash",
727 r#"
728struct Canonical<V> {
729 value: V,
730}
731struct QueryResponse<V> {
732 value: V,
733}
734fn test<R>(query_response: Canonical<QueryResponse<R>>) {
735 &query_response.value;
736}
737"#,
738 );
739}
740
722fn infer(content: &str) -> String { 741fn infer(content: &str) -> String {
723 let (db, _, file_id) = MockDatabase::with_single_file(content); 742 let (db, _, file_id) = MockDatabase::with_single_file(content);
724 let source_file = db.parse(file_id); 743 let source_file = db.parse(file_id);