- Passing a compile time type implicitly converted to a typeid would crash instead of producing an error. #2568

This commit is contained in:
Christoffer Lerno
2025-11-08 22:17:58 +01:00
parent 7063e684ba
commit 0da6bf4455
5 changed files with 25 additions and 8 deletions

View File

@@ -532,7 +532,8 @@ fn bool List.remove_first_item(&self, Type value) @if(ELEMENT_IS_EQUATABLE)
fn usz List.remove_item(&self, Type value) @if(ELEMENT_IS_EQUATABLE) fn usz List.remove_item(&self, Type value) @if(ELEMENT_IS_EQUATABLE)
{ {
usz old_size = self.size; usz old_size = self.size;
defer { defer
{
if (old_size != self.size) self._update_size_change(old_size, self.size); if (old_size != self.size) self._update_size_change(old_size, self.size);
} }
return list_common::list_remove_item(self, value); return list_common::list_remove_item(self, value);

View File

@@ -16,6 +16,7 @@
- Fix fmod `a %= 0f`. - Fix fmod `a %= 0f`.
- Regression vector ABI: initializing a struct containing a NPOT vector with a constant value would crash LLVM. #2559 - Regression vector ABI: initializing a struct containing a NPOT vector with a constant value would crash LLVM. #2559
- Error message with hashmap shows "mangled" name instead of original #2562. - Error message with hashmap shows "mangled" name instead of original #2562.
- Passing a compile time type implicitly converted to a typeid would crash instead of producing an error. #2568
### Stdlib changes ### Stdlib changes

View File

@@ -4183,6 +4183,7 @@ INLINE void expr_rewrite_const_slice(Expr *expr, Type *type, ConstInitializer *i
INLINE void expr_rewrite_const_typeid(Expr *expr, Type *type) INLINE void expr_rewrite_const_typeid(Expr *expr, Type *type)
{ {
ASSERT(type->type_kind != TYPE_UNTYPED_LIST);
expr->expr_kind = EXPR_CONST; expr->expr_kind = EXPR_CONST;
expr->const_expr.const_kind = CONST_TYPEID; expr->const_expr.const_kind = CONST_TYPEID;
expr->const_expr.typeid = type->canonical; expr->const_expr.typeid = type->canonical;

View File

@@ -6103,11 +6103,7 @@ static inline bool sema_expr_analyse_access(SemaContext *context, Expr *expr, bo
case CT_TYPES: case CT_TYPES:
RETURN_SEMA_ERROR(parent, "You cannot take the typeid of a compile time type."); RETURN_SEMA_ERROR(parent, "You cannot take the typeid of a compile time type.");
default: default:
expr->type = type_typeid; expr_rewrite_const_typeid(expr, parent->type_expr->type->canonical);
expr->expr_kind = EXPR_CONST;
expr->const_expr.const_kind = CONST_TYPEID;
expr->const_expr.typeid = parent->type_expr->type->canonical;
expr->resolve_status = RESOLVE_DONE;
return true; return true;
} }
UNREACHABLE UNREACHABLE
@@ -11737,8 +11733,15 @@ static inline bool sema_cast_rvalue(SemaContext *context, Expr *expr, bool mutat
if (mutate) sema_expr_flatten_const_ident(expr->access_resolved_expr.parent); if (mutate) sema_expr_flatten_const_ident(expr->access_resolved_expr.parent);
return true; return true;
case EXPR_TYPEINFO: case EXPR_TYPEINFO:
expr_rewrite_const_typeid(expr, expr->type_expr->type); switch (expr->type_expr->type->type_kind)
return true; {
case CT_TYPES:
RETURN_SEMA_ERROR(expr, "You cannot take the typeid of a compile time type.");
default:
expr_rewrite_const_typeid(expr, expr->type_expr->type);
return true;
}
UNREACHABLE
case EXPR_CT_IDENT: case EXPR_CT_IDENT:
if (mutate && !sema_cast_ct_ident_rvalue(context, expr)) return false; if (mutate && !sema_cast_ct_ident_rvalue(context, expr)) return false;
break; break;

View File

@@ -0,0 +1,11 @@
module test;
import std;
macro test(x)
{
var $Type = $typeof(x);
}
fn int main()
{
test($typeof({})); // #error: You cannot take the typeid of a compile time type
return 0;
}