Precompiler doesn’t create `kInvokeFieldDispatcher` functions for callback fields with optional parameters

A recent PR failed on Flutter, but only when code is called in AOT release mode (JIT/debug works fine). Here’s the relevant part of the crash log:

2018-09-24T21:32:27.882616: stdout: [  +19 ms] I/flutter ( 4203): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
2018-09-24T21:32:27.882735: stdout: [   +1 ms] E/DartVM  ( 4203): ../../third_party/dart/runtime/vm/object.h: 6258: error: Handle check failed: saw Closure: (RouteSettings, (BuildContext) => Widget) => MaterialPageRoute expected TypeArguments
stdout: [        ] E/DartVM  ( 4203): Dumping native stack trace for thread 1082
stdout: [        ] E/DartVM  ( 4203):   [0x8f563ba1] Unknown symbol
2018-09-24T21:32:27.889829: stdout: [   +7 ms] E/DartVM  ( 4203):   [0x8f563ba1] Unknown symbol
2018-09-24T21:32:27.934663: stdout: [  +44 ms] E/DartVM  ( 4203):   [0x8f625491] Unknown symbol
stdout: [        ] E/DartVM  ( 4203): -- End of DumpStackTrace
2018-09-24T21:32:28.003378: stdout: [  +68 ms] Successfully connected to service protocol: http://127.0.0.1:62057/
2018-09-24T21:32:28.006533: stdout: [   +3 ms] getVM: {}
2018-09-24T21:32:28.019089: stdout: [  +12 ms] getIsolate: {isolateId: isolates/738645851}

And the relevant source bits:

typedef PageRouteFactory = PageRoute<T> Function<T>(RouteSettings settings, WidgetBuilder builder);

...
      // widget.pageRouteBuilder is a final PageRouteFactory
      final Route<dynamic> route = widget.pageRouteBuilder<dynamic>(
        settings,
        builder,
      );

which gets passed in as:

   WidgetsApp(
        pageRouteBuilder: <T>(RouteSettings settings, WidgetBuilder builder) =>
            MaterialPageRoute<T>(settings: settings, builder: builder),
...

If I rework the typedef to be like:

typedef PageRouteFactory = PageRoute<dynamic> Function(RouteSettings settings, WidgetBuilder builder);
...
   WidgetsApp(
        pageRouteBuilder: (RouteSettings settings, WidgetBuilder builder) =>
            MaterialPageRoute<dynamic>(settings: settings, builder: builder),

It’s fine in AOT.

I’ve tried to create a simplified repro a few different ways, but whatever I do doesn’t seem to reproduce the crash. However, using the PR branch to run any material/cupertino app does reliably reproduce the crash.

Author: Fantashit

1 thought on “Precompiler doesn’t create `kInvokeFieldDispatcher` functions for callback fields with optional parameters

Comments are closed.