mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 10:49:00 +00:00
2b8411f626
This language feature allows type promotion to apply to private final fields, e.g.: class C { final int? _x; C(this._x); } f(C c) { if (c._x != null) { print(c._x.abs()); // (1) } } Previously the line marked (1) would have needed to be written `print(c._x!.abs());`. Note that to ensure soundness, there are certain restrictions: - Public fields don't undergo promotion (because a public field might be overridden by a class in some other library). - Non-final fields don't undergo promotion (because a non-final field might be modified as a side effect of code executed between the type test and the field's usage). - Fields that are forwarded to `noSuchMethod` in the same library don't undergo promotion (because there's no guarantee that `noSuchMethod` will return the same value on every invocation). For example: class C { final int? _x; C(this._x); } class D implements C { @override noSuchMethod(...) => ...; } f(C c) { if (c._x != null) { print(c._x.abs()); // ERROR: `c._x` might dispatch to // `D.noSuchMethod`, in which case there's // no guarantee that it will return a // non-null value the second time it's // invoked. } } - If two classes define fields or getters of the same name, and promotion is not permitted for one of them, then it isn't permitted for the other. This is because there might be a class in some other library that's a subclass of both classes, causing a reference to one field or getter to dispatch to the other. For example: class C { final int? _x; C(this._x); } class D { int? get _x => ...; } f(C c) { if (c._x != null) { print(c._x.abs()); // ERROR: `c._x` might dispatch to `D._x` // (e.g. because some library might declare // `class E extends D implements C`), in // which case there's no guarantee that it // will return a non-null value the second // time it's invoked. } } Change-Id: Ib9183581aa0194377e38ab70d37c3e9f0bb57a75 Bug: https://github.com/dart-lang/language/issues/2020 Tested: TAP global presubmit Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/314600 Reviewed-by: Ryan Macnak <rmacnak@google.com> Reviewed-by: Nate Bosch <nbosch@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
44 lines
1.1 KiB
C++
44 lines
1.1 KiB
C++
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
// NOTE: THIS FILE IS GENERATED. DO NOT EDIT.
|
|
//
|
|
// Instead modify 'tools/experimental_features.yaml' and run
|
|
// 'dart tools/generate_experimental_flags.dart' to update.
|
|
//
|
|
// Current version: 3.2.0
|
|
|
|
#ifndef RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
|
|
#define RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
|
|
|
|
namespace dart {
|
|
|
|
enum class ExperimentalFeature {
|
|
inference_update_2,
|
|
sealed_class,
|
|
class_modifiers,
|
|
records,
|
|
patterns,
|
|
unnamed_libraries,
|
|
inference_update_1,
|
|
enhanced_enums,
|
|
named_arguments_anywhere,
|
|
super_parameters,
|
|
constructor_tearoffs,
|
|
generic_metadata,
|
|
triple_shift,
|
|
nonfunction_type_aliases,
|
|
non_nullable,
|
|
extension_methods,
|
|
constant_update_2018,
|
|
control_flow_collections,
|
|
set_literals,
|
|
spread_collections,
|
|
};
|
|
|
|
bool GetExperimentalFeatureDefault(ExperimentalFeature feature);
|
|
const char* GetExperimentalFeatureName(ExperimentalFeature feature);
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
|