Turn on the experimental feature inference-update-1.

Fixes https://github.com/dart-lang/language/issues/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 <rnystrom@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Liam Appelbe <liama@google.com>
Reviewed-by: Michael Thomsen <mit@google.com>
This commit is contained in:
Paul Berry 2022-05-24 13:54:23 +00:00 committed by Commit Bot
parent ddad653842
commit 0a92b0c3aa
7 changed files with 85 additions and 33 deletions

View file

@ -1,5 +1,52 @@
## 2.18.0
### Language
The following features are new in the Dart 2.18 [language version][]. To use
them, you must set the lower bound on the SDK constraint for your package to
2.18 or greater (`sdk: '>=2.18.0 <3.0.0'`).
[language version]: https://dart.dev/guides/language/evolution
- **[Enhanced type inference for generic invocations with function
literals][]**: Invocations of generic methods/constructors that supply
function literal arguments now have improved type inference. This primarily
affects the `Iterable.fold` method. For example, in previous versions of
Dart, the compiler would fail to infer an appropriate type for the parameter
`a`:
```dart
void main() {
List<int> ints = [1, 2, 3];
var maximum = ints.fold(0, (a, b) => a < b ? b : a);
}
```
With this improvement, `a` receives its type from the initial value, `0`.
On rare occasions, the wrong type will be inferred, leading to a compile-time
error, for example in this code, type inference will infer that `a` has a
type of `Null`:
```dart
void main() {
List<int> ints = [1, 2, 3];
var maximumOrNull = ints.fold(null,
(a, b) => a == null || a < b ? b : a);
}
```
This can be worked around by supplying the appropriate type as an explicit
type argument to `fold`:
```dart
void main() {
List<int> ints = [1, 2, 3];
var maximumOrNull = ints.fold<int?>(null,
(a, b) => a == null || a < b ? b : a);
}
```
### Core libraries
#### `dart:html`

View file

@ -197,7 +197,7 @@ class ExperimentalFeatures {
documentation:
'Horizontal type inference for function expressions passed to generic invocations.',
experimentalReleaseVersion: null,
releaseVersion: null,
releaseVersion: Version.parse('2.18.0'),
);
static final inference_update_2 = ExperimentalFeature(
@ -350,7 +350,7 @@ class IsEnabledByDefault {
static const bool generic_metadata = true;
/// Default state of the experiment "inference-update-1"
static const bool inference_update_1 = false;
static const bool inference_update_1 = true;
/// Default state of the experiment "inference-update-2"
static const bool inference_update_2 = false;

View file

@ -125,7 +125,7 @@ class ExperimentalFlag {
static const ExperimentalFlag inferenceUpdate1 = const ExperimentalFlag(
name: 'inference-update-1',
isEnabledByDefault: false,
isEnabledByDefault: true,
isExpired: false,
enabledVersion: const Version(2, 18),
experimentEnabledVersion: const Version(2, 18),

View file

@ -18,19 +18,8 @@ namespace dart {
bool GetExperimentalFeatureDefault(ExperimentalFeature feature) {
constexpr bool kFeatureValues[] = {
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true, true, true, true, true, true, true,
true, true, true, true, true, true, true,
};
ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureValues));
return kFeatureValues[static_cast<int>(feature)];
@ -38,19 +27,20 @@ bool GetExperimentalFeatureDefault(ExperimentalFeature feature) {
const char* GetExperimentalFeatureName(ExperimentalFeature feature) {
constexpr const char* kFeatureNames[] = {
"nonfunction-type-aliases",
"non-nullable",
"extension-methods",
"constant-update-2018",
"control-flow-collections",
"generic-metadata",
"set-literals",
"spread-collections",
"triple-shift",
"constructor-tearoffs",
"enhanced-enums",
"named-arguments-anywhere",
"super-parameters",
"nonfunction-type-aliases",
"non-nullable",
"extension-methods",
"constant-update-2018",
"control-flow-collections",
"generic-metadata",
"set-literals",
"spread-collections",
"triple-shift",
"constructor-tearoffs",
"enhanced-enums",
"named-arguments-anywhere",
"super-parameters",
"inference-update-1",
};
ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureNames));
return kFeatureNames[static_cast<int>(feature)];

View file

@ -27,6 +27,7 @@ enum class ExperimentalFeature {
enhanced_enums,
named_arguments_anywhere,
super_parameters,
inference_update_1,
};
bool GetExperimentalFeatureDefault(ExperimentalFeature feature);

View file

@ -18,7 +18,7 @@ main() {
Expect.throwsRangeError(() => it.elementAt(0), name);
Expect.throwsStateError(() => it.reduce((a, b) => a), name);
Expect.throwsStateError(() => it.singleWhere((_) => true), name);
Expect.equals(42, it.fold(42, (a, b) => "not 42"), name);
Expect.equals(42, it.fold<dynamic>(42, (a, b) => "not 42"), name);
Expect.equals(42, it.firstWhere((v) => true, orElse: () => 42), name);
Expect.equals(42, it.lastWhere((v) => true, orElse: () => 42), name);
Expect.equals("", it.join("separator"), name);

View file

@ -125,9 +125,6 @@ features:
macros:
help: "Static meta-programming"
inference-update-1:
help: "Horizontal type inference for function expressions passed to generic invocations."
inference-update-2:
help: "Type promotion for fields"
@ -264,3 +261,20 @@ features:
void main(){
print(C('feature enabled').foo);
}
inference-update-1:
help: "Horizontal type inference for function expressions passed to generic invocations."
enabledIn: '2.18.0'
validation: |
void test(List<int> list) {
var a = list.fold(0, (x, y) => x + y);
f(a);
}
void f<T>(T t) {
if (T == int) {
print('feature enabled');
}
}
void main() {
test([1, 2, 3]);
}