Skip to content
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

[red-knot] Consolidate all gradual types into single Type variant #15386

Merged
merged 11 commits into from
Jan 10, 2025

Conversation

dcreager
Copy link
Member

@dcreager dcreager commented Jan 9, 2025

Prompted by #15381 (comment):

One nit: I think we need to consider Any and Unknown and Todo as all (gradually) equivalent to each other, and thus type & Any and type & Unknown and type & Todo as also equivalent. The distinction between Any vs Unknown vs Todo is entirely about provenance/debugging, there is no type level distinction. (And I've been wondering if the Any vs Unknown distinction is really worth it.)

The thought here is that most places want to treat Any, Unknown, and Todo identically. So this PR simplifies things by having a single Type::Any variant, and moves the provenance part into a new AnyType type. If you need to treat e.g. Todo differently, you still can by pattern-matching into the AnyType. But if you don't, you can just use Type::Any(_).

(This would also allow us to (more easily) distinguish "unknown via an unannotated value" from "unknown because of a typing error" should we want to do that in the future)

@dcreager dcreager changed the title Consolidate all gradual types into single Type variant [red-knot] Consolidate all gradual types into single Type variant Jan 9, 2025
@dcreager dcreager added the red-knot Multi-file analysis & type inference label Jan 9, 2025
Copy link
Contributor

@sharkdp sharkdp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it! (haven't reviewed each and every change, but I guess it's more or less mechanical)

Copy link
Contributor

github-actions bot commented Jan 9, 2025

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@AlexWaygood
Copy link
Member

Brilliant idea! Is it possibly worth calling the variant and struct Type::Gradual and GradualType rather than Type::Any and AnyType? Type::Any(AnyType::Unknown) reads a bit strangely to me

@AlexWaygood
Copy link
Member

Also: all roads lead to Rome

crates/red_knot_python_semantic/src/types.rs Outdated Show resolved Hide resolved
crates/red_knot_python_semantic/src/types/class_base.rs Outdated Show resolved Hide resolved
Copy link
Member Author

@dcreager dcreager left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brilliant idea! Is it possibly worth calling the variant and struct Type::Gradual and GradualType rather than Type::Any and AnyType? Type::Any(AnyType::Unknown) reads a bit strangely to me

Done

crates/red_knot_python_semantic/src/types.rs Outdated Show resolved Hide resolved
crates/red_knot_python_semantic/src/types/class_base.rs Outdated Show resolved Hide resolved
Copy link
Member Author

@dcreager dcreager left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but I guess it's more or less mechanical

That is a good callout. I did try to make this a pure refactoring. For instance, there are a couple of places where we were doing something only for a Todo, but not for Any or Unknown. Instead of inspecting and possibly changing those in this PR, I've left them as-is so that this PR does not combine a refactoring with a logic change.

Comment on lines 4154 to 4155
todo @ Type::Todo(_) => return Ok(todo),
todo @ Type::Any(AnyType::Todo(_)) => return Ok(todo),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.g. here

crates/red_knot_python_semantic/src/types.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is excellent!!

crates/red_knot_python_semantic/src/types.rs Outdated Show resolved Hide resolved
crates/red_knot_python_semantic/src/types.rs Outdated Show resolved Hide resolved
crates/red_knot_python_semantic/src/types.rs Outdated Show resolved Hide resolved
crates/red_knot_python_semantic/src/types/class_base.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes handling these in match statements so much nicer!

@@ -1085,9 +1082,16 @@ impl<'db> Type<'db> {
pub(crate) fn is_same_gradual_form(self, other: Type<'db>) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note on seeing this method, wondering why we need it, and going to look: I wonder if maybe we shouldn't allow Any/Unknown/Todo to coexist in the same union/intersection, and instead should just define a hierarchy of preference, e.g. Todo takes top priority, Any second, and Unknown third?

Definitely not something for this PR, just musing.

crates/red_knot_python_semantic/src/types.rs Outdated Show resolved Hide resolved
@dcreager dcreager merged commit baf0683 into main Jan 10, 2025
21 checks passed
@dcreager dcreager deleted the dcreager/consolidate-any branch January 10, 2025 02:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
red-knot Multi-file analysis & type inference
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants