fix: enforce the try rule at every position
SPEC.md allows `try` only inside a function returning an error union, but the check sat in the FE_N_EXPR_STMT case, so it only ever saw a bare `try e;` and walked past `var x = try e;` and `x = try e;`. Move it onto the try expression in check_expr and drop the statement-level copy. This could not land before M7: closing the hole forces m5/runtime.fe's `run` to return an error union, and value returns from `-> !T` need contextual success construction. That arrives with M7, and `run` is now `-> !i32`, so the rule can be enforced. Supersedes the SPEC.AUDIT.md entry that recorded the blockage. M1-M7: 183 passed.
This commit is contained in:
+8
-4
@@ -871,6 +871,12 @@ static FeType *check_expr(FeCheckerState *s, FeNode *n)
|
|||||||
if (known(a) && !fe_type_is_integer(a))
|
if (known(a) && !fe_type_is_integer(a))
|
||||||
err(c, n->loc, "unary '-' requires integer");
|
err(c, n->loc, "unary '-' requires integer");
|
||||||
} else if (strcmp(op, "try") == 0) {
|
} else if (strcmp(op, "try") == 0) {
|
||||||
|
/* SPEC 6.4: try is only allowed inside a function returning an error
|
||||||
|
union. Checked on the expression rather than on the statement so
|
||||||
|
that it also covers `var x = try e;` and `x = try e;`, which the
|
||||||
|
statement-level check walked straight past. */
|
||||||
|
if (!s->ret || s->ret->kind != FE_TYPE_ERROR_UNION)
|
||||||
|
err(c,n->loc,"try requires an enclosing error result");
|
||||||
if (a && a->kind==FE_TYPE_ERROR_UNION)
|
if (a && a->kind==FE_TYPE_ERROR_UNION)
|
||||||
a=a->error_value;
|
a=a->error_value;
|
||||||
else {
|
else {
|
||||||
@@ -1549,11 +1555,9 @@ static void check_stmt(FeCheckerState *s, FeNode *n)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FE_N_EXPR_STMT:
|
case FE_N_EXPR_STMT:
|
||||||
|
/* The enclosing-error-result check lives on the try expression itself,
|
||||||
|
so a bare `try e;` needs nothing extra here. */
|
||||||
check_expr(s, n->a);
|
check_expr(s, n->a);
|
||||||
if (n->a && n->a->kind==FE_N_UNARY && n->a->text &&
|
|
||||||
strcmp(n->a->text,"try")==0 &&
|
|
||||||
(!s->ret || s->ret->kind!=FE_TYPE_ERROR_UNION))
|
|
||||||
err(c,n->loc,"try requires an enclosing error result");
|
|
||||||
break;
|
break;
|
||||||
case FE_N_DEFER:
|
case FE_N_DEFER:
|
||||||
++s->defer_depth;
|
++s->defer_depth;
|
||||||
|
|||||||
Reference in New Issue
Block a user