aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/generics.rs
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2021-04-05 02:50:10 +0100
committerJonas Schievink <[email protected]>2021-04-05 02:50:10 +0100
commit7c0c713a102ee86ee32af115acba63a5c3b3a657 (patch)
treeefa1f5aee1521d720bc6e83db26b53f00d7562a0 /crates/hir_def/src/generics.rs
parentadcf18e27dc04b60fede859f3d6c22b99d4fd513 (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.rs37
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.
5use std::sync::Arc;
6 5
7use base_db::FileId; 6use base_db::FileId;
8use either::Either; 7use 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)]
31pub struct TypeParamData { 30pub 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)]
39pub struct LifetimeParamData { 38pub 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)]
45pub struct ConstParamData { 44pub 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)]
51pub enum TypeParamProvenance { 50pub 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)]
59pub struct GenericParams { 58pub 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)]
71pub enum WherePredicate { 70pub 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)]
78pub enum WherePredicateTypeTarget { 77pub 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>) {