Improve error message for non-promotion due to assignment.

This is clearer because:

- The use of "could not be promoted" is consistent with the other "why
  not promoted" messages.

- We avoid speculating about whether the variable might be assigned a
  null value; this should help avoid confusion in cases where the user
  can see that assigning a null value is impossible, but promotion
  still fails.

- We avoid the phrase "intervening write", which is a little too
  erudite.

Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: I0b8a2132dc99dd06769677f98e6257e9b55ad9d6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193820
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
This commit is contained in:
Paul Berry 2021-04-03 13:43:36 +00:00 committed by commit-bot@chromium.org
parent a8590a287e
commit 1cffb93ad7
5 changed files with 29 additions and 25 deletions

View file

@ -9707,14 +9707,17 @@ const MessageCode messageVarReturnType = const MessageCode("VarReturnType",
r"""Try removing the keyword 'var', or replacing it with the name of the return type.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name, String string)>
templateVariableCouldBeNullDueToWrite =
const Template<Message Function(String name, String string)>(
messageTemplate:
r"""Variable '#name' could be null due to an intervening write.""",
tipTemplate:
r"""Try null checking the variable after the write. See #string""",
withArguments: _withArgumentsVariableCouldBeNullDueToWrite);
const Template<
Message Function(
String name,
String
string)> templateVariableCouldBeNullDueToWrite = const Template<
Message Function(String name, String string)>(
messageTemplate:
r"""Variable '#name' could not be promoted due to an assignment.""",
tipTemplate:
r"""Try null checking the variable after the assignment. See #string""",
withArguments: _withArgumentsVariableCouldBeNullDueToWrite);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(String name, String string)>
@ -9731,8 +9734,9 @@ Message _withArgumentsVariableCouldBeNullDueToWrite(
if (string.isEmpty) throw 'No string provided';
return new Message(codeVariableCouldBeNullDueToWrite,
message:
"""Variable '${name}' could be null due to an intervening write.""",
tip: """Try null checking the variable after the write. See ${string}""",
"""Variable '${name}' could not be promoted due to an assignment.""",
tip:
"""Try null checking the variable after the assignment. See ${string}""",
arguments: {'name': name, 'string': string});
}

View file

@ -3555,8 +3555,8 @@ class _WhyNotPromotedVisitor
Expression writeExpression, NonPromotionReason reason) {
return DiagnosticMessageImpl(
filePath: source.fullName,
message: "Variable '$variableName' could be null due to an intervening "
"write. See ${reason.documentationLink}",
message: "Variable '$variableName' could not be promoted due to an "
"assignment. See ${reason.documentationLink}",
offset: writeExpression.offset,
length: writeExpression.length);
}

View file

@ -4655,8 +4655,8 @@ MultipleVarianceModifiers:
analyzerCode: ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS
VariableCouldBeNullDueToWrite:
template: "Variable '#name' could be null due to an intervening write."
tip: "Try null checking the variable after the write. See #string"
template: "Variable '#name' could not be promoted due to an assignment."
tip: "Try null checking the variable after the assignment. See #string"
FieldNotPromoted:
template: "'#name' refers to a property so it couldn't be promoted."

View file

@ -11,7 +11,7 @@ direct_assignment(int? i, int? j) {
if (i == null) return;
i = j;
//^
// [context 1] Variable 'i' could be null due to an intervening write.
// [context 1] Variable 'i' could not be promoted due to an assignment.
i.isEven;
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
@ -23,7 +23,7 @@ compound_assignment(C? c, int i) {
if (c == null) return;
c += i;
//^
// [context 2] Variable 'c' could be null due to an intervening write.
// [context 2] Variable 'c' could not be promoted due to an assignment.
c.cProperty;
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
@ -35,7 +35,7 @@ via_postfix_op(C? c) {
if (c == null) return;
c++;
//^
// [context 3] Variable 'c' could be null due to an intervening write.
// [context 3] Variable 'c' could not be promoted due to an assignment.
c.cProperty;
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
@ -47,7 +47,7 @@ via_prefix_op(C? c) {
if (c == null) return;
++c;
//^
// [context 4] Variable 'c' could be null due to an intervening write.
// [context 4] Variable 'c' could not be promoted due to an assignment.
c.cProperty;
// ^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
@ -59,7 +59,7 @@ via_for_each_statement(int? i, List<int?> list) {
if (i == null) return;
for (i in list) {
// ^
// [context 5] Variable 'i' could be null due to an intervening write.
// [context 5] Variable 'i' could not be promoted due to an assignment.
i.isEven;
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
@ -72,7 +72,7 @@ via_for_each_list_element(int? i, List<int?> list) {
if (i == null) return;
[for (i in list) i.isEven];
// ^
// [context 6] Variable 'i' could be null due to an intervening write.
// [context 6] Variable 'i' could not be promoted due to an assignment.
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
@ -83,7 +83,7 @@ via_for_each_set_element(int? i, List<int?> list) {
if (i == null) return;
({for (i in list) i.isEven});
// ^
// [context 7] Variable 'i' could be null due to an intervening write.
// [context 7] Variable 'i' could not be promoted due to an assignment.
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
@ -94,7 +94,7 @@ via_for_each_map_key(int? i, List<int?> list) {
if (i == null) return;
({for (i in list) i.isEven: null});
// ^
// [context 8] Variable 'i' could be null due to an intervening write.
// [context 8] Variable 'i' could not be promoted due to an assignment.
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^
@ -105,7 +105,7 @@ via_for_each_map_value(int? i, List<int?> list) {
if (i == null) return;
({for (i in list) null: i.isEven});
// ^
// [context 9] Variable 'i' could be null due to an intervening write.
// [context 9] Variable 'i' could not be promoted due to an assignment.
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// ^

View file

@ -32,7 +32,7 @@ property_get_of_variable(int? i, int? j) {
if (i == null) return;
i = j;
//^
// [context 1] Variable 'i' could be null due to an intervening write.
// [context 1] Variable 'i' could not be promoted due to an assignment.
i.isEven;
// ^^^^^^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
@ -44,7 +44,7 @@ extension_property_get_of_variable(int? i, int? j) {
if (i == null) return;
i = j;
//^
// [context 2] Variable 'i' could be null due to an intervening write.
// [context 2] Variable 'i' could not be promoted due to an assignment.
i.propertyOnNullableInt;
i.propertyOnNonNullInt;
// ^^^^^^^^^^^^^^^^^^^^