Added new type utils function isLiteralLikeType and fixed a few literal-related bugs that were masked by other logic. (#8828)

This commit is contained in:
Eric Traut 2024-08-25 09:43:28 -07:00 committed by GitHub
parent ecef512ade
commit bdea6d0064
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 22 additions and 10 deletions

View File

@ -311,6 +311,7 @@ import {
isEllipsisType, isEllipsisType,
isIncompleteUnknown, isIncompleteUnknown,
isInstantiableMetaclass, isInstantiableMetaclass,
isLiteralLikeType,
isLiteralType, isLiteralType,
isMaybeDescriptorInstance, isMaybeDescriptorInstance,
isMetaclassInstance, isMetaclassInstance,
@ -1717,7 +1718,7 @@ export function createTypeEvaluator(
return mapSubtypes(type, (subtype) => { return mapSubtypes(type, (subtype) => {
if (isClass(subtype)) { if (isClass(subtype)) {
if (subtype.priv.literalValue !== undefined) { if (subtype.priv.literalValue !== undefined) {
return ClassType.cloneWithLiteral(subtype, /* value */ undefined); subtype = ClassType.cloneWithLiteral(subtype, /* value */ undefined);
} }
if (ClassType.isBuiltIn(subtype, 'LiteralString')) { if (ClassType.isBuiltIn(subtype, 'LiteralString')) {
@ -22994,16 +22995,12 @@ export function createTypeEvaluator(
// If we're enforcing invariance, literal types must match. // If we're enforcing invariance, literal types must match.
if ((flags & AssignTypeFlags.Invariant) !== 0) { if ((flags & AssignTypeFlags.Invariant) !== 0) {
const srcIsLiteral = srcType.priv.literalValue !== undefined; const srcIsLiteral = isLiteralLikeType(srcType);
const destIsLiteral = destType.priv.literalValue !== undefined; const destIsLiteral = isLiteralLikeType(destType);
if (srcIsLiteral !== destIsLiteral) { if (srcIsLiteral !== destIsLiteral) {
return false; return false;
} }
} else {
// If the dest is an 'object', it's assignable.
if (ClassType.isBuiltIn(destType, 'object')) {
return true;
}
} }
for (let ancestorIndex = inheritanceChain.length - 1; ancestorIndex >= 0; ancestorIndex--) { for (let ancestorIndex = inheritanceChain.length - 1; ancestorIndex >= 0; ancestorIndex--) {
@ -23732,7 +23729,10 @@ export function createTypeEvaluator(
return true; return true;
} }
if (destType.priv.literalValue !== undefined) { if (
destType.priv.literalValue !== undefined &&
ClassType.isSameGenericClass(destType, concreteSrcType)
) {
const srcLiteral = concreteSrcType.priv.literalValue; const srcLiteral = concreteSrcType.priv.literalValue;
if (srcLiteral === undefined || !ClassType.isLiteralValueSame(concreteSrcType, destType)) { if (srcLiteral === undefined || !ClassType.isLiteralValueSame(concreteSrcType, destType)) {
diag?.addMessage( diag?.addMessage(

View File

@ -1259,6 +1259,18 @@ export function isLiteralTypeOrUnion(type: Type, allowNone = false): boolean {
return false; return false;
} }
export function isLiteralLikeType(type: ClassType): boolean {
if (type.priv.literalValue !== undefined) {
return true;
}
if (ClassType.isBuiltIn(type, 'LiteralString')) {
return true;
}
return false;
}
export function containsLiteralType(type: Type, includeTypeArgs = false): boolean { export function containsLiteralType(type: Type, includeTypeArgs = false): boolean {
class ContainsLiteralTypeWalker extends TypeWalker { class ContainsLiteralTypeWalker extends TypeWalker {
foundLiteral = false; foundLiteral = false;
@ -1269,7 +1281,7 @@ export function containsLiteralType(type: Type, includeTypeArgs = false): boolea
override visitClass(classType: ClassType): void { override visitClass(classType: ClassType): void {
if (isClassInstance(classType)) { if (isClassInstance(classType)) {
if (isLiteralType(classType) || ClassType.isBuiltIn(classType, 'LiteralString')) { if (isLiteralLikeType(classType)) {
this.foundLiteral = true; this.foundLiteral = true;
this.cancelWalk(); this.cancelWalk();
} }