Skip to content

Experiment with tracking which entities actually may be narrowed #51525

Description

In Pyright, narrowing can be avoided by keeping track of which entities actually get narrowed within a given scope. This could save a good amount of time by avoiding redundant walks up the control flow graph just to discover nothing interesting a given variable or property.

I'm not sure if Pyright also tracks the first location at which an entity may be narrowed, but that information could also be used to signal when a narrowing walk needs to stop.

This would come at the cost of some memory overhead, but we'd need to experiment to see what the trade-offs are.

Activity

  1. jakebailey commented on Nov 14, 2022

    @jakebailey
    Member

    I think the code in question for pyright was introduced in:

  2. fatcerberus commented on Nov 14, 2022

    @fatcerberus

    Wait, does TS walk the control flow graph backwards to discover narrowings? I always figured the graph looked something like x = string | number -> if (true) x = string -> else x = number and the compiler would know exactly which part of the tree it was in at the time it encountered a reference to x so it could just look up the current type directly.

  3. DanielRosenwasser commented on Nov 14, 2022

    @DanielRosenwasser
    MemberAuthor

    It does walk backwards. If it walked forwards, it would have to retain the context of all potential narrowing operations (and for all potential types we'd want to narrow from - which is occasionally necessary for things like narrowing constraints of generics rather than the generics themselves). That wouldn't work in our system where checking an expression should be as lazy as possible.

    Anyway, in line with that, there are definitely opportunities for us to optimize here.

  4. fatcerberus commented on Nov 14, 2022

    @fatcerberus

    I guess that makes sense now that I think about it - there really aren't any "set the type to string" style narrowings - even typeof x === 'string' can narrow to never if the original type doesn't overlap with string. Otherwise you could probably do some kind of short-circuiting logic.

  5. added a commit that references this issue on May 30, 2023
    b8a7bbe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Domain: PerformanceReports of unusually slow behaviorExperimentation NeededSomeone needs to try this out to see what happensRescheduledThis issue was previously scheduled to an earlier milestoneSuggestionAn idea for TypeScript

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions