1use hir_expand::name::Name;
5use la_arena::Idx;
6use rustc_abi::ExternAbi;
7use thin_vec::ThinVec;
8
9use crate::{
10 LifetimeParamId, TypeParamId,
11 expr_store::{ExpressionStore, path::Path},
12 hir::{ExprId, PatId},
13};
14
15#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
16pub enum Mutability {
17 Shared,
18 Mut,
19}
20
21impl Mutability {
22 pub fn from_mutable(mutable: bool) -> Mutability {
23 if mutable { Mutability::Mut } else { Mutability::Shared }
24 }
25
26 pub fn as_keyword_for_ref(self) -> &'static str {
27 match self {
28 Mutability::Shared => "",
29 Mutability::Mut => "mut ",
30 }
31 }
32
33 pub fn as_keyword_for_ptr(self) -> &'static str {
34 match self {
35 Mutability::Shared => "const ",
36 Mutability::Mut => "mut ",
37 }
38 }
39
40 #[must_use]
44 pub fn is_mut(&self) -> bool {
45 matches!(self, Self::Mut)
46 }
47
48 #[must_use]
52 pub fn is_shared(&self) -> bool {
53 matches!(self, Self::Shared)
54 }
55}
56
57#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
58pub enum Rawness {
59 RawPtr,
60 Ref,
61}
62
63impl Rawness {
64 pub fn from_raw(is_raw: bool) -> Rawness {
65 if is_raw { Rawness::RawPtr } else { Rawness::Ref }
66 }
67
68 pub fn is_raw(&self) -> bool {
69 matches!(self, Self::RawPtr)
70 }
71}
72
73#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
74pub struct PathId(TypeRefId);
77
78impl PathId {
79 #[inline]
80 pub fn from_type_ref_unchecked(type_ref: TypeRefId) -> Self {
81 Self(type_ref)
82 }
83
84 #[inline]
85 pub fn type_ref(self) -> TypeRefId {
86 self.0
87 }
88}
89
90#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
91pub struct TraitRef {
92 pub path: PathId,
93}
94
95#[derive(Clone, PartialEq, Eq, Hash, Debug)]
96pub struct FnType {
97 pub binder: Option<Box<[Name]>>,
98 pub params: Box<[(Option<Name>, TypeRefId)]>,
99 pub is_varargs: bool,
100 pub is_unsafe: bool,
101 pub abi: ExternAbi,
102}
103
104impl FnType {
105 #[inline]
106 pub fn split_params_and_ret(&self) -> (&[(Option<Name>, TypeRefId)], TypeRefId) {
107 let (ret, params) = self.params.split_last().expect("should have at least return type");
108 (params, ret.1)
109 }
110}
111
112#[derive(Clone, PartialEq, Eq, Hash, Debug)]
113pub struct ArrayType {
114 pub ty: TypeRefId,
115 pub len: ConstRef,
116}
117
118#[derive(Clone, PartialEq, Eq, Hash, Debug)]
119pub struct RefType {
120 pub ty: TypeRefId,
121 pub lifetime: Option<LifetimeRefId>,
122 pub mutability: Mutability,
123}
124
125#[derive(Clone, PartialEq, Eq, Hash, Debug)]
127pub enum TypeRef {
128 Never,
129 Placeholder,
130 Tuple(ThinVec<TypeRefId>),
131 Path(Path),
132 RawPtr(TypeRefId, Mutability),
133 Reference(Box<RefType>),
136 Array(ArrayType),
137 Slice(TypeRefId),
138 Fn(Box<FnType>),
140 ImplTrait(ThinVec<TypeBound>),
141 DynTrait(ThinVec<TypeBound>),
142 TypeParam(TypeParamId),
143 PatternType(TypeRefId, PatId),
144 Error,
145}
146
147#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
148const _: () = assert!(size_of::<TypeRef>() == 24);
149
150pub type TypeRefId = Idx<TypeRef>;
151
152pub type LifetimeRefId = Idx<LifetimeRef>;
153
154#[derive(Clone, PartialEq, Eq, Hash, Debug)]
155pub enum LifetimeRef {
156 Named(Name),
157 Static,
158 Placeholder,
159 Param(LifetimeParamId),
160 Error,
161}
162
163#[derive(Clone, PartialEq, Eq, Hash, Debug)]
164pub enum TypeBound {
165 Path(PathId, TraitBoundModifier),
166 ForLifetime(ThinVec<Name>, PathId),
167 Lifetime(LifetimeRefId),
168 Use(ThinVec<UseArgRef>),
169 Error,
170}
171
172#[cfg(target_pointer_width = "64")]
173const _: [(); 16] = [(); size_of::<TypeBound>()];
174
175#[derive(Clone, PartialEq, Eq, Hash, Debug)]
176pub enum UseArgRef {
177 Name(Name),
178 Lifetime(LifetimeRefId),
179}
180
181#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
184pub enum TraitBoundModifier {
185 None,
186 Maybe,
187}
188
189impl TypeRef {
190 pub(crate) fn unit() -> TypeRef {
191 TypeRef::Tuple(ThinVec::new())
192 }
193}
194
195impl TypeBound {
196 pub fn as_path<'a>(&self, map: &'a ExpressionStore) -> Option<(&'a Path, TraitBoundModifier)> {
197 match self {
198 &TypeBound::Path(p, m) => Some((&map[p], m)),
199 &TypeBound::ForLifetime(_, p) => Some((&map[p], TraitBoundModifier::None)),
200 TypeBound::Lifetime(_) | TypeBound::Error | TypeBound::Use(_) => None,
201 }
202 }
203}
204
205#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
206pub struct ConstRef {
207 pub expr: ExprId,
208}