Skip to content

Commit

Permalink
Fixed bug that caused type alias to Never or NoReturn to lose its…
Browse files Browse the repository at this point in the history
… type alias association in some circumstances. (#9127)
  • Loading branch information
erictraut authored Oct 1, 2024
1 parent c2364e4 commit 606e12e
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 10 deletions.
21 changes: 11 additions & 10 deletions packages/pyright-internal/src/analyzer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Representation of types used during type analysis within Python.
*/

import { partition } from '../common/collectionUtils';
import { assert } from '../common/debug';
import { Uri } from '../common/uri/uri';
import { ArgumentNode, ExpressionNode, NameNode, ParamCategory } from '../parser/parseNodes';
Expand Down Expand Up @@ -3650,19 +3651,19 @@ export interface CombineTypesOptions {
// are combined into a UnionType. NeverTypes are filtered out.
// If no types remain in the end, a NeverType is returned.
export function combineTypes(subtypes: Type[], options?: CombineTypesOptions): Type {
// Filter out any "Never" and "NoReturn" types.
let sawNoReturn = false;
let neverTypes: NeverType[];

if (subtypes.some((subtype) => subtype.category === TypeCategory.Never))
subtypes = subtypes.filter((subtype) => {
if (subtype.category === TypeCategory.Never && subtype.priv.isNoReturn) {
sawNoReturn = true;
}
return subtype.category !== TypeCategory.Never;
});
// Filter out any Never or NoReturn types.
[neverTypes, subtypes] = partition<Type, NeverType>(subtypes, isNever);

if (subtypes.length === 0) {
return sawNoReturn ? NeverType.createNoReturn() : NeverType.createNever();
if (neverTypes.length > 0) {
// Prefer NoReturn over Never. This approach preserves type alias
// information if present.
return neverTypes.find((t) => t.priv.isNoReturn) ?? neverTypes[0];
}

return NeverType.createNever();
}

// Handle the common case where there is only one type.
Expand Down
16 changes: 16 additions & 0 deletions packages/pyright-internal/src/common/collectionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,22 @@ export function appendArray<T>(to: T[], elementsToPush: T[]) {
}
}

/** Works like Array.filter except that it returns a second array with the filtered elements. **/
export function partition<T, S extends T>(array: readonly T[], cb: (value: T) => boolean): [S[], T[]] {
const trueItems: S[] = [];
const falseItems: T[] = [];

for (const item of array) {
if (cb(item)) {
trueItems.push(item as S);
} else {
falseItems.push(item);
}
}

return [trueItems, falseItems];
}

/** Works like Array.prototype.find, returning `undefined` if no element satisfying the predicate is found. */
export function find<T, U extends T>(
array: readonly T[],
Expand Down

0 comments on commit 606e12e

Please sign in to comment.