]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rust/typecheck/rust-tyty-call.cc
gccrs: Add missing location info to coercions
[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
71 delete res;
72 i++;
73 }
74
75 if (i != call.num_params ())
76 {
77 rust_error_at (call.get_locus (),
78 "unexpected number of arguments %lu expected %lu",
79 (unsigned long) i, (unsigned long) call.num_params ());
80 return;
81 }
82
83 resolved = type.clone ();
84}
85
86void
87TypeCheckCallExpr::visit (FnType &type)
88{
89 type.monomorphize ();
90 if (call.num_params () != type.num_params ())
91 {
92 if (type.is_varadic ())
93 {
94 if (call.num_params () < type.num_params ())
95 {
96 rust_error_at (call.get_locus (),
97 "unexpected number of arguments %lu expected %lu",
98 (unsigned long) call.num_params (),
99 (unsigned long) type.num_params ());
100 return;
101 }
102 }
103 else
104 {
105 rust_error_at (call.get_locus (),
106 "unexpected number of arguments %lu expected %lu",
107 (unsigned long) call.num_params (),
108 (unsigned long) type.num_params ());
109 return;
110 }
111 }
112
113 size_t i = 0;
114 for (auto &argument : call.get_arguments ())
115 {
af22b54a 116 Location arg_locus = argument->get_locus ();
06688fe4
PH
117 auto argument_expr_tyty
118 = Resolver::TypeCheckExpr::Resolve (argument.get ());
119 if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
120 {
121 rust_error_at (
122 argument->get_locus (),
123 "failed to resolve type for argument expr in CallExpr");
124 return;
125 }
126
127 // it might be a varadic function
128 if (i < type.num_params ())
129 {
130 auto fnparam = type.param_at (i);
af22b54a
PH
131 HIR::Pattern *fn_param_pattern = fnparam.first;
132 BaseType *param_ty = fnparam.second;
133 Location param_locus
134 = fn_param_pattern == nullptr
135 ? mappings->lookup_location (param_ty->get_ref ())
136 : fn_param_pattern->get_locus ();
137
138 HirId coercion_side_id = argument->get_mappings ().get_hirid ();
06688fe4 139 auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site (
af22b54a
PH
140 coercion_side_id, TyWithLocation (param_ty, param_locus),
141 TyWithLocation (argument_expr_tyty, arg_locus),
142 argument->get_locus ());
06688fe4
PH
143 if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
144 {
145 rust_error_at (argument->get_locus (),
146 "Type Resolution failure on parameter");
147 return;
148 }
149 }
150
151 i++;
152 }
153
154 if (i < call.num_params ())
155 {
156 rust_error_at (call.get_locus (),
157 "unexpected number of arguments %lu expected %lu",
158 (unsigned long) i, (unsigned long) call.num_params ());
159 return;
160 }
161
162 type.monomorphize ();
163 resolved = type.get_return_type ()->clone ();
164}
165
166void
167TypeCheckCallExpr::visit (FnPtr &type)
168{
169 if (call.num_params () != type.num_params ())
170 {
171 rust_error_at (call.get_locus (),
172 "unexpected number of arguments %lu expected %lu",
173 (unsigned long) call.num_params (),
174 (unsigned long) type.num_params ());
175 return;
176 }
177
178 size_t i = 0;
179 for (auto &argument : call.get_arguments ())
180 {
af22b54a
PH
181 Location arg_locus = argument->get_locus ();
182 BaseType *fnparam = type.param_at (i);
06688fe4
PH
183 auto argument_expr_tyty
184 = Resolver::TypeCheckExpr::Resolve (argument.get ());
185 if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
186 {
187 rust_error_at (
188 argument->get_locus (),
189 "failed to resolve type for argument expr in CallExpr");
190 return;
191 }
192
193 auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site (
af22b54a
PH
194 argument->get_mappings ().get_hirid (), TyWithLocation (fnparam),
195 TyWithLocation (argument_expr_tyty, arg_locus), argument->get_locus ());
06688fe4
PH
196 if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
197 {
198 rust_error_at (argument->get_locus (),
199 "Type Resolution failure on parameter");
200 return;
201 }
202
203 i++;
204 }
205
206 if (i != call.num_params ())
207 {
208 rust_error_at (call.get_locus (),
209 "unexpected number of arguments %lu expected %lu",
210 (unsigned long) i, (unsigned long) call.num_params ());
211 return;
212 }
213
214 resolved = type.get_return_type ()->monomorphized_clone ();
215}
216
217// method call checker
218
219void
220TypeCheckMethodCallExpr::visit (FnType &type)
221{
222 type.get_self_type ()->unify (adjusted_self);
223
224 // +1 for the receiver self
225 size_t num_args_to_call = call.num_params () + 1;
226 if (num_args_to_call != type.num_params ())
227 {
228 rust_error_at (call.get_locus (),
229 "unexpected number of arguments %lu expected %lu",
230 (unsigned long) call.num_params (),
231 (unsigned long) type.num_params ());
232 return;
233 }
234
235 size_t i = 1;
236 for (auto &argument : call.get_arguments ())
237 {
af22b54a
PH
238 Location arg_locus = argument->get_locus ();
239
06688fe4 240 auto fnparam = type.param_at (i);
af22b54a
PH
241 HIR::Pattern *fn_param_pattern = fnparam.first;
242 BaseType *param_ty = fnparam.second;
243 Location param_locus
244 = fn_param_pattern == nullptr
245 ? mappings->lookup_location (param_ty->get_ref ())
246 : fn_param_pattern->get_locus ();
247
06688fe4
PH
248 auto argument_expr_tyty
249 = Resolver::TypeCheckExpr::Resolve (argument.get ());
250 if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
251 {
252 rust_error_at (
253 argument->get_locus (),
254 "failed to resolve type for argument expr in CallExpr");
255 return;
256 }
257
af22b54a 258 HirId coercion_side_id = argument->get_mappings ().get_hirid ();
06688fe4 259 auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site (
af22b54a
PH
260 coercion_side_id, TyWithLocation (param_ty, param_locus),
261 TyWithLocation (argument_expr_tyty, arg_locus), argument->get_locus ());
06688fe4
PH
262 if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
263 {
264 rust_error_at (argument->get_locus (),
265 "Type Resolution failure on parameter");
266 return;
267 }
268
269 i++;
270 }
271
272 if (i != num_args_to_call)
273 {
274 rust_error_at (call.get_locus (),
275 "unexpected number of arguments %lu expected %lu",
276 (unsigned long) i, (unsigned long) call.num_params ());
277 return;
278 }
279
280 type.monomorphize ();
281
282 resolved = type.get_return_type ()->monomorphized_clone ();
283}
284
285} // namespace TyTy
286} // namespace Rust