Skip to content

Commit 0a92b0c

Browse files
stereotype441Commit Bot
authored and
Commit Bot
committed
Turn on the experimental feature inference-update-1.
Fixes dart-lang/language#731. Change-Id: I5fee1470efe7b891b79dcfecd33bc3670590efb3 Tested: trybots, and global presubmit in the internal mono repo Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/243530 Reviewed-by: Bob Nystrom <[email protected]> Commit-Queue: Paul Berry <[email protected]> Reviewed-by: Liam Appelbe <[email protected]> Reviewed-by: Michael Thomsen <[email protected]>
1 parent ddad653 commit 0a92b0c

File tree

7 files changed

+85
-33
lines changed

7 files changed

+85
-33
lines changed

CHANGELOG.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,52 @@
11
## 2.18.0
22

3+
### Language
4+
5+
The following features are new in the Dart 2.18 [language version][]. To use
6+
them, you must set the lower bound on the SDK constraint for your package to
7+
2.18 or greater (`sdk: '>=2.18.0 <3.0.0'`).
8+
9+
[language version]: https://dart.dev/guides/language/evolution
10+
11+
- **[Enhanced type inference for generic invocations with function
12+
literals][]**: Invocations of generic methods/constructors that supply
13+
function literal arguments now have improved type inference. This primarily
14+
affects the `Iterable.fold` method. For example, in previous versions of
15+
Dart, the compiler would fail to infer an appropriate type for the parameter
16+
`a`:
17+
18+
```dart
19+
void main() {
20+
List<int> ints = [1, 2, 3];
21+
var maximum = ints.fold(0, (a, b) => a < b ? b : a);
22+
}
23+
```
24+
25+
With this improvement, `a` receives its type from the initial value, `0`.
26+
27+
On rare occasions, the wrong type will be inferred, leading to a compile-time
28+
error, for example in this code, type inference will infer that `a` has a
29+
type of `Null`:
30+
31+
```dart
32+
void main() {
33+
List<int> ints = [1, 2, 3];
34+
var maximumOrNull = ints.fold(null,
35+
(a, b) => a == null || a < b ? b : a);
36+
}
37+
```
38+
39+
This can be worked around by supplying the appropriate type as an explicit
40+
type argument to `fold`:
41+
42+
```dart
43+
void main() {
44+
List<int> ints = [1, 2, 3];
45+
var maximumOrNull = ints.fold<int?>(null,
46+
(a, b) => a == null || a < b ? b : a);
47+
}
48+
```
49+
350
### Core libraries
451

552
#### `dart:html`

pkg/analyzer/lib/src/dart/analysis/experiments.g.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ class ExperimentalFeatures {
197197
documentation:
198198
'Horizontal type inference for function expressions passed to generic invocations.',
199199
experimentalReleaseVersion: null,
200-
releaseVersion: null,
200+
releaseVersion: Version.parse('2.18.0'),
201201
);
202202

203203
static final inference_update_2 = ExperimentalFeature(
@@ -350,7 +350,7 @@ class IsEnabledByDefault {
350350
static const bool generic_metadata = true;
351351

352352
/// Default state of the experiment "inference-update-1"
353-
static const bool inference_update_1 = false;
353+
static const bool inference_update_1 = true;
354354

355355
/// Default state of the experiment "inference-update-2"
356356
static const bool inference_update_2 = false;

pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class ExperimentalFlag {
125125

126126
static const ExperimentalFlag inferenceUpdate1 = const ExperimentalFlag(
127127
name: 'inference-update-1',
128-
isEnabledByDefault: false,
128+
isEnabledByDefault: true,
129129
isExpired: false,
130130
enabledVersion: const Version(2, 18),
131131
experimentEnabledVersion: const Version(2, 18),

runtime/vm/experimental_features.cc

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,39 +18,29 @@ namespace dart {
1818

1919
bool GetExperimentalFeatureDefault(ExperimentalFeature feature) {
2020
constexpr bool kFeatureValues[] = {
21-
true,
22-
true,
23-
true,
24-
true,
25-
true,
26-
true,
27-
true,
28-
true,
29-
true,
30-
true,
31-
true,
32-
true,
33-
true,
21+
true, true, true, true, true, true, true,
22+
true, true, true, true, true, true, true,
3423
};
3524
ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureValues));
3625
return kFeatureValues[static_cast<int>(feature)];
3726
}
3827

3928
const char* GetExperimentalFeatureName(ExperimentalFeature feature) {
4029
constexpr const char* kFeatureNames[] = {
41-
"nonfunction-type-aliases",
42-
"non-nullable",
43-
"extension-methods",
44-
"constant-update-2018",
45-
"control-flow-collections",
46-
"generic-metadata",
47-
"set-literals",
48-
"spread-collections",
49-
"triple-shift",
50-
"constructor-tearoffs",
51-
"enhanced-enums",
52-
"named-arguments-anywhere",
53-
"super-parameters",
30+
"nonfunction-type-aliases",
31+
"non-nullable",
32+
"extension-methods",
33+
"constant-update-2018",
34+
"control-flow-collections",
35+
"generic-metadata",
36+
"set-literals",
37+
"spread-collections",
38+
"triple-shift",
39+
"constructor-tearoffs",
40+
"enhanced-enums",
41+
"named-arguments-anywhere",
42+
"super-parameters",
43+
"inference-update-1",
5444
};
5545
ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureNames));
5646
return kFeatureNames[static_cast<int>(feature)];

runtime/vm/experimental_features.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ enum class ExperimentalFeature {
2727
enhanced_enums,
2828
named_arguments_anywhere,
2929
super_parameters,
30+
inference_update_1,
3031
};
3132

3233
bool GetExperimentalFeatureDefault(ExperimentalFeature feature);

tests/corelib/iterable_empty_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ main() {
1818
Expect.throwsRangeError(() => it.elementAt(0), name);
1919
Expect.throwsStateError(() => it.reduce((a, b) => a), name);
2020
Expect.throwsStateError(() => it.singleWhere((_) => true), name);
21-
Expect.equals(42, it.fold(42, (a, b) => "not 42"), name);
21+
Expect.equals(42, it.fold<dynamic>(42, (a, b) => "not 42"), name);
2222
Expect.equals(42, it.firstWhere((v) => true, orElse: () => 42), name);
2323
Expect.equals(42, it.lastWhere((v) => true, orElse: () => 42), name);
2424
Expect.equals("", it.join("separator"), name);

tools/experimental_features.yaml

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,6 @@ features:
125125
macros:
126126
help: "Static meta-programming"
127127

128-
inference-update-1:
129-
help: "Horizontal type inference for function expressions passed to generic invocations."
130-
131128
inference-update-2:
132129
help: "Type promotion for fields"
133130

@@ -264,3 +261,20 @@ features:
264261
void main(){
265262
print(C('feature enabled').foo);
266263
}
264+
265+
inference-update-1:
266+
help: "Horizontal type inference for function expressions passed to generic invocations."
267+
enabledIn: '2.18.0'
268+
validation: |
269+
void test(List<int> list) {
270+
var a = list.fold(0, (x, y) => x + y);
271+
f(a);
272+
}
273+
void f<T>(T t) {
274+
if (T == int) {
275+
print('feature enabled');
276+
}
277+
}
278+
void main() {
279+
test([1, 2, 3]);
280+
}

0 commit comments

Comments
 (0)