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-type-check-stmt.h"
20 : #include "rust-hir-type-check-type.h"
21 : #include "rust-hir-type-check-expr.h"
22 : #include "rust-hir-type-check-implitem.h"
23 : #include "rust-hir-type-check-item.h"
24 : #include "rust-hir-type-check-pattern.h"
25 : #include "rust-type-util.h"
26 :
27 : namespace Rust {
28 : namespace Resolver {
29 :
30 : TyTy::BaseType *
31 22359 : TypeCheckStmt::Resolve (HIR::Stmt &stmt)
32 : {
33 22359 : TypeCheckStmt resolver;
34 22359 : stmt.accept_vis (resolver);
35 22359 : return resolver.infered;
36 22359 : }
37 :
38 : void
39 9252 : TypeCheckStmt::visit (HIR::ExprStmt &stmt)
40 : {
41 9252 : infered = TypeCheckExpr::Resolve (stmt.get_expr ());
42 9252 : }
43 :
44 : void
45 46 : TypeCheckStmt::visit (HIR::EmptyStmt &stmt)
46 : {
47 46 : infered = TyTy::TupleType::get_unit_type ();
48 46 : }
49 :
50 : void
51 16 : TypeCheckStmt::visit (HIR::ExternBlock &extern_block)
52 : {
53 32 : for (auto &item : extern_block.get_extern_items ())
54 : {
55 16 : TypeCheckTopLevelExternItem::Resolve (*item, extern_block);
56 : }
57 16 : }
58 :
59 : void
60 54 : TypeCheckStmt::visit (HIR::ConstantItem &constant)
61 : {
62 54 : TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ());
63 54 : if (!constant.has_expr ())
64 : {
65 1 : infered = type;
66 1 : return;
67 : }
68 :
69 53 : TyTy::BaseType *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
70 :
71 106 : infered = coercion_site (
72 53 : constant.get_mappings ().get_hirid (),
73 53 : TyTy::TyWithLocation (type, constant.get_type ().get_locus ()),
74 53 : TyTy::TyWithLocation (expr_type, constant.get_expr ().get_locus ()),
75 : constant.get_locus ());
76 53 : context->insert_type (constant.get_mappings (), infered);
77 : }
78 :
79 : void
80 12640 : TypeCheckStmt::visit (HIR::LetStmt &stmt)
81 : {
82 12640 : infered = TyTy::TupleType::get_unit_type ();
83 :
84 12640 : auto &stmt_pattern = stmt.get_pattern ();
85 12640 : TyTy::BaseType *init_expr_ty = nullptr;
86 12640 : location_t init_expr_locus = UNKNOWN_LOCATION;
87 12640 : if (stmt.has_init_expr ())
88 : {
89 11501 : init_expr_locus = stmt.get_init_expr ().get_locus ();
90 11501 : init_expr_ty = TypeCheckExpr::Resolve (stmt.get_init_expr ());
91 11501 : if (init_expr_ty->get_kind () == TyTy::TypeKind::ERROR)
92 : return;
93 :
94 11470 : init_expr_ty->append_reference (
95 11470 : stmt_pattern.get_mappings ().get_hirid ());
96 : }
97 :
98 12609 : TyTy::BaseType *specified_ty = nullptr;
99 12609 : location_t specified_ty_locus;
100 12609 : if (stmt.has_type ())
101 : {
102 2082 : specified_ty = TypeCheckType::Resolve (stmt.get_type ());
103 2082 : specified_ty_locus = stmt.get_type ().get_locus ();
104 : }
105 :
106 : // let x:i32 = 123;
107 12609 : if (specified_ty != nullptr && init_expr_ty != nullptr)
108 : {
109 3636 : coercion_site (stmt.get_mappings ().get_hirid (),
110 1818 : TyTy::TyWithLocation (specified_ty, specified_ty_locus),
111 1818 : TyTy::TyWithLocation (init_expr_ty, init_expr_locus),
112 : stmt.get_locus ());
113 1818 : TypeCheckPattern::Resolve (stmt_pattern, specified_ty);
114 : }
115 : else
116 : {
117 : // let x:i32;
118 10791 : if (specified_ty != nullptr)
119 : {
120 264 : TypeCheckPattern::Resolve (stmt_pattern, specified_ty);
121 : }
122 : // let x = 123;
123 10527 : else if (init_expr_ty != nullptr)
124 : {
125 9652 : TypeCheckPattern::Resolve (stmt_pattern, init_expr_ty);
126 : }
127 : // let x;
128 : else
129 : {
130 875 : auto infer
131 875 : = new TyTy::InferType (stmt_pattern.get_mappings ().get_hirid (),
132 : TyTy::InferType::InferTypeKind::GENERAL,
133 : TyTy::InferType::TypeHint::Default (),
134 875 : stmt.get_locus ());
135 875 : TypeCheckPattern::Resolve (stmt_pattern, infer);
136 : }
137 : }
138 : }
139 :
140 : void
141 0 : TypeCheckStmt::visit (HIR::TypePath &path)
142 : {
143 0 : infered = TypeCheckType::Resolve (path);
144 0 : }
145 : void
146 0 : TypeCheckStmt::visit (HIR::QualifiedPathInType &path)
147 : {
148 0 : infered = TypeCheckType::Resolve (path);
149 0 : }
150 :
151 : void
152 136 : TypeCheckStmt::visit (HIR::TupleStruct &struct_decl)
153 : {
154 136 : infered = TypeCheckItem::Resolve (struct_decl);
155 136 : }
156 :
157 : void
158 7 : TypeCheckStmt::visit (HIR::Enum &enum_decl)
159 : {
160 7 : infered = TypeCheckItem::Resolve (enum_decl);
161 7 : }
162 :
163 : void
164 129 : TypeCheckStmt::visit (HIR::StructStruct &struct_decl)
165 : {
166 129 : infered = TypeCheckItem::Resolve (struct_decl);
167 129 : }
168 :
169 : void
170 0 : TypeCheckStmt::visit (HIR::Union &union_decl)
171 : {
172 0 : infered = TypeCheckItem::Resolve (union_decl);
173 0 : }
174 :
175 : void
176 64 : TypeCheckStmt::visit (HIR::Function &function)
177 : {
178 64 : infered = TypeCheckItem::Resolve (function);
179 64 : }
180 :
181 : void
182 0 : TypeCheckStmt::visit (HIR::Module &module)
183 : {
184 0 : infered = TypeCheckItem::Resolve (module);
185 0 : }
186 :
187 : void
188 0 : TypeCheckStmt::visit (HIR::TypeAlias &type_alias)
189 : {
190 0 : infered = TypeCheckItem::Resolve (type_alias);
191 0 : }
192 :
193 : void
194 1 : TypeCheckStmt::visit (HIR::StaticItem &static_item)
195 : {
196 1 : infered = TypeCheckItem::Resolve (static_item);
197 1 : }
198 :
199 : void
200 6 : TypeCheckStmt::visit (HIR::Trait &trait)
201 : {
202 6 : infered = TypeCheckItem::Resolve (trait);
203 6 : }
204 :
205 : void
206 8 : TypeCheckStmt::visit (HIR::ImplBlock &impl)
207 : {
208 8 : infered = TypeCheckItem::Resolve (impl);
209 8 : }
210 :
211 : } // namespace Resolver
212 : } // namespace Rust
|