mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
parent
5834ff0cc5
commit
bcce77700f
@ -4631,7 +4631,51 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
|
|||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fn_eval_cacheable(Scope *scope) {
|
static bool return_type_is_cacheable(TypeTableEntry *return_type) {
|
||||||
|
switch (return_type->id) {
|
||||||
|
case TypeTableEntryIdInvalid:
|
||||||
|
zig_unreachable();
|
||||||
|
case TypeTableEntryIdMetaType:
|
||||||
|
case TypeTableEntryIdVoid:
|
||||||
|
case TypeTableEntryIdBool:
|
||||||
|
case TypeTableEntryIdUnreachable:
|
||||||
|
case TypeTableEntryIdInt:
|
||||||
|
case TypeTableEntryIdFloat:
|
||||||
|
case TypeTableEntryIdNumLitFloat:
|
||||||
|
case TypeTableEntryIdNumLitInt:
|
||||||
|
case TypeTableEntryIdUndefLit:
|
||||||
|
case TypeTableEntryIdNullLit:
|
||||||
|
case TypeTableEntryIdNamespace:
|
||||||
|
case TypeTableEntryIdBoundFn:
|
||||||
|
case TypeTableEntryIdFn:
|
||||||
|
case TypeTableEntryIdBlock:
|
||||||
|
case TypeTableEntryIdOpaque:
|
||||||
|
case TypeTableEntryIdPromise:
|
||||||
|
case TypeTableEntryIdErrorSet:
|
||||||
|
case TypeTableEntryIdEnum:
|
||||||
|
case TypeTableEntryIdPointer:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case TypeTableEntryIdArray:
|
||||||
|
case TypeTableEntryIdStruct:
|
||||||
|
case TypeTableEntryIdUnion:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case TypeTableEntryIdMaybe:
|
||||||
|
return return_type_is_cacheable(return_type->data.maybe.child_type);
|
||||||
|
|
||||||
|
case TypeTableEntryIdErrorUnion:
|
||||||
|
return return_type_is_cacheable(return_type->data.error_union.payload_type);
|
||||||
|
|
||||||
|
case TypeTableEntryIdArgTuple:
|
||||||
|
zig_panic("TODO var args at comptime is currently not supported");
|
||||||
|
}
|
||||||
|
zig_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fn_eval_cacheable(Scope *scope, TypeTableEntry *return_type) {
|
||||||
|
if (!return_type_is_cacheable(return_type))
|
||||||
|
return false;
|
||||||
while (scope) {
|
while (scope) {
|
||||||
if (scope->id == ScopeIdVarDecl) {
|
if (scope->id == ScopeIdVarDecl) {
|
||||||
ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
|
ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
|
||||||
|
|||||||
@ -196,6 +196,6 @@ TypeTableEntry *get_auto_err_set_type(CodeGen *g, FnTableEntry *fn_entry);
|
|||||||
uint32_t get_coro_frame_align_bytes(CodeGen *g);
|
uint32_t get_coro_frame_align_bytes(CodeGen *g);
|
||||||
bool fn_type_can_fail(FnTypeId *fn_type_id);
|
bool fn_type_can_fail(FnTypeId *fn_type_id);
|
||||||
bool type_can_fail(TypeTableEntry *type_entry);
|
bool type_can_fail(TypeTableEntry *type_entry);
|
||||||
bool fn_eval_cacheable(Scope *scope);
|
bool fn_eval_cacheable(Scope *scope, TypeTableEntry *return_type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -11878,7 +11878,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
|
|||||||
return_type = specified_return_type;
|
return_type = specified_return_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cacheable = fn_eval_cacheable(exec_scope);
|
bool cacheable = fn_eval_cacheable(exec_scope, return_type);
|
||||||
IrInstruction *result = nullptr;
|
IrInstruction *result = nullptr;
|
||||||
if (cacheable) {
|
if (cacheable) {
|
||||||
auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope);
|
auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope);
|
||||||
|
|||||||
@ -369,7 +369,7 @@ fn calcDecodedSizeExactUnsafe(source: []const u8, pad_char: u8) usize {
|
|||||||
|
|
||||||
|
|
||||||
test "base64" {
|
test "base64" {
|
||||||
@setEvalBranchQuota(5000);
|
@setEvalBranchQuota(8000);
|
||||||
testBase64() catch unreachable;
|
testBase64() catch unreachable;
|
||||||
comptime (testBase64() catch unreachable);
|
comptime (testBase64() catch unreachable);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ comptime {
|
|||||||
_ = @import("cases/bugs/394.zig");
|
_ = @import("cases/bugs/394.zig");
|
||||||
_ = @import("cases/bugs/655.zig");
|
_ = @import("cases/bugs/655.zig");
|
||||||
_ = @import("cases/bugs/656.zig");
|
_ = @import("cases/bugs/656.zig");
|
||||||
|
_ = @import("cases/bugs/828.zig");
|
||||||
_ = @import("cases/cast.zig");
|
_ = @import("cases/cast.zig");
|
||||||
_ = @import("cases/const_slice_child.zig");
|
_ = @import("cases/const_slice_child.zig");
|
||||||
_ = @import("cases/coroutines.zig");
|
_ = @import("cases/coroutines.zig");
|
||||||
|
|||||||
37
test/cases/bugs/828.zig
Normal file
37
test/cases/bugs/828.zig
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
const CountBy = struct {
|
||||||
|
a: usize,
|
||||||
|
|
||||||
|
const One = CountBy {
|
||||||
|
.a = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn counter(self: &const CountBy) Counter {
|
||||||
|
return Counter {
|
||||||
|
.i = 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Counter = struct {
|
||||||
|
i: usize,
|
||||||
|
|
||||||
|
pub fn count(self: &Counter) bool {
|
||||||
|
self.i += 1;
|
||||||
|
return self.i <= 10;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn constCount(comptime cb: &const CountBy, comptime unused: u32) void {
|
||||||
|
comptime {
|
||||||
|
var cnt = cb.counter();
|
||||||
|
if(cnt.i != 0) @compileError("Counter instance reused!");
|
||||||
|
while(cnt.count()){}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "comptime struct return should not return the same instance" {
|
||||||
|
//the first parameter must be passed by reference to trigger the bug
|
||||||
|
//a second parameter is required to trigger the bug
|
||||||
|
const ValA = constCount(&CountBy.One, 12);
|
||||||
|
const ValB = constCount(&CountBy.One, 15);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user