Skip to content

[red-knot] Add support for unpacking targets in comprehensions #15369

@dhruvmanila

Description

@dhruvmanila

This should be very similar to what was done in the for statement (#15058).

Notes:

One difference between the for statement and comprehension is that the type of value expression needs to be inferred from different scope for the first comprehension. This could be done by extending the UnpackValue enum to include a Comprehension variant with a is_first boolean field.

I'm worried that this logic (

// Two things are different if it's the first comprehension:
// (1) We must lookup the `ScopedExpressionId` of the iterable expression in the outer scope,
// because that's the scope we visit it in in the semantic index builder
// (2) We must *not* call `self.extend()` on the result of the type inference,
// because `ScopedExpressionId`s are only meaningful within their own scope, so
// we'd add types for random wrong expressions in the current scope
let iterable_ty = if is_first {
let lookup_scope = self
.index
.parent_scope_id(self.scope().file_scope_id(self.db()))
.expect("A comprehension should never be the top-level scope")
.to_scope_id(self.db(), self.file());
result.expression_ty(iterable.scoped_expression_id(self.db(), lookup_scope))
} else {
self.extend(result);
result.expression_ty(iterable.scoped_expression_id(self.db(), self.scope()))
};
) would need to be duplicated (1) in infer_comprehension_definition when the target is just a name expression and (2) in Unpacker::unpack to get the unpack value type from the correct scope.

Metadata

Metadata

Assignees

No one assigned

    Labels

    tyMulti-file analysis & type inference

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions