diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-19 18:03:36 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-19 18:03:36 +0000 |
commit | 1c296d54e3dcc36c1a778873f26035000a352ba2 (patch) | |
tree | 0a6ce660ee32080287284c93bffaaaada91f3584 /crates/ra_hir/src/ty | |
parent | bade91db081a3465dea3547ab8ab669f78fde9dc (diff) | |
parent | 5f3509e140d19b989db418a00ac6778c622cde5d (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.rs | 17 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 89 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/function_generics.txt | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/generic_chain.txt | 29 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/generics_in_patterns.txt | 17 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/struct_generics.txt | 15 |
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 | ||
9 | use ra_db::SourceRootId; | 9 | use ra_db::SourceRootId; |
10 | 10 | ||
11 | use crate::{HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function, impl_block::{ImplId, ImplBlock, ImplItem}}; | 11 | use crate::{ |
12 | HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function, | ||
13 | impl_block::{ImplId, ImplBlock, ImplItem}, | ||
14 | generics::GenericParams | ||
15 | }; | ||
12 | use super::Ty; | 16 | use 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] | ||
422 | fn infer_struct_generics() { | ||
423 | check_inference( | ||
424 | r#" | ||
425 | struct A<T> { | ||
426 | x: T, | ||
427 | } | ||
428 | |||
429 | fn 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] | ||
442 | fn infer_generics_in_patterns() { | ||
443 | check_inference( | ||
444 | r#" | ||
445 | struct A<T> { | ||
446 | x: T, | ||
447 | } | ||
448 | |||
449 | enum Option<T> { | ||
450 | Some(T), | ||
451 | None, | ||
452 | } | ||
453 | |||
454 | fn 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] | ||
468 | fn infer_function_generics() { | ||
469 | check_inference( | ||
470 | r#" | ||
471 | fn id<T>(t: T) -> T { t } | ||
472 | |||
473 | fn 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] | ||
484 | fn infer_generic_chain() { | ||
485 | check_inference( | ||
486 | r#" | ||
487 | struct A<T> { | ||
488 | x: T, | ||
489 | } | ||
490 | impl<T2> A<T2> { | ||
491 | fn x(self) -> T2 { | ||
492 | self.x | ||
493 | } | ||
494 | } | ||
495 | fn id<T>(t: T) -> T { t } | ||
496 | |||
497 | fn 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 | |||
421 | fn infer(content: &str) -> String { | 510 | fn 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 | ||