mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:57:35 +00:00
Don't promote this
inside extension methods.
Bug: https://github.com/dart-lang/sdk/issues/44652 Change-Id: I05e5acfbff1d498fa3ad513d956510909ec7d24f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/178920 Commit-Queue: Paul Berry <paulberry@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
4ea0bae02a
commit
10917ffd55
|
@ -0,0 +1,24 @@
|
|||
// 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.
|
||||
|
||||
// This test verifies that `this` cannot be promoted, even if it appears in an
|
||||
// extension method.
|
||||
|
||||
class C {
|
||||
void insideClass() {
|
||||
if (this is D) {
|
||||
this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class D extends C {}
|
||||
|
||||
extension on C {
|
||||
void insideExtension() {
|
||||
if (this is D) {
|
||||
this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
import 'dart:core' hide MapEntry;
|
||||
|
||||
import 'package:_fe_analyzer_shared/src/util/link.dart';
|
||||
import 'package:front_end/src/api_prototype/lowering_predicates.dart';
|
||||
import 'package:kernel/ast.dart';
|
||||
import 'package:kernel/src/legacy_erasure.dart';
|
||||
import 'package:kernel/type_algebra.dart' show Substitution;
|
||||
|
@ -6567,8 +6568,12 @@ class InferenceVisitor
|
|||
if (nonNullableType != variable.type) {
|
||||
promotedType = nonNullableType;
|
||||
}
|
||||
} else if (!variable.isLocalFunction) {
|
||||
} else if (variable.isLocalFunction) {
|
||||
// Don't promote local functions.
|
||||
} else if (isExtensionThis(variable)) {
|
||||
// Don't promote the synthetic variable `#this` that we use to represent
|
||||
// `this` inside extension methods.
|
||||
} else {
|
||||
promotedType = inferrer.flowAnalysis.variableRead(node, variable);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
// 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.
|
||||
|
||||
// This test verifies that attempts to promote the type of `this` inside an
|
||||
// extension method have no effect.
|
||||
|
||||
void f(dynamic d) {}
|
||||
|
||||
class C {
|
||||
int? cProp;
|
||||
}
|
||||
|
||||
extension on C? {
|
||||
void testCQuestion() {
|
||||
if (this != null) {
|
||||
f(this.cProp);
|
||||
//^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
|
||||
// ^
|
||||
// [cfe] Property 'cProp' cannot be accessed on 'C?' because it is potentially null.
|
||||
f(cProp);
|
||||
//^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
|
||||
// [cfe] Property 'cProp' cannot be accessed on 'C?' because it is potentially null.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
int? dProp;
|
||||
}
|
||||
|
||||
extension on C {
|
||||
void testC() {
|
||||
if (this is D) {
|
||||
f(this.dProp);
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
|
||||
// [cfe] The getter 'dProp' isn't defined for the class 'C'.
|
||||
f(dProp);
|
||||
//^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
|
||||
// [cfe] The getter 'dProp' isn't defined for the class 'C'.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main() {
|
||||
C().testCQuestion();
|
||||
C().testC();
|
||||
D().testCQuestion();
|
||||
D().testC();
|
||||
(null as C?).testCQuestion();
|
||||
}
|
Loading…
Reference in a new issue