Skip to content

Commit 0744540

Browse files
committed
Add comment explaining the identity specialization
1 parent 836d02c commit 0744540

1 file changed

Lines changed: 11 additions & 0 deletions

File tree

  • crates/red_knot_python_semantic/src

crates/red_knot_python_semantic/src/types.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3763,8 +3763,19 @@ impl<'db> Type<'db> {
37633763
}
37643764
});
37653765

3766+
// Construct an instance type that we can use to look up the `__init__` instance method.
3767+
// This performs the same logic as `Type::to_instance`, except for generic class literals.
37663768
// TODO: we should use the actual return type of `__new__` to determine the instance type
37673769
let init_ty = match self {
3770+
// This is the only match arm that is different from `Type::to_instance`. Instead of
3771+
// using the _default_ specialization, we use the _identity_ specialization, which maps
3772+
// each of the class's generic typevars to itself. The end result is a generic alias
3773+
// that still has the typevars in it, which we need to be able to infer a
3774+
// specialization when we call the `__init__` method. This is how we simulate a
3775+
// "partially initialized" object, where we don't yet know the actual specialization
3776+
// (so we simulate that with the identity specialization), while still being able to do
3777+
// an _instance_ lookup of `__init__` (which would apply the default specialization if
3778+
// we were to perform it directly on the non-specialized generic class literal).
37683779
Type::ClassLiteral(generic @ ClassLiteralType::Generic(_)) => {
37693780
Type::instance(generic.identity_specialization(db))
37703781
}

0 commit comments

Comments
 (0)