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 <flodiebold@gmail.com>
This commit is contained in:
commit
92faa2225a
3 changed files with 33 additions and 2 deletions
|
|
@ -450,7 +450,6 @@ impl Ty {
|
|||
}
|
||||
|
||||
pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
|
||||
f(self);
|
||||
match self {
|
||||
Ty::Slice(t) | Ty::Array(t) => t.walk(f),
|
||||
Ty::RawPtr(t, _) => t.walk(f),
|
||||
|
|
@ -490,10 +489,10 @@ impl Ty {
|
|||
| Ty::Infer(_)
|
||||
| Ty::Unknown => {}
|
||||
}
|
||||
f(self);
|
||||
}
|
||||
|
||||
fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
|
||||
f(self);
|
||||
match self {
|
||||
Ty::Slice(t) | Ty::Array(t) => Arc::make_mut(t).walk_mut(f),
|
||||
Ty::RawPtr(t, _) => Arc::make_mut(t).walk_mut(f),
|
||||
|
|
@ -544,6 +543,7 @@ impl Ty {
|
|||
| Ty::Infer(_)
|
||||
| Ty::Unknown => {}
|
||||
}
|
||||
f(self);
|
||||
}
|
||||
|
||||
fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Ty {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
created: "2019-02-11T21:59:04.302375838Z"
|
||||
creator: insta@0.6.1
|
||||
source: crates/ra_hir/src/ty/tests.rs
|
||||
expression: "&result"
|
||||
---
|
||||
[92; 106) 'query_response': Canonical<QueryResponse<R>>
|
||||
[137; 167) '{ ...lue; }': ()
|
||||
[143; 164) '&query....value': &QueryResponse<R>
|
||||
[144; 158) 'query_response': Canonical<QueryResponse<R>>
|
||||
[144; 164) 'query_....value': QueryResponse<R>
|
||||
|
||||
|
|
@ -719,6 +719,25 @@ fn extra_compiler_flags() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_nested_generics_crash() {
|
||||
// another crash found typechecking rustc
|
||||
check_inference(
|
||||
"infer_nested_generics_crash",
|
||||
r#"
|
||||
struct Canonical<V> {
|
||||
value: V,
|
||||
}
|
||||
struct QueryResponse<V> {
|
||||
value: V,
|
||||
}
|
||||
fn test<R>(query_response: Canonical<QueryResponse<R>>) {
|
||||
&query_response.value;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
fn infer(content: &str) -> String {
|
||||
let (db, _, file_id) = MockDatabase::with_single_file(content);
|
||||
let source_file = db.parse(file_id);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue