calleeExpr
calleeExpr generates the function part of a call expression (f in f(x)), but
not the callee argument to the @call() builtin. Its purpose is to
distinguish between standard calls and method call syntax a.b(). Thus, if
the lhs is a field access, we return using the field union field;
otherwise, we use the direct union field.
Function parameters
Parameters
- gz:*GenZir
- scope:*Scope
- call_rl:ResultInfo.Loc
- override_decl_literal_type:Zir.Inst.Ref
- If this is not `.none` and this call is a decl literal form (`.foo(...)`), then this
- node:Ast.Node.Index
Functions in this namespace
Functions
Source
Implementation
fn calleeExpr(
gz: *GenZir,
scope: *Scope,
call_rl: ResultInfo.Loc,
/// If this is not `.none` and this call is a decl literal form (`.foo(...)`), then this
/// type is used as the decl literal result type instead of the result type from `call_rl`.
override_decl_literal_type: Zir.Inst.Ref,
node: Ast.Node.Index,
) InnerError!Callee {
const astgen = gz.astgen;
const tree = astgen.tree;
const tag = tree.nodeTag(node);
switch (tag) {
.field_access => {
const object_node, const field_ident = tree.nodeData(node).node_and_token;
const str_index = try astgen.identAsString(field_ident);
// Capture the object by reference so we can promote it to an
// address in Sema if needed.
const lhs = try expr(gz, scope, .{ .rl = .ref }, object_node);
const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
try emitDbgStmt(gz, cursor);
return .{ .field = .{
.obj_ptr = lhs,
.field_name_start = str_index,
} };
},
.enum_literal => {
const res_ty = res_ty: {
if (override_decl_literal_type != .none) break :res_ty override_decl_literal_type;
break :res_ty try call_rl.resultType(gz, node) orelse {
// No result type; lower to a literal call of an enum literal.
return .{ .direct = try expr(gz, scope, .{ .rl = .none }, node) };
};
};
// Decl literal call syntax, e.g.
// `const foo: T = .init();`
// Look up `init` in `T`, but don't try and coerce it.
const str_index = try astgen.identAsString(tree.nodeMainToken(node));
const callee = try gz.addPlNode(.decl_literal_no_coerce, node, Zir.Inst.Field{
.lhs = res_ty,
.field_name_start = str_index,
});
return .{ .direct = callee };
},
else => return .{ .direct = try expr(gz, scope, .{ .rl = .none }, node) },
}
}