aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-01-19 18:03:36 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-01-19 18:03:36 +0000
commit1c296d54e3dcc36c1a778873f26035000a352ba2 (patch)
tree0a6ce660ee32080287284c93bffaaaada91f3584 /crates/ra_hir/src/ty
parentbade91db081a3465dea3547ab8ab669f78fde9dc (diff)
parent5f3509e140d19b989db418a00ac6778c622cde5d (diff)
Merge #576
576: Beginnings of generics r=matklad a=flodiebold This implements the beginnings of the generics infrastructure; generic parameters for structs work and are correctly substituted in fields. Functions and methods aren't handled at all yet (as the tests show). The name resolution in `ty` really needs refactoring now, I hope to do that next ;) Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs17
-rw-r--r--crates/ra_hir/src/ty/tests.rs89
-rw-r--r--crates/ra_hir/src/ty/tests/data/function_generics.txt14
-rw-r--r--crates/ra_hir/src/ty/tests/data/generic_chain.txt29
-rw-r--r--crates/ra_hir/src/ty/tests/data/generics_in_patterns.txt17
-rw-r--r--crates/ra_hir/src/ty/tests/data/struct_generics.txt15
6 files changed, 178 insertions, 3 deletions
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index b221bd142..9f65c5fe1 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -8,7 +8,11 @@ use rustc_hash::FxHashMap;
8 8
9use ra_db::SourceRootId; 9use ra_db::SourceRootId;
10 10
11use crate::{HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function, impl_block::{ImplId, ImplBlock, ImplItem}}; 11use crate::{
12 HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function,
13 impl_block::{ImplId, ImplBlock, ImplItem},
14 generics::GenericParams
15};
12use super::Ty; 16use super::Ty;
13 17
14/// This is used as a key for indexing impls. 18/// This is used as a key for indexing impls.
@@ -64,8 +68,15 @@ impl CrateImplBlocks {
64 if let Some(_target_trait) = impl_data.target_trait() { 68 if let Some(_target_trait) = impl_data.target_trait() {
65 // ignore for now 69 // ignore for now
66 } else { 70 } else {
67 let target_ty = 71 // TODO provide generics of impl
68 Ty::from_hir(db, &module, Some(&impl_block), impl_data.target_type()); 72 let generics = GenericParams::default();
73 let target_ty = Ty::from_hir(
74 db,
75 &module,
76 Some(&impl_block),
77 &generics,
78 impl_data.target_type(),
79 );
69 if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { 80 if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
70 self.impls 81 self.impls
71 .entry(target_ty_fp) 82 .entry(target_ty_fp)
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index fc4054159..06e32df59 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -418,6 +418,95 @@ fn test() {
418 ); 418 );
419} 419}
420 420
421#[test]
422fn infer_struct_generics() {
423 check_inference(
424 r#"
425struct A<T> {
426 x: T,
427}
428
429fn test(a1: A<u32>, i: i32) {
430 a1.x;
431 let a2 = A { x: i };
432 a2.x;
433 let a3 = A::<i128> { x: 1 };
434 a3.x;
435}
436"#,
437 "struct_generics.txt",
438 );
439}
440
441#[test]
442fn infer_generics_in_patterns() {
443 check_inference(
444 r#"
445struct A<T> {
446 x: T,
447}
448
449enum Option<T> {
450 Some(T),
451 None,
452}
453
454fn test(a1: A<u32>, o: Option<u64>) {
455 let A { x: x2 } = a1;
456 let A::<i64> { x: x3 } = A { x: 1 };
457 match o {
458 Option::Some(t) => t,
459 _ => 1,
460 };
461}
462"#,
463 "generics_in_patterns.txt",
464 );
465}
466
467#[test]
468fn infer_function_generics() {
469 check_inference(
470 r#"
471fn id<T>(t: T) -> T { t }
472
473fn test() {
474 id(1u32);
475 id::<i128>(1);
476 let x: u64 = id(1);
477}
478"#,
479 "function_generics.txt",
480 );
481}
482
483#[test]
484fn infer_generic_chain() {
485 check_inference(
486 r#"
487struct A<T> {
488 x: T,
489}
490impl<T2> A<T2> {
491 fn x(self) -> T2 {
492 self.x
493 }
494}
495fn id<T>(t: T) -> T { t }
496
497fn test() -> i128 {
498 let x = 1;
499 let y = id(x);
500 let a = A { x: id(y) };
501 let z = id(a.x);
502 let b = A { x: z };
503 b.x()
504}
505"#,
506 "generic_chain.txt",
507 );
508}
509
421fn infer(content: &str) -> String { 510fn infer(content: &str) -> String {
422 let (db, _, file_id) = MockDatabase::with_single_file(content); 511 let (db, _, file_id) = MockDatabase::with_single_file(content);
423 let source_file = db.source_file(file_id); 512 let source_file = db.source_file(file_id);
diff --git a/crates/ra_hir/src/ty/tests/data/function_generics.txt b/crates/ra_hir/src/ty/tests/data/function_generics.txt
new file mode 100644
index 000000000..e44d26cfd
--- /dev/null
+++ b/crates/ra_hir/src/ty/tests/data/function_generics.txt
@@ -0,0 +1,14 @@
1[10; 11) 't': [unknown]
2[21; 26) '{ t }': [unknown]
3[23; 24) 't': [unknown]
4[38; 98) '{ ...(1); }': ()
5[44; 46) 'id': fn(T) -> T
6[44; 52) 'id(1u32)': T
7[47; 51) '1u32': u32
8[58; 68) 'id::<i128>': fn(T) -> T
9[58; 71) 'id::<i128>(1)': T
10[69; 70) '1': T
11[81; 82) 'x': T
12[90; 92) 'id': fn(T) -> T
13[90; 95) 'id(1)': T
14[93; 94) '1': T
diff --git a/crates/ra_hir/src/ty/tests/data/generic_chain.txt b/crates/ra_hir/src/ty/tests/data/generic_chain.txt
new file mode 100644
index 000000000..568e00846
--- /dev/null
+++ b/crates/ra_hir/src/ty/tests/data/generic_chain.txt
@@ -0,0 +1,29 @@
1[53; 57) 'self': A<[unknown]>
2[65; 87) '{ ... }': [unknown]
3[75; 79) 'self': A<[unknown]>
4[75; 81) 'self.x': [unknown]
5[99; 100) 't': [unknown]
6[110; 115) '{ t }': [unknown]
7[112; 113) 't': [unknown]
8[135; 261) '{ ....x() }': i128
9[146; 147) 'x': T
10[150; 151) '1': T
11[162; 163) 'y': T
12[166; 168) 'id': fn(T) -> T
13[166; 171) 'id(x)': T
14[169; 170) 'x': T
15[182; 183) 'a': A<T>
16[186; 200) 'A { x: id(y) }': A<T>
17[193; 195) 'id': fn(T) -> T
18[193; 198) 'id(y)': T
19[196; 197) 'y': T
20[211; 212) 'z': T
21[215; 217) 'id': fn(T) -> T
22[215; 222) 'id(a.x)': T
23[218; 219) 'a': A<T>
24[218; 221) 'a.x': T
25[233; 234) 'b': A<T>
26[237; 247) 'A { x: z }': A<T>
27[244; 245) 'z': T
28[254; 255) 'b': A<T>
29[254; 259) 'b.x()': i128
diff --git a/crates/ra_hir/src/ty/tests/data/generics_in_patterns.txt b/crates/ra_hir/src/ty/tests/data/generics_in_patterns.txt
new file mode 100644
index 000000000..1b01ef19e
--- /dev/null
+++ b/crates/ra_hir/src/ty/tests/data/generics_in_patterns.txt
@@ -0,0 +1,17 @@
1[79; 81) 'a1': A<u32>
2[91; 92) 'o': Option<u64>
3[107; 244) '{ ... }; }': ()
4[117; 128) 'A { x: x2 }': A<u32>
5[124; 126) 'x2': u32
6[131; 133) 'a1': A<u32>
7[143; 161) 'A::<i6...: x3 }': A<i64>
8[157; 159) 'x3': i64
9[164; 174) 'A { x: 1 }': A<i64>
10[171; 172) '1': i64
11[180; 241) 'match ... }': u64
12[186; 187) 'o': Option<u64>
13[198; 213) 'Option::Some(t)': Option<u64>
14[211; 212) 't': u64
15[217; 218) 't': u64
16[228; 229) '_': Option<u64>
17[233; 234) '1': u64
diff --git a/crates/ra_hir/src/ty/tests/data/struct_generics.txt b/crates/ra_hir/src/ty/tests/data/struct_generics.txt
new file mode 100644
index 000000000..1024a39a9
--- /dev/null
+++ b/crates/ra_hir/src/ty/tests/data/struct_generics.txt
@@ -0,0 +1,15 @@
1[36; 38) 'a1': A<u32>
2[48; 49) 'i': i32
3[56; 147) '{ ...3.x; }': ()
4[62; 64) 'a1': A<u32>
5[62; 66) 'a1.x': u32
6[76; 78) 'a2': A<i32>
7[81; 91) 'A { x: i }': A<i32>
8[88; 89) 'i': i32
9[97; 99) 'a2': A<i32>
10[97; 101) 'a2.x': i32
11[111; 113) 'a3': A<i128>
12[116; 134) 'A::<i1...x: 1 }': A<i128>
13[131; 132) '1': i128
14[140; 142) 'a3': A<i128>
15[140; 144) 'a3.x': i128