Alias and distinct types didn't check the underlying type wasn't compile time or optional.

This commit is contained in:
Christoffer Lerno
2025-09-19 18:05:29 +02:00
parent 59fd777198
commit b03ae8bb17
4 changed files with 50 additions and 4 deletions

View File

@@ -34,6 +34,7 @@
- Fix compile time format check when the formatting string is a constant slice.
- Compiler segfault for invalid e-mails in project.json. #2488
- Taking `.ordinal` from an enum passed by pointer and then taking the address of this result would return the enum, not int.
- Alias and distinct types didn't check the underlying type wasn't compile time or optional.
### Stdlib changes
- Added generic `InterfaceList` to store a list of values that implement a specific interface

View File

@@ -1910,7 +1910,7 @@ static inline Decl *parse_typedef_declaration(ParseContext *c)
return poisoned_decl;
}
// 2. Now parse the type which we know is here.
ASSIGN_TYPE_OR_RET(decl->distinct, parse_type(c), poisoned_decl);
ASSIGN_TYPE_OR_RET(decl->distinct, parse_optional_type(c), poisoned_decl);
ASSERT(!tok_is(c, TOKEN_LBRACE));

View File

@@ -41,7 +41,7 @@ static bool sema_analyse_attributes_for_var(SemaContext *context, Decl *decl, bo
static bool sema_check_section(SemaContext *context, Attr *attr);
static inline bool sema_analyse_attribute_decl(SemaContext *context, SemaContext *c, Decl *decl, bool *erase_decl);
static inline bool sema_analyse_typedef(SemaContext *context, Decl *decl, bool *erase_decl);
static inline bool sema_analyse_type_alias(SemaContext *context, Decl *decl, bool *erase_decl);
static bool sema_analyse_variable_type(SemaContext *context, Type *type, SourceSpan span);
static inline bool sema_analyse_alias(SemaContext *context, Decl *decl, bool *erase_decl);
static inline bool sema_analyse_distinct(SemaContext *context, Decl *decl, bool *erase_decl);
@@ -1460,7 +1460,7 @@ static inline bool sema_analyse_fntype(SemaContext *context, Decl *decl, bool *e
return sema_analyse_function_signature(context, decl, NULL, sig->abi, sig);
}
static inline bool sema_analyse_typedef(SemaContext *context, Decl *decl, bool *erase_decl)
static inline bool sema_analyse_type_alias(SemaContext *context, Decl *decl, bool *erase_decl)
{
if (!sema_analyse_attributes(context, decl, decl->attributes, ATTR_ALIAS, erase_decl)) return decl_poison(decl);
if (*erase_decl) return true;
@@ -1478,6 +1478,24 @@ static inline bool sema_analyse_typedef(SemaContext *context, Decl *decl, bool *
TypeInfo *info = decl->type_alias_decl.type_info;
info->in_def = true;
if (!sema_resolve_type_info(context, info, RESOLVE_TYPE_DEFAULT)) return false;
if (type_is_optional(info->type))
{
RETURN_SEMA_ERROR(info, "You cannot create an alias for an optional type like %s.", type_quoted_error_string(info->type));
}
switch (sema_resolve_storage_type(context, info->type))
{
case STORAGE_ERROR:
return false;
case STORAGE_NORMAL:
case STORAGE_UNKNOWN:
case STORAGE_VOID:
break;
case STORAGE_WILDCARD:
RETURN_SEMA_ERROR(info, "You cannot create an alias for the wildcard type.");
case STORAGE_COMPILE_TIME:
RETURN_SEMA_ERROR(info, "You cannot create an alias for %s as it is a compile time type.",
type_invalid_storage_type_name(info->type));
}
decl->type->canonical = info->type->canonical;
// Do we need anything else?
return true;
@@ -1504,6 +1522,20 @@ static inline bool sema_analyse_distinct(SemaContext *context, Decl *decl, bool
// Optional isn't allowed of course.
if (type_is_optional(info->type)) RETURN_SEMA_ERROR(decl, "You cannot create a distinct type from an optional.");
switch (sema_resolve_storage_type(context, info->type))
{
case STORAGE_ERROR:
return false;
case STORAGE_NORMAL:
case STORAGE_UNKNOWN:
case STORAGE_VOID:
break;
case STORAGE_WILDCARD:
RETURN_SEMA_ERROR(info, "You cannot create a distinct type from the wildcard type.");
case STORAGE_COMPILE_TIME:
RETURN_SEMA_ERROR(info, "You cannot create a distinct type for %s as it is a compile time type.",
type_invalid_storage_type_name(info->type));
}
// Distinct types drop the canonical part.
info->type = info->type->canonical;
@@ -5386,7 +5418,7 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl)
if (!sema_analyse_distinct(context, decl, &erase_decl)) goto FAILED;
break;
case DECL_TYPEDEF:
if (!sema_analyse_typedef(context, decl, &erase_decl)) goto FAILED;
if (!sema_analyse_type_alias(context, decl, &erase_decl)) goto FAILED;
break;
case DECL_ENUM:
if (!sema_analyse_enum(context, decl, &erase_decl)) goto FAILED;

View File

@@ -0,0 +1,13 @@
module test;
import std;
struct Foo { struct x { int a; } }
alias Floo = $typeof(Foo.x); // #error: You cannot create an alias for a member reference as it is a compile time type
alias Void = void?; // #error: You cannot create an alias for an optional type
typedef Floo2 = $typeof(Foo.x); // #error: You cannot create a distinct type for a member reference
typedef Void2 = void?; // #error: You cannot create a distinct type from
fn void main()
{
}