Closed TimWhiting closed 1 year ago
Same error doesn't exist with dart compile js
Here is a minimal reproducible snippet without riverpod (using the web-simple template):
// main.dart
import 'baz.dart';
void main() {
var foo = Foo();
print(foo.bar());
}
class Foo = Bar with Baz;
class Bar {}
// baz.dart
mixin Baz {
int? _foo;
void bar() {
_foo = 100;
}
}
The error happens only, when the Baz
mixin is defined in a different library than Foo
.
Any update on this ?!
I'm "engaging" with the engineers now. Thanks for your patience!
Upvoting this because this is a blocking issue with a client.
I narrowed down a little more from @schultek's example.
So basically, the issue occurs with this syntax when it's used with Mixin: class Foo = Bar with Baz
// main.dart
import 'baz.dart';
void main() {
var foo = Foo();
var fooWork = FooWork();
fooWork.bar();
foo.bar();
}
class Foo = Bar with Baz; // crash
class FooWork extends Bar with Baz{} // doesn't crash
class Bar {}
// baz.dart
mixin Baz {
int? _foo;
void bar() {
_foo = 100;
}
}
@leehack – did that patch to riverpod fix the issue?
@kevmoo yep. It's tested and merged in the main, but I wish it to be fixed from dart anyway. I think the syntax makes the code cleaner. Not sure how widespread the syntax is, but maybe there are many packages impacted by this issue.
Also, it'd be nice for that syntax to also be documented somewhere. The first I saw it was in the RiverPod code, and Remi claims that he found it by going through the compiler sources. :)
Thank you @TimWhiting and other for reporting the issue and providing a great repro! I am looking into this currently, apologies for the delay.
Maybe related: https://github.com/dart-lang/sdk/issues/46867
Looks like this is the culprit DDC-generated code that causes the stack overflow. Will see how it can be fixed:
class AutoDisposeFutureProviderElement extends FutureProviderElement_AutoDisposeProviderElementMixin$36 {
static ['_#_#tearOff'](T, provider) {
return new (future_provider.AutoDisposeFutureProviderElement$(T)).__(provider);
}
get [_keepAliveLinks]() {
return this[_keepAliveLinks]; // Calling itself here!
}
set [_keepAliveLinks](value) {
return this[_keepAliveLinks] = value;
}
get [_maintainState]() {
return this[_maintainState];
}
set [_maintainState](value) {
return this[_maintainState] = value;
}
get maintainState() {
return super.maintainState;
}
set maintainState(value) {
return super.maintainState = value;
}
keepAlive() {
return super.keepAlive();
}
mayNeedDispose() {
return super.mayNeedDispose();
}
runOnDispose() {
return super.runOnDispose();
}
}
@leehack thank you for the great repro! Here is where the fault lies. I'll post updates on my progress.
Update: found the culprit - we haven't marked the mixin declaration class fields as virtual, so overrides were not working correctly. Testing out the fix currently.
Will this get included in a hotfix release of Dart and Flutter? It's quite a serious issue. I myself ran into it in my large Flutter app that does not use Provider.
@hacker1024 I am working on it, will update on if and when!
dart --version
2.19.0-266.0.dev
, also on stable / beta channels web / chromeVery similar issue to https://github.com/dart-lang/sdk/issues/44636.
Simplest reproduction so far: Edit: See @schultek's minimum sample below for a simpler reproduction.
dart create -t web-simple call_stack_overflow && cd call_stack_overflow
void main() { final container = ProviderContainer(); final value = container.read(stringValue.state); querySelector('#output')?.text = 'Your ${value.state} app is running.'; }
final stringValue = StateProvider.autoDispose((ref) => 'Hello world');
....... at set [_keepAliveLinks] (auto_dispose.dart:42:7) at set [_keepAliveLinks] (auto_dispose.dart:42:7) at set [_keepAliveLinks] (auto_dispose.dart:42:7) at AutoDisposeProviderElementMixin. (auto_dispose.dart:6:24)
at StateProviderElement_AutoDisposeProviderElementMixin$36. (base.dart:81:48)
at new AutoDisposeStateProviderElement. (auto_dispose.dart:42:7)
at AutoDisposeStateProvider.new.createElement (auto_dispose.dart:31:44)
at [_create] (container.dart:49:32)
at framework._StateReader.new.getElement (container.dart:41:52)
at container.dart:434:37
at framework.ProviderContainer.new.readProviderElement (container.dart:466:14)
at ProviderElementProxy.new.read (proxy_provider_listenable.dart:112:25)
at framework.ProviderContainer.new.read (container.dart:257:20)
at main$ (main.dart:25:26)
at main.dart.bootstrap.js:273:10
at Array.forEach ()
at window.$dartRunMain (main.dart.bootstrap.js:272:32)
at :1:8
at Object.runMain (client.js:8777:21)