dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.25k stars 1.58k forks source link

NNBD: Dart throws unexpected runtime exception when calls function with Null type parameter. #40399

Closed iarkh closed 4 years ago

iarkh commented 4 years ago

Dart VM version: 2.8.0-edge.40f23c735f04433e4fc334fbd674474bd3de0f8b (Tue Jan 28 01:14:48 2020 +0000) on "linux_x64"

NNBD Spec reads that FutureOr is nullable type.

Please try to run the following code:

import "dart:async";
void testGenericDynamic <T extends dynamic >() { print(T); }
void testGenericFutureOr<T extends FutureOr>() { print(T); }

void main() {
  testGenericDynamic <Null>();
  testGenericFutureOr<Null>();   // runtime error here
}

Analyzer passes with this. Dart throws unexpected runtime error on the testGenericFutureOr<Null>(); line.

Seems like dart should pass here too. Or, if something was changed and FutureOr is non-nullable, it should throw compile error instead.

Sample output is:

$ dartanalyzer --enable-experiment=non-nullable test.dart Analyzing test.dart... No issues found! $ dart --enable-experiment=non-nullable test.dart Null Unhandled exception: type 'Null' is not a subtype of type 'T' of 'non-nullable type parameter'

0 testGenericFutureOr (file:///home/iarkh/dart/dart-sdk/sdk/tests/co191/src/LanguageFeatures/nnbd/test.dart)

1 main (file:///home/iarkh/dart/dart-sdk/sdk/tests/co191/src/LanguageFeatures/nnbd/test.dart:7:3)

2 _startIsolate. (dart:isolate-patch/isolate_patch.dart:300:19)

3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:167:12)

lrhn commented 4 years ago

IT should not fail. The bound of T in testGenericFutureOr is FutureOr<dynamic> (or FutureOr<Object?>, I don't remember exactly where that landed, but it doesn't matter here).

The Null type is a subtype of that and should be accepted.

johnniwinther commented 4 years ago

It seems to be a runtime problem.

Maybe this is related to the current encoding of FutureOr types in kernel: https://github.com/dart-lang/sdk/issues/40123

crelier commented 4 years ago

This was fixed by https://github.com/dart-lang/sdk/commit/4f35a405ff387555a41fe7d134a53268499d56fd