From 6c5acbd92f49378e075d5a87a3054a4b27e60177 Mon Sep 17 00:00:00 2001 From: ergl Date: Wed, 5 May 2021 14:17:09 +0200 Subject: [PATCH] Improve error message on destructuring of non-tuple types --- .release-notes/3753.md | 41 ++++++++++++++++++++++++++++++++++++ src/libponyc/expr/operator.c | 4 ++++ 2 files changed, 45 insertions(+) create mode 100644 .release-notes/3753.md diff --git a/.release-notes/3753.md b/.release-notes/3753.md new file mode 100644 index 0000000000..3be1efdaa9 --- /dev/null +++ b/.release-notes/3753.md @@ -0,0 +1,41 @@ +## Improve error message when attempting to destructure non-tuple types + +Sometimes, the compiler will infer that the return type of an expression is an union or an intersection of multiple types. If the user tries to destructure such result into a tuple, the compiler will emit an error, but it won't show the user what the inferred type is. This could be confusing to users, as they wouldn't know what went wrong with the code, unless they added explicit type annotations to the assigned variables. + +Starting with this release, the compiler will now show what the inferred type is, so that the user can spot the problem without needing to explicitly annotate their code. + +As an example, the following piece of Pony code: + +```pony +actor Main + new create(env: Env) => + (let str, let size) = + if true then + let str' = String(5) .> append("hello") + (str', USize(5)) + else + ("world", USize(5)) + end +``` + +would fail to compile on previous releases with the following error message: + +``` +Error: +main.pony:3:25: can't destructure a union using assignment, use pattern matching instead + (let str, let size) = + ^ +``` + +Starting with this release, the error message will show the inferred type of the expression: + +``` +Error: +main.pony:3:25: can't destructure a union using assignment, use pattern matching instead + (let str, let size) = + ^ + Info: + main.pony:4:7: inferred type of expression: ((String ref, USize val^) | (String val, USize val^)) + if true then + ^ +``` diff --git a/src/libponyc/expr/operator.c b/src/libponyc/expr/operator.c index 732272cc36..04aa8698f7 100644 --- a/src/libponyc/expr/operator.c +++ b/src/libponyc/expr/operator.c @@ -389,12 +389,16 @@ bool expr_assign(pass_opt_t* opt, ast_t* ast) ast_error(opt->check.errors, ast, "can't destructure a union using assignment, use pattern matching " "instead"); + ast_error_continue(opt->check.errors, right, + "inferred type of expression: %s", ast_print_type(r_type)); break; case TK_ISECTTYPE: ast_error(opt->check.errors, ast, "can't destructure an intersection using assignment, use pattern " "matching instead"); + ast_error_continue(opt->check.errors, right, + "inferred type of expression: %s", ast_print_type(r_type)); break; default: