aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-02-23 16:10:17 -0500
committerGitHub <noreply@github.com>2022-02-23 16:10:17 -0500
commitecf56d85efa227acf1bd9cab9ad2d5af05f7efe5 (patch)
treed83ccefd98555c33d492273cb20f86fe78965416 /src/Sema.zig
parent88d1258e08e668e620d5f8f4681315e555acbcd2 (diff)
parentab4d693cfc82465c42021ba6f18c65fdd5f969e6 (diff)
downloadzig-ecf56d85efa227acf1bd9cab9ad2d5af05f7efe5.tar.gz
zig-ecf56d85efa227acf1bd9cab9ad2d5af05f7efe5.zip
Merge pull request #10969 from Vexu/stage2
stage2: fn typeinfo params
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig87
1 files changed, 76 insertions, 11 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 88c559cfce..1de9714eb8 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -3351,9 +3351,10 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
// Check for the possibility of this pattern:
// %a = ret_ptr
// %b = store(%a, %c)
- // Where %c is an error union. In such case we need to add to the current function's
- // inferred error set, if any.
- if (sema.typeOf(operand).zigTypeTag() == .ErrorUnion and
+ // Where %c is an error union or error set. In such case we need to add
+ // to the current function's inferred error set, if any.
+ if ((sema.typeOf(operand).zigTypeTag() == .ErrorUnion or
+ sema.typeOf(operand).zigTypeTag() == .ErrorSet) and
sema.fn_ret_ty.zigTypeTag() == .ErrorUnion)
{
if (Zir.refToIndex(extra.lhs)) |ptr_index| {
@@ -7665,6 +7666,8 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const container_type = try sema.resolveType(block, lhs_src, extra.lhs);
const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs);
+ // tuples are structs but they don't have a namespace
+ if (container_type.isTuple()) return Air.Inst.Ref.bool_false;
const namespace = container_type.getNamespace() orelse return sema.fail(
block,
lhs_src,
@@ -9886,7 +9889,65 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
}),
),
.Fn => {
+ // TODO: look into memoizing this result.
const info = ty.fnInfo();
+ var params_anon_decl = try block.startAnonDecl(src);
+ defer params_anon_decl.deinit();
+
+ const param_vals = try params_anon_decl.arena().alloc(Value, info.param_types.len);
+ for (param_vals) |*param_val, i| {
+ const param_ty = info.param_types[i];
+ const is_generic = param_ty.tag() == .generic_poison;
+ const param_ty_val = if (is_generic)
+ Value.@"null"
+ else
+ try Value.Tag.opt_payload.create(
+ params_anon_decl.arena(),
+ try Value.Tag.ty.create(params_anon_decl.arena(), param_ty),
+ );
+
+ const param_fields = try params_anon_decl.arena().create([3]Value);
+ param_fields.* = .{
+ // is_generic: bool,
+ Value.makeBool(is_generic),
+ // is_noalias: bool,
+ Value.@"false", // TODO
+ // arg_type: ?type,
+ param_ty_val,
+ };
+ param_val.* = try Value.Tag.@"struct".create(params_anon_decl.arena(), param_fields);
+ }
+
+ const args_val = v: {
+ const fn_info_decl = (try sema.namespaceLookup(
+ block,
+ src,
+ type_info_ty.getNamespace().?,
+ "Fn",
+ )).?;
+ try sema.mod.declareDeclDependency(sema.owner_decl, fn_info_decl);
+ try sema.ensureDeclAnalyzed(fn_info_decl);
+ const param_info_decl = (try sema.namespaceLookup(
+ block,
+ src,
+ fn_info_decl.val.castTag(.ty).?.data.getNamespace().?,
+ "Param",
+ )).?;
+ try sema.mod.declareDeclDependency(sema.owner_decl, param_info_decl);
+ try sema.ensureDeclAnalyzed(param_info_decl);
+ const new_decl = try params_anon_decl.finish(
+ try Type.Tag.array.create(params_anon_decl.arena(), .{
+ .len = param_vals.len,
+ .elem_type = param_info_decl.ty,
+ }),
+ try Value.Tag.array.create(
+ params_anon_decl.arena(),
+ param_vals,
+ ),
+ );
+ break :v try Value.Tag.decl_ref.create(sema.arena, new_decl);
+ };
+
const field_values = try sema.arena.alloc(Value, 6);
// calling_convention: CallingConvention,
field_values[0] = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(info.cc));
@@ -9897,9 +9958,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
// is_var_args: bool,
field_values[3] = Value.makeBool(info.is_var_args);
// return_type: ?type,
- field_values[4] = try Value.Tag.ty.create(sema.arena, ty.fnReturnType());
- // args: []const FnArg,
- field_values[5] = Value.@"null"; // TODO
+ field_values[4] = try Value.Tag.ty.create(sema.arena, info.return_type);
+ // args: []const Fn.Param,
+ field_values[5] = args_val;
return sema.addConstant(
type_info_ty,
@@ -10102,7 +10163,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
}),
try Value.Tag.array.create(
fields_anon_decl.arena(),
- try fields_anon_decl.arena().dupe(Value, enum_field_vals),
+ enum_field_vals,
),
);
break :v try Value.Tag.decl_ref.create(sema.arena, new_decl);
@@ -12128,7 +12189,7 @@ fn checkPtrOperand(
ty: Type,
) CompileError!void {
switch (ty.zigTypeTag()) {
- .Pointer => {},
+ .Pointer => return,
.Fn => {
const msg = msg: {
const msg = try sema.errMsg(
@@ -12145,8 +12206,10 @@ fn checkPtrOperand(
};
return sema.failWithOwnedErrorMsg(msg);
},
- else => return sema.fail(block, ty_src, "expected pointer, found '{}'", .{ty}),
+ .Optional => if (ty.isPtrLikeOptional()) return,
+ else => {},
}
+ return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty});
}
fn checkPtrType(
@@ -12156,7 +12219,7 @@ fn checkPtrType(
ty: Type,
) CompileError!void {
switch (ty.zigTypeTag()) {
- .Pointer => {},
+ .Pointer => return,
.Fn => {
const msg = msg: {
const msg = try sema.errMsg(
@@ -12173,8 +12236,10 @@ fn checkPtrType(
};
return sema.failWithOwnedErrorMsg(msg);
},
- else => return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty}),
+ .Optional => if (ty.isPtrLikeOptional()) return,
+ else => {},
}
+ return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{ty});
}
fn checkVectorElemType(