]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rust/typecheck/rust-tyty-call.cc
gccrs: Add feature gate for "rust-intrinsic".
[thirdparty/gcc.git] / gcc / rust / typecheck / rust-tyty-call.cc
CommitLineData
83ffe9cd 1// Copyright (C) 2020-2023 Free Software Foundation, Inc.
06688fe4
PH
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-tyty-call.h"
20#include "rust-hir-type-check-expr.h"
21
22namespace Rust {
23namespace TyTy {
24
25void
26TypeCheckCallExpr::visit (ADTType &type)
27{
28 rust_assert (!variant.is_error ());
29 if (variant.get_variant_type () != TyTy::VariantDef::VariantType::TUPLE)
30 {
31 rust_error_at (
32 call.get_locus (),
33 "expected function, tuple struct or tuple variant, found struct %<%s%>",
34 type.get_name ().c_str ());
35 return;
36 }
37
38 if (call.num_params () != variant.num_fields ())
39 {
40 rust_error_at (call.get_locus (),
41 "unexpected number of arguments %lu expected %lu",
42 (unsigned long) call.num_params (),
43 (unsigned long) variant.num_fields ());
44 return;
45 }
46
47 size_t i = 0;
48 for (auto &argument : call.get_arguments ())
49 {
50 StructFieldType *field = variant.get_field_at_index (i);
51 BaseType *field_tyty = field->get_field_type ();
af22b54a 52 Location arg_locus = argument->get_locus ();
06688fe4
PH
53
54 BaseType *arg = Resolver::TypeCheckExpr::Resolve (argument.get ());
55 if (arg->get_kind () == TyTy::TypeKind::ERROR)
56 {
57 rust_error_at (argument->get_locus (),
58 "failed to resolve argument type");
59 return;
60 }
61
af22b54a 62 HirId coercion_side_id = argument->get_mappings ().get_hirid ();
06688fe4 63 auto res = Resolver::TypeCheckBase::coercion_site (
af22b54a
PH
64 coercion_side_id, TyWithLocation (field_tyty),
65 TyWithLocation (arg, arg_locus), argument->get_locus ());
06688fe4
PH
66 if (res->get_kind () == TyTy::TypeKind::ERROR)
67 {
68 return;
69 }
70
06688fe4
PH
71 i++;
72 }
73
74 if (i != call.num_params ())
75 {
76 rust_error_at (call.get_locus (),
77 "unexpected number of arguments %lu expected %lu",
78 (unsigned long) i, (unsigned long) call.num_params ());
79 return;
80 }
81
82 resolved = type.clone ();
83}
84
85void
86TypeCheckCallExpr::visit (FnType &type)
87{
06688fe4
PH
88 if (call.num_params () != type.num_params ())
89 {
90 if (type.is_varadic ())
91 {
92 if (call.num_params () < type.num_params ())
93 {
94 rust_error_at (call.get_locus (),
95 "unexpected number of arguments %lu expected %lu",
96 (unsigned long) call.num_params (),
97 (unsigned long) type.num_params ());
98 return;
99 }
100 }
101 else
102 {
103 rust_error_at (call.get_locus (),
104 "unexpected number of arguments %lu expected %lu",
105 (unsigned long) call.num_params (),
106 (unsigned long) type.num_params ());
107 return;
108 }
109 }
110
111 size_t i = 0;
112 for (auto &argument : call.get_arguments ())
113 {
af22b54a 114 Location arg_locus = argument->get_locus ();
06688fe4
PH
115 auto argument_expr_tyty
116 = Resolver::TypeCheckExpr::Resolve (argument.get ());
117 if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
118 {
119 rust_error_at (
120 argument->get_locus (),
121 "failed to resolve type for argument expr in CallExpr");
122 return;
123 }
124
125 // it might be a varadic function
126 if (i < type.num_params ())
127 {
128 auto fnparam = type.param_at (i);
af22b54a
PH
129 HIR::Pattern *fn_param_pattern = fnparam.first;
130 BaseType *param_ty = fnparam.second;
131 Location param_locus
132 = fn_param_pattern == nullptr
133 ? mappings->lookup_location (param_ty->get_ref ())
134 : fn_param_pattern->get_locus ();
135
136 HirId coercion_side_id = argument->get_mappings ().get_hirid ();
06688fe4 137 auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site (
af22b54a
PH
138 coercion_side_id, TyWithLocation (param_ty, param_locus),
139 TyWithLocation (argument_expr_tyty, arg_locus),
140 argument->get_locus ());
06688fe4
PH
141 if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
142 {
06688fe4
PH
143 return;
144 }
145 }
146
147 i++;
148 }
149
150 if (i < call.num_params ())
151 {
152 rust_error_at (call.get_locus (),
153 "unexpected number of arguments %lu expected %lu",
154 (unsigned long) i, (unsigned long) call.num_params ());
155 return;
156 }
157
158 type.monomorphize ();
159 resolved = type.get_return_type ()->clone ();
160}
161
162void
163TypeCheckCallExpr::visit (FnPtr &type)
164{
165 if (call.num_params () != type.num_params ())
166 {
167 rust_error_at (call.get_locus (),
168 "unexpected number of arguments %lu expected %lu",
169 (unsigned long) call.num_params (),
170 (unsigned long) type.num_params ());
171 return;
172 }
173
174 size_t i = 0;
175 for (auto &argument : call.get_arguments ())
176 {
af22b54a
PH
177 Location arg_locus = argument->get_locus ();
178 BaseType *fnparam = type.param_at (i);
06688fe4
PH
179 auto argument_expr_tyty
180 = Resolver::TypeCheckExpr::Resolve (argument.get ());
181 if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
182 {
183 rust_error_at (
184 argument->get_locus (),
185 "failed to resolve type for argument expr in CallExpr");
186 return;
187 }
188
189 auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site (
af22b54a
PH
190 argument->get_mappings ().get_hirid (), TyWithLocation (fnparam),
191 TyWithLocation (argument_expr_tyty, arg_locus), argument->get_locus ());
06688fe4
PH
192 if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
193 {
06688fe4
PH
194 return;
195 }
196
197 i++;
198 }
199
200 if (i != call.num_params ())
201 {
202 rust_error_at (call.get_locus (),
203 "unexpected number of arguments %lu expected %lu",
204 (unsigned long) i, (unsigned long) call.num_params ());
205 return;
206 }
207
208 resolved = type.get_return_type ()->monomorphized_clone ();
209}
210
211// method call checker
212
4d021d9e
PH
213TypeCheckMethodCallExpr::TypeCheckMethodCallExpr (
214 Analysis::NodeMapping call_mappings, std::vector<Argument> &args,
215 Location call_locus, Location receiver_locus, TyTy::BaseType *adjusted_self,
216 Resolver::TypeCheckContext *context)
217 : call_mappings (call_mappings), arguments (args), call_locus (call_locus),
218 receiver_locus (receiver_locus), adjusted_self (adjusted_self),
219 context (context), mappings (Analysis::Mappings::get ())
220{}
221
222BaseType *
223TypeCheckMethodCallExpr::go (FnType *ref, HIR::MethodCallExpr &call,
224 TyTy::BaseType *adjusted_self,
225 Resolver::TypeCheckContext *context)
226{
227 std::vector<Argument> args;
228 for (auto &arg : call.get_arguments ())
229 {
230 BaseType *argument_expr_tyty
231 = Resolver::TypeCheckExpr::Resolve (arg.get ());
232 if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
233 {
234 rust_error_at (arg->get_locus (),
235 "failed to resolve type for argument");
236 return new ErrorType (ref->get_ref ());
237 }
238
239 Argument a (arg->get_mappings (), argument_expr_tyty, arg->get_locus ());
240 args.push_back (std::move (a));
241 }
242
243 TypeCheckMethodCallExpr checker (call.get_mappings (), args,
244 call.get_locus (),
245 call.get_receiver ()->get_locus (),
246 adjusted_self, context);
247 return checker.check (*ref);
248}
249
250BaseType *
251TypeCheckMethodCallExpr::go (FnType *ref, Analysis::NodeMapping call_mappings,
252 std::vector<Argument> &args, Location call_locus,
253 Location receiver_locus,
254 TyTy::BaseType *adjusted_self,
255 Resolver::TypeCheckContext *context)
256{
257 TypeCheckMethodCallExpr checker (call_mappings, args, call_locus,
258 receiver_locus, adjusted_self, context);
259 return checker.check (*ref);
260}
261
262BaseType *
263TypeCheckMethodCallExpr::check (FnType &type)
06688fe4 264{
7ad24d80 265 Resolver::TypeCheckBase::unify_site (
4d021d9e
PH
266 call_mappings.get_hirid (), TyWithLocation (type.get_self_type ()),
267 TyWithLocation (adjusted_self, receiver_locus), call_locus);
06688fe4
PH
268
269 // +1 for the receiver self
4d021d9e 270 size_t num_args_to_call = arguments.size () + 1;
06688fe4
PH
271 if (num_args_to_call != type.num_params ())
272 {
4d021d9e 273 rust_error_at (call_locus,
06688fe4 274 "unexpected number of arguments %lu expected %lu",
4d021d9e 275 (unsigned long) num_args_to_call,
06688fe4 276 (unsigned long) type.num_params ());
4d021d9e 277 return new ErrorType (type.get_ref ());
06688fe4
PH
278 }
279
280 size_t i = 1;
4d021d9e 281 for (auto &argument : arguments)
06688fe4 282 {
4d021d9e 283 Location arg_locus = argument.get_locus ();
af22b54a 284
06688fe4 285 auto fnparam = type.param_at (i);
af22b54a
PH
286 HIR::Pattern *fn_param_pattern = fnparam.first;
287 BaseType *param_ty = fnparam.second;
288 Location param_locus
289 = fn_param_pattern == nullptr
290 ? mappings->lookup_location (param_ty->get_ref ())
291 : fn_param_pattern->get_locus ();
292
4d021d9e
PH
293 auto argument_expr_tyty = argument.get_argument_type ();
294 HirId coercion_side_id = argument.get_mappings ().get_hirid ();
06688fe4 295 auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site (
af22b54a 296 coercion_side_id, TyWithLocation (param_ty, param_locus),
4d021d9e 297 TyWithLocation (argument_expr_tyty, arg_locus), arg_locus);
06688fe4
PH
298 if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
299 {
4d021d9e 300 return new ErrorType (type.get_ref ());
06688fe4
PH
301 }
302
303 i++;
304 }
305
306 if (i != num_args_to_call)
307 {
4d021d9e 308 rust_error_at (call_locus,
06688fe4 309 "unexpected number of arguments %lu expected %lu",
4d021d9e
PH
310 (unsigned long) i, (unsigned long) arguments.size ());
311 return new ErrorType (type.get_ref ());
06688fe4
PH
312 }
313
314 type.monomorphize ();
315
4d021d9e 316 return type.get_return_type ()->monomorphized_clone ();
06688fe4
PH
317}
318
319} // namespace TyTy
320} // namespace Rust