diff --git a/lib/std/core/builtin.c3 b/lib/std/core/builtin.c3 index 84a0c2536..e09a55c10 100644 --- a/lib/std/core/builtin.c3 +++ b/lib/std/core/builtin.c3 @@ -108,6 +108,25 @@ macro anycast(any v, $Type) @builtin return ($Type*)v.ptr; } +<* + @return "The value in the pointer" + @return? TYPE_MISMATCH +*> +macro any.as(self, $Type) +{ + if (self.type != $Type.typeid) return TYPE_MISMATCH?; + return *($Type*)self.ptr; +} + +<* + @require self.type == $Type : "The 'any' contained an unexpected type." + @return "The value in the pointer" +*> +macro any.to(self, $Type) +{ + return *($Type*)self.ptr; +} + macro bool @assignable_to(#foo, $Type) @const @builtin @deprecated("use '$defined($Type x = #foo)'") => $defined(*&&($Type){} = #foo); macro @addr(#val) @builtin diff --git a/releasenotes.md b/releasenotes.md index bb9ff7e9e..8d81705df 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -21,6 +21,7 @@ - `@if($defined((char*){}.foo()))` does not error if `foo` is missing. - Hard limit of 127 characters for identifiers. - `$$LINE` would sometimes incorrectly be constant. +- Fix error message when a method has the wrong type for the first argument. ### Stdlib changes - Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads. @@ -33,6 +34,7 @@ - Return of Thread `join()` is now "@maydiscard". - Add `poly1305` one-time Message Authentication Code and associated tests. #2639 - Add `Elf32_Shdr` and `Elf64_Shdr` to `std::os::linux`. +- Add `any.to` and `any.as`. ## 0.7.8 Change list diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index bed9be8a2..856866fb8 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -1235,7 +1235,7 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig, inferred_type = method_parent->type; break; case VARDECL_PARAM_CT_TYPE: - RETURN_SEMA_ERROR(param, "Expected a parameter of type %s here.", method_parent->type); + RETURN_SEMA_ERROR(param, "Expected a parameter of type %s here.", type_quoted_error_string(method_parent->type)); default: UNREACHABLE } @@ -5510,12 +5510,10 @@ bool sema_analyse_method_register(SemaContext *context, Decl *method) bool sema_analyse_decl(SemaContext *context, Decl *decl) { if (decl->resolve_status == RESOLVE_DONE) return decl_ok(decl); - DEBUG_LOG(">>> Analyse declaration [%s] in %s.", decl_safe_name(decl), context_filename(context)); SemaContext temp_context; context = context_transform_for_eval(context, &temp_context, decl->unit); - if (decl->resolve_status == RESOLVE_RUNNING) { SEMA_ERROR(decl, decl->name @@ -5595,7 +5593,6 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl) sema_context_destroy(&temp_context); DEBUG_LOG("<<< Analysis of [%s] successful.", decl_safe_name(decl)); - return true; FAILED: sema_context_destroy(&temp_context); diff --git a/test/unit/regression/any.c3 b/test/unit/regression/any.c3 index 6050070f9..afa3b39da 100644 --- a/test/unit/regression/any.c3 +++ b/test/unit/regression/any.c3 @@ -11,6 +11,14 @@ fn void any_compare() alias AnyAlias = any; +fn void any_to_as() +{ + int x = 3; + any a = &x; + test::eq(a.to(int), 3); + test::eq(a.as(int)!!, 3); +} + fn void test_aliasing() { int x;