dart-lang / dart-lang/language

Extensions on nested generic mixins don't promote types properly

Open
#3,382 6 comments 0 reactions 0 assignees View on GitHub
request
Dominant language
TeX
Stars
2.9k
Forks
239
Avg merge
2d 18h
Merged PRs (30d)
14

Description

When declaring extensions on nested generic mixins `Mixin>` for example; the last type `T` is lost, and the compiler thinks it's dynamic.
leading to runtime errors when the type mismatches.
```dart
mixin TestMixin {
void operateOnValue(T value);
}
// First class expects a string.
class C1 with TestMixin {
@override
void operateOnValue(String value) {
print('operateOnValue: $value');
}
}

// Second class expects C1 which is a TestMixin
// so this class is matched with TestMixin>
class C2 with TestMixin {
@override
void operateOnValue(C1 value) {
// do nothing.
}
}

// extension targets TestMixin>.
extension NestedMixinExt>
on TestMixin {
void operateOnNestedValue(TestSub nestedMixin, TSub sub) {
print('calling operateOnValue, sub type is: $TSub');
nestedMixin.operateOnValue(sub);
}
}

void main(List arguments) {
final c1 = C1(); //TestMixin
final c2 = C2(); //TestMixin == TestMixin>

c2.operateOnNestedValue(c1, 'hello'); // prints "operateOnValue: hello" as expected.
c2.operateOnNestedValue(c1, 50); // compiles normally, and throws runtime error.
// type 'int' is not a subtype of type 'String' of 'value'
}
```
output of the program is:
```
calling operateOnValue with value hello, sub type is: dynamic
operateOnValue: hello
calling operateOnValue with value 50, sub type is: dynamic
Unhandled exception:
type 'int' is not a subtype of type 'String' of 'value'
```
also in my use case, I can't change the extension to
```dart
extension NestedMixinExt on TestMixin>
```
since I need access to the exact nested type.

dart info:
- Dart 3.1.3 (stable) (Tue Sep 26 14:25:13 2023 +0000) on "windows_x64"
- on windows / "Windows 10 Pro N" 10.0 (Build 19045)

Contributor guide

Open the contributing guide

Research direction

Start with the supplied Dart reproduction and its main entry point, focusing on the NestedMixinExt declaration and the two operateOnNestedValue calls. Investigate why T is treated as dynamic; done means the nested String type is preserved and the call passing 50 is rejected rather than failing at runtime.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.