aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs12
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap54
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_impl_generics.snap39
-rw-r--r--crates/ra_hir/src/ty/snapshots/tests__infer_impl_generics_with_autoderef.snap16
-rw-r--r--crates/ra_hir/src/ty/tests.rs52
5 files changed, 141 insertions, 32 deletions
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 8d1076774..94b757af2 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -118,11 +118,13 @@ impl Ty {
118 // TODO: cache this as a query? 118 // TODO: cache this as a query?
119 // - if so, what signature? (TyFingerprint, Name)? 119 // - if so, what signature? (TyFingerprint, Name)?
120 // - or maybe cache all names and def_ids of methods per fingerprint? 120 // - or maybe cache all names and def_ids of methods per fingerprint?
121 pub fn lookup_method(self, db: &impl HirDatabase, name: &Name) -> Option<Function> { 121 /// Look up the method with the given name, returning the actual autoderefed
122 self.iterate_methods(db, |f| { 122 /// receiver type (but without autoref applied yet).
123 pub fn lookup_method(self, db: &impl HirDatabase, name: &Name) -> Option<(Ty, Function)> {
124 self.iterate_methods(db, |ty, f| {
123 let sig = f.signature(db); 125 let sig = f.signature(db);
124 if sig.name() == name && sig.has_self_param() { 126 if sig.name() == name && sig.has_self_param() {
125 Some(f) 127 Some((ty.clone(), f))
126 } else { 128 } else {
127 None 129 None
128 } 130 }
@@ -134,7 +136,7 @@ impl Ty {
134 pub fn iterate_methods<T>( 136 pub fn iterate_methods<T>(
135 self, 137 self,
136 db: &impl HirDatabase, 138 db: &impl HirDatabase,
137 mut callback: impl FnMut(Function) -> Option<T>, 139 mut callback: impl FnMut(&Ty, Function) -> Option<T>,
138 ) -> Option<T> { 140 ) -> Option<T> {
139 // For method calls, rust first does any number of autoderef, and then one 141 // For method calls, rust first does any number of autoderef, and then one
140 // autoref (i.e. when the method takes &self or &mut self). We just ignore 142 // autoref (i.e. when the method takes &self or &mut self). We just ignore
@@ -156,7 +158,7 @@ impl Ty {
156 for item in impl_block.items(db) { 158 for item in impl_block.items(db) {
157 match item { 159 match item {
158 ImplItem::Method(f) => { 160 ImplItem::Method(f) => {
159 if let Some(result) = callback(f) { 161 if let Some(result) = callback(&derefed_ty, f) {
160 return Some(result); 162 return Some(result);
161 } 163 }
162 } 164 }
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap
index 626f31252..d1ce87b0a 100644
--- a/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_generic_chain.snap
@@ -1,36 +1,36 @@
1--- 1---
2created: "2019-01-27T14:52:29.938713255+00:00" 2created: "2019-02-16T20:53:59.655361804Z"
3creator: [email protected] 3creator: [email protected]
4expression: "&result"
5source: crates/ra_hir/src/ty/tests.rs 4source: crates/ra_hir/src/ty/tests.rs
5expression: "&result"
6--- 6---
7[53; 57) 'self': A<[unknown]> 7[53; 57) 'self': A<T2>
8[65; 87) '{ ... }': [unknown] 8[65; 87) '{ ... }': T2
9[75; 79) 'self': A<[unknown]> 9[75; 79) 'self': A<T2>
10[75; 81) 'self.x': [unknown] 10[75; 81) 'self.x': T2
11[99; 100) 't': T 11[99; 100) 't': T
12[110; 115) '{ t }': T 12[110; 115) '{ t }': T
13[112; 113) 't': T 13[112; 113) 't': T
14[135; 261) '{ ....x() }': i128 14[135; 261) '{ ....x() }': i128
15[146; 147) 'x': i32 15[146; 147) 'x': i128
16[150; 151) '1': i32 16[150; 151) '1': i128
17[162; 163) 'y': i32 17[162; 163) 'y': i128
18[166; 168) 'id': fn id<i32>(T) -> T 18[166; 168) 'id': fn id<i128>(T) -> T
19[166; 171) 'id(x)': i32 19[166; 171) 'id(x)': i128
20[169; 170) 'x': i32 20[169; 170) 'x': i128
21[182; 183) 'a': A<i32> 21[182; 183) 'a': A<i128>
22[186; 200) 'A { x: id(y) }': A<i32> 22[186; 200) 'A { x: id(y) }': A<i128>
23[193; 195) 'id': fn id<i32>(T) -> T 23[193; 195) 'id': fn id<i128>(T) -> T
24[193; 198) 'id(y)': i32 24[193; 198) 'id(y)': i128
25[196; 197) 'y': i32 25[196; 197) 'y': i128
26[211; 212) 'z': i32 26[211; 212) 'z': i128
27[215; 217) 'id': fn id<i32>(T) -> T 27[215; 217) 'id': fn id<i128>(T) -> T
28[215; 222) 'id(a.x)': i32 28[215; 222) 'id(a.x)': i128
29[218; 219) 'a': A<i32> 29[218; 219) 'a': A<i128>
30[218; 221) 'a.x': i32 30[218; 221) 'a.x': i128
31[233; 234) 'b': A<i32> 31[233; 234) 'b': A<i128>
32[237; 247) 'A { x: z }': A<i32> 32[237; 247) 'A { x: z }': A<i128>
33[244; 245) 'z': i32 33[244; 245) 'z': i128
34[254; 255) 'b': A<i32> 34[254; 255) 'b': A<i128>
35[254; 259) 'b.x()': i128 35[254; 259) 'b.x()': i128
36 36
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_impl_generics.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_impl_generics.snap
new file mode 100644
index 000000000..44f00a52e
--- /dev/null
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_impl_generics.snap
@@ -0,0 +1,39 @@
1---
2created: "2019-02-16T21:58:14.029368845Z"
3creator: [email protected]
4source: crates/ra_hir/src/ty/tests.rs
5expression: "&result"
6---
7[74; 78) 'self': A<X, Y>
8[85; 107) '{ ... }': X
9[95; 99) 'self': A<X, Y>
10[95; 101) 'self.x': X
11[117; 121) 'self': A<X, Y>
12[128; 150) '{ ... }': Y
13[138; 142) 'self': A<X, Y>
14[138; 144) 'self.y': Y
15[163; 167) 'self': A<X, Y>
16[169; 170) 't': T
17[188; 223) '{ ... }': (X, Y, T)
18[198; 217) '(self.....y, t)': (X, Y, T)
19[199; 203) 'self': A<X, Y>
20[199; 205) 'self.x': X
21[207; 211) 'self': A<X, Y>
22[207; 213) 'self.y': Y
23[215; 216) 't': T
24[245; 342) '{ ...(1); }': ()
25[255; 256) 'a': A<u64, i64>
26[259; 281) 'A { x:...1i64 }': A<u64, i64>
27[266; 270) '1u64': u64
28[275; 279) '1i64': i64
29[287; 288) 'a': A<u64, i64>
30[287; 292) 'a.x()': u64
31[298; 299) 'a': A<u64, i64>
32[298; 303) 'a.y()': i64
33[309; 310) 'a': A<u64, i64>
34[309; 319) 'a.z(1i128)': (u64, i64, i128)
35[313; 318) '1i128': i128
36[325; 326) 'a': A<u64, i64>
37[325; 339) 'a.z::<u128>(1)': (u64, i64, u128)
38[337; 338) '1': u128
39
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_impl_generics_with_autoderef.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_impl_generics_with_autoderef.snap
new file mode 100644
index 000000000..f609eaf7c
--- /dev/null
+++ b/crates/ra_hir/src/ty/snapshots/tests__infer_impl_generics_with_autoderef.snap
@@ -0,0 +1,16 @@
1---
2created: "2019-02-17T13:35:06.385679926Z"
3creator: [email protected]
4source: crates/ra_hir/src/ty/tests.rs
5expression: "&result"
6---
7[78; 82) 'self': &Option<T>
8[98; 100) '{}': ()
9[111; 112) 'o': Option<u32>
10[127; 165) '{ ...f(); }': ()
11[133; 146) '(&o).as_ref()': Option<&u32>
12[134; 136) '&o': &Option<u32>
13[135; 136) 'o': Option<u32>
14[152; 153) 'o': Option<u32>
15[152; 162) 'o.as_ref()': Option<&u32>
16
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 203f1fe4d..5eb9c4f5b 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -507,6 +507,58 @@ fn test() {
507} 507}
508 508
509#[test] 509#[test]
510fn infer_impl_generics() {
511 check_inference(
512 "infer_impl_generics",
513 r#"
514struct A<T1, T2> {
515 x: T1,
516 y: T2,
517}
518impl<Y, X> A<X, Y> {
519 fn x(self) -> X {
520 self.x
521 }
522 fn y(self) -> Y {
523 self.y
524 }
525 fn z<T>(self, t: T) -> (X, Y, T) {
526 (self.x, self.y, t)
527 }
528}
529
530fn test() -> i128 {
531 let a = A { x: 1u64, y: 1i64 };
532 a.x();
533 a.y();
534 a.z(1i128);
535 a.z::<u128>(1);
536}
537"#,
538 );
539}
540
541#[test]
542fn infer_impl_generics_with_autoderef() {
543 check_inference(
544 "infer_impl_generics_with_autoderef",
545 r#"
546enum Option<T> {
547 Some(T),
548 None,
549}
550impl<T> Option<T> {
551 fn as_ref(&self) -> Option<&T> {}
552}
553fn test(o: Option<u32>) {
554 (&o).as_ref();
555 o.as_ref();
556}
557"#,
558 );
559}
560
561#[test]
510fn infer_generic_chain() { 562fn infer_generic_chain() {
511 check_inference( 563 check_inference(
512 "infer_generic_chain", 564 "infer_generic_chain",