-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Analyzer: incorrect default value override warning. #49112
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
Comments
Yes, it looks that the analyzer uses runtime type equality for constants. I vague remember that we decided (considered?) dropping the warning for not equal default value? |
I also have a vague memory that we had decided to do this globally (including non-null safe code), but if so apparently I never got around to filing the correct issues. |
I remember discussing this and a vague sentiment towards doing that but I don't know if we ever fully decided. I would be fine with removing this warning. |
The reason the CFE doesn't complain about this is that it never checks default values on override - the check was simply never implemented in the CFE. |
Eliminating the warning entirely seems both future-safe and benign. (We might want to have a lint for the same thing, such that developers and organizations who consider the default value of a parameter to be part of the public API can be notified about cases where an override changes the default.) However, there is an informal property about constants and legacy code which is/was useful during migration, mentioned here:
The fact that corner cases like So maybe we should focus on flagging those expressions as dangerous when in a mixed program, rather than working harder to let them slip through silently? This calls for another look at the potential fixes:
I was wondering why the Anyway, I suppose the following will qualify as a 'not good way', but 'lib.dart' could help in the following way (especially if the maintainers of 'lib.dart' get a heads-up about the subtle problems with // Library 'lib.dart'.
class O {}
class A<T extends Object> { // <---- This class is being migrated
void foo({Iterable<T> p1 = const <Never>[]}) {
print(p1.runtimeType);
}
static const fooP1Default = const <Never>[]; // This declaration helps legacy importers.
}
// Library 'opted_out.dart'.
// @dart=2.9
import "n009lib.dart";
class C implements A<O> {
@override
void foo({Iterable<O> p1 = A.fooP1Default}) {
print(p1.runtimeType);
}
}
void main() {
C().foo();
A().foo();
} |
One more possible approach: Use the (potential future) ability to denote default values explicitly, as proposed in dart-lang/language#2269: // --- Library 'lib.dart'
class O {}
class A<T extends Object> { // <---- This class is being migrated
void foo({Iterable<T> p1 = const <Never>[]}) {
print(p1.runtimeType);
}
}
// --- Library 'opted_out.dart'.
// @dart=2.9
import "lib.dart";
class C implements A<O> {
@override
void foo({Iterable<O> p1 = A.default}) { // This line has changed, the rest is unchanged.
print(p1.runtimeType);
}
}
void main() {
C().foo();
A().foo();
} We could have tool support for changing default values to use |
Fyi @srawlins it might make sense to prioritize this issue to help with null safety migrations. |
Is this affecting null safety migrations? How are people working around it? |
More context is at |
We're now hitting this in mockito-generated code, so I will remove invalid_override_different_default_values_named and invalid_override_different_default_values_positional from analyzer entirely. |
The analyzer code base currently suggests that these are warnings from the spec (by defining them in In either case, it would be good for us to do an audit to see which warnings analyzer has that it thinks are from the spec but that actually aren't, and, if we want to keep them, make it clear that they're not from the spec. |
The following code:
lib.dart
opted_out.dart
Produces the following error from the dart analyzer:
I believe this is incorrect. The CFE emits no diagnostics here, and the runtime values printed are both
List<Never>
I suspect there is an ambiguity in the spec: in one place we indicate that
Never
shall be treated asNull
in legacy libraries, but for constant canonicalization, we specify thatNever
should be treated asNever*
.Unfortunately this leaves users with no good way to migrate the first library above without breaking the second library.
I wonder if perhaps we should simply drop this warning, either entirely (since that's where null safety is going), or else not ever issue it across opted in/opted out libraries? That is, even if we warn when an opted out method overrides another opted out method with a different default, we probably shouldn't be warning if an opted out method overrides an opted in method with a different default.
cc @lrhn @eernstg @munificent @scheglov @bwilkerson @srawlins @johnniwinther
The text was updated successfully, but these errors were encountered: