aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-08-05 23:23:05 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-08-05 23:26:11 -0700
commit7e9b23e6dce4d87615acd635f3731731a8601d39 (patch)
tree392b32ff570328a8fcd984013ad844b063beaa77 /src/Sema.zig
parentc7dc451a2a06a0ade0bb44a48cb6e5cde6e237df (diff)
downloadzig-7e9b23e6dce4d87615acd635f3731731a8601d39.tar.gz
zig-7e9b23e6dce4d87615acd635f3731731a8601d39.zip
Sema: respect requiresComptime of function return types
When doing a function call, if the return type requires comptime, the function is analyzed as an inline/comptime call. There is an important TODO here. I will reproduce the comment from this commit: > In the case of a comptime/inline function call of a generic function, > the function return type needs to be the resolved return type based on > the function parameter type expressions being evaluated with comptime arguments > passed in. Otherwise, it ends up being .generic_poison and failing the > comptime/inline function call analysis.
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig27
1 files changed, 18 insertions, 9 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 73f22aa845..825737e4c5 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -2461,7 +2461,8 @@ fn analyzeCall(
const gpa = sema.gpa;
- const is_comptime_call = block.is_comptime or modifier == .compile_time;
+ const is_comptime_call = block.is_comptime or modifier == .compile_time or
+ func_ty_info.return_type.requiresComptime();
const is_inline_call = is_comptime_call or modifier == .always_inline or
func_ty_info.cc == .Inline;
const result: Air.Inst.Ref = if (is_inline_call) res: {
@@ -3609,6 +3610,8 @@ fn funcCommon(
return mod.fail(&block.base, src, "TODO implement support for function prototypes to have alignment specified", .{});
}
+ is_generic = is_generic or bare_return_type.requiresComptime();
+
const return_type = if (!inferred_error_set or bare_return_type.tag() == .generic_poison)
bare_return_type
else blk: {
@@ -5334,18 +5337,18 @@ fn analyzeArithmetic(
) CompileError!Air.Inst.Ref {
const lhs_ty = sema.typeOf(lhs);
const rhs_ty = sema.typeOf(rhs);
- if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) {
+ const lhs_zig_ty_tag = try lhs_ty.zigTypeTagOrPoison();
+ const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison();
+ if (lhs_zig_ty_tag == .Vector and rhs_zig_ty_tag == .Vector) {
if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) {
return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{
- lhs_ty.arrayLen(),
- rhs_ty.arrayLen(),
+ lhs_ty.arrayLen(), rhs_ty.arrayLen(),
});
}
return sema.mod.fail(&block.base, src, "TODO implement support for vectors in zirBinOp", .{});
- } else if (lhs_ty.zigTypeTag() == .Vector or rhs_ty.zigTypeTag() == .Vector) {
+ } else if (lhs_zig_ty_tag == .Vector or rhs_zig_ty_tag == .Vector) {
return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{
- lhs_ty,
- rhs_ty,
+ lhs_ty, rhs_ty,
});
}
@@ -5365,7 +5368,9 @@ fn analyzeArithmetic(
const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat;
if (!is_int and !(is_float and floatOpAllowed(zir_tag))) {
- return sema.mod.fail(&block.base, src, "invalid operands to binary expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) });
+ return sema.mod.fail(&block.base, src, "invalid operands to binary expression: '{s}' and '{s}'", .{
+ @tagName(lhs_zig_ty_tag), @tagName(rhs_zig_ty_tag),
+ });
}
if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {
@@ -6164,6 +6169,10 @@ fn analyzeRet(
const casted_operand = if (!need_coercion) operand else op: {
const func = sema.func.?;
const fn_ty = func.owner_decl.ty;
+ // TODO: In the case of a comptime/inline function call of a generic function,
+ // this needs to be the resolved return type based on the function parameter type
+ // expressions being evaluated with comptime arguments passed in. Otherwise, this
+ // ends up being .generic_poison and failing the comptime/inline function call analysis.
const fn_ret_ty = fn_ty.fnReturnType();
break :op try sema.coerce(block, fn_ret_ty, operand, src);
};
@@ -9093,7 +9102,7 @@ fn typeHasOnePossibleValue(
.inferred_alloc_const => unreachable,
.inferred_alloc_mut => unreachable,
- .generic_poison => unreachable,
+ .generic_poison => return error.GenericPoison,
};
}