Rebecca Chen
90d · built 2026-08-09
90-day totals
- Commits
- 252
- Grow
- 2.8
- Maintenance
- 9.2
- Fixes
- 4.4
- Total ETV
- 16.4
Where this dev ranks
Percentile against the global top-100 leaderboard (all-time totals).
- By commits
- Top 1 %
- By Growth share
- Top 89 %
30-day trajectory
Last 30 days vs. the 30 days before. Up arrows on Growth and ETV mean improvement; up arrow on Fixes share means more time on fixes (worse).
↑+385.0 %
vs 20 prior
↑+13.3 pp
recent vs prior
↓-0.3 pp
recent vs prior
Daily performance
Daily ETV, stacked by Growth, Maintenance and Fixes.
Work-mix over time
Share of Growth / Maintenance / Fixes over a rolling 7-day window. Reads as 'where is effort flowing right now'.
Repository spread
Where this developer's commits land. Concentrated work (top1 > 80%) vs polymath spread (top1 < 30%).
Most impactful commits
Top 20 by ETV in the 90-day window.
- 0.9ETVTake narrowed facets' new `present` bit into account in subscript inference Summary: When a dict key facet is known to be present due to an `in` check, suppress errors on key access about the key possibly being absent. Adds a regression test for a tricky corner case that an earlier draft got wrong: overwriting the value should not affect presence. Note that this updates subscripting to handle the `present` bit correctly but does not yet update `narrow.rs` to *set* the `present` bit, so user-facing behavior is not yet fixed. Reviewed By: yangdanny97 Differential Revision: D107801901 fbshipit-source-id: 2854cab22c0ec167edb48fca8111c0d8e2c8d8efgithub.com-facebook-pyrefly · e13a8135 · 2026-06-10
- 0.8ETVChange AnswersSolver::error to take ErrorKind directly [9/16] Summary: Pyrefly's error reporting API has grown unwieldy. ErrorCollector currently has two methods for emitting errors (add and add_with_annotations_and_quick_fixes) whose signatures grow every time we add a new optional decoration like annotations or quick fixes. This stack introduces a builder pattern (design: P2307835290, implementation plan: P2307836987) that replaces these methods with an error_builder() returning a chainable ErrorBuilder, making error construction explicit and extensible. This commit changes AnswersSolver::error from taking ErrorInfo to taking ErrorKind directly. After commits 6-7 migrated all ErrorInfo::new and ErrorInfo::Context call sites away, only ErrorInfo::Kind(k) callers remain — this is a purely mechanical replacement. The method now delegates to error_builder internally. All ~250 callers are updated to pass ErrorKind directly, and unused ErrorInfo imports are removed. Reviewed By: fangyi-zhou Differential Revision: D103990096 fbshipit-source-id: e74b693775121033dde6a58c4a8d76ae09779124github.com-facebook-pyrefly · c8170021 · 2026-05-12
- 0.7ETVSplit pyrefly_types/src/callable.rs into two files Summary: `callable.rs` was getting really long. This diff splits out a new `function.rs` (named so because it contains `FuncMetadata`, `FuncFacts`, etc.) and updates import paths accordingly, with no other changes. Reviewed By: maggiemoss Differential Revision: D114987156 fbshipit-source-id: 5dfec425605fbf2d7807f045bc50839c9446275egithub.com-facebook-pyrefly · fea518f9 · 2026-08-06
- 0.7ETVPrefer to insert `from` imports Summary: The previous diffs in this stack made it so that when we double-click on an inlay hint to import it, we also insert any required imports. However, the implementation defaulted to inserting `import foo` and `foo.X`, even though the hint shows `X` unless the module name is needed for disambiguation. This diff makes it so that we prefer to insert `from foo import X` and `X`. We still reuse `import foo` if it already exists in the file. Reviewed By: yangdanny97 Differential Revision: D114664767 fbshipit-source-id: 2c3ba897507b95750fb6fb7e31d5438a8ad16393github.com-facebook-pyrefly · 785a3d54 · 2026-08-05
- 0.6ETVSeparate synthesized and non-synthesized functions in `FunctionKind` Summary: `FunctionKind::Def` represented both functions defined in the source code and callables synthesized by the type checker. The latter have no source definition, which forced `FuncId` to carry an optional definition index. This diff gives synthesized callables a separate `FunctionKind::Synthesized` identity and makes the definition index non-optional on non-synthesized functions. This makes source identity an invariant of the type rather than a convention. `FuncId` is renamed to `FuncDefId` to make it more obvious that we're dealing with source definitions and to match `FuncDefIndex`'s naming convention. This prepares `FuncDefId` to carry richer source information. Concretely: ```diff - pub struct FuncId { + pub struct FuncDefId { - pub def_index: Option<FuncDefIndex>, + pub def_index: FuncDefIndex>, ... } + pub struct FuncSymbol { + module: Module, + cls: Option<Class>, + name: Name, + } pub enum FunctionKind { Def(Arc<FuncDefId>), + Synthesized(Arc<FuncSymbol>), ... } impl FunctionKind { - fn definition_id(&self) -> Option<&FuncId> { ... } + fn to_func_symbol(&self) -> Option<FuncSymbol> { ... } + fn as_func_def_id(&self) -> Option<&FuncDefId> { ... } } ``` Context: This is part of a small stack whose goal is to make non-synthesized functions store `QName`. On its own, this is already a nice simplification that unifies how functions and classes store identity. It will also enable further refactors to make pyrefly use resolved source symbols rather than passing around strings everywhere, which will in turn make it easier to create clear code boundaries between the core type checker and third-party library support. Reviewed By: grievejia Differential Revision: D114987025 fbshipit-source-id: c6a952433f882f2979a8d87cbd902f2d756f5099github.com-facebook-pyrefly · e7eb8d2a · 2026-08-07
- 0.4ETVExclude union names from ordering and type equality Summary: Unions should be compared only by their members; the name is display-only metadata. Reviewed By: yangdanny97 Differential Revision: D112931511 fbshipit-source-id: 1f1419eebdcbd079a7248d93a58388a925d71962github.com-facebook-pyrefly · 204f13e3 · 2026-07-21
- 0.4ETVMove residual-related functions that only operate on Type + TypeHeap to the types crate Summary: This stack: reorganizes some of the callable residual code to make it clearer which parts of the logic are tightly coupled to the solver, which will make it easier for me to make solver changes. This diff: moves Solver functions that access nothing from the Solver except `self.heap` into the types crate. They are turned into methods on the appropriate types that accept a `&TypeHeap` argument. No functional change. Reviewed By: yangdanny97 Differential Revision: D106045944 fbshipit-source-id: bb7abe3efa6dca4bacff3bcabd00fb7812359f7agithub.com-facebook-pyrefly · 6fe64d1e · 2026-05-22
- 0.4ETVPreserve function qualified names Summary: `FuncDefId` currently stores a module, optional class, name, and a flattened path of enclosing functions. That representation cannot describe arbitrary nesting such as a class inside a function inside another class, so information about the function's nesting context is lost between the binding and answers phases. This diff instead makes `FuncDefId` store a `QName`, which is both more informative and simpler. Concretely: ```diff pub struct FuncDefId { - pub module: Module, - pub name: Name, - pub outer_funcs: Option<Name>, + qname: QName, ... } ``` Context: This is part of a small stack whose goal is to make non-synthesized functions store `QName`. On its own, this is already a nice simplification that unifies how functions and classes store identity. It will also enable further refactors to make pyrefly use resolved source symbols rather than passing around strings everywhere, which will in turn make it easier to create clear code boundaries between the core type checker and third-party library support. Reviewed By: grievejia Differential Revision: D114987093 fbshipit-source-id: 84ebfb57452a693e0122ef61dbad6b58aa8bf976github.com-facebook-pyrefly · 5a15c07e · 2026-08-07
- 0.3ETVModel possible legacy type parameter cases explicitly Summary: A possible legacy type parameter binding previously accepted any key slice, including empty and mixed parameter/module groups. Represent bare parameters and nonempty module groups as separate enum cases so consumers can handle their actual semantics exhaustively and impossible states cannot be constructed accidentally. Reviewed By: grievejia Differential Revision: D114648278 fbshipit-source-id: f27f2472818fec8d15c36f1497a5cefcedee99e7github.com-facebook-pyrefly · c63e4acc · 2026-08-04
- 0.3ETVMigrate direct ErrorCollector::add calls to builder [10/16] Summary: Pyrefly's error reporting API has grown unwieldy. ErrorCollector currently has two methods for emitting errors (add and add_with_annotations_and_quick_fixes) whose signatures grow every time we add a new optional decoration like annotations or quick fixes. This stack introduces a builder pattern (design: P2307835290, implementation plan: P2307836987) that replaces these methods with an error_builder() returning a chainable ErrorBuilder, making error construction explicit and extensible. This commit migrates all ~48 direct errors.add(range, ErrorInfo::Kind(k), vec1![msg]) calls to use the builder. Single-line messages become errors.error_builder(range, kind, msg).emit(). Multi-line Vec1 messages are split into header + with_detail() chains. Dynamic Vec1 built with pushes are converted to conditional builder chains. Files modified across alt/, binding/, module/, and state/. Unused ErrorInfo and vec1 imports are removed. Reviewed By: fangyi-zhou Differential Revision: D103990088 fbshipit-source-id: 5f2a534ec943b5e50e8fb6bbbd18da5696417841github.com-facebook-pyrefly · 0e74a475 · 2026-05-12
- 0.3ETVFix overly aggressive cyclic self-reference check Summary: Improves pyrefly's check for cyclic self-references in recursive aliases to accept more aliases. The only ones it rejects now are: * Uninhabited types, like `type X = tuple[X, X]`. * Types that are inhabited only by nestings of empty containers, like `type Y = list[Y]`. * Union types where the self-reference is pointless, like `type Z = int | Z`. Fixes https://github.com/facebook/pyrefly/issues/3235. Reviewed By: yangdanny97 Differential Revision: D107783755 fbshipit-source-id: c30975f36d8f9a39438f76306e77f17633015a52github.com-facebook-pyrefly · 2f4e0524 · 2026-06-08
- 0.3ETVCheck for when a quantified satisfies another quantified's constraints Summary: is_subset_eq's logic for determining whether a type T satisifies a constrained Quantified failed to take into account the case in which T is also a Quantified. This diff adds handling for that case, in a new `quantified_satisfies_constraints` method. Reviewed By: stroxler Differential Revision: D107588970 fbshipit-source-id: d7bdea3d91b4d41228482698c975f40b466c48a0github.com-facebook-pyrefly · 353e544f · 2026-06-05
- 0.2ETVDeprecate the `pytorch-efficiency-lints` config option Summary: The new `pytorch-efficiency-lints` error kind is strictly more powerful than the `--pytorch-efficiency-lints` flag, so let's deprecate the latter. Reviewed By: yangdanny97 Differential Revision: D114969494 fbshipit-source-id: 3f6e1df0d85c3682902f7b2e737bf8e812436ad5github.com-facebook-pyrefly · 0fa254c7 · 2026-08-06
- 0.2ETVUnify var traversal in solver.rs Summary: * Adds a new `resolve_vars` function that handles var traversal for both `expand_vars` and `deep_force`, allowing us to clean up some duplication and redundant helpers. * Moves dimension canonicalization into `simplify_mut` so we can get rid of `simplify_forced_type`. * Removes a couple no-longer-relevant TODOs. No functional change. Reviewed By: yangdanny97 Differential Revision: D106076328 fbshipit-source-id: 63d4277da296a6380cca01a06f8308ab19a625b3github.com-facebook-pyrefly · 1389b585 · 2026-05-26
- 0.2ETVSimplify `finish_quantified_*` cluster of Solver functions Summary: Previously, the solver had five finish_quantified_* functions: three pub, one pub(crate), and one private. This diff gets us down to two: one pub and one private. It also adds a `finish_quantified` wrapper on AnswersSolver to reduce boilerplate, like we do already do with `is_subset_eq` and friends. This *is* a functional change: we now always create a Subset object and do overload pruning when calling `finish_quantified`. CI does not find any change to user-facing behavior. Reviewed By: yangdanny97 Differential Revision: D106052351 fbshipit-source-id: 8307e2ff6f1941b013d6b1d320073d48acea962egithub.com-facebook-pyrefly · fbcbbc6e · 2026-05-22
- 0.2ETVCreate `pyrefly/lib/alt/types/instance.rs` Summary: Moves `InstanceKind` and `Instance` into their own file in preparation for reusing them. No functional change. Reviewed By: grievejia Differential Revision: D105456425 fbshipit-source-id: 8c7b1765afe9ee156684c472e1c84d16da814aa4github.com-facebook-pyrefly · 7478e058 · 2026-05-19
- 0.2ETVSanitize self-referential vars when pruning overload branches Summary: Fixes https://github.com/facebook/pyrefly/issues/3749. Reviewed By: yangdanny97 Differential Revision: D108200384 fbshipit-source-id: d6a629f4f0a083f6697e1895828db85daa491d58github.com-facebook-pyrefly · 9c7a537d · 2026-06-11
- 0.2ETVRelax overly strict metaclass conflict detection Summary: When a class has multiple possible metaclasses through a `metaclass=...` declaration and/or inherited metaclasses, pyrefly grabbed the first metaclass using MRO precedence and then checked if it was legal. What the runtime actually does is look at all the possible metaclasses and choose a legal one, if one exists. This diff adjusts pyrefly's logic to match the runtime. The error message for metaclass conflicts has also been tweaked. The new selection process doesn't always select the direct metaclass in case of a conflict, so the "is not a subclass" language sometimes misleadingly implied that a base's metaclass needed to be modified. Finally, I modified `Metaclass::Inherited` to also store the direct `metaclass=...` declaration, so that `implicit-abstract-class` detection continues to work. Reviewed By: grievejia Differential Revision: D114434102 fbshipit-source-id: 8185d1cc1871f0f456ce4ceba2c3964d2aaa938agithub.com-facebook-pyrefly · 4276c055 · 2026-08-05
- 0.2ETVRename `expected_types` to `argmap` and wrap it in a struct Summary: No functional change. I'm planning to add more info to this map, so let's first rename it and make it more structured. Context: This stack is a ground-up re-implementation of https://github.com/facebook/pyrefly/pull/1447. It has a narrower focus (just omits irrelevant parameter types, doesn't try to do any handling of other kinds of call errors), reuses the existing signature display code, tracks parameters by name instead of index, and filters all overload signatures rather than just the closest one. Reviewed By: grievejia Differential Revision: D108230388 fbshipit-source-id: 3a7f63d9143cc2767566f414b7994e4eff015d5cgithub.com-facebook-pyrefly · 276aabb4 · 2026-06-12
- 0.2ETVRead generic residuals from the call context Summary: Context: this stack migrates generic residuals from being stored on Variable to being stored on CallContext. This has several advantages: * This makes generic residuals look a lot more like overload residuals, which will enable code sharing in a later diff. * Separating residuals and variables makes the solver (a little) more modular. * At least to me, it makes more sense for the conceptual unit to be a *set* of residuals associated with a call, rather than a single residual describing a standalone property of a variable. This diff: switches `generalize_class_targs` and `finish_quantified_with_pruning` to read generic residual information from `GenericResidualCapture` on `CallContext` instead of the `residuals` field on `Variable::Quantified`. Remove the dual-write from the previous diff. One wrinkle is that during Callable subset checking, contravariant parameter comparisons negate the `argument_side`, which disables `record_deferred_residual_target_vars` for parameter-side vars. Those vars only appear in `witness_vars` indirectly — through union-find unification with vars that ARE in `witness_vars`. To handle this, we have to resolves vars through the union-find root before matching against `witness_vars`. Also stores generic residuals in overload branch snapshots, so `materialize_overload_residual_branch_value` can determine whether a snapshotted `Quantified` var should produce a `callable_residual_generic` type. Reviewed By: stroxler Differential Revision: D106163696 fbshipit-source-id: 1570cdb954f63fe6d829b94b5118178538b661f1github.com-facebook-pyrefly · ea593dfd · 2026-05-27