diff options
author | Jonas Schievink <[email protected]> | 2021-04-05 02:50:10 +0100 |
---|---|---|
committer | Jonas Schievink <[email protected]> | 2021-04-05 02:50:10 +0100 |
commit | 7c0c713a102ee86ee32af115acba63a5c3b3a657 (patch) | |
tree | efa1f5aee1521d720bc6e83db26b53f00d7562a0 /crates/hir_def/src/generics.rs | |
parent | adcf18e27dc04b60fede859f3d6c22b99d4fd513 (diff) |
Intern `GenericParams`
Also share the same instance between `ItemTree` and `generic_params`
query.
Diffstat (limited to 'crates/hir_def/src/generics.rs')
-rw-r--r-- | crates/hir_def/src/generics.rs | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs index d55c189d4..de5acced8 100644 --- a/crates/hir_def/src/generics.rs +++ b/crates/hir_def/src/generics.rs | |||
@@ -2,7 +2,6 @@ | |||
2 | //! structs, impls, traits, etc. This module provides a common HIR for these | 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 | 3 | //! generic parameters. See also the `Generics` type and the `generics_of` query |
4 | //! in rustc. | 4 | //! in rustc. |
5 | use std::sync::Arc; | ||
6 | 5 | ||
7 | use base_db::FileId; | 6 | use base_db::FileId; |
8 | use either::Either; | 7 | use either::Either; |
@@ -27,7 +26,7 @@ use crate::{ | |||
27 | }; | 26 | }; |
28 | 27 | ||
29 | /// Data about a generic type parameter (to a function, struct, impl, ...). | 28 | /// Data about a generic type parameter (to a function, struct, impl, ...). |
30 | #[derive(Clone, PartialEq, Eq, Debug)] | 29 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
31 | pub struct TypeParamData { | 30 | pub struct TypeParamData { |
32 | pub name: Option<Name>, | 31 | pub name: Option<Name>, |
33 | pub default: Option<Interned<TypeRef>>, | 32 | pub default: Option<Interned<TypeRef>>, |
@@ -35,19 +34,19 @@ pub struct TypeParamData { | |||
35 | } | 34 | } |
36 | 35 | ||
37 | /// Data about a generic lifetime parameter (to a function, struct, impl, ...). | 36 | /// Data about a generic lifetime parameter (to a function, struct, impl, ...). |
38 | #[derive(Clone, PartialEq, Eq, Debug)] | 37 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
39 | pub struct LifetimeParamData { | 38 | pub struct LifetimeParamData { |
40 | pub name: Name, | 39 | pub name: Name, |
41 | } | 40 | } |
42 | 41 | ||
43 | /// Data about a generic const parameter (to a function, struct, impl, ...). | 42 | /// Data about a generic const parameter (to a function, struct, impl, ...). |
44 | #[derive(Clone, PartialEq, Eq, Debug)] | 43 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
45 | pub struct ConstParamData { | 44 | pub struct ConstParamData { |
46 | pub name: Name, | 45 | pub name: Name, |
47 | pub ty: Interned<TypeRef>, | 46 | pub ty: Interned<TypeRef>, |
48 | } | 47 | } |
49 | 48 | ||
50 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] | 49 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
51 | pub enum TypeParamProvenance { | 50 | pub enum TypeParamProvenance { |
52 | TypeParamList, | 51 | TypeParamList, |
53 | TraitSelf, | 52 | TraitSelf, |
@@ -55,7 +54,7 @@ pub enum TypeParamProvenance { | |||
55 | } | 54 | } |
56 | 55 | ||
57 | /// Data about the generic parameters of a function, struct, impl, etc. | 56 | /// Data about the generic parameters of a function, struct, impl, etc. |
58 | #[derive(Clone, PartialEq, Eq, Debug, Default)] | 57 | #[derive(Clone, PartialEq, Eq, Debug, Default, Hash)] |
59 | pub struct GenericParams { | 58 | pub struct GenericParams { |
60 | pub types: Arena<TypeParamData>, | 59 | pub types: Arena<TypeParamData>, |
61 | pub lifetimes: Arena<LifetimeParamData>, | 60 | pub lifetimes: Arena<LifetimeParamData>, |
@@ -67,14 +66,14 @@ pub struct GenericParams { | |||
67 | /// where clauses like `where T: Foo + Bar` are turned into multiple of these. | 66 | /// where clauses like `where T: Foo + Bar` are turned into multiple of these. |
68 | /// It might still result in multiple actual predicates though, because of | 67 | /// It might still result in multiple actual predicates though, because of |
69 | /// associated type bindings like `Iterator<Item = u32>`. | 68 | /// associated type bindings like `Iterator<Item = u32>`. |
70 | #[derive(Clone, PartialEq, Eq, Debug)] | 69 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
71 | pub enum WherePredicate { | 70 | pub enum WherePredicate { |
72 | TypeBound { target: WherePredicateTypeTarget, bound: TypeBound }, | 71 | TypeBound { target: WherePredicateTypeTarget, bound: TypeBound }, |
73 | Lifetime { target: LifetimeRef, bound: LifetimeRef }, | 72 | Lifetime { target: LifetimeRef, bound: LifetimeRef }, |
74 | ForLifetime { lifetimes: Box<[Name]>, target: WherePredicateTypeTarget, bound: TypeBound }, | 73 | ForLifetime { lifetimes: Box<[Name]>, target: WherePredicateTypeTarget, bound: TypeBound }, |
75 | } | 74 | } |
76 | 75 | ||
77 | #[derive(Clone, PartialEq, Eq, Debug)] | 76 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
78 | pub enum WherePredicateTypeTarget { | 77 | pub enum WherePredicateTypeTarget { |
79 | TypeRef(Interned<TypeRef>), | 78 | TypeRef(Interned<TypeRef>), |
80 | /// For desugared where predicates that can directly refer to a type param. | 79 | /// For desugared where predicates that can directly refer to a type param. |
@@ -92,7 +91,7 @@ impl GenericParams { | |||
92 | pub(crate) fn generic_params_query( | 91 | pub(crate) fn generic_params_query( |
93 | db: &dyn DefDatabase, | 92 | db: &dyn DefDatabase, |
94 | def: GenericDefId, | 93 | def: GenericDefId, |
95 | ) -> Arc<GenericParams> { | 94 | ) -> Interned<GenericParams> { |
96 | let _p = profile::span("generic_params_query"); | 95 | let _p = profile::span("generic_params_query"); |
97 | 96 | ||
98 | let generics = match def { | 97 | let generics = match def { |
@@ -100,47 +99,49 @@ impl GenericParams { | |||
100 | let id = id.lookup(db).id; | 99 | let id = id.lookup(db).id; |
101 | let tree = id.item_tree(db); | 100 | let tree = id.item_tree(db); |
102 | let item = &tree[id.value]; | 101 | let item = &tree[id.value]; |
103 | tree[item.generic_params].clone() | 102 | item.generic_params.clone() |
104 | } | 103 | } |
105 | GenericDefId::AdtId(AdtId::StructId(id)) => { | 104 | GenericDefId::AdtId(AdtId::StructId(id)) => { |
106 | let id = id.lookup(db).id; | 105 | let id = id.lookup(db).id; |
107 | let tree = id.item_tree(db); | 106 | let tree = id.item_tree(db); |
108 | let item = &tree[id.value]; | 107 | let item = &tree[id.value]; |
109 | tree[item.generic_params].clone() | 108 | item.generic_params.clone() |
110 | } | 109 | } |
111 | GenericDefId::AdtId(AdtId::EnumId(id)) => { | 110 | GenericDefId::AdtId(AdtId::EnumId(id)) => { |
112 | let id = id.lookup(db).id; | 111 | let id = id.lookup(db).id; |
113 | let tree = id.item_tree(db); | 112 | let tree = id.item_tree(db); |
114 | let item = &tree[id.value]; | 113 | let item = &tree[id.value]; |
115 | tree[item.generic_params].clone() | 114 | item.generic_params.clone() |
116 | } | 115 | } |
117 | GenericDefId::AdtId(AdtId::UnionId(id)) => { | 116 | GenericDefId::AdtId(AdtId::UnionId(id)) => { |
118 | let id = id.lookup(db).id; | 117 | let id = id.lookup(db).id; |
119 | let tree = id.item_tree(db); | 118 | let tree = id.item_tree(db); |
120 | let item = &tree[id.value]; | 119 | let item = &tree[id.value]; |
121 | tree[item.generic_params].clone() | 120 | item.generic_params.clone() |
122 | } | 121 | } |
123 | GenericDefId::TraitId(id) => { | 122 | GenericDefId::TraitId(id) => { |
124 | let id = id.lookup(db).id; | 123 | let id = id.lookup(db).id; |
125 | let tree = id.item_tree(db); | 124 | let tree = id.item_tree(db); |
126 | let item = &tree[id.value]; | 125 | let item = &tree[id.value]; |
127 | tree[item.generic_params].clone() | 126 | item.generic_params.clone() |
128 | } | 127 | } |
129 | GenericDefId::TypeAliasId(id) => { | 128 | GenericDefId::TypeAliasId(id) => { |
130 | let id = id.lookup(db).id; | 129 | let id = id.lookup(db).id; |
131 | let tree = id.item_tree(db); | 130 | let tree = id.item_tree(db); |
132 | let item = &tree[id.value]; | 131 | let item = &tree[id.value]; |
133 | tree[item.generic_params].clone() | 132 | item.generic_params.clone() |
134 | } | 133 | } |
135 | GenericDefId::ImplId(id) => { | 134 | GenericDefId::ImplId(id) => { |
136 | let id = id.lookup(db).id; | 135 | let id = id.lookup(db).id; |
137 | let tree = id.item_tree(db); | 136 | let tree = id.item_tree(db); |
138 | let item = &tree[id.value]; | 137 | let item = &tree[id.value]; |
139 | tree[item.generic_params].clone() | 138 | item.generic_params.clone() |
139 | } | ||
140 | GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => { | ||
141 | Interned::new(GenericParams::default()) | ||
140 | } | 142 | } |
141 | GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => GenericParams::default(), | ||
142 | }; | 143 | }; |
143 | Arc::new(generics) | 144 | generics |
144 | } | 145 | } |
145 | 146 | ||
146 | fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) { | 147 | fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) { |