diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-02-23 16:10:17 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-23 16:10:17 -0500 |
| commit | ecf56d85efa227acf1bd9cab9ad2d5af05f7efe5 (patch) | |
| tree | d83ccefd98555c33d492273cb20f86fe78965416 /src/Sema.zig | |
| parent | 88d1258e08e668e620d5f8f4681315e555acbcd2 (diff) | |
| parent | ab4d693cfc82465c42021ba6f18c65fdd5f969e6 (diff) | |
| download | zig-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.zig | 87 |
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( |
