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
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
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-toplevel.h"
20 #include "rust-hir-type-check-enumitem.h"
21 #include "rust-hir-type-check-type.h"
22 #include "rust-hir-type-check-expr.h"
23 #include "rust-hir-type-check-pattern.h"
24 #include "rust-hir-type-check-implitem.h"
29 TypeCheckTopLevel::TypeCheckTopLevel () : TypeCheckBase () {}
32 TypeCheckTopLevel::Resolve (HIR::Item
&item
)
34 rust_assert (item
.get_hir_kind () == HIR::Node::BaseKind::VIS_ITEM
);
35 HIR::VisItem
&vis_item
= static_cast<HIR::VisItem
&> (item
);
37 TypeCheckTopLevel resolver
;
38 vis_item
.accept_vis (resolver
);
42 TypeCheckTopLevel::visit (HIR::TypeAlias
&alias
)
44 TyTy::BaseType
*actual_type
45 = TypeCheckType::Resolve (alias
.get_type_aliased ().get ());
47 context
->insert_type (alias
.get_mappings (), actual_type
);
49 for (auto &where_clause_item
: alias
.get_where_clause ().get_items ())
51 ResolveWhereClauseItem::Resolve (*where_clause_item
.get ());
56 TypeCheckTopLevel::visit (HIR::TupleStruct
&struct_decl
)
58 std::vector
<TyTy::SubstitutionParamMapping
> substitutions
;
59 if (struct_decl
.has_generics ())
60 resolve_generic_params (struct_decl
.get_generic_params (), substitutions
);
62 for (auto &where_clause_item
: struct_decl
.get_where_clause ().get_items ())
64 ResolveWhereClauseItem::Resolve (*where_clause_item
.get ());
67 std::vector
<TyTy::StructFieldType
*> fields
;
69 for (auto &field
: struct_decl
.get_fields ())
71 TyTy::BaseType
*field_type
72 = TypeCheckType::Resolve (field
.get_field_type ().get ());
73 TyTy::StructFieldType
*ty_field
74 = new TyTy::StructFieldType (field
.get_mappings ().get_hirid (),
75 std::to_string (idx
), field_type
,
77 fields
.push_back (ty_field
);
78 context
->insert_type (field
.get_mappings (), ty_field
->get_field_type ());
83 const CanonicalPath
*canonical_path
= nullptr;
84 bool ok
= mappings
->lookup_canonical_path (
85 struct_decl
.get_mappings ().get_nodeid (), &canonical_path
);
87 RustIdent ident
{*canonical_path
, struct_decl
.get_locus ()};
89 // its a single variant ADT
90 std::vector
<TyTy::VariantDef
*> variants
;
91 variants
.push_back (new TyTy::VariantDef (
92 struct_decl
.get_mappings ().get_hirid (), struct_decl
.get_identifier (),
93 ident
, TyTy::VariantDef::VariantType::TUPLE
, nullptr, std::move (fields
)));
95 // Process #[repr(X)] attribute, if any
96 const AST::AttrVec
&attrs
= struct_decl
.get_outer_attrs ();
97 TyTy::ADTType::ReprOptions repr
98 = parse_repr_options (attrs
, struct_decl
.get_locus ());
101 = new TyTy::ADTType (struct_decl
.get_mappings ().get_hirid (),
102 mappings
->get_next_hir_id (),
103 struct_decl
.get_identifier (), ident
,
104 TyTy::ADTType::ADTKind::TUPLE_STRUCT
,
105 std::move (variants
), std::move (substitutions
), repr
);
107 context
->insert_type (struct_decl
.get_mappings (), type
);
111 TypeCheckTopLevel::visit (HIR::Module
&module
)
113 for (auto &item
: module
.get_items ())
114 TypeCheckTopLevel::Resolve (*item
.get ());
118 TypeCheckTopLevel::visit (HIR::StructStruct
&struct_decl
)
120 std::vector
<TyTy::SubstitutionParamMapping
> substitutions
;
121 if (struct_decl
.has_generics ())
122 resolve_generic_params (struct_decl
.get_generic_params (), substitutions
);
124 for (auto &where_clause_item
: struct_decl
.get_where_clause ().get_items ())
126 ResolveWhereClauseItem::Resolve (*where_clause_item
.get ());
129 std::vector
<TyTy::StructFieldType
*> fields
;
130 for (auto &field
: struct_decl
.get_fields ())
132 TyTy::BaseType
*field_type
133 = TypeCheckType::Resolve (field
.get_field_type ().get ());
134 TyTy::StructFieldType
*ty_field
135 = new TyTy::StructFieldType (field
.get_mappings ().get_hirid (),
136 field
.get_field_name (), field_type
,
138 fields
.push_back (ty_field
);
139 context
->insert_type (field
.get_mappings (), ty_field
->get_field_type ());
143 const CanonicalPath
*canonical_path
= nullptr;
144 bool ok
= mappings
->lookup_canonical_path (
145 struct_decl
.get_mappings ().get_nodeid (), &canonical_path
);
147 RustIdent ident
{*canonical_path
, struct_decl
.get_locus ()};
149 // its a single variant ADT
150 std::vector
<TyTy::VariantDef
*> variants
;
151 variants
.push_back (new TyTy::VariantDef (
152 struct_decl
.get_mappings ().get_hirid (), struct_decl
.get_identifier (),
153 ident
, TyTy::VariantDef::VariantType::STRUCT
, nullptr, std::move (fields
)));
155 // Process #[repr(X)] attribute, if any
156 const AST::AttrVec
&attrs
= struct_decl
.get_outer_attrs ();
157 TyTy::ADTType::ReprOptions repr
158 = parse_repr_options (attrs
, struct_decl
.get_locus ());
161 = new TyTy::ADTType (struct_decl
.get_mappings ().get_hirid (),
162 mappings
->get_next_hir_id (),
163 struct_decl
.get_identifier (), ident
,
164 TyTy::ADTType::ADTKind::STRUCT_STRUCT
,
165 std::move (variants
), std::move (substitutions
), repr
);
167 context
->insert_type (struct_decl
.get_mappings (), type
);
171 TypeCheckTopLevel::visit (HIR::Enum
&enum_decl
)
173 std::vector
<TyTy::SubstitutionParamMapping
> substitutions
;
174 if (enum_decl
.has_generics ())
175 resolve_generic_params (enum_decl
.get_generic_params (), substitutions
);
177 std::vector
<TyTy::VariantDef
*> variants
;
178 int64_t discriminant_value
= 0;
179 for (auto &variant
: enum_decl
.get_variants ())
181 TyTy::VariantDef
*field_type
182 = TypeCheckEnumItem::Resolve (variant
.get (), discriminant_value
);
184 discriminant_value
++;
185 variants
.push_back (field_type
);
189 const CanonicalPath
*canonical_path
= nullptr;
191 = mappings
->lookup_canonical_path (enum_decl
.get_mappings ().get_nodeid (),
194 RustIdent ident
{*canonical_path
, enum_decl
.get_locus ()};
198 = new TyTy::ADTType (enum_decl
.get_mappings ().get_hirid (),
199 mappings
->get_next_hir_id (),
200 enum_decl
.get_identifier (), ident
,
201 TyTy::ADTType::ADTKind::ENUM
, std::move (variants
),
202 std::move (substitutions
));
204 context
->insert_type (enum_decl
.get_mappings (), type
);
208 TypeCheckTopLevel::visit (HIR::Union
&union_decl
)
210 std::vector
<TyTy::SubstitutionParamMapping
> substitutions
;
211 if (union_decl
.has_generics ())
212 resolve_generic_params (union_decl
.get_generic_params (), substitutions
);
214 for (auto &where_clause_item
: union_decl
.get_where_clause ().get_items ())
216 ResolveWhereClauseItem::Resolve (*where_clause_item
.get ());
219 std::vector
<TyTy::StructFieldType
*> fields
;
220 for (auto &variant
: union_decl
.get_variants ())
222 TyTy::BaseType
*variant_type
223 = TypeCheckType::Resolve (variant
.get_field_type ().get ());
224 TyTy::StructFieldType
*ty_variant
225 = new TyTy::StructFieldType (variant
.get_mappings ().get_hirid (),
226 variant
.get_field_name (), variant_type
,
227 variant
.get_locus ());
228 fields
.push_back (ty_variant
);
229 context
->insert_type (variant
.get_mappings (),
230 ty_variant
->get_field_type ());
234 const CanonicalPath
*canonical_path
= nullptr;
236 = mappings
->lookup_canonical_path (union_decl
.get_mappings ().get_nodeid (),
239 RustIdent ident
{*canonical_path
, union_decl
.get_locus ()};
241 // there is only a single variant
242 std::vector
<TyTy::VariantDef
*> variants
;
243 variants
.push_back (new TyTy::VariantDef (
244 union_decl
.get_mappings ().get_hirid (), union_decl
.get_identifier (),
245 ident
, TyTy::VariantDef::VariantType::STRUCT
, nullptr, std::move (fields
)));
248 = new TyTy::ADTType (union_decl
.get_mappings ().get_hirid (),
249 mappings
->get_next_hir_id (),
250 union_decl
.get_identifier (), ident
,
251 TyTy::ADTType::ADTKind::UNION
, std::move (variants
),
252 std::move (substitutions
));
254 context
->insert_type (union_decl
.get_mappings (), type
);
258 TypeCheckTopLevel::visit (HIR::StaticItem
&var
)
260 TyTy::BaseType
*type
= TypeCheckType::Resolve (var
.get_type ());
261 TyTy::BaseType
*expr_type
= TypeCheckExpr::Resolve (var
.get_expr ());
263 TyTy::BaseType
*unified
264 = coercion_site (var
.get_mappings ().get_hirid (),
265 TyTy::TyWithLocation (type
, var
.get_type ()->get_locus ()),
266 TyTy::TyWithLocation (expr_type
,
267 var
.get_expr ()->get_locus ()),
269 context
->insert_type (var
.get_mappings (), unified
);
273 TypeCheckTopLevel::visit (HIR::ConstantItem
&constant
)
275 TyTy::BaseType
*type
= TypeCheckType::Resolve (constant
.get_type ());
276 TyTy::BaseType
*expr_type
= TypeCheckExpr::Resolve (constant
.get_expr ());
278 TyTy::BaseType
*unified
= unify_site (
279 constant
.get_mappings ().get_hirid (),
280 TyTy::TyWithLocation (type
, constant
.get_type ()->get_locus ()),
281 TyTy::TyWithLocation (expr_type
, constant
.get_expr ()->get_locus ()),
282 constant
.get_locus ());
283 context
->insert_type (constant
.get_mappings (), unified
);
287 TypeCheckTopLevel::visit (HIR::Function
&function
)
289 std::vector
<TyTy::SubstitutionParamMapping
> substitutions
;
290 if (function
.has_generics ())
291 resolve_generic_params (function
.get_generic_params (), substitutions
);
293 for (auto &where_clause_item
: function
.get_where_clause ().get_items ())
295 ResolveWhereClauseItem::Resolve (*where_clause_item
.get ());
298 TyTy::BaseType
*ret_type
= nullptr;
299 if (!function
.has_function_return_type ())
301 = TyTy::TupleType::get_unit_type (function
.get_mappings ().get_hirid ());
305 = TypeCheckType::Resolve (function
.get_return_type ().get ());
306 if (resolved
->get_kind () == TyTy::TypeKind::ERROR
)
308 rust_error_at (function
.get_locus (),
309 "failed to resolve return type");
313 ret_type
= resolved
->clone ();
315 function
.get_return_type ()->get_mappings ().get_hirid ());
318 std::vector
<std::pair
<HIR::Pattern
*, TyTy::BaseType
*>> params
;
319 for (auto ¶m
: function
.get_function_params ())
321 // get the name as well required for later on
322 auto param_tyty
= TypeCheckType::Resolve (param
.get_type ());
324 std::pair
<HIR::Pattern
*, TyTy::BaseType
*> (param
.get_param_name (),
327 context
->insert_type (param
.get_mappings (), param_tyty
);
328 TypeCheckPattern::Resolve (param
.get_param_name (), param_tyty
);
331 const CanonicalPath
*canonical_path
= nullptr;
333 = mappings
->lookup_canonical_path (function
.get_mappings ().get_nodeid (),
337 RustIdent ident
{*canonical_path
, function
.get_locus ()};
338 auto fnType
= new TyTy::FnType (function
.get_mappings ().get_hirid (),
339 function
.get_mappings ().get_defid (),
340 function
.get_function_name (), ident
,
341 TyTy::FnType::FNTYPE_DEFAULT_FLAGS
, ABI::RUST
,
342 std::move (params
), ret_type
,
343 std::move (substitutions
));
345 context
->insert_type (function
.get_mappings (), fnType
);
349 TypeCheckTopLevel::visit (HIR::ImplBlock
&impl_block
)
351 std::vector
<TyTy::SubstitutionParamMapping
> substitutions
;
352 if (impl_block
.has_generics ())
353 resolve_generic_params (impl_block
.get_generic_params (), substitutions
);
355 for (auto &where_clause_item
: impl_block
.get_where_clause ().get_items ())
357 ResolveWhereClauseItem::Resolve (*where_clause_item
.get ());
360 auto self
= TypeCheckType::Resolve (impl_block
.get_type ().get ());
361 if (self
->get_kind () == TyTy::TypeKind::ERROR
)
364 for (auto &impl_item
: impl_block
.get_impl_items ())
365 TypeCheckTopLevelImplItem::Resolve (impl_item
.get (), self
, substitutions
);
369 TypeCheckTopLevel::visit (HIR::ExternBlock
&extern_block
)
371 for (auto &item
: extern_block
.get_extern_items ())
373 TypeCheckTopLevelExternItem::Resolve (item
.get (), extern_block
);
377 } // namespace Resolver