support shorthand enums in value-if
This commit is contained in:
@@ -38,12 +38,12 @@ Infer_Local :: struct {
|
||||
declared: types.Type,
|
||||
statement: ast.Stmt_Id,
|
||||
mutable: bool,
|
||||
// open_const/open_float mark a local whose initializer is an unannotated numeric
|
||||
// constant: like an open-constant global, it can adopt a backward demand from use.
|
||||
open_const: bool,
|
||||
open_float: bool,
|
||||
const_value: i128,
|
||||
demanded: bool,
|
||||
// Open numeric constants and value sources can adopt a backward demand from use.
|
||||
open_const: bool,
|
||||
open_float: bool,
|
||||
open_value_source: bool,
|
||||
const_value: i128,
|
||||
demanded: bool,
|
||||
}
|
||||
|
||||
Build_Local :: struct {
|
||||
@@ -5125,6 +5125,9 @@ infer_compound_expr :: proc(
|
||||
}
|
||||
field_expected := field.type if is_runtime_type(checker, field.type) else types.INVALID
|
||||
actual := infer_nested_expr(checker, keyed_expr.left, locals, pkg, file, demanded, local_types, field_expected)
|
||||
_ = record_demand(
|
||||
checker, keyed_expr.left, field_expected, locals, local_types, pkg, file,
|
||||
)
|
||||
if !is_inferred_record_field(checker, slot) {
|
||||
continue
|
||||
}
|
||||
@@ -5960,7 +5963,7 @@ infer_statements :: proc(
|
||||
block_type := declared_block if is_runtime_type(checker, declared_block) else types.INVALID
|
||||
local := Infer_Local{
|
||||
name=statement.name, type=block_type, declared=declared_block,
|
||||
statement=statement_id, mutable=!statement.immutable,
|
||||
statement=statement_id, mutable=!statement.immutable, open_value_source=true,
|
||||
}
|
||||
append(locals, local)
|
||||
record_infer_local_type(local, local_types)
|
||||
@@ -6488,10 +6491,12 @@ merge_global_demand :: proc(checker: ^Checker, global: ast.Global_Id, demand: ty
|
||||
return changed
|
||||
}
|
||||
|
||||
// merge_local_demand records a concrete numeric demand onto an open-constant local.
|
||||
// The first demand replaces the literal's default type; later demands may only widen
|
||||
// within the chosen family.
|
||||
// merge_local_demand records a concrete demand onto an unresolved value source or
|
||||
// open numeric constant. Numeric demands retain their literal-family restrictions.
|
||||
merge_local_demand :: proc(checker: ^Checker, local: ^Infer_Local, demand: types.Type, local_types: []types.Type) -> bool {
|
||||
if local.open_value_source {
|
||||
return merge_infer_local_type(checker, local, demand, local_types)
|
||||
}
|
||||
if !(local.open_const && open_integer_accepts_demand(checker, local.const_value, demand) ||
|
||||
local.open_float && open_float_accepts_demand(checker, demand)) {
|
||||
return false
|
||||
@@ -10924,10 +10929,12 @@ build_block :: proc(
|
||||
// leaves `expr` invalid and stashes the block in `body`. Build it, then
|
||||
// declare the local from the yielded value (its type for an untyped `::`).
|
||||
if statement.expr == ast.INVALID_EXPR {
|
||||
expected := types.INVALID
|
||||
typed := is_runtime_type(checker, type_from_syntax(checker, statement.type, ctx.pkg, ctx.file))
|
||||
if typed {
|
||||
expected = type_from_syntax(checker, statement.type, ctx.pkg, ctx.file)
|
||||
declared := type_from_syntax(checker, statement.type, ctx.pkg, ctx.file)
|
||||
expected := declared if is_runtime_type(checker, declared) else types.INVALID
|
||||
if !is_runtime_type(checker, expected) &&
|
||||
int(statement_id) < len(ctx.local_types) &&
|
||||
is_runtime_type(checker, ctx.local_types[statement_id]) {
|
||||
expected = ctx.local_types[statement_id]
|
||||
}
|
||||
value, value_type := build_value_source(ctx, &body, statement.body, expected, statement.span, statement.label, statement.value_control_flow)
|
||||
if _, found := find_build_local(ctx.locals^[duplicate_start:], statement.name); found {
|
||||
|
||||
Reference in New Issue
Block a user