Line data Source code
1 : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
2 :
3 : // This file is part of GCC.
4 :
5 : // GCC is free software; you can redistribute it and/or modify it under
6 : // the terms of the GNU General Public License as published by the Free
7 : // Software Foundation; either version 3, or (at your option) any later
8 : // version.
9 :
10 : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : // for more details.
14 :
15 : // You should have received a copy of the GNU General Public License
16 : // along with GCC; see the file COPYING3. If not see
17 : // <http://www.gnu.org/licenses/>.
18 :
19 : #include "rust-hir-expr.h"
20 : #include "rust-hir-type-check-type.h"
21 : #include "rust-hir-type-check-expr.h"
22 : #include "rust-hir-type-check-enumitem.h"
23 : #include "rust-type-util.h"
24 : #include "rust-immutable-name-resolution-context.h"
25 :
26 : namespace Rust {
27 : namespace Resolver {
28 :
29 : TyTy::VariantDef *
30 1202 : TypeCheckEnumItem::Resolve (HIR::EnumItem &item, int64_t last_discriminant)
31 : {
32 1202 : TypeCheckEnumItem resolver (last_discriminant);
33 1202 : switch (item.get_enum_item_kind ())
34 : {
35 434 : case HIR::EnumItem::EnumItemKind::Named:
36 434 : resolver.visit (static_cast<HIR::EnumItem &> (item));
37 434 : break;
38 :
39 413 : case HIR::EnumItem::EnumItemKind::Tuple:
40 413 : resolver.visit (static_cast<HIR::EnumItemTuple &> (item));
41 413 : break;
42 :
43 86 : case HIR::EnumItem::EnumItemKind::Struct:
44 86 : resolver.visit (static_cast<HIR::EnumItemStruct &> (item));
45 86 : break;
46 :
47 269 : case HIR::EnumItem::EnumItemKind::Discriminant:
48 269 : resolver.visit (static_cast<HIR::EnumItemDiscriminant &> (item));
49 269 : break;
50 : }
51 1202 : return resolver.variant;
52 1202 : }
53 :
54 1202 : TypeCheckEnumItem::TypeCheckEnumItem (int64_t last_discriminant)
55 1202 : : TypeCheckBase (), variant (nullptr), last_discriminant (last_discriminant)
56 1202 : {}
57 :
58 : void
59 434 : TypeCheckEnumItem::visit (HIR::EnumItem &item)
60 : {
61 434 : if (last_discriminant == INT64_MAX)
62 0 : rust_error_at (item.get_locus (), "discriminant too big");
63 :
64 868 : Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
65 434 : item.get_mappings ().get_nodeid (),
66 434 : mappings.get_next_hir_id (
67 434 : item.get_mappings ().get_crate_num ()),
68 434 : item.get_mappings ().get_local_defid ());
69 434 : auto discim_expr = std::make_unique<HIR::LiteralExpr> (
70 868 : HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
71 : HIR::Literal::LitType::INT,
72 1302 : PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
73 :
74 434 : TyTy::BaseType *isize = nullptr;
75 434 : bool ok = context->lookup_builtin ("isize", &isize);
76 434 : rust_assert (ok);
77 434 : context->insert_type (mapping, isize);
78 :
79 434 : auto &nr_ctx
80 434 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
81 :
82 434 : CanonicalPath canonical_path
83 434 : = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid ());
84 :
85 434 : RustIdent ident{canonical_path, item.get_locus ()};
86 434 : variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
87 434 : item.get_mappings ().get_defid (),
88 434 : item.get_identifier ().as_string (), ident,
89 1736 : std::move (discim_expr));
90 434 : }
91 :
92 : void
93 269 : TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
94 : {
95 269 : if (last_discriminant == INT64_MAX)
96 0 : rust_error_at (item.get_locus (), "discriminant too big");
97 :
98 269 : auto &discriminant = item.get_discriminant_expression ();
99 269 : auto capacity_type = TypeCheckExpr::Resolve (discriminant);
100 269 : if (capacity_type->get_kind () == TyTy::TypeKind::ERROR)
101 0 : return;
102 :
103 269 : TyTy::ISizeType *expected_ty
104 269 : = new TyTy::ISizeType (discriminant.get_mappings ().get_hirid ());
105 269 : context->insert_type (discriminant.get_mappings (), expected_ty);
106 :
107 269 : unify_site (item.get_mappings ().get_hirid (),
108 269 : TyTy::TyWithLocation (expected_ty),
109 269 : TyTy::TyWithLocation (capacity_type), item.get_locus ());
110 :
111 269 : auto &nr_ctx
112 269 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
113 :
114 269 : CanonicalPath canonical_path
115 269 : = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid ());
116 :
117 269 : RustIdent ident{canonical_path, item.get_locus ()};
118 269 : variant
119 269 : = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
120 269 : item.get_mappings ().get_defid (),
121 269 : item.get_identifier ().as_string (), ident,
122 1076 : item.get_discriminant_expression ().clone_expr ());
123 269 : }
124 :
125 : void
126 413 : TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
127 : {
128 413 : if (last_discriminant == INT64_MAX)
129 0 : rust_error_at (item.get_locus (), "discriminant too big");
130 :
131 413 : std::vector<TyTy::StructFieldType *> fields;
132 413 : size_t idx = 0;
133 840 : for (auto &field : item.get_tuple_fields ())
134 : {
135 427 : TyTy::BaseType *field_type
136 427 : = TypeCheckType::Resolve (field.get_field_type ());
137 427 : TyTy::StructFieldType *ty_field
138 854 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
139 427 : std::to_string (idx), field_type,
140 427 : field.get_locus ());
141 427 : fields.push_back (ty_field);
142 427 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
143 427 : idx++;
144 : }
145 :
146 826 : Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
147 413 : item.get_mappings ().get_nodeid (),
148 413 : mappings.get_next_hir_id (
149 413 : item.get_mappings ().get_crate_num ()),
150 413 : item.get_mappings ().get_local_defid ());
151 413 : auto discim_expr = std::make_unique<HIR::LiteralExpr> (
152 826 : HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
153 : HIR::Literal::LitType::INT,
154 1239 : PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
155 :
156 413 : TyTy::BaseType *isize = nullptr;
157 413 : bool ok = context->lookup_builtin ("isize", &isize);
158 413 : rust_assert (ok);
159 413 : context->insert_type (mapping, isize);
160 :
161 413 : auto &nr_ctx
162 413 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
163 :
164 413 : CanonicalPath canonical_path
165 413 : = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid ());
166 :
167 413 : RustIdent ident{canonical_path, item.get_locus ()};
168 413 : variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
169 413 : item.get_mappings ().get_defid (),
170 413 : item.get_identifier ().as_string (), ident,
171 : TyTy::VariantDef::VariantType::TUPLE,
172 1652 : std::move (discim_expr), fields);
173 413 : }
174 :
175 : void
176 86 : TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
177 : {
178 86 : if (last_discriminant == INT64_MAX)
179 0 : rust_error_at (item.get_locus (), "discriminant too big");
180 :
181 86 : std::vector<TyTy::StructFieldType *> fields;
182 228 : for (auto &field : item.get_struct_fields ())
183 : {
184 142 : TyTy::BaseType *field_type
185 142 : = TypeCheckType::Resolve (field.get_field_type ());
186 142 : TyTy::StructFieldType *ty_field
187 142 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
188 142 : field.get_field_name ().as_string (),
189 284 : field_type, field.get_locus ());
190 142 : fields.push_back (ty_field);
191 142 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
192 : }
193 :
194 172 : Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
195 86 : item.get_mappings ().get_nodeid (),
196 86 : mappings.get_next_hir_id (
197 86 : item.get_mappings ().get_crate_num ()),
198 86 : item.get_mappings ().get_local_defid ());
199 86 : auto discrim_expr = std::make_unique<HIR::LiteralExpr> (
200 172 : HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
201 : HIR::Literal::LitType::INT,
202 258 : PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
203 :
204 86 : TyTy::BaseType *isize = nullptr;
205 86 : bool ok = context->lookup_builtin ("isize", &isize);
206 86 : rust_assert (ok);
207 86 : context->insert_type (mapping, isize);
208 :
209 86 : auto &nr_ctx
210 86 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
211 :
212 86 : CanonicalPath canonical_path
213 86 : = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid ());
214 :
215 86 : RustIdent ident{canonical_path, item.get_locus ()};
216 86 : variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
217 86 : item.get_mappings ().get_defid (),
218 86 : item.get_identifier ().as_string (), ident,
219 : TyTy::VariantDef::VariantType::STRUCT,
220 344 : std::move (discrim_expr), fields);
221 86 : }
222 :
223 : } // namespace Resolver
224 : } // namespace Rust
|