stage2: validate param and variable types

This commit is contained in:
Vexu
2020-08-18 13:57:09 +03:00
parent 7c15c9428e
commit 31d8efc6b3
2 changed files with 48 additions and 1 deletions

View File

@@ -1062,6 +1062,45 @@ pub const Type = extern union {
}
}
/// Returns if type can be used for a runtime variable
pub fn isValidVarType(self: Type) bool {
var ty = self;
while (true) switch (ty.zigTypeTag()) {
.Bool,
.Int,
.Float,
.ErrorSet,
.Enum,
.Frame,
.AnyFrame,
.Vector,
=> return true,
.BoundFn,
.ComptimeFloat,
.ComptimeInt,
.EnumLiteral,
.NoReturn,
.Type,
.Void,
.Undefined,
.Null,
.Opaque,
=> return false,
.Optional => {
var buf: Payload.Pointer = undefined;
return ty.optionalChild(&buf).isValidVarType();
},
.Pointer, .Array => ty = ty.elemType(),
.ErrorUnion => @panic("TODO fn isValidVarType"),
.Fn => @panic("TODO fn isValidVarType"),
.Struct => @panic("TODO struct isValidVarType"),
.Union => @panic("TODO union isValidVarType"),
};
}
/// Asserts the type is a pointer or array type.
pub fn elemType(self: Type) Type {
return switch (self.tag()) {

View File

@@ -364,6 +364,9 @@ fn analyzeInstEnsureResultNonError(mod: *Module, scope: *Scope, inst: *zir.Inst.
fn analyzeInstAlloc(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
const var_type = try resolveType(mod, scope, inst.positionals.operand);
if (!var_type.isValidVarType()) {
return mod.fail(scope, inst.base.src, "variable of type '{}' must be const or comptime", .{var_type});
}
const ptr_type = try mod.singlePtrType(scope, inst.base.src, true, var_type);
const b = try mod.requireRuntimeBlock(scope, inst.base.src);
return mod.addNoOp(b, inst.base.src, ptr_type, .alloc);
@@ -760,7 +763,12 @@ fn analyzeInstFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) Inne
const arena = scope.arena();
const param_types = try arena.alloc(Type, fntype.positionals.param_types.len);
for (fntype.positionals.param_types) |param_type, i| {
param_types[i] = try resolveType(mod, scope, param_type);
const resolved = try resolveType(mod, scope, param_type);
// TODO skip for comptime params
if (!resolved.isValidVarType()) {
return mod.fail(scope, param_type.src, "parameter of type '{}' must be declared comptime", .{resolved});
}
param_types[i] = resolved;
}
const payload = try arena.create(Type.Payload.Function);