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 1223 : TypeCheckEnumItem::Resolve (HIR::EnumItem &item, int64_t last_discriminant)
32 : {
33 1223 : TypeCheckEnumItem resolver (last_discriminant);
34 1223 : switch (item.get_enum_item_kind ())
35 : {
36 446 : case HIR::EnumItem::EnumItemKind::Named:
37 446 : resolver.visit (static_cast<HIR::EnumItem &> (item));
38 446 : break;
39 :
40 416 : case HIR::EnumItem::EnumItemKind::Tuple:
41 416 : resolver.visit (static_cast<HIR::EnumItemTuple &> (item));
42 416 : break;
43 :
44 86 : case HIR::EnumItem::EnumItemKind::Struct:
45 86 : resolver.visit (static_cast<HIR::EnumItemStruct &> (item));
46 86 : break;
47 :
48 275 : case HIR::EnumItem::EnumItemKind::Discriminant:
49 275 : resolver.visit (static_cast<HIR::EnumItemDiscriminant &> (item));
50 275 : break;
51 : }
52 1223 : return resolver.variant;
53 1223 : }
54 :
55 1223 : TypeCheckEnumItem::TypeCheckEnumItem (int64_t last_discriminant)
56 1223 : : TypeCheckBase (), variant (nullptr), last_discriminant (last_discriminant)
57 1223 : {}
58 :
59 : void
60 446 : TypeCheckEnumItem::visit (HIR::EnumItem &item)
61 : {
62 446 : if (last_discriminant == INT64_MAX)
63 0 : rust_error_at (item.get_locus (), "discriminant too big");
64 :
65 892 : Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
66 446 : item.get_mappings ().get_nodeid (),
67 446 : mappings.get_next_hir_id (
68 446 : item.get_mappings ().get_crate_num ()),
69 446 : item.get_mappings ().get_local_defid ());
70 446 : auto discim_expr = std::make_unique<HIR::LiteralExpr> (
71 892 : HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
72 : HIR::Literal::LitType::INT,
73 1338 : PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
74 :
75 446 : TyTy::BaseType *isize = nullptr;
76 446 : bool ok = context->lookup_builtin ("isize", &isize);
77 446 : rust_assert (ok);
78 446 : context->insert_type (mapping, isize);
79 :
80 446 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
81 :
82 446 : CanonicalPath canonical_path
83 446 : = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid (),
84 446 : Resolver2_0::Namespace::Types);
85 :
86 446 : RustIdent ident{canonical_path, item.get_locus ()};
87 446 : variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
88 446 : item.get_mappings ().get_defid (),
89 446 : item.get_identifier ().as_string (), ident,
90 1784 : std::move (discim_expr));
91 446 : }
92 :
93 : void
94 275 : TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
95 : {
96 275 : if (last_discriminant == INT64_MAX)
97 0 : rust_error_at (item.get_locus (), "discriminant too big");
98 :
99 275 : auto &discriminant = item.get_discriminant_expression ();
100 275 : auto capacity_type = TypeCheckExpr::Resolve (discriminant);
101 275 : if (capacity_type->get_kind () == TyTy::TypeKind::ERROR)
102 1 : return;
103 :
104 274 : TyTy::ISizeType *expected_ty
105 274 : = new TyTy::ISizeType (discriminant.get_mappings ().get_hirid ());
106 274 : context->insert_type (discriminant.get_mappings (), expected_ty);
107 :
108 274 : unify_site (item.get_mappings ().get_hirid (),
109 274 : TyTy::TyWithLocation (expected_ty),
110 274 : TyTy::TyWithLocation (capacity_type), item.get_locus ());
111 :
112 274 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
113 :
114 274 : CanonicalPath canonical_path
115 274 : = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid (),
116 274 : Resolver2_0::Namespace::Types);
117 :
118 274 : RustIdent ident{canonical_path, item.get_locus ()};
119 274 : variant
120 274 : = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
121 274 : item.get_mappings ().get_defid (),
122 274 : item.get_identifier ().as_string (), ident,
123 1096 : item.get_discriminant_expression ().clone_expr ());
124 274 : }
125 :
126 : void
127 416 : TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
128 : {
129 416 : if (last_discriminant == INT64_MAX)
130 0 : rust_error_at (item.get_locus (), "discriminant too big");
131 :
132 416 : std::vector<TyTy::StructFieldType *> fields;
133 416 : size_t idx = 0;
134 846 : for (auto &field : item.get_tuple_fields ())
135 : {
136 430 : TyTy::BaseType *field_type
137 430 : = TypeCheckType::Resolve (field.get_field_type ());
138 430 : TyTy::StructFieldType *ty_field
139 860 : = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
140 430 : std::to_string (idx), field_type,
141 430 : field.get_locus ());
142 430 : fields.push_back (ty_field);
143 430 : context->insert_type (field.get_mappings (), ty_field->get_field_type ());
144 430 : idx++;
145 : }
146 :
147 832 : Analysis::NodeMapping mapping (item.get_mappings ().get_crate_num (),
148 416 : item.get_mappings ().get_nodeid (),
149 416 : mappings.get_next_hir_id (
150 416 : item.get_mappings ().get_crate_num ()),
151 416 : item.get_mappings ().get_local_defid ());
152 416 : auto discim_expr = std::make_unique<HIR::LiteralExpr> (
153 832 : HIR::LiteralExpr (mapping, std::to_string (last_discriminant),
154 : HIR::Literal::LitType::INT,
155 1248 : PrimitiveCoreType::CORETYPE_I64, item.get_locus (), {}));
156 :
157 416 : TyTy::BaseType *isize = nullptr;
158 416 : bool ok = context->lookup_builtin ("isize", &isize);
159 416 : rust_assert (ok);
160 416 : context->insert_type (mapping, isize);
161 :
162 416 : auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
163 :
164 416 : CanonicalPath canonical_path
165 416 : = nr_ctx.to_canonical_path (item.get_mappings ().get_nodeid (),
166 416 : Resolver2_0::Namespace::Types);
167 :
168 416 : RustIdent ident{canonical_path, item.get_locus ()};
169 416 : variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
170 416 : item.get_mappings ().get_defid (),
171 416 : item.get_identifier ().as_string (), ident,
172 : TyTy::VariantDef::VariantType::TUPLE,
173 1664 : std::move (discim_expr), fields);
174 416 : }
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
|