follow up to #32195
NextActionHandler loggingMiddleware<
State extends Built<State, StateBuilder>,
StateBuilder extends Builder<State, StateBuilder>,
Actions extends ReduxActions>(
MiddlewareApi<State, StateBuilder, Actions> api) =>
(next) => (a) {
new Logger('rx.logging_middleware ${a.name}')
..fine('')
..finer(a.payload is SecuritySensitive
? ' == security sensitive information omitted == '
// `.toString()` is required for Thunk where payload is a function
: (a.payload as Object).toString());
next(a);
};
is passed to https://github.com/davidmarne/built_redux/blob/master/lib/src/store.dart#L29
using
class RxStore extends Store<RxApp, RxAppBuilder, RxAppActions> {
RxStore(
{Reducer reducer,
RxApp defaultState,
RxAppActions actions,
Iterable<Middleware<RxApp, RxAppBuilder, RxAppActions>> middleware})
: super((reducer ?? RxApp.reducer().build()) as Reducer,
defaultState ?? new RxApp(), actions ?? new RxAppActions(),
middleware:
middleware ?? [loggingMiddleware]);
}
at https://github.com/davidmarne/built_redux/blob/master/lib/src/store.dart#L54
Iterable<NextActionHandler> chain = middleware.map((m) => m(api));
and then chain.toList() causes
type '(MiddlewareApi<RxApp, RxAppBuilder, RxAppActions>) => ((Action) => void) => (Action) => void' is not a subtype of type '(MiddlewareApi) => ((Action) => void) => (Action) => void' of 'm'
I haven't found anything where MiddlewareApi was used without type parameters.
@zoechi I can't figure this one out based just on this information. Is it possible to create a repro?
Sure, should be possible. Thanks for having a look
I wasn't yet able to reproduce outside the full project :-/
@zoechi You can try to narrow it down by looking at sprinkling few debug prints.
print(middleware.runtimeType);
for (dynamic x in middleware) {
print("--- ${x.runtimeType}");
}
List<NextActionHandler> chain = middleware.map<NextActionHandler>((m) => m(api)).toList();
in RxStore you can add also some
RxStore(
{Reducer reducer,
RxApp defaultState,
RxAppActions actions,
Iterable<Middleware<RxApp, RxAppBuilder, RxAppActions>> middleware})
: super((reducer ?? RxApp.reducer().build()) as Reducer,
defaultState ?? new RxApp(), actions ?? new RxAppActions(),
middleware:
middleware ?? [loggingMiddleware]) {
print("RxStore(${middleware.runtimeType}, ${this.middleware.runtimeType})");
}
What happens if you alter the code like this?
[ +429 ms] I/flutter ( 4052): List<(MiddlewareApi<RxApp, RxAppBuilder, RxAppActions>) => ((Action) => void) => (Action) => void>
[ ] I/flutter ( 4052): --- (MiddlewareApi<RxApp, RxAppBuilder, RxAppActions>) => ((Action) => void) => (Action) => void
[+16123 ms] I/flutter ( 4052): --- (MiddlewareApi<RxApp, RxAppBuilder, RxAppActions>) => ((Action) => void) => (Action) => void
[+15729 ms] I/flutter ( 4052): 0 2018-02-20 07:17:15.737380 SEVERE lookatmybaby_flutter.sentry_error_reporter:
[ ] I/flutter ( 4052): error: type '(MiddlewareApi<RxApp, RxAppBuilder, RxAppActions>) => ((Action) => void) => (Action) => void' is not a subtype of type '(MiddlewareApi) => ((Action) => void) => (Action) => void' of 'm'
[ +1 ms] I/flutter ( 4052): #0 new Store.<anonymous closure> (package:built_redux/src/store.dart)
[ ] I/flutter ( 4052): #1 MappedListIterable.elementAt (dart:_internal/iterable.dart:414:29)
[ ] I/flutter ( 4052): #2 ListIterable.reduce (dart:_internal/iterable.dart:181:15)
[ ] I/flutter ( 4052): #3 new Store (package:built_redux/src/store.dart:62:52)
[ ] I/flutter ( 4052): #4 new RxStore (package:lookatmybaby_shared/src/client/state/app.dart)
[ ] I/flutter ( 4052): #5 initAndRunApp (package:lookatmybaby_flutter/app.dart:31:21)
[ ] I/flutter ( 4052): <asynchronous suspension>
[ ] I/flutter ( 4052): #6 main.<anonymous closure> (file:///Users/zoechi/dart/customers/lookatyou/lookatmybaby/lookatmybaby_flutter/lib/main_zoechi.dart:19:9)
[ ] I/flutter ( 4052): #7 _rootRun (dart:async/zone.dart:1126:13)
[ ] I/flutter ( 4052): #8 _CustomZone.run (dart:async/zone.dart:1023:19)
[ ] I/flutter ( 4052): #9 runZoned (dart:async/zone.dart:1490:19)
[ ] I/flutter ( 4052): #10 main (file:///Users/zoechi/dart/customers/lookatyou/lookatmybaby/lookatmybaby_flutter/lib/main_zoechi.dart:16:3)
[ ] I/flutter ( 4052): #11 _startIsolate.<anonymous closure> (dart:isolate/isolate_patch.dart:279:19)
[ ] I/flutter ( 4052): #12 _RawReceivePortImpl._handleMessage (dart:isolate/isolate_patch.dart:165:
The exception is thrown in the constructor of Store so the constructor body of RxStore is not executed
The code is in a shared package that I use in a Flutter project.
When I tried to create a reproduction I created a new project and copied the code I thought was relevant. I couldn't reproduce.
Then I added a new Flutter project to the reproduction and invoked it from there, but still couldn't reproduce.
Now I added a bin/main.dart to my shared package and I also can't reproduce.
So it looks like something in my Flutter project triggers it.
When I run it from bin/main it prints
--- (MiddlewareApi) => ((Action) => void) => (Action) => void
--- (MiddlewareApi) => ((Action) => void) => (Action) => void
Dart VM version: 2.0.0-dev.26.0 (Thu Feb 15 03:06:13 2018 +0100) on "macos_x64"
same with
Dart VM version: 2.0.0-dev.28.0 (Mon Feb 19 18:49:30 2018 +0100) on "macos_x64"
When I run it from command line with
dart --preview-dart-2 --reify-generic-functions bin/main.dart
I get
List
---
---
```
could there be another option that is used in my Flutter project?
Why is it not used in the new Flutter project?
With
dart --preview-dart-2 --reify bin/main.dart
I get
--- (MiddlewareApi) => ((Action) => void) => (Action) => void
--- (MiddlewareApi) => ((Action) => void) => (Action) => void
Can you do this for me:
find . -iname '*.dill'$ pub global activate kernel
$ pub global run kernel:dump xyz.dill xyz.txt
The open xyz.txt, locate the Store class and post the whole thing here.
I feel like we need to verify what type inference inferred.
It doesn't create the file
(rxdart_2) $ pub global run kernel:dump main_zoechi.dart.dill xyz.txt
Unhandled exception:
RangeError (index): Invalid value: Valid value range is empty: 76
#0 List.[] (dart:core-patch/dart:core/array.dart:10)
#1 BinaryBuilder.readCanonicalNameReference (package:kernel/binary/ast_from_binary.dart:288)
#2 BinaryBuilder.readLibrary (package:kernel/binary/ast_from_binary.dart:329)
#3 BinaryBuilder._readOneProgram (package:kernel/binary/ast_from_binary.dart:259)
#4 BinaryBuilder.readProgram (package:kernel/binary/ast_from_binary.dart:220)
#5 loadProgramFromBinary (package:kernel/kernel.dart:27)
#6 main (file:///Users/zoechi/.pub-cache/hosted/pub.dartlang.org/kernel-0.2.0/bin/dump.dart:9)
#7 _startIsolate.<anonymous closure> (dart:isolate-patch/dart:isolate/isolate_patch.dart:277)
#8 _RawReceivePortImpl._handleMessage (dart:isolate-patch/dart:isolate/isolate_patch.dart:165)
Hmm. Can you trying doing an AOT build of your application, via flutter build aot and then trying to dump it again?
That doesn't seem to produce a *.dill file
Previously I run it from IntelliJ's debugger. When I just run it from IntelliJ (without the debugger) I get the same error output as above
I meant flutter build aot --preview-dart-2 sorry for the confusion.
Sorry, stupid me :-/ Forgot it because it is applied automatically in the run configuration when run from IntelliJ
Now I get
(rxdart_2) $ pub global run kernel:dump lib/main_zoechi.dart.dill xyz.txt
Unhandled exception:
RangeError (index): Invalid value: Valid value range is empty: 93
#0 List.[] (dart:core-patch/dart:core/array.dart:10)
#1 BinaryBuilder.readCanonicalNameReference (package:kernel/binary/ast_from_binary.dart:288)
#2 BinaryBuilder.readLibrary (package:kernel/binary/ast_from_binary.dart:329)
#3 BinaryBuilder._readOneProgram (package:kernel/binary/ast_from_binary.dart:259)
#4 BinaryBuilder.readProgram (package:kernel/binary/ast_from_binary.dart:220)
#5 loadProgramFromBinary (package:kernel/kernel.dart:27)
#6 main (file:///Users/zoechi/.pub-cache/hosted/pub.dartlang.org/kernel-0.2.0/bin/dump.dart:9)
#7 _startIsolate.<anonymous closure> (dart:isolate-patch/dart:isolate/isolate_patch.dart:277)
#8 _RawReceivePortImpl._handleMessage (dart:isolate-patch/dart:isolate/isolate_patch.dart:165)
โ] Flutter (on Mac OS X 10.13.3 17D47, locale en-AT, channel dev)
โข Flutter version 0.1.2 at /Users/zoechi/flutter/flutter
โข Framework revision 8a65872ef9 (6 days ago), 2018-02-13 23:32:28 -0800
โข Engine revision 05c5f817eb
โข Tools Dart version 2.0.0-dev.22.0
โข Engine Dart version 2.0.0-edge.3c4dccbd46f152be9e1b6ca95c57357e8e48057c
lass RxStore extends sto3::Store<sto::RxApp, sto::RxAppBuilder, app8::RxAppActions> {
constructor โข({(sto::RxApp, act2::Action<dynamic>, sto::RxAppBuilder) โ void reducer = null, sto::RxApp defaultState = null, app8::RxAppActions actions = null, core::Iterable<(mid::MiddlewareApi<sto::RxApp, sto::RxAppBuilder, app8::RxAppActions>) โ ((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void> middleware = null}) โ void
: super sto3::Store::โข(let final (sto::RxApp, act2::Action<dynamic>, sto::RxAppBuilder) โ void #t4247 = reducer in #t4247.==(null) ?{(sto::RxApp, act2::Action<dynamic>, sto::RxAppBuilder) โ void} sto::RxApp::reducer().{red::ReducerBuilder::build}() as{TypeError} (sto::RxApp, act2::Action<dynamic>, sto::RxAppBuilder) โ void : #t4247, let final sto::RxApp #t4248 = defaultState in #t4248.==(null) ?{sto::RxApp} sto::RxApp::โข() : #t4248, let final app8::RxAppActions #t4249 = actions in #t4249.==(null) ?{app8::RxAppActions} app8::_$RxAppActions::โข() : #t4249, middleware: let final core::Iterable<(mid::MiddlewareApi<sto::RxApp, sto::RxAppBuilder, app8::RxAppActions>) โ ((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void> #t4250 = middleware in #t4250.==(null) ?{core::Iterable<(mid::MiddlewareApi<sto::RxApp, sto::RxAppBuilder, app8::RxAppActions>) โ ((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void>} <(mid::MiddlewareApi<sto::RxApp, sto::RxAppBuilder, app8::RxAppActions>) โ ((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void>[log3::loggingMiddleware<sto::RxApp, sto::RxAppBuilder, app8::RxAppActions>, err3::errorReporterMiddleware<sto::RxApp, sto::RxAppBuilder, app8::RxAppActions>] : #t4250)
;
abstract forwarding-stub method replaceState(generic-covariant-impl sto::RxApp state) โ void;
abstract forwarding-stub set _state(generic-covariant-impl sto::RxApp _) โ void;
abstract forwarding-stub set _actions(generic-covariant-impl app8::RxAppActions _) โ void;
}
ibrary from "package:built_redux/src/store.dart" as sto3 {
import "dart:async";
import "dart:core";
import "package:built_value/built_value.dart";
import "package:built_redux/src/action.dart";
import "package:built_redux/src/middleware.dart";
import "package:built_redux/src/typedefs.dart";
import "package:built_redux/src/store_change.dart";
class Store<State extends bui::Built<sto3::Store::State, sto3::Store::StateBuilder>, StateBuilder extends bui::Builder<sto3::Store::State, sto3::Store::StateBuilder>, Actions extends act2::ReduxActions> extends core::Object {
final field asy::StreamController<sto4::StoreChange<sto3::Store::State, sto3::Store::StateBuilder, dynamic>> _stateController = asy::StreamController::broadcast<sto4::StoreChange<sto3::Store::State, sto3::Store::StateBuilder, dynamic>>();
generic-covariant-impl generic-covariant-interface field sto3::Store::State _state = null;
generic-covariant-impl generic-covariant-interface field sto3::Store::Actions _actions = null;
constructor โข((sto3::Store::State, act2::Action<dynamic>, sto3::Store::StateBuilder) โ void reducer, sto3::Store::State defaultState, sto3::Store::Actions actions, {core::Iterable<(mid::MiddlewareApi<sto3::Store::State, sto3::Store::StateBuilder, sto3::Store::Actions>) โ ((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void> middleware = const <(mid::MiddlewareApi<core::Object, core::Object, core::Object>) โ ((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void>[]}) โ void
: super core::Object::โข() {
this.{sto3::Store::_state} = defaultState;
this.{sto3::Store::_actions} = actions;
final mid::MiddlewareApi<sto3::Store::State, sto3::Store::StateBuilder, sto3::Store::Actions> api = new mid::MiddlewareApi::โข<sto3::Store::State, sto3::Store::StateBuilder, sto3::Store::Actions>(this);
(act2::Action<dynamic>) โ void handler = (act2::Action<dynamic> action) โ core::Null {
sto3::Store::State state = this.{sto3::Store::_state}.{bui::Built::rebuild}((sto3::Store::StateBuilder b) โ void => reducer.call(this.{sto3::Store::_state}, action, b));
if(this.{sto3::Store::_state}.{core::Object::==}(state))
return;
this.{sto3::Store::_stateController}.{asy::StreamController::add}(new sto4::StoreChange::โข<sto3::Store::State, sto3::Store::StateBuilder, dynamic>(state, this.{sto3::Store::_state}, action));
this.{sto3::Store::_state} = state;
};
if(middleware.{core::Iterable::length}.{core::num::>}(0)) {
core::Iterable<((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void> chain = middleware.{core::Iterable::map}<((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void>(((mid::MiddlewareApi<sto3::Store::State, sto3::Store::StateBuilder, sto3::Store::Actions>) โ ((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void m) โ ((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void => m.call(api));
core::print(middleware.{core::Object::runtimeType});
for (dynamic x in middleware) {
core::print("--- ${x.{core::Object::runtimeType}}");
}
((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void combinedMiddleware = chain.{core::Iterable::reduce}((((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void composed, ((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void middleware) โ ((act2::Action<dynamic>) โ void) โ (act2::Action<dynamic>) โ void => ((act2::Action<dynamic>) โ void handler) โ (act2::Action<dynamic>) โ void => composed.call(middleware.call(handler)));
handler = combinedMiddleware.call(handler);
}
actions.{act2::ReduxActions::setDispatcher}(handler);
}
method dispose() โ asy::Future<core::Null> /* originally async */ {
final asy::Completer<core::Null> :completer = asy::Completer::sync<core::Null>();
asy::FutureOr<core::Null> :return_value;
dynamic :async_stack_trace;
dynamic :async_op_then;
dynamic :async_op_error;
dynamic :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) โ dynamic yielding
try {
#L1776:
{
[yield] let dynamic #t6111 = asy::_awaitHelper(this.{sto3::Store::_stateController}.{asy::StreamController::close}(), :async_op_then, :async_op_error, :async_op) in null;
:result;
this.{sto3::Store::_state} = null;
this.{sto3::Store::_actions} = null;
}
:completer.{asy::Completer::complete}(:return_value);
return;
}
on dynamic catch(dynamic :exception, dynamic :stack_trace) {
:completer.{asy::Completer::completeError}(:exception, :stack_trace);
}
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
:async_op_then = asy::_asyncThenWrapperHelper(:async_op);
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
asy::Future::microtask<dynamic>(:async_op);
return :completer.{asy::Completer::future};
}
method replaceState(generic-covariant-impl generic-covariant-interface sto3::Store::State state) โ void {
if(!this.{sto3::Store::_state}.{core::Object::==}(state)) {
this.{sto3::Store::_stateController}.{asy::StreamController::add}(new sto4::StoreChange::โข<sto3::Store::State, sto3::Store::StateBuilder, dynamic>(state, this.{sto3::Store::_state}, new act2::Action::โข<core::Null>("replaceState", null)));
this.{sto3::Store::_state} = state;
}
}
get state() โ sto3::Store::State
return this.{sto3::Store::_state};
get stream() โ asy::Stream<sto4::StoreChange<sto3::Store::State, sto3::Store::StateBuilder, dynamic>>
return this.{sto3::Store::_stateController}.{asy::StreamController::stream};
get actions() โ sto3::Store::Actions
return this.{sto3::Store::_actions};
get nextState() โ asy::Stream<sto3::Store::State>
return this.{sto3::Store::stream}.{asy::Stream::map}<sto3::Store::State>((sto4::StoreChange<sto3::Store::State, sto3::Store::StateBuilder, dynamic> change) โ sto3::Store::State => change.{sto4::StoreChange::next});
method substateStream<Substate extends core::Object>((sto3::Store::State) โ sto3::Store::substateStream::Substate mapper) โ asy::Stream<typ5::SubstateChange<sto3::Store::substateStream::Substate>>
return this.{sto3::Store::stream}.{asy::Stream::map}<typ5::SubstateChange<sto3::Store::substateStream::Substate>>((sto4::StoreChange<sto3::Store::State, sto3::Store::StateBuilder, dynamic> c) โ typ5::SubstateChange<sto3::Store::substateStream::Substate> => new typ5::SubstateChange::โข<sto3::Store::substateStream::Substate>(mapper.call(c.{sto4::StoreChange::prev}), mapper.call(c.{sto4::StoreChange::next}))).{asy::Stream::where}((typ5::SubstateChange<sto3::Store::substateStream::Substate> c) โ core::bool => !c.{typ5::SubstateChange::prev}.{core::Object::==}(c.{typ5::SubstateChange::next}));
method nextSubstate<Substate extends core::Object>((sto3::Store::State) โ sto3::Store::nextSubstate::Substate mapper) โ asy::Stream<sto3::Store::nextSubstate::Substate>
return this.{sto3::Store::substateStream}<sto3::Store::nextSubstate::Substate>(mapper).{asy::Stream::map}<sto3::Store::nextSubstate::Substate>((typ5::SubstateChange<sto3::Store::nextSubstate::Substate> change) โ sto3::Store::nextSubstate::Substate => change.{typ5::SubstateChange::next});
method actionStream<Payload extends core::Object>(act2::ActionName<sto3::Store::actionStream::Payload> actionName) โ asy::Stream<sto4::StoreChange<sto3::Store::State, sto3::Store::StateBuilder, sto3::Store::actionStream::Payload>>
return this.{sto3::Store::stream}.{asy::Stream::where}((sto4::StoreChange<sto3::Store::State, sto3::Store::StateBuilder, dynamic> c) โ core::bool => c.{sto4::StoreChange::action}.{act2::Action::name}.{core::String::==}(actionName.{act2::ActionName::name})).{asy::Stream::map}<sto4::StoreChange<sto3::Store::State, sto3::Store::StateBuilder, sto3::Store::actionStream::Payload>>((sto4::StoreChange<sto3::Store::State, sto3::Store::StateBuilder, dynamic> c) โ sto4::StoreChange<sto3::Store::State, sto3::Store::StateBuilder, sto3::Store::actionStream::Payload> => c as sto4::StoreChange<sto3::Store::State, sto3::Store::StateBuilder, sto3::Store::actionStream::Payload>);
}
}
Thanks a lot @zoechi for you help. Eventually I managed to repro it locally, issue is in the VM's Kernel to IL translation layer. Fix is in the CQ.
The regression test for this issue is failing on dart2js-with-kernel --strong --minified. See https://dart-review.googlesource.com/c/sdk/+/42566
The crash info and reproduction command is in the log at
https://logs.chromium.org/v/?s=chromium%2Fbb%2Fclient.dart%2Fdart2js-linux-d8-minified-4-5-be%2F10268%2F%2B%2Frecipes%2Fsteps%2Fdart2js-with-kernel-strong-d8_tests%2F0%2Fstdout
and is (in part):
FAILED: dart2js-d8 release_x64 language_2/vm/regress_32204_test
Expected: Pass
Actual: Crash
Unexpected compile error.
--- Command "dart2js" (took 693ms):
DART_CONFIGURATION=ReleaseX64 out/ReleaseX64/dart-sdk/bin/dart2js --sync-async --generate-code-with-compile-time-errors --test-mode --allow-mock-compilation --categories=all --minify --use-kernel --strong --packages=/b/build/slave/dart2js-linux-d8-minified-4-5-be/build/sdk/.packages /b/build/slave/dart2js-linux-d8-minified-4-5-be/build/sdk/tests/language_2/vm/regress_32204_test.dart --out=/b/build/slave/dart2js-linux-d8-minified-4-5-be/build/sdk/out/ReleaseX64/generated_compilations/dart2js-strong-minified-sdk/tests_language_2_vm_regress_32204_test/out.js
exit code:
-10
stdout:
tests/language_2/vm/regress_32204_test.dart:19:3:
Internal Error: Runtime type information not available for type_variable_local(A.T) in (local(A.#v), local(A.#f)) for j:signature(A_f.$signature).
A(B
^
The compiler is broken.
When compiling the above element, the compiler crashed. It is not
possible to tell if this is caused by a problem in your program or
not. Regardless, the compiler should not crash.
The Dart team would greatly appreciate if you would take a moment to
report this problem at http://dartbug.com/new.
Please include the following information:
#
Thanks for letting us know - at this time, while we are implementing the 2.0 features, we are tracking all test strong-mode dart2js issues directly in the status files. I'll close this issue to track it all in a single place. Once we ship our 2.0 implementation, we expect we'll start using the issue tracker for remaining bugs.
Most helpful comment
Thanks a lot @zoechi for you help. Eventually I managed to repro it locally, issue is in the VM's Kernel to IL translation layer. Fix is in the CQ.