mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-04 09:44:40 +00:00
Fix override_entity_in_scope behaviour to correctly to report the changes upstream better
This commit is contained in:
@@ -343,22 +343,36 @@ void override_entity_in_scope(Entity *original_entity, Entity *new_entity) {
|
||||
return;
|
||||
}
|
||||
|
||||
// IMPORTANT TODO(bill)
|
||||
// Date: 2018-09-29
|
||||
// This assert fails on `using import` if the name of the alias is the same. What should be the expected behaviour?
|
||||
// Namespace collision or override? Overridding is the current behaviour
|
||||
// IMPORTANT NOTE(bill, 2021-04-10): Overriding behaviour was flawed in that the
|
||||
// original entity was still used check checked, but the checking was only
|
||||
// relying on "constant" data such as the Entity.type and Entity.Constant.value
|
||||
//
|
||||
// using import "foo"
|
||||
// bar :: foo.bar;
|
||||
|
||||
// GB_ASSERT_MSG(found_entity == original_entity, "%.*s == %.*s", LIT(found_entity->token.string), LIT(new_entity->token.string));
|
||||
// Therefore two things can be done: the type can be assigned to state that it
|
||||
// has been "evaluated" and the variant data can be copied across
|
||||
|
||||
string_map_set(&found_scope->elements, original_name, new_entity);
|
||||
|
||||
original_entity->type = new_entity->type;
|
||||
|
||||
if (original_entity->identifier == nullptr) {
|
||||
original_entity->identifier = new_entity->identifier;
|
||||
}
|
||||
if (original_entity->identifier != nullptr &&
|
||||
original_entity->identifier->kind == Ast_Ident) {
|
||||
original_entity->identifier->Ident.entity = new_entity;
|
||||
}
|
||||
original_entity->flags |= EntityFlag_Overridden;
|
||||
|
||||
// IMPORTANT NOTE(bill, 2021-04-10): copy only the variants
|
||||
// This is most likely NEVER required, but it does not at all hurt to keep
|
||||
isize offset = cast(u8 *)&original_entity->Dummy.start - cast(u8 *)original_entity;
|
||||
isize size = gb_size_of(*original_entity) - offset;
|
||||
gb_memmove(cast(u8 *)original_entity, cast(u8 *)new_entity, size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, Type *named_type) {
|
||||
void check_const_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Ast *init, Type *named_type) {
|
||||
GB_ASSERT(e->type == nullptr);
|
||||
GB_ASSERT(e->kind == Entity_Constant);
|
||||
|
||||
@@ -374,6 +388,7 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init,
|
||||
|
||||
Operand operand = {};
|
||||
|
||||
Entity *other_entity = nullptr;
|
||||
if (init != nullptr) {
|
||||
Entity *entity = nullptr;
|
||||
if (init->kind == Ast_Ident) {
|
||||
@@ -412,7 +427,6 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init,
|
||||
GB_ASSERT(operand.proc_group->kind == Entity_ProcGroup);
|
||||
// NOTE(bill, 2020-06-10): It is better to just clone the contents than overriding the entity in the scope
|
||||
// Thank goodness I made entities a tagged union to allow for this implace patching
|
||||
// override_entity_in_scope(e, operand.proc_group);
|
||||
e->kind = Entity_ProcGroup;
|
||||
e->ProcGroup.entities = array_clone(heap_allocator(), operand.proc_group->ProcGroup.entities);
|
||||
return;
|
||||
@@ -454,7 +468,6 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init,
|
||||
error(decl->attributes[0], "Constant alias declarations cannot have attributes");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -846,7 +859,7 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
||||
}
|
||||
}
|
||||
|
||||
void check_global_variable_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init_expr) {
|
||||
void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Ast *init_expr) {
|
||||
GB_ASSERT(e->type == nullptr);
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
|
||||
@@ -946,7 +959,7 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *e, Ast *type_expr,
|
||||
check_init_variable(ctx, e, &o, str_lit("variable declaration"));
|
||||
}
|
||||
|
||||
void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, DeclInfo *d) {
|
||||
void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d) {
|
||||
GB_ASSERT(pg_entity->kind == Entity_ProcGroup);
|
||||
auto *pge = &pg_entity->ProcGroup;
|
||||
String proc_group_name = pg_entity->token.string;
|
||||
@@ -1074,7 +1087,7 @@ void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, DeclInfo *d)
|
||||
|
||||
}
|
||||
|
||||
void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_type) {
|
||||
void check_entity_decl(CheckerContext *ctx, Entity *&e, DeclInfo *d, Type *named_type) {
|
||||
if (e->state == EntityState_Resolved) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -79,15 +79,12 @@ void check_expr_with_type_hint (CheckerContext *c, Operand *o, Ast *e,
|
||||
Type * check_type (CheckerContext *c, Ast *expression);
|
||||
Type * check_type_expr (CheckerContext *c, Ast *expression, Type *named_type);
|
||||
Type * make_optional_ok_type (Type *value, bool typed=true);
|
||||
void check_type_decl (CheckerContext *c, Entity *e, Ast *type_expr, Type *def);
|
||||
Entity * check_selector (CheckerContext *c, Operand *operand, Ast *node, Type *type_hint);
|
||||
Entity * check_ident (CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name);
|
||||
Entity * find_polymorphic_record_entity (CheckerContext *c, Type *original_type, isize param_count, Array<Operand> const &ordered_operands, bool *failure);
|
||||
void check_not_tuple (CheckerContext *c, Operand *operand);
|
||||
void convert_to_typed (CheckerContext *c, Operand *operand, Type *target_type);
|
||||
gbString expr_to_string (Ast *expression);
|
||||
void check_entity_decl (CheckerContext *c, Entity *e, DeclInfo *decl, Type *named_type);
|
||||
void check_const_decl (CheckerContext *c, Entity *e, Ast *type_expr, Ast *init_expr, Type *named_type);
|
||||
void check_proc_body (CheckerContext *c, Token token, DeclInfo *decl, Type *type, Ast *body);
|
||||
void update_expr_type (CheckerContext *c, Ast *e, Type *type, bool final);
|
||||
bool check_is_terminating (Ast *node, String const &label);
|
||||
|
||||
@@ -2190,8 +2190,6 @@ Type *check_poly_path_pop(CheckerContext *c) {
|
||||
|
||||
|
||||
|
||||
void check_entity_decl(CheckerContext *c, Entity *e, DeclInfo *d, Type *named_type);
|
||||
|
||||
Array<Entity *> proc_group_entities(CheckerContext *c, Operand o) {
|
||||
Array<Entity *> procs = {};
|
||||
if (o.mode == Addressing_ProcGroup) {
|
||||
|
||||
@@ -396,6 +396,10 @@ void check_add_import_decl(CheckerContext *c, Ast *decl);
|
||||
void check_add_foreign_import_decl(CheckerContext *c, Ast *decl);
|
||||
|
||||
|
||||
void check_entity_decl(CheckerContext *c, Entity *&e, DeclInfo *d, Type *named_type);
|
||||
void check_const_decl(CheckerContext *c, Entity *&e, Ast *type_expr, Ast *init_expr, Type *named_type);
|
||||
void check_type_decl(CheckerContext *c, Entity *e, Ast *type_expr, Type *def);
|
||||
|
||||
bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global = false);
|
||||
void check_collect_entities(CheckerContext *c, Slice<Ast *> const &nodes);
|
||||
void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws);
|
||||
|
||||
@@ -33,39 +33,41 @@ String const entity_strings[] = {
|
||||
};
|
||||
|
||||
enum EntityFlag : u64 {
|
||||
EntityFlag_Visited = 1<<0,
|
||||
EntityFlag_Used = 1<<1,
|
||||
EntityFlag_Using = 1<<2,
|
||||
EntityFlag_Field = 1<<3,
|
||||
EntityFlag_Param = 1<<4,
|
||||
EntityFlag_Result = 1<<5,
|
||||
EntityFlag_ArrayElem = 1<<6,
|
||||
EntityFlag_Ellipsis = 1<<7,
|
||||
EntityFlag_NoAlias = 1<<8,
|
||||
EntityFlag_TypeField = 1<<9,
|
||||
EntityFlag_Value = 1<<10,
|
||||
EntityFlag_Sret = 1<<11,
|
||||
EntityFlag_ByVal = 1<<12,
|
||||
EntityFlag_BitFieldValue = 1<<13,
|
||||
EntityFlag_PolyConst = 1<<14,
|
||||
EntityFlag_NotExported = 1<<15,
|
||||
EntityFlag_ConstInput = 1<<16,
|
||||
EntityFlag_Visited = 1ull<<0,
|
||||
EntityFlag_Used = 1ull<<1,
|
||||
EntityFlag_Using = 1ull<<2,
|
||||
EntityFlag_Field = 1ull<<3,
|
||||
EntityFlag_Param = 1ull<<4,
|
||||
EntityFlag_Result = 1ull<<5,
|
||||
EntityFlag_ArrayElem = 1ull<<6,
|
||||
EntityFlag_Ellipsis = 1ull<<7,
|
||||
EntityFlag_NoAlias = 1ull<<8,
|
||||
EntityFlag_TypeField = 1ull<<9,
|
||||
EntityFlag_Value = 1ull<<10,
|
||||
EntityFlag_Sret = 1ull<<11,
|
||||
EntityFlag_ByVal = 1ull<<12,
|
||||
EntityFlag_BitFieldValue = 1ull<<13,
|
||||
EntityFlag_PolyConst = 1ull<<14,
|
||||
EntityFlag_NotExported = 1ull<<15,
|
||||
EntityFlag_ConstInput = 1ull<<16,
|
||||
|
||||
EntityFlag_Static = 1<<17,
|
||||
EntityFlag_Static = 1ull<<17,
|
||||
|
||||
EntityFlag_ImplicitReference = 1<<18, // NOTE(bill): equivalent to `const &` in C++
|
||||
EntityFlag_ImplicitReference = 1ull<<18, // NOTE(bill): equivalent to `const &` in C++
|
||||
|
||||
EntityFlag_SoaPtrField = 1<<19, // to allow s.x[0] where `s.x` is a pointer rather than a slice
|
||||
EntityFlag_SoaPtrField = 1ull<<19, // to allow s.x[0] where `s.x` is a pointer rather than a slice
|
||||
|
||||
EntityFlag_ProcBodyChecked = 1<<20,
|
||||
EntityFlag_ProcBodyChecked = 1ull<<20,
|
||||
|
||||
EntityFlag_CVarArg = 1<<21,
|
||||
EntityFlag_AutoCast = 1<<22,
|
||||
EntityFlag_CVarArg = 1ull<<21,
|
||||
EntityFlag_AutoCast = 1ull<<22,
|
||||
|
||||
EntityFlag_Disabled = 1<<24,
|
||||
EntityFlag_Cold = 1<<25, // procedure is rarely called
|
||||
EntityFlag_Disabled = 1ull<<24,
|
||||
EntityFlag_Cold = 1ull<<25, // procedure is rarely called
|
||||
|
||||
EntityFlag_Test = 1<<30,
|
||||
EntityFlag_Test = 1ull<<30,
|
||||
|
||||
EntityFlag_Overridden = 1ull<<63,
|
||||
|
||||
};
|
||||
|
||||
@@ -125,6 +127,9 @@ struct Entity {
|
||||
// IMPORTANT NOTE(bill): This must be a discriminated union because of patching
|
||||
// later entity kinds
|
||||
union {
|
||||
struct {
|
||||
u8 start;
|
||||
} Dummy;
|
||||
struct {
|
||||
ExactValue value;
|
||||
ParameterValue param_value;
|
||||
|
||||
Reference in New Issue
Block a user