-
Notifications
You must be signed in to change notification settings - Fork 207
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
Extensions on nested generic mixins don't promote types properly #3382
Comments
extension NestedMixinExt<TSub, TestSub extends TestMixin<TSub>>
on TestMixin<TestSub> { this looks like generic parameter which are under-constrained in a match. Try having just one type parameter: extension NestedMixinExt<TSub> on TestMixin<TestMixin<TSub>> {
void operateOnNestedValue(TestMixin<TSub> nestedMixin, TSub sub) {
print('calling operateOnValue, sub type is: $TSub');
nestedMixin.operateOnValue(sub);
}
} Generally, if you have something with two type parameters, trying to infer them from something that only has one, is very often going to leave one of the type parameters under-constrained, and you risk it being inferred as |
@lrhn Thanks for your response. However, as stated in the issue:
this is because the function signature I have is actually something like this: TestSub operateOnNestedValue(TestSub nestedMixin, TSub sub) where I need to return the exact input type. |
Note that a very similar issue has been discussed in #620. The common ground is that both this issue and 620 asks for the ability to receive a type argument like |
The real constraint that is desired here is that for extension NestedMixinExt<TSub, TestSub extends TestMixin<TSub>> the second occurrence of That way, matching a If we get variance annotations, maybe it's possible to make extension NestedMixinExt<TSub, TestSub extends TestMixin<inout TSub>> which forces an invariant subtype check on Still, it's much more complicated to introduce further constraints, either in subtyping or between type parameters, than just saying that you want "the type that extension NestedMixinExt<TestSub extends TestMixin<final TSub>> That's the most direct expression of what is really wanted: Not a second parameter that is forced to relate to the other parameter's type, but simply the actual type parameter that was found for that other parameter. Also avoids having to ignore some type parameters when calling, because they're not useful, they're just there to attempt to capture types on the side (which just doesn't work today). |
exactly! this is what I hope would be possible, just like pattern matching with instances, I hope there will be pattern matching with types. |
We should note that it is already possible to handle the given example in a very direct manner: mixin TestMixin<T> {
void operateOnValue(T value);
}
// First class expects a string.
class C1 with TestMixin<String> {
@override
void operateOnValue(String value) {
print('operateOnValue: $value');
}
}
// Second class expects C1 which is a TestMixin<String>
// so this class is matched with TestMixin<TestMixin<String>>
class C2 with TestMixin<C1> {
@override
void operateOnValue(C1 value) {
// do nothing.
}
}
// extension targets TestMixin<TestMixin<TSub>>.
extension NestedMixinExt<TSub> on TestMixin<TestMixin<TSub>> {
void operateOnNestedValue(TestMixin<TSub> nestedMixin, TSub sub) {
print('calling operateOnValue, sub type is: $TSub');
nestedMixin.operateOnValue(sub);
}
}
void main(List<String> arguments) {
final c1 = C1(); // TestMixin<String>
final c2 = C2(); // TestMixin<C1> == TestMixin<TestMixin<String>>
c2.operateOnNestedValue(c1, 'hello'); // Prints "operateOnValue: hello" as expected.
c2.operateOnNestedValue(c1, 50); // Compile-time error.
} The idea is simply that we specify the A proposal for a more general mechanism that would allow us to look up the value of a type argument in a superinterface is given here: #3324, but I think it's interesting that we can already do certain things in this area using extensions. |
When declaring extensions on nested generic mixins
Mixin<Mixin<T>>
for example; the last typeT
is lost, and the compiler thinks it's dynamic.leading to runtime errors when the type mismatches.
output of the program is:
also in my use case, I can't change the extension to
since I need access to the exact nested type.
dart info:
The text was updated successfully, but these errors were encountered: