Legacy. Remove star types from more type operations.

Change-Id: I0bad6f5d7fa9e843224b1948f55ea5dcefc7026c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/356284
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Phil Quitslund <pquitslund@google.com>
This commit is contained in:
Konstantin Shcheglov 2024-03-07 22:59:51 +00:00 committed by Commit Queue
parent 6b9e8cd47b
commit 5281b9c0f8
13 changed files with 15 additions and 118 deletions

View file

@ -95,7 +95,7 @@ import 'package:meta/meta.dart';
// TODO(scheglov): Clean up the list of implicitly analyzed files.
class AnalysisDriver {
/// The version of data format, should be incremented on every format change.
static const int DATA_VERSION = 350;
static const int DATA_VERSION = 351;
/// The number of exception contexts allowed to write. Once this field is
/// zero, we stop writing any new exception contexts in this process.

View file

@ -67,16 +67,6 @@ class TopMergeHelper {
return typeSystem.objectQuestion;
}
// NNBD_TOP_MERGE(Object*, void) = void
// NNBD_TOP_MERGE(void, Object*) = void
var T_isObjectStar =
T_nullability == NullabilitySuffix.star && T.isDartCoreObject;
var S_isObjectStar =
S_nullability == NullabilitySuffix.star && S.isDartCoreObject;
if (T_isObjectStar && S_isVoid || T_isVoid && S_isObjectStar) {
return typeSystem.objectQuestion;
}
// NNBD_TOP_MERGE(dynamic, void) = void
// NNBD_TOP_MERGE(void, dynamic) = void
if (T_isDynamic && S_isVoid || T_isVoid && S_isDynamic) {
@ -92,45 +82,16 @@ class TopMergeHelper {
return S;
}
// NNBD_TOP_MERGE(Object*, dynamic) = Object?
// NNBD_TOP_MERGE(dynamic, Object*) = Object?
if (T_isObjectStar && S_isDynamic || T_isDynamic && S_isObjectStar) {
return typeSystem.objectQuestion;
}
// Merge nullabilities.
var T_isNone = T_nullability == NullabilitySuffix.none;
var S_isNone = S_nullability == NullabilitySuffix.none;
if (!T_isNone || !S_isNone) {
var T_isQuestion = T_nullability == NullabilitySuffix.question;
var T_isStar = T_nullability == NullabilitySuffix.star;
var S_isQuestion = S_nullability == NullabilitySuffix.question;
var S_isStar = S_nullability == NullabilitySuffix.star;
NullabilitySuffix resultNullability;
if (T_isQuestion && S_isQuestion ||
T_isQuestion && S_isStar ||
T_isStar && S_isQuestion) {
// NNBD_TOP_MERGE(T?, S?) = NNBD_TOP_MERGE(T, S)?
// NNBD_TOP_MERGE(T?, S*) = NNBD_TOP_MERGE(T, S)?
// NNBD_TOP_MERGE(T*, S?) = NNBD_TOP_MERGE(T, S)?
resultNullability = NullabilitySuffix.question;
} else if (T_isStar && S_isStar) {
// NNBD_TOP_MERGE(T*, S*) = NNBD_TOP_MERGE(T, S)*
resultNullability = NullabilitySuffix.star;
} else if (T_isStar && S_isNone || T_isNone && S_isStar) {
// NNBD_TOP_MERGE(T*, S) = NNBD_TOP_MERGE(T, S)
// NNBD_TOP_MERGE(T, S*) = NNBD_TOP_MERGE(T, S)
resultNullability = NullabilitySuffix.none;
} else {
throw StateError('$T_nullability vs $S_nullability');
}
var T_isQuestion = T_nullability == NullabilitySuffix.question;
var S_isQuestion = S_nullability == NullabilitySuffix.question;
if (T_isQuestion && S_isQuestion) {
var T_none = (T as TypeImpl).withNullability(NullabilitySuffix.none);
var S_none = (S as TypeImpl).withNullability(NullabilitySuffix.none);
var R_none = topMerge(T_none, S_none) as TypeImpl;
return R_none.withNullability(resultNullability);
return R_none.withNullability(NullabilitySuffix.question);
} else if (T_isQuestion || S_isQuestion) {
throw StateError('$T_nullability vs $S_nullability');
}
assert(T_nullability == NullabilitySuffix.none);

View file

@ -1514,9 +1514,6 @@ class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
if (nullabilitySuffix == NullabilitySuffix.question ||
bound.nullabilitySuffix == NullabilitySuffix.question) {
newNullabilitySuffix = NullabilitySuffix.question;
} else if (nullabilitySuffix == NullabilitySuffix.star ||
bound.nullabilitySuffix == NullabilitySuffix.star) {
newNullabilitySuffix = NullabilitySuffix.star;
} else {
newNullabilitySuffix = NullabilitySuffix.none;
}

View file

@ -107,21 +107,13 @@ DartType substitute(
}
/// 1. Substituting T=X! into T! yields X!
/// 2. Substituting T=X* into T! yields X*
/// 3. Substituting T=X? into T! yields X?
/// 4. Substituting T=X! into T* yields X*
/// 5. Substituting T=X* into T* yields X*
/// 6. Substituting T=X? into T* yields X?
/// 7. Substituting T=X! into T? yields X?
/// 8. Substituting T=X* into T? yields X?
/// 9. Substituting T=X? into T? yields X?
NullabilitySuffix uniteNullabilities(NullabilitySuffix a, NullabilitySuffix b) {
if (a == NullabilitySuffix.question || b == NullabilitySuffix.question) {
return NullabilitySuffix.question;
}
if (a == NullabilitySuffix.star || b == NullabilitySuffix.star) {
return NullabilitySuffix.star;
}
return NullabilitySuffix.none;
}
@ -328,7 +320,7 @@ class _NullSubstitution extends MapSubstitution {
DartType getSubstitute(TypeParameterElement parameter, bool upperBound) {
return TypeParameterTypeImpl(
element: parameter,
nullabilitySuffix: NullabilitySuffix.star,
nullabilitySuffix: NullabilitySuffix.none,
);
}

View file

@ -104,33 +104,6 @@ class TypeConstraintGatherer {
return true;
}
// If `P` is a legacy type `P0*` then the match holds under constraint
// set `C`:
// Only if `P0` is a subtype match for `Q` under constraint set `C`.
if (P_nullability == NullabilitySuffix.star) {
var P0 = (P as TypeImpl).withNullability(NullabilitySuffix.none);
return trySubtypeMatch(P0, Q, leftSchema);
}
// If `Q` is a legacy type `Q0*` then the match holds under constraint
// set `C`:
if (Q_nullability == NullabilitySuffix.star) {
// If `P` is `dynamic` or `void` and `P` is a subtype match
// for `Q0` under constraint set `C`.
if (_typeSystemOperations.isDynamic(P) ||
_typeSystemOperations.isVoid(P)) {
var rewind = _constraints.length;
var Q0 = (Q as TypeImpl).withNullability(NullabilitySuffix.none);
if (trySubtypeMatch(P, Q0, leftSchema)) {
return true;
}
_constraints.length = rewind;
}
// Or if `P` is a subtype match for `Q0?` under constraint set `C`.
var Qq = (Q as TypeImpl).withNullability(NullabilitySuffix.question);
return trySubtypeMatch(P, Qq, leftSchema);
}
// If `Q` is `FutureOr<Q0>` the match holds under constraint set `C`:
if (_typeSystemOperations.matchFutureOr(Q) case var Q0?
when Q_nullability == NullabilitySuffix.none) {

View file

@ -41,7 +41,7 @@ class UnknownInferredType extends TypeImpl {
String get name => Keyword.DYNAMIC.lexeme;
@override
NullabilitySuffix get nullabilitySuffix => NullabilitySuffix.star;
NullabilitySuffix get nullabilitySuffix => NullabilitySuffix.question;
@override
bool operator ==(Object other) => identical(other, this);

View file

@ -316,7 +316,7 @@ class ReturnTypeVerifier {
//
var lowerBound = expectedElement.instantiate(
typeArguments: [NeverTypeImpl.instance],
nullabilitySuffix: NullabilitySuffix.star,
nullabilitySuffix: NullabilitySuffix.none,
);
return _typeSystem.isSubtypeOf(lowerBound, returnType);
}

View file

@ -545,7 +545,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
// be done.
var lowerBound = typeProvider.futureElement.instantiate(
typeArguments: fixedTypeList(NeverTypeImpl.instance),
nullabilitySuffix: NullabilitySuffix.star,
nullabilitySuffix: NullabilitySuffix.none,
);
var imposedType = bodyContext.imposedType;
if (imposedType != null &&

View file

@ -37,7 +37,7 @@ class ElementFactory {
static InterfaceType get objectType {
return _objectType ??= object.instantiate(
typeArguments: const [],
nullabilitySuffix: NullabilitySuffix.star,
nullabilitySuffix: NullabilitySuffix.none,
);
}

View file

@ -142,10 +142,9 @@ class Tag {
static const int InterfaceType = 7;
static const int InterfaceType_noTypeArguments_none = 8;
static const int InterfaceType_noTypeArguments_question = 9;
static const int InterfaceType_noTypeArguments_star = 10;
static const int RecordType = 11;
static const int TypeParameterType = 12;
static const int VoidType = 13;
static const int RecordType = 10;
static const int TypeParameterType = 11;
static const int VoidType = 12;
}
enum TypeAnnotationLocationKind {

View file

@ -2098,14 +2098,6 @@ class ResolutionReader {
nullabilitySuffix: NullabilitySuffix.question,
);
return _readAliasElementArguments(type);
} else if (tag == Tag.InterfaceType_noTypeArguments_star) {
var element = readElement() as InterfaceElement;
var type = InterfaceTypeImpl(
element: element,
typeArguments: const <DartType>[],
nullabilitySuffix: NullabilitySuffix.star,
);
return _readAliasElementArguments(type);
} else if (tag == Tag.InvalidType) {
var type = InvalidTypeImpl.instance;
return _readAliasElementArguments(type);

View file

@ -806,8 +806,6 @@ class ResolutionSink extends _SummaryDataWriter {
writeByte(Tag.InterfaceType_noTypeArguments_none);
} else if (nullabilitySuffix == NullabilitySuffix.question) {
writeByte(Tag.InterfaceType_noTypeArguments_question);
} else if (nullabilitySuffix == NullabilitySuffix.star) {
writeByte(Tag.InterfaceType_noTypeArguments_star);
}
// TODO(scheglov): Write raw
writeElement(type.element);

View file

@ -541,21 +541,6 @@ class SubstituteWithNullabilityTest extends _Base {
);
_assertSubstitution(type, {U: intNone}, 'A<int>?');
}
test_interface_star() async {
// class A<T> {}
var T = typeParameter('T');
var A = class_(name: 'A', typeParameters: [T]);
var U = typeParameter('U');
var type = A.instantiate(
typeArguments: [
U.instantiate(nullabilitySuffix: NullabilitySuffix.none),
],
nullabilitySuffix: NullabilitySuffix.star,
);
_assertSubstitution(type, {U: intNone}, 'A<int>*');
}
}
class _Base extends AbstractTypeSystemTest {