stage2: type inference for local var

This commit is contained in:
Andrew Kelley
2020-12-31 02:42:48 -07:00
parent a46d24af1c
commit 7deb1f4f6c
4 changed files with 20 additions and 7 deletions

2
BRANCH_TODO Normal file
View File

@@ -0,0 +1,2 @@
* no need for payload on inferred_alloc for the type
* compile error for "variable of type '{}' must be const or comptime" after resolving types

View File

@@ -625,9 +625,9 @@ fn varDecl(
const alloc = try addZIRUnOp(mod, scope, name_src, .alloc_mut, type_inst);
break :a .{ .alloc = alloc, .result_loc = .{ .ptr = alloc } };
} else a: {
const alloc = try addZIRNoOp(mod, scope, name_src, .alloc_inferred_mut);
resolve_inferred_alloc = alloc;
break :a .{ .alloc = alloc, .result_loc = .{ .inferred_ptr = alloc.castTag(.alloc_inferred_mut).? } };
const alloc = try addZIRNoOpT(mod, scope, name_src, .alloc_inferred);
resolve_inferred_alloc = &alloc.base;
break :a .{ .alloc = &alloc.base, .result_loc = .{ .inferred_ptr = alloc } };
};
const init_inst = try expr(mod, scope, var_data.result_loc, init_node);
if (resolve_inferred_alloc) |inst| {

View File

@@ -275,7 +275,6 @@ pub fn generate(file: *C, module: *Module, decl: *Decl) !void {
try writer.writeAll(" {");
const func: *Module.Fn = func_payload.data;
//func.dump(module.*);
const instructions = func.analysis.success.instructions;
if (instructions.len > 0) {
try writer.writeAll("\n");
@@ -297,6 +296,7 @@ pub fn generate(file: *C, module: *Module, decl: *Decl) !void {
.cmp_neq => try genBinOp(&ctx, file, inst.castTag(.cmp_neq).?, "!="),
.dbg_stmt => try genDbgStmt(&ctx, inst.castTag(.dbg_stmt).?),
.intcast => try genIntCast(&ctx, file, inst.castTag(.intcast).?),
.load => try genLoad(&ctx, file, inst.castTag(.load).?),
.ret => try genRet(&ctx, file, inst.castTag(.ret).?),
.retvoid => try genRetVoid(file),
.store => try genStore(&ctx, file, inst.castTag(.store).?),
@@ -431,6 +431,16 @@ fn genRetVoid(file: *C) !?[]u8 {
return null;
}
fn genLoad(ctx: *Context, file: *C, inst: *Inst.UnOp) !?[]u8 {
const operand = try ctx.resolveInst(inst.operand);
const writer = file.main.writer();
try indent(file);
const local_name = try ctx.name();
try renderTypeAndName(ctx, writer, inst.base.ty, local_name, .Const);
try writer.print(" = *{s};\n", .{operand});
return local_name;
}
fn genRet(ctx: *Context, file: *C, inst: *Inst.UnOp) !?[]u8 {
try indent(file);
const writer = file.main.writer();
@@ -442,7 +452,6 @@ fn genIntCast(ctx: *Context, file: *C, inst: *Inst.UnOp) !?[]u8 {
if (inst.base.isUnused())
return null;
try indent(file);
const op = inst.operand;
const writer = file.main.writer();
const name = try ctx.name();
const from = try ctx.resolveInst(inst.operand);

View File

@@ -52,7 +52,7 @@ pub fn addCases(ctx: *TestContext) !void {
}
{
var case = ctx.exeFromCompiledC("inferred local const", .{});
var case = ctx.exeFromCompiledC("inferred local const and var", .{});
case.addCompareOutput(
\\fn add(a: i32, b: i32) i32 {
@@ -61,7 +61,9 @@ pub fn addCases(ctx: *TestContext) !void {
\\
\\export fn main() c_int {
\\ const x = add(1, 2);
\\ return x - 3;
\\ var y = add(3, 0);
\\ y -= x;
\\ return y;
\\}
, "");
}