libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / rust / typecheck / rust-hir-type-check-enumitem.cc
blob9fcb442e0de5d04eb014c71a91bf77dbb2d0eb8e
1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
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.
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.
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/>.
19 #include "rust-hir-type-check-type.h"
20 #include "rust-hir-type-check-expr.h"
21 #include "rust-hir-type-check-enumitem.h"
22 #include "rust-type-util.h"
24 namespace Rust {
25 namespace Resolver {
27 TyTy::VariantDef *
28 TypeCheckEnumItem::Resolve (HIR::EnumItem *item, int64_t last_discriminant)
30 TypeCheckEnumItem resolver (last_discriminant);
31 switch (item->get_enum_item_kind ())
33 case HIR::EnumItem::EnumItemKind::Named:
34 resolver.visit (static_cast<HIR::EnumItem &> (*item));
35 break;
37 case HIR::EnumItem::EnumItemKind::Tuple:
38 resolver.visit (static_cast<HIR::EnumItemTuple &> (*item));
39 break;
41 case HIR::EnumItem::EnumItemKind::Struct:
42 resolver.visit (static_cast<HIR::EnumItemStruct &> (*item));
43 break;
45 case HIR::EnumItem::EnumItemKind::Discriminant:
46 resolver.visit (static_cast<HIR::EnumItemDiscriminant &> (*item));
47 break;
49 return resolver.variant;
52 TypeCheckEnumItem::TypeCheckEnumItem (int64_t last_discriminant)
53 : TypeCheckBase (), variant (nullptr), last_discriminant (last_discriminant)
56 void
57 TypeCheckEnumItem::visit (HIR::EnumItem &item)
59 if (last_discriminant == INT64_MAX)
60 rust_error_at (item.get_locus (), "discriminant too big");
62 Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
63 item.get_mappings ().get_nodeid (),
64 mappings->get_next_hir_id (
65 item.get_mappings ().get_crate_num ()),
66 item.get_mappings ().get_local_defid ());
67 HIR::LiteralExpr *discim_expr
68 = new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
69 HIR::Literal::LitType::INT,
70 PrimitiveCoreType::CORETYPE_I64, item.get_locus (),
71 {});
73 TyTy::BaseType *isize = nullptr;
74 bool ok = context->lookup_builtin ("isize", &isize);
75 rust_assert (ok);
76 context->insert_type (mapping, isize);
78 const CanonicalPath *canonical_path = nullptr;
79 ok = mappings->lookup_canonical_path (item.get_mappings ().get_nodeid (),
80 &canonical_path);
81 rust_assert (ok);
83 RustIdent ident{*canonical_path, item.get_locus ()};
84 variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
85 item.get_mappings ().get_defid (),
86 item.get_identifier ().as_string (), ident,
87 discim_expr);
90 void
91 TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
93 if (last_discriminant == INT64_MAX)
94 rust_error_at (item.get_locus (), "discriminant too big");
96 auto &discriminant = item.get_discriminant_expression ();
97 auto capacity_type = TypeCheckExpr::Resolve (discriminant.get ());
98 if (capacity_type->get_kind () == TyTy::TypeKind::ERROR)
99 return;
101 TyTy::ISizeType *expected_ty
102 = new TyTy::ISizeType (discriminant->get_mappings ().get_hirid ());
103 context->insert_type (discriminant->get_mappings (), expected_ty);
105 unify_site (item.get_mappings ().get_hirid (),
106 TyTy::TyWithLocation (expected_ty),
107 TyTy::TyWithLocation (capacity_type), item.get_locus ());
109 const CanonicalPath *canonical_path = nullptr;
110 bool ok = mappings->lookup_canonical_path (item.get_mappings ().get_nodeid (),
111 &canonical_path);
112 rust_assert (ok);
114 RustIdent ident{*canonical_path, item.get_locus ()};
115 variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
116 item.get_mappings ().get_defid (),
117 item.get_identifier ().as_string (), ident,
118 item.get_discriminant_expression ().get ());
121 void
122 TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
124 if (last_discriminant == INT64_MAX)
125 rust_error_at (item.get_locus (), "discriminant too big");
127 std::vector<TyTy::StructFieldType *> fields;
128 size_t idx = 0;
129 for (auto &field : item.get_tuple_fields ())
131 TyTy::BaseType *field_type
132 = TypeCheckType::Resolve (field.get_field_type ().get ());
133 TyTy::StructFieldType *ty_field
134 = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
135 std::to_string (idx), field_type,
136 field.get_locus ());
137 fields.push_back (ty_field);
138 context->insert_type (field.get_mappings (), ty_field->get_field_type ());
139 idx++;
142 Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
143 item.get_mappings ().get_nodeid (),
144 mappings->get_next_hir_id (
145 item.get_mappings ().get_crate_num ()),
146 item.get_mappings ().get_local_defid ());
147 HIR::LiteralExpr *discim_expr
148 = new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
149 HIR::Literal::LitType::INT,
150 PrimitiveCoreType::CORETYPE_I64, item.get_locus (),
151 {});
153 TyTy::BaseType *isize = nullptr;
154 bool ok = context->lookup_builtin ("isize", &isize);
155 rust_assert (ok);
156 context->insert_type (mapping, isize);
158 const CanonicalPath *canonical_path = nullptr;
159 ok = mappings->lookup_canonical_path (item.get_mappings ().get_nodeid (),
160 &canonical_path);
161 rust_assert (ok);
163 RustIdent ident{*canonical_path, item.get_locus ()};
164 variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
165 item.get_mappings ().get_defid (),
166 item.get_identifier ().as_string (), ident,
167 TyTy::VariantDef::VariantType::TUPLE,
168 discim_expr, fields);
171 void
172 TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
174 if (last_discriminant == INT64_MAX)
175 rust_error_at (item.get_locus (), "discriminant too big");
177 std::vector<TyTy::StructFieldType *> fields;
178 for (auto &field : item.get_struct_fields ())
180 TyTy::BaseType *field_type
181 = TypeCheckType::Resolve (field.get_field_type ().get ());
182 TyTy::StructFieldType *ty_field
183 = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
184 field.get_field_name ().as_string (),
185 field_type, field.get_locus ());
186 fields.push_back (ty_field);
187 context->insert_type (field.get_mappings (), ty_field->get_field_type ());
190 Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
191 item.get_mappings ().get_nodeid (),
192 mappings->get_next_hir_id (
193 item.get_mappings ().get_crate_num ()),
194 item.get_mappings ().get_local_defid ());
195 HIR::LiteralExpr *discrim_expr
196 = new HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
197 HIR::Literal::LitType::INT,
198 PrimitiveCoreType::CORETYPE_I64, item.get_locus (),
199 {});
201 TyTy::BaseType *isize = nullptr;
202 bool ok = context->lookup_builtin ("isize", &isize);
203 rust_assert (ok);
204 context->insert_type (mapping, isize);
206 const CanonicalPath *canonical_path = nullptr;
207 ok = mappings->lookup_canonical_path (item.get_mappings ().get_nodeid (),
208 &canonical_path);
209 rust_assert (ok);
211 RustIdent ident{*canonical_path, item.get_locus ()};
212 variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
213 item.get_mappings ().get_defid (),
214 item.get_identifier ().as_string (), ident,
215 TyTy::VariantDef::VariantType::STRUCT,
216 discrim_expr, fields);
219 } // namespace Resolver
220 } // namespace Rust