Skip to content

getRecursionIdentity currently runs a boolean AND instead of a bitwise AND on the objectFlags of its input #54320

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
angryzor opened this issue May 19, 2023 · 0 comments Β· Fixed by #54321
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@angryzor
Copy link
Contributor

Bug Report

πŸ”Ž Search Terms

  • getRecursionIdentity

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I did not review the FAQ as this is most probably an oversight.

⏯ Playground Link

Not applicable

πŸ’» Code

The function getRecursionIdentity currently contains the following code:

    // The recursion identity of a type is an object identity that is shared among multiple instantiations of the type.
    // We track recursion identities in order to identify deeply nested and possibly infinite type instantiations with
    // the same origin. For example, when type parameters are in scope in an object type such as { x: T }, all
    // instantiations of that type have the same recursion identity. The default recursion identity is the object
    // identity of the type, meaning that every type is unique. Generally, types with constituents that could circularly
    // reference the type have a recursion identity that differs from the object identity.
    function getRecursionIdentity(type: Type): object {
        // Object and array literals are known not to contain recursive references and don't need a recursion identity.
        if (type.flags & TypeFlags.Object && !isObjectOrArrayLiteralType(type)) {
            if (getObjectFlags(type) && ObjectFlags.Reference && (type as TypeReference).node) {
                // Deferred type references are tracked through their associated AST node. This gives us finer
                // granularity than using their associated target because each manifest type reference has a
                // unique AST node.
                return (type as TypeReference).node!;
            }
            if (type.symbol && !(getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol.flags & SymbolFlags.Class)) {
                // We track all object types that have an associated symbol (representing the origin of the type), but
                // exclude the static side of classes from this check since it shares its symbol with the instance side.
                return type.symbol;
            }
            if (isTupleType(type)) {
                return type.target;
            }
        }

πŸ™ Actual behavior

This code contains a bug in the following if condition:

if (getObjectFlags(type) && ObjectFlags.Reference && (type as TypeReference).node) {

It applies a boolean AND between the objectFlags of the type and the ObjectFlags.Reference flag.

πŸ™‚ Expected behavior

This should be a bitwise AND.

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Help Wanted You can do this labels May 22, 2023
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone May 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Help Wanted You can do this
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants