Skip to content

Commit 2e1e99a

Browse files
philbertydkm
authored andcommitted
Refactor method call type checking
We used a visitor interface to handle type checking argument passing on method call expressions. This was completely unnessecary as all method calls should _always_ be to TyTy::FnType's. The benifit here is that we need to reuse this interface to handle method resolution type checking for FnTrait calls as closure calls dont have an HIR::MethodExpr so we need a more abstract interface so that we can specify the types directly with relevant location info.
1 parent 10b942b commit 2e1e99a

File tree

3 files changed

+106
-74
lines changed

3 files changed

+106
-74
lines changed

gcc/rust/typecheck/rust-hir-type-check-expr.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -1162,7 +1162,8 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
11621162
rust_debug ("type-checking method_call: {%s}", lookup->debug_str ().c_str ());
11631163

11641164
TyTy::BaseType *function_ret_tyty
1165-
= TyTy::TypeCheckMethodCallExpr::go (lookup, expr, adjusted_self, context);
1165+
= TyTy::TypeCheckMethodCallExpr::go (static_cast<TyTy::FnType *> (lookup),
1166+
expr, adjusted_self, context);
11661167
if (function_ret_tyty == nullptr
11671168
|| function_ret_tyty->get_kind () == TyTy::TypeKind::ERROR)
11681169
{

gcc/rust/typecheck/rust-tyty-call.cc

+68-30
Original file line numberDiff line numberDiff line change
@@ -216,29 +216,77 @@ TypeCheckCallExpr::visit (FnPtr &type)
216216

217217
// method call checker
218218

219-
void
220-
TypeCheckMethodCallExpr::visit (FnType &type)
219+
TypeCheckMethodCallExpr::TypeCheckMethodCallExpr (
220+
Analysis::NodeMapping call_mappings, std::vector<Argument> &args,
221+
Location call_locus, Location receiver_locus, TyTy::BaseType *adjusted_self,
222+
Resolver::TypeCheckContext *context)
223+
: call_mappings (call_mappings), arguments (args), call_locus (call_locus),
224+
receiver_locus (receiver_locus), adjusted_self (adjusted_self),
225+
context (context), mappings (Analysis::Mappings::get ())
226+
{}
227+
228+
BaseType *
229+
TypeCheckMethodCallExpr::go (FnType *ref, HIR::MethodCallExpr &call,
230+
TyTy::BaseType *adjusted_self,
231+
Resolver::TypeCheckContext *context)
232+
{
233+
std::vector<Argument> args;
234+
for (auto &arg : call.get_arguments ())
235+
{
236+
BaseType *argument_expr_tyty
237+
= Resolver::TypeCheckExpr::Resolve (arg.get ());
238+
if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
239+
{
240+
rust_error_at (arg->get_locus (),
241+
"failed to resolve type for argument");
242+
return new ErrorType (ref->get_ref ());
243+
}
244+
245+
Argument a (arg->get_mappings (), argument_expr_tyty, arg->get_locus ());
246+
args.push_back (std::move (a));
247+
}
248+
249+
TypeCheckMethodCallExpr checker (call.get_mappings (), args,
250+
call.get_locus (),
251+
call.get_receiver ()->get_locus (),
252+
adjusted_self, context);
253+
return checker.check (*ref);
254+
}
255+
256+
BaseType *
257+
TypeCheckMethodCallExpr::go (FnType *ref, Analysis::NodeMapping call_mappings,
258+
std::vector<Argument> &args, Location call_locus,
259+
Location receiver_locus,
260+
TyTy::BaseType *adjusted_self,
261+
Resolver::TypeCheckContext *context)
262+
{
263+
TypeCheckMethodCallExpr checker (call_mappings, args, call_locus,
264+
receiver_locus, adjusted_self, context);
265+
return checker.check (*ref);
266+
}
267+
268+
BaseType *
269+
TypeCheckMethodCallExpr::check (FnType &type)
221270
{
222271
Resolver::TypeCheckBase::unify_site (
223-
call.get_mappings ().get_hirid (), TyWithLocation (type.get_self_type ()),
224-
TyWithLocation (adjusted_self, call.get_receiver ()->get_locus ()),
225-
call.get_locus ());
272+
call_mappings.get_hirid (), TyWithLocation (type.get_self_type ()),
273+
TyWithLocation (adjusted_self, receiver_locus), call_locus);
226274

227275
// +1 for the receiver self
228-
size_t num_args_to_call = call.num_params () + 1;
276+
size_t num_args_to_call = arguments.size () + 1;
229277
if (num_args_to_call != type.num_params ())
230278
{
231-
rust_error_at (call.get_locus (),
279+
rust_error_at (call_locus,
232280
"unexpected number of arguments %lu expected %lu",
233-
(unsigned long) call.num_params (),
281+
(unsigned long) num_args_to_call,
234282
(unsigned long) type.num_params ());
235-
return;
283+
return new ErrorType (type.get_ref ());
236284
}
237285

238286
size_t i = 1;
239-
for (auto &argument : call.get_arguments ())
287+
for (auto &argument : arguments)
240288
{
241-
Location arg_locus = argument->get_locus ();
289+
Location arg_locus = argument.get_locus ();
242290

243291
auto fnparam = type.param_at (i);
244292
HIR::Pattern *fn_param_pattern = fnparam.first;
@@ -248,41 +296,31 @@ TypeCheckMethodCallExpr::visit (FnType &type)
248296
? mappings->lookup_location (param_ty->get_ref ())
249297
: fn_param_pattern->get_locus ();
250298

251-
auto argument_expr_tyty
252-
= Resolver::TypeCheckExpr::Resolve (argument.get ());
253-
if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
254-
{
255-
rust_error_at (
256-
argument->get_locus (),
257-
"failed to resolve type for argument expr in CallExpr");
258-
return;
259-
}
260-
261-
HirId coercion_side_id = argument->get_mappings ().get_hirid ();
299+
auto argument_expr_tyty = argument.get_argument_type ();
300+
HirId coercion_side_id = argument.get_mappings ().get_hirid ();
262301
auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site (
263302
coercion_side_id, TyWithLocation (param_ty, param_locus),
264-
TyWithLocation (argument_expr_tyty, arg_locus), argument->get_locus ());
303+
TyWithLocation (argument_expr_tyty, arg_locus), arg_locus);
265304
if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR)
266305
{
267-
rust_error_at (argument->get_locus (),
268-
"Type Resolution failure on parameter");
269-
return;
306+
rust_error_at (arg_locus, "Type Resolution failure on parameter");
307+
return new ErrorType (type.get_ref ());
270308
}
271309

272310
i++;
273311
}
274312

275313
if (i != num_args_to_call)
276314
{
277-
rust_error_at (call.get_locus (),
315+
rust_error_at (call_locus,
278316
"unexpected number of arguments %lu expected %lu",
279-
(unsigned long) i, (unsigned long) call.num_params ());
280-
return;
317+
(unsigned long) i, (unsigned long) arguments.size ());
318+
return new ErrorType (type.get_ref ());
281319
}
282320

283321
type.monomorphize ();
284322

285-
resolved = type.get_return_type ()->monomorphized_clone ();
323+
return type.get_return_type ()->monomorphized_clone ();
286324
}
287325

288326
} // namespace TyTy

gcc/rust/typecheck/rust-tyty-call.h

+36-43
Original file line numberDiff line numberDiff line change
@@ -84,58 +84,51 @@ class TypeCheckCallExpr : private TyVisitor
8484
Analysis::Mappings *mappings;
8585
};
8686

87-
class TypeCheckMethodCallExpr : private TyVisitor
87+
class Argument
8888
{
8989
public:
90-
// Resolve the Method parameters and return back the return type
91-
static BaseType *go (BaseType *ref, HIR::MethodCallExpr &call,
92-
TyTy::BaseType *adjusted_self,
93-
Resolver::TypeCheckContext *context)
94-
{
95-
TypeCheckMethodCallExpr checker (call, adjusted_self, context);
96-
ref->accept_vis (checker);
97-
return checker.resolved;
98-
}
90+
Argument (Analysis::NodeMapping mapping, BaseType *argument_type,
91+
Location locus)
92+
: mapping (mapping), argument_type (argument_type), locus (locus)
93+
{}
9994

100-
void visit (InferType &) override { gcc_unreachable (); }
101-
void visit (TupleType &) override { gcc_unreachable (); }
102-
void visit (ArrayType &) override { gcc_unreachable (); }
103-
void visit (SliceType &) override { gcc_unreachable (); }
104-
void visit (BoolType &) override { gcc_unreachable (); }
105-
void visit (IntType &) override { gcc_unreachable (); }
106-
void visit (UintType &) override { gcc_unreachable (); }
107-
void visit (FloatType &) override { gcc_unreachable (); }
108-
void visit (USizeType &) override { gcc_unreachable (); }
109-
void visit (ISizeType &) override { gcc_unreachable (); }
110-
void visit (ErrorType &) override { gcc_unreachable (); }
111-
void visit (ADTType &) override { gcc_unreachable (); };
112-
void visit (CharType &) override { gcc_unreachable (); }
113-
void visit (ReferenceType &) override { gcc_unreachable (); }
114-
void visit (PointerType &) override { gcc_unreachable (); }
115-
void visit (ParamType &) override { gcc_unreachable (); }
116-
void visit (StrType &) override { gcc_unreachable (); }
117-
void visit (NeverType &) override { gcc_unreachable (); }
118-
void visit (PlaceholderType &) override { gcc_unreachable (); }
119-
void visit (ProjectionType &) override { gcc_unreachable (); }
120-
void visit (DynamicObjectType &) override { gcc_unreachable (); }
95+
Location get_locus () const { return locus; }
12196

122-
// FIXME
123-
void visit (FnPtr &type) override { gcc_unreachable (); }
97+
BaseType *get_argument_type () { return argument_type; }
12498

125-
// call fns
126-
void visit (FnType &type) override;
127-
void visit (ClosureType &type) override { gcc_unreachable (); }
99+
Analysis::NodeMapping get_mappings () const { return mapping; }
128100

129101
private:
130-
TypeCheckMethodCallExpr (HIR::MethodCallExpr &c,
102+
Analysis::NodeMapping mapping;
103+
BaseType *argument_type;
104+
Location locus;
105+
};
106+
107+
class TypeCheckMethodCallExpr
108+
{
109+
public:
110+
static BaseType *go (FnType *ref, HIR::MethodCallExpr &call,
111+
TyTy::BaseType *adjusted_self,
112+
Resolver::TypeCheckContext *context);
113+
114+
static BaseType *go (FnType *ref, Analysis::NodeMapping call_mappings,
115+
std::vector<Argument> &args, Location call_locus,
116+
Location receiver_locus, TyTy::BaseType *adjusted_self,
117+
Resolver::TypeCheckContext *context);
118+
119+
protected:
120+
BaseType *check (FnType &type);
121+
122+
TypeCheckMethodCallExpr (Analysis::NodeMapping call_mappings,
123+
std::vector<Argument> &args, Location call_locus,
124+
Location receiver_locus,
131125
TyTy::BaseType *adjusted_self,
132-
Resolver::TypeCheckContext *context)
133-
: resolved (nullptr), call (c), adjusted_self (adjusted_self),
134-
context (context), mappings (Analysis::Mappings::get ())
135-
{}
126+
Resolver::TypeCheckContext *context);
136127

137-
BaseType *resolved;
138-
HIR::MethodCallExpr &call;
128+
Analysis::NodeMapping call_mappings;
129+
std::vector<Argument> &arguments;
130+
Location call_locus;
131+
Location receiver_locus;
139132
TyTy::BaseType *adjusted_self;
140133
Resolver::TypeCheckContext *context;
141134
Analysis::Mappings *mappings;

0 commit comments

Comments
 (0)