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