Skip to content

(Re-)make it an error if control can reach the end of a non-void/dynamic/Null function #4549

@lrhn

Description

@lrhn

The current dartLangSpec.tex says that it's an error to have a return; statement in a (synchronous non-generator) function with a return type that isn't void, dynamic or Null. It also says that it's an error if control flow can reach the end of a function, and a return; in that position would be an error, so reaching the end is equivalent to a return;.
That rule applies to all function types, it's not an error to have a return; in a generator, and in an async function it depends on the future value type.

The Null-safety spec states in the Reachability section:

It is an error if the body of a method, function, getter, or function expression with a potentially non-nullable return type may complete normally.

This is under a statement saying:

A number of errors and warnings are updated to take reachability of statements into account.

The new rule is too vague, it shouldn't apply to async or generator functions, but the text doesn't say that For async non-generator functions it should refer to the future value type, not the return type, and for generators, it should just not say anything. I believe the implementations have only applied the rule to synchronous non-generator functions.

The implementations has taken this to mean that the new rule replaces the existing rule for reaching the end of the body.
That's not unreasonable, since for the case it actually seems to intend, this rule would be redundant with the existing rule that only allows void, dynamic and Null, all of which are definitely nullable.

I think that was a mistake, and we should just declare that the old rule still applies: In any function, if the body can complete normally, it's a compile-time error if a return; would be an error.
(Which we should abstract into a definition like "may return without a value", no synthetic return needs to be inserted.)

By allowing Foo? foo() { ... } to reach the end of the body, we allow errors where the author misses a return on one path.
See fx: flutter/flutter#177695

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureProposed language feature that solves one or more problems

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions