-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Dart 2 class generics bug? #32425
Comments
What Dart/Flutter version are you using? |
@brianegan your code under this line says: // StoreFinder works fine and gives me back a Store!
store = new StoreFinder<S>().of(context); Should it instead say |
@mraleph Indeed it should. Meant only for the second example. Thanks for catching that! This was on Dart 2.0.0-edge.0d5cf900 from the Flutter beta channel. |
I can't see anything obvious in the example, so I'll just give you a different workaround. You can't write: Type x = StoreFinder<S>; but you can use a helper class (or in Dart 2, even a helper function) to get that type: class _TypeOf<T> { Type get type => T; }
Type _typeOf<T>() => T;
...
Type x = new _TypeOf<StoreProvider<S>>().type;
Type y = _typeOf<StoreProvider<S>>(); That might be easier than creating an entire extra class, doing instantiation and using With that, you can write: factory StoreProvider.of() {
Type storeProviderType = _typeOf<StoreProvider<S>>(): // or use the class in Dart 1.
return (context.inheritFromWidgetOfExactType(storeProviderType) as StoreProvider<S>)
.store
} which is almost what you originally wanted. |
Thanks @lrhn, I'll give that a shot and report back! I was definitely trying to avoid |
@lrhn Worked like a charm. I'll go with that approach, thanks so much! General Q: This feels like a bit of a workaround, will something like this be supported in |
Reduction class A<T> { }
final map = {};
class B<T> {
void foo() {
print(map[new A<T>().runtimeType]);
}
}
class C<T, U> {
void build() {
new B<T>().foo();
new B<U>().foo();
}
}
void main() {
map[new A<String>().runtimeType] = 42;
new C<String, String>().build();
} $ pkg/vm/tool/dart2 /tmp/x.dart
null
42 @jensjoha or @crelier: could one of you take a look if you have time? |
I hope so. I intend so. Let's see if I succeed :) |
Yay! If not, maybe even a global helper / standard pattern for this type of thing would be great. @mraleph Thanks for reducing it to a good test case :) |
Thanks for the report. Now, the problem happens when runtimeType canonicalizes the types. Canonicalization fails to ignore the extra type argument and two different "canonical" types exists for A. |
CL is still waiting for a review: https://dart-review.googlesource.com/c/sdk/+/45340 |
Thanks for the fast response and fix :) |
You are welcome. Thanks for the report. |
@lrhn Do you all know if this I changed my code to using Generic Types on Methods / Functions when I upgraded my lib to support Dart 2, and since I've had a ton of bug reports on my repo using this technique. Using the class solution I've got a test suite that relies on this method and it works, but for others it doesn't. |
In Dart 2, |
@eernstg Thanks for the heads up! I'll try that out. Do you happen to know if the |
|
@eernstg Thanks much -- appreciate the info! |
From the example above, calling this code crashes the app in Android. Flutter version Reproduce Logs Build fingerprint: 'Android/sdk_google_phone_x86_64/generic_x86_64:7.0/NYC/4662066:userdebug/dev-keys' |
@brianegan, it would be great if you could provide a standalone reproduction, something like:
This example does not crash:
|
@crelier Hey there -- sorry, I should have updated this thread. I think the problem was perhaps related to what eernstg mentioned above: whether the reified generic functions feature was enabled or not for certain folks / toolchains. I haven't gotten more bug reports with the latest version of the Flutter beta. |
This code does not fail on startup, but during hot reload.
```
//-------------------------------------------------------------------
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final String title;
MyApp({Key key, this.title}) : super(key: key);
@OverRide
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter Redux Demo",
theme: ThemeData(
primarySwatch: Colors.red,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class AppState {
}
class Provider<T> {
}
abstract class PageState<W extends StatefulWidget, S> extends State<W> {
// Workaround to capture generics
static Type _typeOf<T>() => T;
void init() {
final type1 = _typeOf<Provider<AppState>>(); // works
final type2 = _typeOf<Provider<S>>(); // DOES NOT WORK - object.cc: 16408: error: unreachable code
}
}
class MyHomePage extends StatefulWidget {
final String title;
MyHomePage({Key key, this.title}) : super(key: key);
@OverRide
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends PageState<MyHomePage, AppState> {
@OverRide
Widget build(BuildContext context) {
super.init(); // calls into method that causes failure
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
),
),
);
}
}
```
// -----------------------------------------------------------------
Initializing hot reload...
E/DartVM ( 3758): ../../third_party/dart/runtime/vm/object.cc: 16408: error: unreachable code
E/DartVM ( 3758): Dumping native stack trace for thread ec6
E/DartVM ( 3758): [0x0000736d9c49df67] Unknown symbol
E/DartVM ( 3758): [0x0000736d9c49df67] Unknown symbol
E/DartVM ( 3758): [0x0000736d9c739786] Unknown symbol
E/DartVM ( 3758): -- End of DumpStackTrace
F/libc ( 3758): Fatal signal 6 (SIGABRT), code -6 in tid 3782 (Thread-2)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Android/sdk_google_phone_x86_64/generic_x86_64:7.0/NYC/4662066:userdebug/dev-keys'
Revision: '0'
ABI: 'x86_64'
pid: 3758, tid: 3782, name: Thread-2 >>> com.example.helloworld <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
rax 0000000000000000 rbx 0000736d9b5654f8 rcx ffffffffffffffff rdx 0000000000000006
rsi 0000000000000ec6 rdi 0000000000000eae
r8 0000000000000000 r9 000000000000001f r10 0000000000000008 r11 0000000000000202
r12 0000000000000ec6 r13 0000000000000006 r14 0000736d9c7a2837 r15 0000736d9b55dbd0
cs 0000000000000033 ss 000000000000002b
rip 0000736db7c93b67 rbp 0000000000000000 rsp 0000736d9b55da38 eflags 0000000000000202
backtrace:
#00 pc 000000000008db67 /system/lib64/libc.so (tgkill+7)
#1 pc 000000000008a601 /system/lib64/libc.so (pthread_kill+65)
#2 pc 0000000000030241 /system/lib64/libc.so (raise+17)
#3 pc 000000000002877d /system/lib64/libc.so (abort+77)
#4 pc 000000000078c695 /data/app/com.example.helloworld-1/lib/x86_64/libflutter.so
#5 pc 0000000000a8078a /data/app/com.example.helloworld-1/lib/x86_64/libflutter.so
#6 pc 0000000000750ed2 /data/app/com.example.helloworld-1/lib/x86_64/libflutter.so
#7 pc 0000000000704cf6 /data/app/com.example.helloworld-1/lib/x86_64/libflutter.so
#8 pc 000000000071e48f /data/app/com.example.helloworld-1/lib/x86_64/libflutter.so
#9 pc 000000000082ea2c /data/app/com.example.helloworld-1/lib/x86_64/libflutter.so
#10 pc 000000000000063a <anonymous:0000736d98940000>
#11 pc 0000000000020fa0 <anonymous:0000736d8f580000>
#12 pc 0000000000020840 <anonymous:0000736d8f580000>
#13 pc 0000000000002233 <anonymous:0000736d8de00000>
#14 pc 0000000000008523 <anonymous:0000736d8e100000>
#15 pc 000000000000768c <anonymous:0000736d8e100000>
#16 pc 0000000000006f98 <anonymous:0000736d8e100000>
#17 pc 000000000003f2c6 <anonymous:0000736d8e100000>
#18 pc 000000000000687f <anonymous:0000736d8e100000>
#19 pc 00000000000054b2 <anonymous:0000736d8e100000>
#20 pc 00000000000046af <anonymous:0000736d8e100000>
#21 pc 000000000000887b <anonymous:0000736d8e100000>
#22 pc 000000000000768c <anonymous:0000736d8e100000>
#23 pc 0000000000006f98 <anonymous:0000736d8e100000>
#24 pc 000000000000687f <anonymous:0000736d8e100000>
#25 pc 00000000000054b2 <anonymous:0000736d8e100000>
#26 pc 00000000000046af <anonymous:0000736d8e100000>
#27 pc 0000000000031077 <anonymous:0000736d8db80000>
#28 pc 00000000000054b2 <anonymous:0000736d8e100000>
#29 pc 00000000000046af <anonymous:0000736d8e100000>
#30 pc 0000000000031077 <anonymous:0000736d8db80000>
#31 pc 00000000000054b2 <anonymous:0000736d8e100000>
#32 pc 00000000000046af <anonymous:0000736d8e100000>
#33 pc 0000000000031077 <anonymous:0000736d8db80000>
#34 pc 00000000000054b2 <anonymous:0000736d8e100000>
#35 pc 00000000000046af <anonymous:0000736d8e100000>
#36 pc 0000000000031077 <anonymous:0000736d8db80000>
#37 pc 00000000000054b2 <anonymous:0000736d8e100000>
#38 pc 00000000000046af <anonymous:0000736d8e100000>
#39 pc 000000000000887b <anonymous:0000736d8e100000>
#40 pc 000000000000768c <anonymous:0000736d8e100000>
#41 pc 0000000000006f98 <anonymous:0000736d8e100000>
#42 pc 000000000003f2c6 <anonymous:0000736d8e100000>
#43 pc 000000000000687f <anonymous:0000736d8e100000>
#44 pc 00000000000054b2 <anonymous:0000736d8e100000>
#45 pc 00000000000046af <anonymous:0000736d8e100000>
#46 pc 000000000000887b <anonymous:0000736d8e100000>
#47 pc 000000000000768c <anonymous:0000736d8e100000>
#48 pc 0000000000006f98 <anonymous:0000736d8e100000>
#49 pc 000000000000687f <anonymous:0000736d8e100000>
#50 pc 00000000000054b2 <anonymous:0000736d8e100000>
#51 pc 00000000000046af <anonymous:0000736d8e100000>
#52 pc 000000000000887b <anonymous:0000736d8e100000>
#53 pc 000000000000768c <anonymous:0000736d8e100000>
#54 pc 0000000000006f98 <anonymous:0000736d8e100000>
#55 pc 000000000003f2c6 <anonymous:0000736d8e100000>
#56 pc 000000000000687f <anonymous:0000736d8e100000>
#57 pc 00000000000054b2 <anonymous:0000736d8e100000>
#58 pc 00000000000046af <anonymous:0000736d8e100000>
#59 pc 0000000000031077 <anonymous:0000736d8db80000>
#60 pc 00000000000054b2 <anonymous:0000736d8e100000>
#61 pc 00000000000046af <anonymous:0000736d8e100000>
#62 pc 000000000000887b <anonymous:0000736d8e100000>
#63 pc 000000000000768c <anonymous:0000736d8e100000>
Lost connection to device.
|
@kyle-berry-perficient you can make code and log output easier to read, by wrapping it in ``` |
@a-siva, can someone familiar with hot-reload on flutter have a look? Thanks. |
@affinnen can you please open a new issue? |
Hey all,
I've run into a funny issue. What I'm trying to accomplish: Using Generics within a
Type
. I might be approaching this the wrong way!What I'd like to be able to do, but doesn't work:
I have a class like this to get it working:
The problem: If I have the following class and call it like so:
new StoreCaptor<String>()
, everything works!If I have a class like this (with one extra generic), it fails:
new StoreCaptor<String, String>()
However! If I slightly change the second StoreCaptor class called in the same way to use
A
as the generic instead ofS
, everything works?I have no idea why, seems really odd that simply changing the order of the generics in the class will cause my code to work :( My class that calls
StoreFinder
needs to support 2 generics, so I can't simply support one generic. In addition, changing those params around would be a bit weird from an API perspective, so I'd like to keep them in their current order.The text was updated successfully, but these errors were encountered: