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/generics.rs | |
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/generics.rs')
-rw-r--r-- | crates/ra_hir/src/generics.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs new file mode 100644 index 000000000..d8248ad49 --- /dev/null +++ b/crates/ra_hir/src/generics.rs | |||
@@ -0,0 +1,48 @@ | |||
1 | //! Many kinds of items or constructs can have generic parameters: functions, | ||
2 | //! structs, impls, traits, etc. This module provides a common HIR for these | ||
3 | //! generic parameters. See also the `Generics` type and the `generics_of` query | ||
4 | //! in rustc. | ||
5 | |||
6 | use std::sync::Arc; | ||
7 | |||
8 | use ra_syntax::ast::{TypeParamList, AstNode, NameOwner}; | ||
9 | |||
10 | use crate::{db::HirDatabase, DefId, Name, AsName}; | ||
11 | |||
12 | /// Data about a generic parameter (to a function, struct, impl, ...). | ||
13 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
14 | pub struct GenericParam { | ||
15 | pub(crate) idx: u32, | ||
16 | pub(crate) name: Name, | ||
17 | } | ||
18 | |||
19 | /// Data about the generic parameters of a function, struct, impl, etc. | ||
20 | #[derive(Clone, PartialEq, Eq, Debug, Default)] | ||
21 | pub struct GenericParams { | ||
22 | pub(crate) params: Vec<GenericParam>, | ||
23 | } | ||
24 | |||
25 | impl GenericParams { | ||
26 | pub(crate) fn generic_params_query(db: &impl HirDatabase, def_id: DefId) -> Arc<GenericParams> { | ||
27 | let (_file_id, node) = def_id.source(db); | ||
28 | let mut generics = GenericParams::default(); | ||
29 | if let Some(type_param_list) = node.children().find_map(TypeParamList::cast) { | ||
30 | for (idx, type_param) in type_param_list.type_params().enumerate() { | ||
31 | let name = type_param | ||
32 | .name() | ||
33 | .map(AsName::as_name) | ||
34 | .unwrap_or_else(Name::missing); | ||
35 | let param = GenericParam { | ||
36 | idx: idx as u32, | ||
37 | name, | ||
38 | }; | ||
39 | generics.params.push(param); | ||
40 | } | ||
41 | } | ||
42 | Arc::new(generics) | ||
43 | } | ||
44 | |||
45 | pub(crate) fn find_by_name(&self, name: &Name) -> Option<&GenericParam> { | ||
46 | self.params.iter().find(|p| &p.name == name) | ||
47 | } | ||
48 | } | ||