fix [Docs+feature] Consider how Var should be represented in reveal_type and hover #280#2589
Open
asukaminato0721 wants to merge 1 commit intofacebook:mainfrom
Open
fix [Docs+feature] Consider how Var should be represented in reveal_type and hover #280#2589asukaminato0721 wants to merge 1 commit intofacebook:mainfrom
asukaminato0721 wants to merge 1 commit intofacebook:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Updates Pyrefly’s reveal_type behavior and documentation to better reflect unpinned partial types (showing @_) and to prevent reveal_type(...) from counting as a “first use” that pins partial container types.
Changes:
- Add a non-pinning usage mode in the binder and route
typing.reveal_type/typing_extensions.reveal_typeargument evaluation through it. - Add special-export recognition for
reveal_typeand implement display-only overrides so empty[]/{}reveals print@_when still unpinned. - Add regression coverage and update docs to explain
@_in revealed types and hovers.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| website/docs/error-kinds.mdx | Documents @_ placeholder semantics with a reveal_type example. |
| pyrefly/lib/test/simple.rs | Adds regression test ensuring reveal_type doesn’t pin partial types. |
| pyrefly/lib/export/special.rs | Adds RevealType to SpecialExport and recognizes it from typing/typing_extensions. |
| pyrefly/lib/binding/expr.rs | Introduces Usage::NonPinningRead and uses it for RevealType calls. |
| pyrefly/lib/binding/bindings.rs | Ensures NonPinningRead lookups don’t consume first-use inference. |
| pyrefly/lib/alt/special_calls.rs | Implements reveal display override logic for unpinned empty list/dict assignments. |
Comments suppressed due to low confidence (3)
pyrefly/lib/binding/expr.rs:670
- This non-pinning special-case only triggers when the callee resolves to
SpecialExport::RevealType(i.e.,typing.reveal_type/typing_extensions.reveal_type). However, the typechecker also treats an unimported barereveal_type(...)as a pseudo-builtin inalt/call.rs; in that case this branch won’t run and the argument will be ensured under the normalusage, which can still consume first-use inference and pin partial types. Consider extending this handling to also recognize the bare namereveal_typeso the non-pinning behavior is consistent with the solver’s pseudo-builtin support.
node_index: _,
range: _,
func,
arguments,
}) if self.as_special_export(func) == Some(SpecialExport::RevealType) => {
pyrefly/lib/alt/special_calls.rs:151
- This Forward-chain walk uses an arbitrary
remaining = 100cutoff to avoid infinite loops. That makesreveal_typebehavior depend on chain length and can silently stop resolving to the underlyingKey::Definitionfor legitimately deep chains. Prefer using a visited set (as done elsewhere in bindings) to break cycles deterministically without a magic limit.
if let Some(mut idx) = self.bindings().key_to_idx_hashed_opt(Hashed::new(&key))
{
let mut remaining = 100usize;
let def_ident = loop {
if remaining == 0 {
break None;
}
pyrefly/lib/alt/special_calls.rs:238
- When
reveal_partialis true, this transforms allAnyStyle::Implicitoccurrences in the displayed type intoVar::ZERO(@_). That can misrepresent legitimate implicitAnythat are unrelated to the empty-container placeholder (e.g.,PartialTypeWithUpstreamsCompletedintentionally introducesAnyto prevent upstream Vars from leaking). Consider restricting theAny(Implicit) -> @_substitution to the specific override types you synthesize for empty[]/{}(e.g., only whenreveal_overrideisSome) so realAnyremainsAnyin the reveal output.
if reveal_partial {
display_ty.transform_mut(&mut |t| {
if matches!(t, Type::Any(AnyStyle::Implicit)) {
*t = Var::ZERO.to_type(self.heap);
}
});
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
|
No diffs to classify. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #280
Added a non‑pinning usage mode in bindings and wired reveal_type calls to use it, so calling reveal_type(x) doesn’t count as a “first use” that pins partial types. This preserves the intended behavior where later real usage (like x.append(1)) still pins the partial.
Updated special‑export handling to recognize
typing.reveal_type/typing_extensions.reveal_type, enabling special handling in the binder.Implemented reveal_type display overrides for empty list/dict assignments so that, when the variable is still unpinned, the printed type shows
@_rather than Unknown. This is display‑only and doesn’t mutate solver state.Test Plan
Added a regression test that matches the docs example (initial reveal shows
list[@_], subsequent reveal after append(1) shows list[int]) and updated the docs to explain@_.