1
0
mirror of https://github.com/dart-lang/sdk synced 2024-07-05 09:20:04 +00:00

Issue 52202. Fix crash when object pattern type is potentially nullable.

Bug: https://github.com/dart-lang/sdk/issues/52202
Change-Id: I54068a58f68f46c3d75c1586e6ed575b361a22fc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/299380
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
This commit is contained in:
Konstantin Shcheglov 2023-04-28 03:20:39 +00:00 committed by Commit Queue
parent 7d9340156e
commit 7f503e3688
6 changed files with 67 additions and 10 deletions

View File

@ -1280,6 +1280,7 @@ mixin TypeAnalyzer<
for (RecordPatternField<Node, Pattern> field in fields) {
Type propertyType = overridePropertyGetType ??
resolveObjectPatternPropertyGet(
objectPattern: node,
receiverType: requiredType,
field: field,
);
@ -2267,6 +2268,7 @@ mixin TypeAnalyzer<
/// the name of the [field]. If the property cannot be resolved, the client
/// should report an error, and return `dynamic` for recovery.
Type resolveObjectPatternPropertyGet({
required Pattern objectPattern,
required Type receiverType,
required RecordPatternField<Node, Pattern> field,
});

View File

@ -3065,6 +3065,15 @@ class _MiniAstErrors
});
}
@override
void emptyMapPattern({
required Pattern pattern,
}) {
_recordError('emptyMapPattern', {
'pattern': pattern,
});
}
@override
void inconsistentJoinedPatternVariable({
required covariant PatternVariableJoin variable,
@ -3234,15 +3243,6 @@ class _MiniAstErrors
fail('Same error reported twice: $errorText');
}
}
@override
void emptyMapPattern({
required Pattern pattern,
}) {
_recordError('emptyMapPattern', {
'pattern': pattern,
});
}
}
class _MiniAstTypeAnalyzer
@ -3917,6 +3917,7 @@ class _MiniAstTypeAnalyzer
@override
Type resolveObjectPatternPropertyGet({
required Pattern objectPattern,
required Type receiverType,
required shared.RecordPatternField<Node, Pattern> field,
}) {

View File

@ -1618,6 +1618,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
@override
DartType resolveObjectPatternPropertyGet({
required covariant ObjectPatternImpl objectPattern,
required DartType receiverType,
required covariant SharedPatternField field,
}) {
@ -1632,7 +1633,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
receiver: null,
receiverType: receiverType,
name: nameToken.lexeme,
propertyErrorEntity: nameToken,
propertyErrorEntity: objectPattern.type,
nameErrorEntity: nameToken,
);

View File

@ -787,6 +787,47 @@ ObjectPattern
''');
}
test_typeAlias_nullable() async {
await assertErrorsInCode(r'''
typedef A = int?;
void f(x) {
switch (x) {
case A(foo: 0):
break;
}
}
''', [
error(CompileTimeErrorCode.UNCHECKED_PROPERTY_ACCESS_OF_NULLABLE_VALUE,
55, 1),
]);
final node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
ObjectPattern
type: NamedType
name: SimpleIdentifier
token: A
staticElement: self::@typeAlias::A
staticType: null
type: int?
alias: self::@typeAlias::A
leftParenthesis: (
fields
PatternField
name: PatternFieldName
name: foo
colon: :
pattern: ConstantPattern
expression: IntegerLiteral
literal: 0
staticType: int
matchedValueType: dynamic
element: <null>
rightParenthesis: )
matchedValueType: dynamic
''');
}
test_typedef_dynamic_hasName_unresolved() async {
await assertErrorsInCode(r'''
typedef A = dynamic;

View File

@ -11066,6 +11066,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
@override
DartType resolveObjectPatternPropertyGet({
required Pattern objectPattern,
required DartType receiverType,
required shared.RecordPatternField<TreeNode, Pattern> field,
}) {

View File

@ -0,0 +1,11 @@
typedef A = int?;
void f(x) {
switch (x) {
case A(foo: 0):
// ^
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
// [cfe] unspecified
break;
}
}