Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid error using Null type as an iterable in a for-in #36957

Open
MichaelRFairhurst opened this issue May 14, 2019 · 1 comment

Comments

Projects
None yet
2 participants
@MichaelRFairhurst
Copy link
Contributor

commented May 14, 2019

Null x;
for(var i in x) {...}

CFE accepts this, analyzer rejects it. My understanding is that it should be statically valid code.

Post-nnbd, this won't be, but we need to be careful that this might(?) need to work @leafpetersen to confirm.

Never x;
for(var i in x) {...}
@lrhn

This comment has been minimized.

Copy link
Member

commented May 14, 2019

I'm not sure this is valid code now.

The specifcation was changed recently to require the iterated object to be an Iterable.
The spec now says:

\begin{normativeDartCode}
$T$ $\id_1$ = $e$;
\VAR{} $\id_2$ = $id_1$.iterator;
\WHILE{} ($\id_2$.moveNext()) \{
\ \ $D$ \id{} = $\id_2$.current;
\ \ \{ $S$ \}
\}
\end{normativeDartCode}

\noindent
If the static type of $e$ is a top type
(\ref{superBoundedTypes})
then $T$ is \code{Iterable<dynamic>},
otherwise $T$ is the static type of $e$.
It is a compile-time error if $T$ is not assignable to \code{Iterable<dynamic>}.

In short, the for-in loop is equivalent to code starting with:

Null id_1 = null;
var id_2 = id_1.iterator;

This is not type correct, so the program is not valid.
The analyzer matches the specification (the specification might have been changed to match the analyzer, but we did it on purpose).

For Never, I'm not sure whether we'll make it an error to have unreachable code, the example above is definitely invalid because it fails to initialize a non-nullable variable (Never is not nullable) before it's used.
If you had:

Never x = throw "Banana";
for (var y in x) ...

then I guess the same problem would occur when you try to do id_1.identifier where id_1 has type Never. (Unless we decide to allow member access on Never and just give it type Never again).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.