diff --git a/lib/std/core/mem.c3 b/lib/std/core/mem.c3 index c5d45dd42..45140b479 100644 --- a/lib/std/core/mem.c3 +++ b/lib/std/core/mem.c3 @@ -88,7 +88,7 @@ struct Allocator AllocatorFunction function; } -macro malloc($Type) +macro malloc($Type) @builtin { return ($Type*)(mem::alloc($Type.sizeof)); } @@ -147,7 +147,7 @@ fn void*! realloc_checked(void *ptr, usize new_size, usize alignment = 0) return thread_allocator.realloc(ptr, new_size, alignment); } -fn void free(void* ptr) +fn void free(void* ptr) @builtin { return thread_allocator.free(ptr)!!; } diff --git a/lib/std/array.c3 b/lib/std/core/mem_array.c3 similarity index 62% rename from lib/std/array.c3 rename to lib/std/core/mem_array.c3 index 558444cef..45e928fc3 100644 --- a/lib/std/array.c3 +++ b/lib/std/core/mem_array.c3 @@ -1,23 +1,22 @@ // Copyright (c) 2021 Christoffer Lerno. All rights reserved. // Use of this source code is governed by the MIT license // a copy of which can be found in the LICENSE_STDLIB file. -module std::array; +module std::core::mem::array; /** - * @require elements > 0 + * @require usize.typeid.max / elements > $Type.sizeof **/ macro alloc($Type, usize elements) { $Type* ptr = mem::alloc($Type.sizeof * elements, $alignof($Type)); - return ptr[0..(elements - 1)]; + return ptr[:elements]; } /** - * @require elements > 0 + * @require (usize.typeid.max / elements > $Type.sizeof) **/ -macro calloc($Type, usize elements) +macro make($Type, usize elements) { - assert($Type.max / elements < $Type.sizeof); $Type* ptr = mem::calloc($sizeof($Type) * elements, $alignof($Type)); - return ptr[0..(elements - 1)]; + return ptr[:elements]; } diff --git a/lib/std/core/string.c3 b/lib/std/core/string.c3 index 1eb9c95be..c43c1c250 100644 --- a/lib/std/core/string.c3 +++ b/lib/std/core/string.c3 @@ -253,19 +253,6 @@ fn void String.append_char(String* str, char c) data.chars[data.len++] = c; } -macro bool is_pointer_char_array($Type) -{ - var $Type2 = $Type; - $if ($Type.typeid.kind != TypeKind.POINTER): - return false; - $elif ($Type.typeid.inner.kind != TypeKind.ARRAY): - return false; - $elif ($Type.typeid.inner.inner != char.typeid): - return false; - $else: - return true; - $endif; -} macro void String.append(String* str, value) { @@ -281,9 +268,9 @@ macro void String.append(String* str, value) $case Char32: str.append_char32(value); $default: - $if ($Type.typeid.kind == TypeKind.SIGNED_INT || $Type.typeid.kind == TypeKind.UNSIGNED_INT): - str.append_char32((Char32)value); - $elif (is_pointer_char_array($Type)): + $if ($convertable($Type, Char32)): + str.append_char32(value); + $elif ($convertable($Type, char[])): str.append_chars(value); $else: $assert("Unsupported type for appending"); diff --git a/src/compiler/ast.c b/src/compiler/ast.c index 4b70393c2..0fc0aa089 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -260,6 +260,7 @@ bool expr_is_pure(Expr *expr) case EXPR_PTR: case EXPR_STRINGIFY: case EXPR_RETVAL: + case EXPR_CT_CONV: return true; case EXPR_ARGV_TO_SUBARRAY: case EXPR_BITASSIGN: diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index e9a102014..75b9cb09f 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -792,10 +792,18 @@ typedef struct typedef struct { TokenType token_type; - struct + union { - Expr *main_var; - ExprFlatElement *flat_path; + struct + { + Expr *main_var; + ExprFlatElement *flat_path; + }; + struct + { + TypeInfoId type_from; + TypeInfoId type_to; + }; }; } ExprCtCall; @@ -1613,6 +1621,8 @@ extern const char *kw_min; extern const char *kw_elements; extern const char *kw_align; +extern const char *kw_castable; +extern const char *kw_convertable; extern const char *kw_sizeof; extern const char *kw_in; extern const char *kw_out; @@ -2536,6 +2546,7 @@ const char *arch_to_linker_arch(ArchType arch); #define ASSIGN_EXPR_OR_RET(_assign, _expr_stmt, _res) Expr* TEMP(_expr) = (_expr_stmt); if (!expr_ok(TEMP(_expr))) return _res; _assign = TEMP(_expr) #define ASSIGN_EXPRID_OR_RET(_assign, _expr_stmt, _res) Expr* TEMP(_expr) = (_expr_stmt); if (!expr_ok(TEMP(_expr))) return _res; _assign = exprid(TEMP(_expr)) #define ASSIGN_TYPE_OR_RET(_assign, _type_stmt, _res) TypeInfo* TEMP(_type) = (_type_stmt); if (!type_info_ok(TEMP(_type))) return _res; _assign = TEMP(_type) +#define ASSIGN_TYPEID_OR_RET(_assign, _type_stmt, _res) TypeInfo* TEMP(_type) = (_type_stmt); if (!type_info_ok(TEMP(_type))) return _res; _assign = type_infoid(TEMP(_type)) #define ASSIGN_DECL_OR_RET(_assign, _decl_stmt, _res) Decl* TEMP(_decl) = (_decl_stmt); if (!decl_ok(TEMP(_decl))) return _res; _assign = TEMP(_decl) diff --git a/src/compiler/copying.c b/src/compiler/copying.c index 8e9680e13..525b847cc 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -184,6 +184,10 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr) case EXPR_BUILTIN: case EXPR_RETVAL: return expr; + case EXPR_CT_CONV: + MACRO_COPY_TYPEID(expr->ct_call_expr.type_from); + MACRO_COPY_TYPEID(expr->ct_call_expr.type_to); + return expr; case EXPR_DECL: MACRO_COPY_DECL(expr->decl_expr); return expr; diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 3070a6194..172d58d74 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -210,6 +210,7 @@ typedef enum EXPR_COMPOUND_LITERAL, EXPR_CONST, EXPR_CT_CALL, + EXPR_CT_CONV, EXPR_CT_IDENT, EXPR_CT_EVAL, EXPR_COND, @@ -526,6 +527,8 @@ typedef enum TOKEN_CT_STRINGIFY, // $stringify TOKEN_CT_SWITCH, // $switch TOKEN_CT_TYPEOF, // $typeof + TOKEN_CT_CONVERTABLE, // $convertable + TOKEN_CT_CASTABLE, // $castable TOKEN_DOCS_START, // /** TOKEN_DOCS_END, // */ (may start with an arbitrary number of `*` diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 382d6c9a3..4aa964670 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -5567,6 +5567,7 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr) { case NON_RUNTIME_EXPR: case EXPR_COND: + case EXPR_CT_CONV: UNREACHABLE case EXPR_RETVAL: *value = c->retval; diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index 766cd26a7..b0344a2ac 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -8,7 +8,6 @@ #define IF_TRY_CATCH_PREC (PREC_AND + 1) typedef Expr *(*ParseFn)(ParseContext *context, Expr *); -static Expr *parse_expr_or_type_prec(ParseContext *c, TypeInfo **type_ref, Precedence prec); typedef struct { @@ -83,10 +82,10 @@ static inline Expr *parse_catch_unwrap(ParseContext *c) Expr *expr = expr_new(EXPR_CATCH_UNWRAP, c->span); advance_and_verify(c, TOKEN_CATCH); TypeInfo *type = NULL; - ASSIGN_EXPR_OR_RET(Expr * lhs, parse_expr_or_type_prec(c, &type, IF_TRY_CATCH_PREC), poisoned_expr); - if (!lhs) + ASSIGN_EXPR_OR_RET(Expr * lhs, parse_precedence(c, IF_TRY_CATCH_PREC), poisoned_expr); + if (lhs->expr_kind == EXPR_TYPEINFO) { - ASSIGN_TYPE_OR_RET(expr->catch_unwrap_expr.type, type, poisoned_expr); + expr->catch_unwrap_expr.type = lhs->type_expr; ASSIGN_EXPR_OR_RET(expr->catch_unwrap_expr.variable, parse_precedence(c, IF_TRY_CATCH_PREC), poisoned_expr); } else @@ -131,18 +130,17 @@ static inline Expr *parse_try_unwrap(ParseContext *c) { Expr *expr = EXPR_NEW_TOKEN(EXPR_TRY_UNWRAP); advance_and_verify(c, TOKEN_TRY); - TypeInfo *type = NULL; - ASSIGN_EXPR_OR_RET(Expr * lhs, parse_expr_or_type_prec(c, &type, IF_TRY_CATCH_PREC), poisoned_expr); - if (!lhs) + ASSIGN_EXPR_OR_RET(Expr *lhs, parse_precedence(c, IF_TRY_CATCH_PREC), poisoned_expr); + if (lhs->expr_kind == EXPR_TYPEINFO) { - ASSIGN_TYPE_OR_RET(expr->try_unwrap_expr.type, type, poisoned_expr); + expr->try_unwrap_expr.type = lhs->type_expr; ASSIGN_EXPR_OR_RET(expr->try_unwrap_expr.variable, parse_precedence(c, IF_TRY_CATCH_PREC), poisoned_expr); } else { expr->try_unwrap_expr.variable = lhs; } - if (type && expr->try_unwrap_expr.variable->expr_kind != EXPR_IDENTIFIER) + if (lhs->expr_kind == EXPR_TYPEINFO && expr->try_unwrap_expr.variable->expr_kind != EXPR_IDENTIFIER) { SEMA_ERROR(expr->try_unwrap_expr.variable, "A new variable was expected."); return poisoned_expr; @@ -910,6 +908,21 @@ static Expr *parse_ct_call(ParseContext *c, Expr *left) return expr; } +static Expr *parse_ct_conv(ParseContext *c, Expr *left) +{ + assert(!left && "Unexpected left hand side"); + Expr *expr = EXPR_NEW_TOKEN(EXPR_CT_CONV); + expr->ct_call_expr.token_type = c->tok; + advance(c); + CONSUME_OR_RET(TOKEN_LPAREN, poisoned_expr); + ASSIGN_TYPEID_OR_RET(expr->ct_call_expr.type_from, parse_type(c), poisoned_expr); + TRY_CONSUME_AFTER(TOKEN_COMMA, "Expected ',' here.", poisoned_expr); + ASSIGN_TYPEID_OR_RET(expr->ct_call_expr.type_to, parse_type(c), poisoned_expr); + TRY_CONSUME_AFTER(TOKEN_RPAREN, "Expected ')' here.", poisoned_expr); + RANGE_EXTEND_PREV(expr); + return expr; +} + static Expr *parse_identifier(ParseContext *c, Expr *left) { assert(!left && "Unexpected left hand side"); @@ -926,90 +939,6 @@ static Expr *parse_identifier(ParseContext *c, Expr *left) return expr; } -static Expr *parse_type_or_expression_with_path(ParseContext *c, Path *path, TypeInfo **type_ref) -{ - TypeInfo *type; - if (path) - { - type = type_info_new(TYPE_INFO_IDENTIFIER, path->span); - type->unresolved.path = path; - type->unresolved.name = symstr(c); - advance_and_verify(c, TOKEN_TYPE_IDENT); - RANGE_EXTEND_PREV(type); - ASSIGN_TYPE_OR_RET(type, parse_type_with_base(c, type), poisoned_expr); - type->failable = try_consume(c, TOKEN_BANG); - } - else - { - ASSIGN_TYPE_OR_RET(type, parse_failable_type(c), poisoned_expr); - } - if (tok_is(c, TOKEN_LBRACE)) - { - return parse_type_compound_literal_expr_after_type(c, type); - } - if (tok_is(c, TOKEN_DOT)) - { - Expr *expr = expr_new(EXPR_TYPEINFO, type->span); - expr->type_expr = type; - return parse_access_expr(c, expr); - } - *type_ref = type; - return NULL; -} - - - -static Expr *parse_expr_or_type_prec(ParseContext *c, TypeInfo **type_ref, Precedence prec) -{ - switch (c->tok) - { - case TYPELIKE_TOKENS: - return parse_type_or_expression_with_path(c, NULL, type_ref); - case TOKEN_IDENT: - { - bool had_error; - Path *path = parse_path_prefix(c, &had_error); - if (had_error) return poisoned_expr; - if (!path) return parse_precedence(c, prec); - bool is_const = false; - switch (c->tok) - { - case TOKEN_TYPE_IDENT: - return parse_type_or_expression_with_path(c, path, type_ref); - case TOKEN_CONST_IDENT: - is_const = true; - FALLTHROUGH; - case TOKEN_IDENT: - { - Expr *expr = EXPR_NEW_TOKEN(EXPR_IDENTIFIER); - expr->identifier_expr.ident = symstr(c); - expr->identifier_expr.is_const = is_const; - expr->identifier_expr.path = path; - advance(c); - return parse_precedence_with_left_side(c, expr, prec); - } - case TOKEN_HASH_IDENT: - case TOKEN_HASH_CONST_IDENT: - case TOKEN_HASH_TYPE_IDENT: - case TOKEN_CT_CONST_IDENT: - case TOKEN_CT_IDENT: - case TOKEN_CT_TYPE_IDENT: - SEMA_ERROR_HERE("'%s' cannot be used with paths.", symstr(c)); - return poisoned_expr; - default: - SEMA_ERROR_HERE("An identifier was expected after the path."); - return poisoned_expr; - } - } - default: - return parse_precedence(c, prec); - } -} - -Expr *parse_expr_or_type(ParseContext *c, TypeInfo **type_ref) -{ - return parse_expr_or_type_prec(c, type_ref, PREC_ASSIGNMENT); -} static Expr *parse_identifier_starting_expression(ParseContext *c, Expr *left) { @@ -1795,5 +1724,7 @@ ParseRule rules[TOKEN_EOF + 1] = { [TOKEN_CT_TYPEOF] = { parse_type_expr, NULL, PREC_NONE }, [TOKEN_CT_STRINGIFY] = { parse_ct_stringify, NULL, PREC_NONE }, [TOKEN_CT_EVALTYPE] = { parse_type_expr, NULL, PREC_NONE }, + [TOKEN_CT_CONVERTABLE] = { parse_ct_conv, NULL, PREC_NONE }, + [TOKEN_CT_CASTABLE] = { parse_ct_conv, NULL, PREC_NONE }, [TOKEN_LBRACE] = { parse_initializer_list, NULL, PREC_NONE }, }; diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index ee789181a..38525d0a4 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -788,9 +788,9 @@ Decl *parse_decl(ParseContext *c) Expr *parse_decl_or_expr(ParseContext *c, Decl **decl_ref) { TypeInfo *type_info; - Expr *expr = parse_expr_or_type(c, &type_info); - if (expr) return expr; - ASSIGN_DECL_OR_RET(*decl_ref, parse_decl_after_type(c, type_info), poisoned_expr); + Expr *expr = parse_expr(c); + if (expr->expr_kind != EXPR_TYPEINFO) return expr; + ASSIGN_DECL_OR_RET(*decl_ref, parse_decl_after_type(c, expr->type_expr), poisoned_expr); return NULL; } diff --git a/src/compiler/parse_stmt.c b/src/compiler/parse_stmt.c index 89e40e9e3..6b24aad70 100644 --- a/src/compiler/parse_stmt.c +++ b/src/compiler/parse_stmt.c @@ -1034,6 +1034,8 @@ Ast *parse_stmt(ParseContext *c) case TOKEN_RVEC: case TOKEN_CT_ENDFOR: case TOKEN_CT_ENDFOREACH: + case TOKEN_CT_CASTABLE: + case TOKEN_CT_CONVERTABLE: SEMA_ERROR_HERE("Unexpected '%s' found when expecting a statement.", token_type_to_string(c->tok)); advance(c); diff --git a/src/compiler/parser_internal.h b/src/compiler/parser_internal.h index 77a479dde..2a324f6d2 100644 --- a/src/compiler/parser_internal.h +++ b/src/compiler/parser_internal.h @@ -53,7 +53,6 @@ bool try_consume(ParseContext *c, TokenType type); bool consume(ParseContext *c, TokenType type, const char *message, ...); bool consume_const_name(ParseContext *c, const char* type); Expr *parse_precedence_with_left_side(ParseContext *c, Expr *left_side, Precedence precedence); -Expr *parse_expr_or_type(ParseContext *c, TypeInfo **type_ref); INLINE const char *symstr(ParseContext *c) { diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index e26ee5e4b..f5df18d55 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -837,6 +837,7 @@ Expr *recursive_may_narrow_float(Expr *expr, Type *type) case EXPR_STRINGIFY: case EXPR_CT_EVAL: case EXPR_VARIANT: + case EXPR_CT_CONV: UNREACHABLE case EXPR_POST_UNARY: return recursive_may_narrow_float(expr->unary_expr.expr, type); @@ -991,6 +992,7 @@ Expr *recursive_may_narrow_int(Expr *expr, Type *type) case EXPR_STRINGIFY: case EXPR_CT_EVAL: case EXPR_VARIANT: + case EXPR_CT_CONV: UNREACHABLE case EXPR_POST_UNARY: return recursive_may_narrow_int(expr->unary_expr.expr, type); diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 41dea472a..b228ba113 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -315,6 +315,8 @@ bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind) RETRY: switch (expr->expr_kind) { + case EXPR_CT_CONV: + return true; case EXPR_RETVAL: return false; case EXPR_BUILTIN: @@ -3820,7 +3822,7 @@ static Decl *sema_resolve_element_for_name(Decl** decls, DesignatorElement **ele static MemberIndex sema_analyse_designator_index(SemaContext *context, Expr *index) { - if (!sema_analyse_expr_lvalue(context, index)) + if (!sema_analyse_expr(context, index)) { return -1; } @@ -7296,6 +7298,42 @@ static inline bool sema_expr_analyse_ct_call(SemaContext *context, Expr *expr) } } +static inline bool sema_expr_analyse_ct_conv(SemaContext *c, Expr *expr) +{ + TypeInfo *from = type_infoptr(expr->ct_call_expr.type_from); + TypeInfo *to = type_infoptr(expr->ct_call_expr.type_to); + if (!sema_resolve_type_info(c, from)) return false; + if (!sema_resolve_type_info(c, to)) return false; + Type *from_type = from->type; + Type *to_type = to->type; + if (IS_FAILABLE(from)) + { + SEMA_ERROR(from, "Only non-optional types can be checked."); + return false; + } + if (IS_FAILABLE(to)) + { + SEMA_ERROR(to, "Only non-optional types can be checked."); + return false; + } + bool result; + switch (expr->ct_call_expr.token_type) + { + case TOKEN_CT_CONVERTABLE: + result = cast_may_implicit(from_type, to_type, true, false); + break; + case TOKEN_CT_CASTABLE: + result = cast_may_explicit(from_type, to_type, true, false); + break; + default: + UNREACHABLE + } + expr_const_set_bool(&expr->const_expr, result); + expr->type = type_bool; + expr->expr_kind = EXPR_CONST; + return true; +} + static inline BuiltinFunction builtin_by_name(const char *name) { @@ -7375,6 +7413,8 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr) return sema_expr_analyse_retval(context, expr); case EXPR_BUILTIN: return sema_expr_analyse_builtin(context, expr, true); + case EXPR_CT_CONV: + return sema_expr_analyse_ct_conv(context, expr); case EXPR_CT_CALL: return sema_expr_analyse_ct_call(context, expr); case EXPR_HASH_IDENT: diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index e83f4970a..157e47e1f 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -27,7 +27,6 @@ bool sema_resolve_type_info(SemaContext *context, TypeInfo *type_info) } - void context_change_scope_with_flags(SemaContext *context, ScopeFlags flags) { unsigned depth = context->active_scope.depth + 1; diff --git a/src/compiler/symtab.c b/src/compiler/symtab.c index 16a4126ec..bd1e95e8f 100644 --- a/src/compiler/symtab.c +++ b/src/compiler/symtab.c @@ -43,6 +43,8 @@ const char *kw_std__core; const char *kw_std__core__types; const char *kw_typekind; +const char *kw_castable; +const char *kw_convertable; const char *kw_in; const char *kw_out; const char *kw_inout; diff --git a/src/compiler/tokens.c b/src/compiler/tokens.c index ef6763a05..573960b37 100644 --- a/src/compiler/tokens.c +++ b/src/compiler/tokens.c @@ -374,6 +374,10 @@ const char *token_type_to_string(TokenType type) return "$switch"; case TOKEN_CT_TYPEOF: return "$typeof"; + case TOKEN_CT_CONVERTABLE: + return "$convertable"; + case TOKEN_CT_CASTABLE: + return "$castable"; case TOKEN_CT_STRINGIFY: return "$stringify"; case TOKEN_EOF: diff --git a/src/version.h b/src/version.h index 23edb169b..21ededcee 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.2.22" \ No newline at end of file +#define COMPILER_VERSION "0.2.23" \ No newline at end of file diff --git a/test/test_suite/arrays/global_array_non_const.c3 b/test/test_suite/arrays/global_array_non_const.c3 index 7f6512ea8..a0803aaa4 100644 --- a/test/test_suite/arrays/global_array_non_const.c3 +++ b/test/test_suite/arrays/global_array_non_const.c3 @@ -1,7 +1,7 @@ const int CONSTANT = 1; int[CONSTANT] a2; - +int[3] a3 = { [CONSTANT] = 1 }; const bool B = true; int[B] c2; // #error: Expected an integer size. diff --git a/test/test_suite/errors/try_with_weird_stuff.c3 b/test/test_suite/errors/try_with_weird_stuff.c3 index 0561652e0..2cf0bdf0f 100644 --- a/test/test_suite/errors/try_with_weird_stuff.c3 +++ b/test/test_suite/errors/try_with_weird_stuff.c3 @@ -4,7 +4,7 @@ fn void test1() int! a; int b; int*! x; - if (try int &a = a) {} // #error: A new variable was expected. + if (try int 1 = a) {} // #error: A new variable was expected. } fn void test2() diff --git a/test/test_suite2/arrays/global_array_non_const.c3 b/test/test_suite2/arrays/global_array_non_const.c3 index 7f6512ea8..a0803aaa4 100644 --- a/test/test_suite2/arrays/global_array_non_const.c3 +++ b/test/test_suite2/arrays/global_array_non_const.c3 @@ -1,7 +1,7 @@ const int CONSTANT = 1; int[CONSTANT] a2; - +int[3] a3 = { [CONSTANT] = 1 }; const bool B = true; int[B] c2; // #error: Expected an integer size. diff --git a/test/test_suite2/errors/try_with_weird_stuff.c3 b/test/test_suite2/errors/try_with_weird_stuff.c3 index 0561652e0..2cf0bdf0f 100644 --- a/test/test_suite2/errors/try_with_weird_stuff.c3 +++ b/test/test_suite2/errors/try_with_weird_stuff.c3 @@ -4,7 +4,7 @@ fn void test1() int! a; int b; int*! x; - if (try int &a = a) {} // #error: A new variable was expected. + if (try int 1 = a) {} // #error: A new variable was expected. } fn void test2()