Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 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 : 1187 : TypeCheckEnumItem::Resolve (HIR::EnumItem &item, int64_t last_discriminant)
31 : : {
32 : 1187 : TypeCheckEnumItem resolver (last_discriminant);
33 : 1187 : switch (item.get_enum_item_kind ())
34 : : {
35 : 429 : case HIR::EnumItem::EnumItemKind::Named:
36 : 429 : resolver.visit (static_cast<HIR::EnumItem &> (item));
37 : 429 : break;
38 : :
39 : 407 : case HIR::EnumItem::EnumItemKind::Tuple:
40 : 407 : resolver.visit (static_cast<HIR::EnumItemTuple &> (item));
41 : 407 : break;
42 : :
43 : 83 : case HIR::EnumItem::EnumItemKind::Struct:
44 : 83 : resolver.visit (static_cast<HIR::EnumItemStruct &> (item));
45 : 83 : break;
46 : :
47 : 268 : case HIR::EnumItem::EnumItemKind::Discriminant:
48 : 268 : resolver.visit (static_cast<HIR::EnumItemDiscriminant &> (item));
49 : 268 : break;
50 : : }
51 : 1187 : return resolver.variant;
52 : 1187 : }
53 : :
54 : 1187 : TypeCheckEnumItem::TypeCheckEnumItem (int64_t last_discriminant)
55 : 1187 : : TypeCheckBase (), variant (nullptr), last_discriminant (last_discriminant)
56 : 1187 : {}
57 : :
58 : : void
59 : 429 : TypeCheckEnumItem::visit (HIR::EnumItem &item)
60 : : {
61 : 429 : if (last_discriminant == INT64_MAX)
62 : 0 : rust_error_at (item.get_locus (), "discriminant too big");
63 : :
64 : 858 : Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
65 : 429 : item.get_mappings ().get_nodeid (),
66 : 429 : mappings.get_next_hir_id (
67 : 429 : item.get_mappings ().get_crate_num ()),
68 : 429 : item.get_mappings ().get_local_defid ());
69 : 429 : auto discim_expr = std::make_unique<HIR::LiteralExpr> (
70 : 858 : HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
71 : : HIR::Literal::LitType::INT,
72 : 1287 : PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
73 : :
74 : 429 : TyTy::BaseType *isize = nullptr;
75 : 429 : bool ok = context->lookup_builtin ("isize", &isize);
76 : 429 : rust_assert (ok);
77 : 429 : context->insert_type (mapping, isize);
78 : :
79 : 429 : auto &nr_ctx
80 : 429 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
81 : :
82 : 429 : CanonicalPath canonical_path
83 : 429 : = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid ());
84 : :
85 : 429 : RustIdent ident{canonical_path, item.get_locus ()};
86 : 429 : variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
87 : 429 : item.get_mappings ().get_defid (),
88 : 429 : item.get_identifier ().as_string (), ident,
89 : 1716 : std::move (discim_expr));
90 : 429 : }
91 : :
92 : : void
93 : 268 : TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
94 : : {
95 : 268 : if (last_discriminant == INT64_MAX)
96 : 0 : rust_error_at (item.get_locus (), "discriminant too big");
97 : :
98 : 268 : auto &discriminant = item.get_discriminant_expression ();
99 : 268 : auto capacity_type = TypeCheckExpr::Resolve (discriminant);
100 : 268 : if (capacity_type->get_kind () == TyTy::TypeKind::ERROR)
101 : 0 : return;
102 : :
103 : 268 : TyTy::ISizeType *expected_ty
104 : 268 : = new TyTy::ISizeType (discriminant.get_mappings ().get_hirid ());
105 : 268 : context->insert_type (discriminant.get_mappings (), expected_ty);
106 : :
107 : 268 : unify_site (item.get_mappings ().get_hirid (),
108 : 268 : TyTy::TyWithLocation (expected_ty),
109 : 268 : TyTy::TyWithLocation (capacity_type), item.get_locus ());
110 : :
111 : 268 : auto &nr_ctx
112 : 268 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
113 : :
114 : 268 : CanonicalPath canonical_path
115 : 268 : = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid ());
116 : :
117 : 268 : RustIdent ident{canonical_path, item.get_locus ()};
118 : 268 : variant
119 : 268 : = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
120 : 268 : item.get_mappings ().get_defid (),
121 : 268 : item.get_identifier ().as_string (), ident,
122 : 1072 : item.get_discriminant_expression ().clone_expr ());
123 : 268 : }
124 : :
125 : : void
126 : 407 : TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
127 : : {
128 : 407 : if (last_discriminant == INT64_MAX)
129 : 0 : rust_error_at (item.get_locus (), "discriminant too big");
130 : :
131 : 407 : std::vector<TyTy::StructFieldType *> fields;
132 : 407 : size_t idx = 0;
133 : 830 : for (auto &field : item.get_tuple_fields ())
134 : : {
135 : 423 : TyTy::BaseType *field_type
136 : 423 : = TypeCheckType::Resolve (field.get_field_type ());
137 : 423 : TyTy::StructFieldType *ty_field
138 : 846 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
139 : 423 : std::to_string (idx), field_type,
140 : 423 : field.get_locus ());
141 : 423 : fields.push_back (ty_field);
142 : 423 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
143 : 423 : idx++;
144 : : }
145 : :
146 : 814 : Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
147 : 407 : item.get_mappings ().get_nodeid (),
148 : 407 : mappings.get_next_hir_id (
149 : 407 : item.get_mappings ().get_crate_num ()),
150 : 407 : item.get_mappings ().get_local_defid ());
151 : 407 : auto discim_expr = std::make_unique<HIR::LiteralExpr> (
152 : 814 : HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
153 : : HIR::Literal::LitType::INT,
154 : 1221 : PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
155 : :
156 : 407 : TyTy::BaseType *isize = nullptr;
157 : 407 : bool ok = context->lookup_builtin ("isize", &isize);
158 : 407 : rust_assert (ok);
159 : 407 : context->insert_type (mapping, isize);
160 : :
161 : 407 : auto &nr_ctx
162 : 407 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
163 : :
164 : 407 : CanonicalPath canonical_path
165 : 407 : = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid ());
166 : :
167 : 407 : RustIdent ident{canonical_path, item.get_locus ()};
168 : 407 : variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
169 : 407 : item.get_mappings ().get_defid (),
170 : 407 : item.get_identifier ().as_string (), ident,
171 : : TyTy::VariantDef::VariantType::TUPLE,
172 : 1628 : std::move (discim_expr), fields);
173 : 407 : }
174 : :
175 : : void
176 : 83 : TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
177 : : {
178 : 83 : if (last_discriminant == INT64_MAX)
179 : 0 : rust_error_at (item.get_locus (), "discriminant too big");
180 : :
181 : 83 : std::vector<TyTy::StructFieldType *> fields;
182 : 223 : for (auto &field : item.get_struct_fields ())
183 : : {
184 : 140 : TyTy::BaseType *field_type
185 : 140 : = TypeCheckType::Resolve (field.get_field_type ());
186 : 140 : TyTy::StructFieldType *ty_field
187 : 140 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
188 : 140 : field.get_field_name ().as_string (),
189 : 280 : field_type, field.get_locus ());
190 : 140 : fields.push_back (ty_field);
191 : 140 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
192 : : }
193 : :
194 : 166 : Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
195 : 83 : item.get_mappings ().get_nodeid (),
196 : 83 : mappings.get_next_hir_id (
197 : 83 : item.get_mappings ().get_crate_num ()),
198 : 83 : item.get_mappings ().get_local_defid ());
199 : 83 : auto discrim_expr = std::make_unique<HIR::LiteralExpr> (
200 : 166 : HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
201 : : HIR::Literal::LitType::INT,
202 : 249 : PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
203 : :
204 : 83 : TyTy::BaseType *isize = nullptr;
205 : 83 : bool ok = context->lookup_builtin ("isize", &isize);
206 : 83 : rust_assert (ok);
207 : 83 : context->insert_type (mapping, isize);
208 : :
209 : 83 : auto &nr_ctx
210 : 83 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
211 : :
212 : 83 : CanonicalPath canonical_path
213 : 83 : = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid ());
214 : :
215 : 83 : RustIdent ident{canonical_path, item.get_locus ()};
216 : 83 : variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
217 : 83 : item.get_mappings ().get_defid (),
218 : 83 : item.get_identifier ().as_string (), ident,
219 : : TyTy::VariantDef::VariantType::STRUCT,
220 : 332 : std::move (discrim_expr), fields);
221 : 83 : }
222 : :
223 : : } // namespace Resolver
224 : : } // namespace Rust
|