Skip to content

Comments

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

Merged
dcreager merged 11 commits intomainfrom
dcreager/consolidate-any
Jan 10, 2025
Merged

[red-knot] Consolidate all gradual types into single Type variant#15386
dcreager merged 11 commits intomainfrom
dcreager/consolidate-any

Conversation

@dcreager
Copy link
Member

@dcreager dcreager commented Jan 9, 2025

Prompted by astral-sh/ty#222:

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 ty 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)

@github-actions
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

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

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

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!!

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.

@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

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants