A closure literal whose body raises but is annotated non-failable (or has no ! in its return) now gets a lambda-specific diagnostic telling the user to declare the failable return explicitly, instead of the generic "raise is only valid inside a failable function". Failability is never inferred for a lambda, so a raising lambda with no ! is a hard error that should point at the fix. New in_lambda_body flag (save/restore for nesting) set around the lambda body lowering in lowerLambda; diagRaiseNotFailable branches on it. Top-level functions keep the generic message. Test: 1043-errors-lambda-raise-annotation-hint.sx.
21 lines
930 B
Plaintext
21 lines
930 B
Plaintext
// A closure literal whose body `raise`s but is annotated non-failable (or has
|
|
// no `!` in its return) gets a LAMBDA-SPECIFIC diagnostic telling the user to
|
|
// declare the failable return explicitly (ERR E5.1 sub-feature 1). This is the
|
|
// closure analog of the top-level "raise is only valid inside a failable
|
|
// function" error — failability is never inferred for a lambda, it must be
|
|
// declared, so a raising lambda with no `!` is a hard error pointing at the fix.
|
|
|
|
#import "modules/std.sx";
|
|
|
|
E :: error { Neg }
|
|
|
|
take :: (cb: Closure(s32) -> (s32, !E), x: s32) -> s32 { return cb(x) catch e -1; }
|
|
|
|
main :: () -> s32 {
|
|
// `-> s32` (non-failable) but the body raises → lambda-specific hint:
|
|
// "lambda body raises; declare its return type explicitly with
|
|
// `-> (T, !)` or `-> (T, !Named)`"
|
|
print("{}\n", take(closure((x: s32) -> s32 { if x < 0 { raise error.Neg; } return x; }), -1));
|
|
return 0;
|
|
}
|