-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[ty] Make tuple instantiations sound #18987
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
Conversation
|
2e0d2fb
to
0b3b067
Compare
The new errors on |
@@ -2426,6 +2427,7 @@ impl KnownClass { | |||
| Self::Float | |||
| Self::Enum | |||
| Self::ABCMeta | |||
| KnownClass::Iterable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Self::Iterable
to be consistent with the other arms
Some(KnownClass::Tuple) if overload_index == 1 => { | ||
if let [Some(argument)] = overload.parameter_types() { | ||
let overridden_return = | ||
argument.into_tuple().map(Type::Tuple).unwrap_or_else(|| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would avoid unwrapping the argument type just to then rewrap it:
argument.into_tuple().map(Type::Tuple).unwrap_or_else(|| { | |
argument.filter(Type::is_tuple).unwrap_or_else(|| { |
(though it depends on an is_tuple
method that may not exist yet!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
argument
is a type rather than an Option
here so I think this would have to be
argument.into_tuple().map(Type::Tuple).unwrap_or_else(|| { | |
argument.into_tuple().filter(Type::is_tuple).unwrap_or_else(|| { |
Adding a Type::is_tuple
method just for that feels a bit unnecessary to me? No strong opinion though
Type::GenericAlias(alias) => { | ||
let instantiated = Type::instance(db, ClassType::from(alias)); | ||
|
||
let parameters = if alias.origin(db).is_known(db, KnownClass::Tuple) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I follow the constructors here, but can you put a comment with the Python syntax of the signature you're trying to construct here?
let spec = alias.specialization(db).tuple(db); | ||
let mut parameter = | ||
Parameter::positional_only(Some(Name::new_static("iterable"))) | ||
.with_annotated_type(instantiated); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the Tuple::resize
method that #18948 introduces, we can make this work for any tuple, not just one with exactly the same size as the type being constructed. I also have plans to have try_iterator
return a tuple spec describing the return values of the iterator, which would then give us what we need for this to work for any iterable type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the
Tuple::resize
method that #18948 introduces, we can make this work for any tuple, not just one with exactly the same size as the type being constructed.
Hmm, not sure I totally follow this. Can you give an example of something that should be covered in this PR but isn't? :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, wasn't requesting any changes here with this comment, just leaving me/others a breadcrumb for a future improvement
Summary
Ensure that we correctly infer calls such as
tuple((1, 2))
,tuple(range(42))
, etc. Ensure that we emit errors on invalid calls such astuple[int, str]()
.Test Plan
Mdtests