mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Testing for the presence of methods at the top level is prohibited previous to method registration.
This commit is contained in:
@@ -178,7 +178,7 @@ static inline bool sema_create_const_min(Expr *expr, Type *type, Type *flat);
|
||||
static inline bool sema_create_const_max(Expr *expr, Type *type, Type *flat);
|
||||
static inline bool sema_create_const_params(Expr *expr, Type *type);
|
||||
static inline void sema_create_const_membersof(Expr *expr, Type *type, AlignSize alignment, AlignSize offset);
|
||||
static inline void sema_create_const_methodsof(Expr *expr, Type *type);
|
||||
static inline bool sema_create_const_methodsof(SemaContext *context, Expr *expr, Type *type);
|
||||
|
||||
static inline bool expr_both_any_integer_or_integer_bool_vector(Expr *left, Expr *right);
|
||||
static inline bool expr_both_const_foldable(Expr *left, Expr *right, BinaryOp op);
|
||||
@@ -5055,7 +5055,14 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp
|
||||
}
|
||||
if (!member)
|
||||
{
|
||||
if (missing_ref) goto MISSING_REF;
|
||||
if (missing_ref)
|
||||
{
|
||||
if (decl->unit->module->stage < ANALYSIS_POST_REGISTER)
|
||||
{
|
||||
RETURN_SEMA_ERROR(expr, "There might be a method '%s' for %s, but methods for the type have not yet been completely registered, so this yields an error.", name, type_quoted_error_string(parent_type));
|
||||
}
|
||||
goto MISSING_REF;
|
||||
}
|
||||
RETURN_SEMA_ERROR(expr, "No method or inner struct/union '%s.%s' found.", type_to_error_string(decl->type), name);
|
||||
}
|
||||
if (!member->unit)
|
||||
@@ -5532,13 +5539,17 @@ static inline void append_extension_methods(Type *type, Decl **extensions, Expr
|
||||
}
|
||||
}
|
||||
|
||||
static inline void sema_create_const_methodsof(Expr *expr, Type *type)
|
||||
static inline bool sema_create_const_methodsof(SemaContext *context, Expr *expr, Type *type)
|
||||
{
|
||||
Expr **method_exprs = NULL;
|
||||
CONTINUE:
|
||||
if (type_is_user_defined(type))
|
||||
{
|
||||
Decl *decl = type->decl;
|
||||
if (!decl->unit || decl->unit->module->stage < ANALYSIS_POST_REGISTER)
|
||||
{
|
||||
RETURN_SEMA_ERROR(expr, "Methods are not fully determined for %s at this point.", decl->name);
|
||||
}
|
||||
// Interface, prefer interface methods.
|
||||
if (decl->decl_kind == DECL_INTERFACE)
|
||||
{
|
||||
@@ -5555,6 +5566,7 @@ CONTINUE:
|
||||
type = type_find_parent_type(type);
|
||||
if (type) goto CONTINUE;
|
||||
expr_rewrite_const_untyped_list(expr, method_exprs);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -6033,8 +6045,7 @@ static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr,
|
||||
return true;
|
||||
}
|
||||
case TYPE_PROPERTY_METHODSOF:
|
||||
sema_create_const_methodsof(expr, type);
|
||||
return true;
|
||||
return sema_create_const_methodsof(context, expr, type);
|
||||
case TYPE_PROPERTY_PARAMSOF:
|
||||
return sema_create_const_paramsof(expr, flat);
|
||||
case TYPE_PROPERTY_PARAMS:
|
||||
@@ -6563,10 +6574,16 @@ CHECK_DEEPER:
|
||||
if (missing_ref) goto MISSING_REF;
|
||||
RETURN_SEMA_ERROR(expr, "The method '%s' has private visibility.", kw);
|
||||
}
|
||||
if (parent->type->canonical->type_kind == TYPE_INTERFACE)
|
||||
Type *parent_type = parent->type->canonical;
|
||||
ASSERT(type_is_user_defined(parent_type));
|
||||
if (missing_ref && parent_type->decl->unit->module->stage < ANALYSIS_POST_REGISTER)
|
||||
{
|
||||
RETURN_SEMA_ERROR(expr, "There might be a method '%s' for %s, but methods have not yet been completely registered, so analysis fails.", kw, type_quoted_error_string(parent->type));
|
||||
}
|
||||
if (parent_type->type_kind == TYPE_INTERFACE)
|
||||
{
|
||||
if (missing_ref) goto MISSING_REF;
|
||||
RETURN_SEMA_ERROR(expr, "The '%s' interface has no method '%s', did you spell it correctly?", parent->type->canonical->name, kw);
|
||||
RETURN_SEMA_ERROR(expr, "The '%s' interface has no method '%s', did you spell it correctly?", parent_type->name, kw);
|
||||
}
|
||||
if (missing_ref) goto MISSING_REF;
|
||||
RETURN_SEMA_ERROR(expr, "There is no field or method '%s.%s'.", type_to_error_string(parent->type), kw);
|
||||
|
||||
Reference in New Issue
Block a user