mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
switch on compile var marks entire namespaces
as depending on compile vars. closes #154
This commit is contained in:
parent
6ae6b5f5b5
commit
7f90dbbb11
@ -30,13 +30,15 @@ static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *
|
||||
static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
||||
TypeTableEntry *expected_type, AstNode *node);
|
||||
static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node);
|
||||
static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn);
|
||||
static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type);
|
||||
static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn,
|
||||
bool depends_on_compile_var);
|
||||
static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type,
|
||||
bool depends_on_compile_var);
|
||||
static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, AstNode *node,
|
||||
TypeTableEntry *expected_type, uint64_t x);
|
||||
static AstNode *find_decl(BlockContext *context, Buf *name);
|
||||
static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNode *decl_node,
|
||||
bool pointer_only, BlockContext *block_context);
|
||||
bool pointer_only, BlockContext *block_context, bool depends_on_compile_var);
|
||||
static TopLevelDecl *get_as_top_level_decl(AstNode *node);
|
||||
static VariableTableEntry *analyze_variable_declaration_raw(CodeGen *g, ImportTableEntry *import,
|
||||
BlockContext *context, AstNode *source_node,
|
||||
@ -2587,7 +2589,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
|
||||
|
||||
node->data.field_access_expr.is_member_fn = true;
|
||||
FnTableEntry *fn_entry = fn_decl_node->data.fn_proto.fn_table_entry;
|
||||
return resolve_expr_const_val_as_fn(g, node, fn_entry);
|
||||
return resolve_expr_const_val_as_fn(g, node, fn_entry, false);
|
||||
} else {
|
||||
add_node_error(g, node, buf_sprintf("no function named '%s' in '%s'",
|
||||
buf_ptr(field_name), buf_ptr(&bare_struct_type->name)));
|
||||
@ -2642,7 +2644,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
|
||||
AstNode *decl_node = entry ? entry->value : nullptr;
|
||||
if (decl_node) {
|
||||
bool pointer_only = false;
|
||||
return analyze_decl_ref(g, node, decl_node, pointer_only, context);
|
||||
return analyze_decl_ref(g, node, decl_node, pointer_only, context, false);
|
||||
} else {
|
||||
add_node_error(g, node,
|
||||
buf_sprintf("container '%s' has no member called '%s'",
|
||||
@ -2652,7 +2654,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
|
||||
} else if (child_type->id == TypeTableEntryIdPureError) {
|
||||
return analyze_error_literal_expr(g, import, context, node, field_name);
|
||||
} else if (wrapped_in_fn_call) { // this branch should go last, before the error in the else case
|
||||
return resolve_expr_const_val_as_type(g, node, child_type);
|
||||
return resolve_expr_const_val_as_type(g, node, child_type, false);
|
||||
} else {
|
||||
add_node_error(g, node,
|
||||
buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));
|
||||
@ -2671,7 +2673,8 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
|
||||
add_error_note(g, msg, decl_node, buf_sprintf("declared here"));
|
||||
}
|
||||
bool pointer_only = false;
|
||||
return analyze_decl_ref(g, node, decl_node, pointer_only, context);
|
||||
return analyze_decl_ref(g, node, decl_node, pointer_only, context,
|
||||
const_val->depends_on_compile_var);
|
||||
} else {
|
||||
const char *import_name = namespace_import->path ? buf_ptr(namespace_import->path) : "(C import)";
|
||||
add_node_error(g, node,
|
||||
@ -2770,33 +2773,44 @@ static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node)
|
||||
return g->builtin_types.entry_void;
|
||||
}
|
||||
|
||||
static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type) {
|
||||
static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type,
|
||||
bool depends_on_compile_var)
|
||||
{
|
||||
Expr *expr = get_resolved_expr(node);
|
||||
expr->const_val.ok = true;
|
||||
expr->const_val.data.x_type = type;
|
||||
expr->const_val.depends_on_compile_var = depends_on_compile_var;
|
||||
return g->builtin_types.entry_type;
|
||||
}
|
||||
|
||||
static TypeTableEntry *resolve_expr_const_val_as_other_expr(CodeGen *g, AstNode *node, AstNode *other) {
|
||||
static TypeTableEntry *resolve_expr_const_val_as_other_expr(CodeGen *g, AstNode *node, AstNode *other,
|
||||
bool depends_on_compile_var)
|
||||
{
|
||||
Expr *expr = get_resolved_expr(node);
|
||||
Expr *other_expr = get_resolved_expr(other);
|
||||
expr->const_val = other_expr->const_val;
|
||||
expr->const_val.depends_on_compile_var = expr->const_val.depends_on_compile_var ||
|
||||
depends_on_compile_var;
|
||||
return other_expr->type_entry;
|
||||
}
|
||||
|
||||
static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn) {
|
||||
static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn,
|
||||
bool depends_on_compile_var)
|
||||
{
|
||||
Expr *expr = get_resolved_expr(node);
|
||||
expr->const_val.ok = true;
|
||||
expr->const_val.data.x_fn = fn;
|
||||
expr->const_val.depends_on_compile_var = depends_on_compile_var;
|
||||
return fn->type_entry;
|
||||
}
|
||||
|
||||
static TypeTableEntry *resolve_expr_const_val_as_generic_fn(CodeGen *g, AstNode *node,
|
||||
TypeTableEntry *type_entry)
|
||||
TypeTableEntry *type_entry, bool depends_on_compile_var)
|
||||
{
|
||||
Expr *expr = get_resolved_expr(node);
|
||||
expr->const_val.ok = true;
|
||||
expr->const_val.data.x_type = type_entry;
|
||||
expr->const_val.depends_on_compile_var = depends_on_compile_var;
|
||||
return type_entry;
|
||||
}
|
||||
|
||||
@ -2922,7 +2936,7 @@ static bool var_is_pure(VariableTableEntry *var, BlockContext *context) {
|
||||
}
|
||||
|
||||
static TypeTableEntry *analyze_var_ref(CodeGen *g, AstNode *source_node, VariableTableEntry *var,
|
||||
BlockContext *context)
|
||||
BlockContext *context, bool depends_on_compile_var)
|
||||
{
|
||||
get_resolved_expr(source_node)->variable = var;
|
||||
if (!var_is_pure(var, context)) {
|
||||
@ -2931,14 +2945,15 @@ static TypeTableEntry *analyze_var_ref(CodeGen *g, AstNode *source_node, Variabl
|
||||
if (var->is_const && var->val_node) {
|
||||
ConstExprValue *other_const_val = &get_resolved_expr(var->val_node)->const_val;
|
||||
if (other_const_val->ok) {
|
||||
return resolve_expr_const_val_as_other_expr(g, source_node, var->val_node);
|
||||
return resolve_expr_const_val_as_other_expr(g, source_node, var->val_node,
|
||||
depends_on_compile_var);
|
||||
}
|
||||
}
|
||||
return var->type;
|
||||
}
|
||||
|
||||
static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNode *decl_node,
|
||||
bool pointer_only, BlockContext *block_context)
|
||||
bool pointer_only, BlockContext *block_context, bool depends_on_compile_var)
|
||||
{
|
||||
resolve_top_level_decl(g, decl_node, pointer_only);
|
||||
TopLevelDecl *tld = get_as_top_level_decl(decl_node);
|
||||
@ -2948,27 +2963,29 @@ static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNod
|
||||
|
||||
if (decl_node->type == NodeTypeVariableDeclaration) {
|
||||
VariableTableEntry *var = decl_node->data.variable_declaration.variable;
|
||||
return analyze_var_ref(g, source_node, var, block_context);
|
||||
return analyze_var_ref(g, source_node, var, block_context, depends_on_compile_var);
|
||||
} else if (decl_node->type == NodeTypeFnProto) {
|
||||
if (decl_node->data.fn_proto.generic_params.length > 0) {
|
||||
TypeTableEntry *type_entry = decl_node->data.fn_proto.generic_fn_type;
|
||||
assert(type_entry);
|
||||
return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry);
|
||||
return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry, depends_on_compile_var);
|
||||
} else {
|
||||
FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry;
|
||||
assert(fn_entry->type_entry);
|
||||
return resolve_expr_const_val_as_fn(g, source_node, fn_entry);
|
||||
return resolve_expr_const_val_as_fn(g, source_node, fn_entry, depends_on_compile_var);
|
||||
}
|
||||
} else if (decl_node->type == NodeTypeStructDecl) {
|
||||
if (decl_node->data.struct_decl.generic_params.length > 0) {
|
||||
TypeTableEntry *type_entry = decl_node->data.struct_decl.generic_fn_type;
|
||||
assert(type_entry);
|
||||
return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry);
|
||||
return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry, depends_on_compile_var);
|
||||
} else {
|
||||
return resolve_expr_const_val_as_type(g, source_node, decl_node->data.struct_decl.type_entry);
|
||||
return resolve_expr_const_val_as_type(g, source_node, decl_node->data.struct_decl.type_entry,
|
||||
depends_on_compile_var);
|
||||
}
|
||||
} else if (decl_node->type == NodeTypeTypeDecl) {
|
||||
return resolve_expr_const_val_as_type(g, source_node, decl_node->data.type_decl.child_type_entry);
|
||||
return resolve_expr_const_val_as_type(g, source_node, decl_node->data.type_decl.child_type_entry,
|
||||
depends_on_compile_var);
|
||||
} else {
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -2978,25 +2995,25 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import,
|
||||
TypeTableEntry *expected_type, AstNode *node, bool pointer_only)
|
||||
{
|
||||
if (node->data.symbol_expr.override_type_entry) {
|
||||
return resolve_expr_const_val_as_type(g, node, node->data.symbol_expr.override_type_entry);
|
||||
return resolve_expr_const_val_as_type(g, node, node->data.symbol_expr.override_type_entry, false);
|
||||
}
|
||||
|
||||
Buf *variable_name = &node->data.symbol_expr.symbol;
|
||||
|
||||
auto primitive_table_entry = g->primitive_type_table.maybe_get(variable_name);
|
||||
if (primitive_table_entry) {
|
||||
return resolve_expr_const_val_as_type(g, node, primitive_table_entry->value);
|
||||
return resolve_expr_const_val_as_type(g, node, primitive_table_entry->value, false);
|
||||
}
|
||||
|
||||
VariableTableEntry *var = find_variable(g, context, variable_name);
|
||||
if (var) {
|
||||
TypeTableEntry *var_type = analyze_var_ref(g, node, var, context);
|
||||
TypeTableEntry *var_type = analyze_var_ref(g, node, var, context, false);
|
||||
return var_type;
|
||||
}
|
||||
|
||||
AstNode *decl_node = find_decl(context, variable_name);
|
||||
if (decl_node) {
|
||||
return analyze_decl_ref(g, node, decl_node, pointer_only, context);
|
||||
return analyze_decl_ref(g, node, decl_node, pointer_only, context, false);
|
||||
}
|
||||
|
||||
if (import->any_imports_failed) {
|
||||
@ -3819,11 +3836,11 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,
|
||||
return g->builtin_types.entry_invalid;
|
||||
} else {
|
||||
return resolve_expr_const_val_as_type(g, node,
|
||||
get_array_type(g, child_type, const_val->data.x_bignum.data.x_uint));
|
||||
get_array_type(g, child_type, const_val->data.x_bignum.data.x_uint), false);
|
||||
}
|
||||
} else if (context->fn_entry) {
|
||||
return resolve_expr_const_val_as_type(g, node,
|
||||
get_slice_type(g, child_type, node->data.array_type.is_const));
|
||||
get_slice_type(g, child_type, node->data.array_type.is_const), false);
|
||||
} else {
|
||||
add_node_error(g, first_executing_node(size_node),
|
||||
buf_sprintf("unable to evaluate constant expression"));
|
||||
@ -3831,7 +3848,7 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,
|
||||
}
|
||||
} else {
|
||||
return resolve_expr_const_val_as_type(g, node,
|
||||
get_slice_type(g, child_type, node->data.array_type.is_const));
|
||||
get_slice_type(g, child_type, node->data.array_type.is_const), false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3844,7 +3861,7 @@ static TypeTableEntry *analyze_fn_proto_expr(CodeGen *g, ImportTableEntry *impor
|
||||
return type_entry;
|
||||
}
|
||||
|
||||
return resolve_expr_const_val_as_type(g, node, type_entry);
|
||||
return resolve_expr_const_val_as_type(g, node, type_entry, false);
|
||||
}
|
||||
|
||||
static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
||||
@ -4973,7 +4990,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
|
||||
case TypeTableEntryIdUnion:
|
||||
case TypeTableEntryIdFn:
|
||||
case TypeTableEntryIdTypeDecl:
|
||||
return resolve_expr_const_val_as_type(g, node, type_entry);
|
||||
return resolve_expr_const_val_as_type(g, node, type_entry, false);
|
||||
}
|
||||
}
|
||||
case BuiltinFnIdCInclude:
|
||||
@ -5307,10 +5324,10 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp
|
||||
AstNode *impl_decl_node = entry->value;
|
||||
if (impl_decl_node->type == NodeTypeFnProto) {
|
||||
FnTableEntry *fn_table_entry = impl_decl_node->data.fn_proto.fn_table_entry;
|
||||
return resolve_expr_const_val_as_fn(g, node, fn_table_entry);
|
||||
return resolve_expr_const_val_as_fn(g, node, fn_table_entry, false);
|
||||
} else if (impl_decl_node->type == NodeTypeStructDecl) {
|
||||
TypeTableEntry *type_entry = impl_decl_node->data.struct_decl.type_entry;
|
||||
return resolve_expr_const_val_as_type(g, node, type_entry);
|
||||
return resolve_expr_const_val_as_type(g, node, type_entry, false);
|
||||
} else {
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -5324,14 +5341,14 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp
|
||||
preview_fn_proto_instance(g, import, impl_decl_node, child_context);
|
||||
g->generic_table.put(generic_fn_type_id, impl_decl_node);
|
||||
FnTableEntry *fn_table_entry = impl_decl_node->data.fn_proto.fn_table_entry;
|
||||
return resolve_expr_const_val_as_fn(g, node, fn_table_entry);
|
||||
return resolve_expr_const_val_as_fn(g, node, fn_table_entry, false);
|
||||
} else if (decl_node->type == NodeTypeStructDecl) {
|
||||
AstNode *impl_decl_node = ast_clone_subtree(decl_node, &g->next_node_index);
|
||||
g->generic_table.put(generic_fn_type_id, impl_decl_node);
|
||||
scan_struct_decl(g, import, child_context, impl_decl_node);
|
||||
TypeTableEntry *type_entry = impl_decl_node->data.struct_decl.type_entry;
|
||||
resolve_struct_type(g, import, type_entry);
|
||||
return resolve_expr_const_val_as_type(g, node, type_entry);
|
||||
return resolve_expr_const_val_as_type(g, node, type_entry, false);
|
||||
} else {
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -5480,7 +5497,7 @@ static TypeTableEntry *analyze_prefix_op_expr(CodeGen *g, ImportTableEntry *impo
|
||||
return g->builtin_types.entry_invalid;
|
||||
} else {
|
||||
return resolve_expr_const_val_as_type(g, node,
|
||||
get_pointer_to_type(g, meta_type, is_const));
|
||||
get_pointer_to_type(g, meta_type, is_const), false);
|
||||
}
|
||||
} else if (child_type->id == TypeTableEntryIdNumLitInt ||
|
||||
child_type->id == TypeTableEntryIdNumLitFloat)
|
||||
@ -5520,7 +5537,7 @@ static TypeTableEntry *analyze_prefix_op_expr(CodeGen *g, ImportTableEntry *impo
|
||||
add_node_error(g, node, buf_create_from_str("unable to wrap unreachable in maybe type"));
|
||||
return g->builtin_types.entry_invalid;
|
||||
} else {
|
||||
return resolve_expr_const_val_as_type(g, node, get_maybe_type(g, meta_type));
|
||||
return resolve_expr_const_val_as_type(g, node, get_maybe_type(g, meta_type), false);
|
||||
}
|
||||
} else if (type_entry->id == TypeTableEntryIdUnreachable) {
|
||||
add_node_error(g, *expr_node, buf_sprintf("unable to wrap unreachable in maybe type"));
|
||||
@ -5548,7 +5565,7 @@ static TypeTableEntry *analyze_prefix_op_expr(CodeGen *g, ImportTableEntry *impo
|
||||
add_node_error(g, node, buf_create_from_str("unable to wrap unreachable in error type"));
|
||||
return g->builtin_types.entry_invalid;
|
||||
} else {
|
||||
return resolve_expr_const_val_as_type(g, node, get_error_type(g, meta_type));
|
||||
return resolve_expr_const_val_as_type(g, node, get_error_type(g, meta_type), false);
|
||||
}
|
||||
} else if (type_entry->id == TypeTableEntryIdUnreachable) {
|
||||
add_node_error(g, *expr_node, buf_sprintf("unable to wrap unreachable in error type"));
|
||||
@ -6159,10 +6176,10 @@ static TypeTableEntry *analyze_expression_pointer_only(CodeGen *g, ImportTableEn
|
||||
return_type = analyze_fn_proto_expr(g, import, context, expected_type, node);
|
||||
break;
|
||||
case NodeTypeErrorType:
|
||||
return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_pure_error);
|
||||
return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_pure_error, false);
|
||||
break;
|
||||
case NodeTypeTypeLiteral:
|
||||
return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_type);
|
||||
return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_type, false);
|
||||
break;
|
||||
case NodeTypeSwitchExpr:
|
||||
return_type = analyze_switch_expr(g, import, context, expected_type, node);
|
||||
|
||||
1
test/a.zig
Normal file
1
test/a.zig
Normal file
@ -0,0 +1 @@
|
||||
pub const a_bool = true;
|
||||
1
test/b.zig
Normal file
1
test/b.zig
Normal file
@ -0,0 +1 @@
|
||||
pub const a_bool = false;
|
||||
@ -1656,3 +1656,17 @@ fn use_generic_param_in_generic_param() {
|
||||
fn a_generic_fn(T: type, a: T)(b: T) -> T {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
|
||||
#attribute("test")
|
||||
fn namespace_depends_on_compile_var() {
|
||||
if (some_namespace.a_bool) {
|
||||
assert(some_namespace.a_bool);
|
||||
} else {
|
||||
assert(!some_namespace.a_bool);
|
||||
}
|
||||
}
|
||||
const some_namespace = switch(@compile_var("os")) {
|
||||
linux => @import("a.zig"),
|
||||
else => @import("b.zig"),
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user