feat: execute explicitly annotated compile-time metadata locals
This commit is contained in:
@@ -1406,6 +1406,7 @@ tagged_type_metadata_recompiles_owned_private_nominal_payloads test {
|
||||
` value Selected :: { value = 40 }
|
||||
` if (lib.read(lib.make(), value) != 42) return -4
|
||||
` if (lib.score(lib.make(), 40) != 42) return -6
|
||||
` if (lib.score_local(40) != 42) return -7
|
||||
` snapshot Storage() :: {
|
||||
` original = { values = [{ value = 19 }, { value = 21 }] },
|
||||
` nested = { values = [true] },
|
||||
@@ -1468,6 +1469,13 @@ tagged_type_metadata_recompiles_owned_private_nominal_payloads test {
|
||||
` if (saved.payload.children[0]? != Child) return -1
|
||||
` return i16(saved.payload.count) + bias
|
||||
`}
|
||||
`score_local proc(bias i16) i16 {
|
||||
` config Config := { children = [Child, null], count = 2 }
|
||||
` saved :: config
|
||||
` config.children[0] = bool
|
||||
` if (saved.children[0]? != Child) return -1
|
||||
` return i16(saved.count) + bias
|
||||
`}
|
||||
,
|
||||
)
|
||||
defer arraylist.deinit(&imported)
|
||||
|
||||
@@ -148,6 +148,9 @@ elaborate proc(
|
||||
if (!parameter.comptime and type_storage_annotation(&original,
|
||||
resolution.storage.bindings, parameter.type, 0)) needed = true
|
||||
}
|
||||
if (!ast.function_external(&original, id)
|
||||
and type_local_storage(&original, resolution.storage.bindings,
|
||||
ast.function_decl(&original, id).body, 0)) needed = true
|
||||
}
|
||||
if (class == .statement and ast.stmt_kind(&original, id) == .declaration
|
||||
and type_storage_annotation(&original, resolution.storage.bindings,
|
||||
@@ -1857,6 +1860,23 @@ type_storage_annotation proc(tree @ast.Tree, bindings []sema.Binding, input ast.
|
||||
return false
|
||||
}
|
||||
|
||||
# explicit metadata locals have no runtime storage, just like metadata parameters.
|
||||
# do not classify ordinary local type aliases as constant-input procedures.
|
||||
@hide:file
|
||||
type_local_storage proc(tree @ast.Tree, bindings []sema.Binding, id ast.NodeId, depth usize) bool {
|
||||
if (depth >= 128) return false
|
||||
if (ast.node_class(tree, id) == .statement and ast.stmt_kind(tree, id) == .declaration) {
|
||||
declaration :: ast.statement_decl(tree, id)
|
||||
if (declaration.type) |annotation| {
|
||||
if (type_storage_annotation(tree, bindings, annotation, 0)) return true
|
||||
}
|
||||
}
|
||||
for (0..ast.child_count(tree, id)) |i| {
|
||||
if (type_local_storage(tree, bindings, ast.child(tree, id, i), depth + 1)) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@hide:file
|
||||
compiletime_call proc(state @State, function ast.NodeId) bool {
|
||||
if (type_record_storage(state, ast.function_decl(&state.tree, function).return_type, 0)) return true
|
||||
@@ -1864,7 +1884,9 @@ compiletime_call proc(state @State, function ast.NodeId) bool {
|
||||
parameter :: ast.param(&state.tree, ast.function_param(&state.tree, function, i))
|
||||
if (!parameter.comptime and type_record_storage(state, parameter.type, 0)) return true
|
||||
}
|
||||
return false
|
||||
return (!ast.function_external(&state.tree, function)
|
||||
and type_local_storage(&state.tree, state.bindings.items,
|
||||
ast.function_decl(&state.tree, function).body, 0))
|
||||
}
|
||||
|
||||
@hide:file
|
||||
@@ -1917,7 +1939,7 @@ specialize_call proc(state @mut State, call, function, expected ast.NodeId) void
|
||||
state.depth += 1
|
||||
defer state.depth -= 1
|
||||
count :: ast.function_param_count(&state.tree, function)
|
||||
# ordinary metadata inputs and metadata results require a fully constant call.
|
||||
# metadata inputs, results and explicit locals require a fully constant call.
|
||||
type_result :: compiletime_call(state, function)
|
||||
runtime := usize(0)
|
||||
for (0..count) |i| {
|
||||
|
||||
Reference in New Issue
Block a user