diff --git a/crates/ty_python_semantic/src/types/call/bind.rs b/crates/ty_python_semantic/src/types/call/bind.rs index f94498abf4..978bdbf842 100644 --- a/crates/ty_python_semantic/src/types/call/bind.rs +++ b/crates/ty_python_semantic/src/types/call/bind.rs @@ -4623,9 +4623,7 @@ impl<'db> BindingError<'db> { } } - if !typevar.is_self(context.db()) - && let Some(typevar_definition) = typevar.definition(context.db()) - { + if let Some(typevar_definition) = typevar.definition(context.db()) { let module = parsed_module(context.db(), typevar_definition.file(context.db())) .load(context.db()); let typevar_range = typevar_definition.full_range(context.db(), &module); diff --git a/crates/ty_python_semantic/src/types/generics.rs b/crates/ty_python_semantic/src/types/generics.rs index 290daac22a..64b761f7ee 100644 --- a/crates/ty_python_semantic/src/types/generics.rs +++ b/crates/ty_python_semantic/src/types/generics.rs @@ -96,7 +96,14 @@ pub(crate) fn typing_self<'db>( let identity = TypeVarIdentity::new( db, ast::name::Name::new_static("Self"), - class.definition(db), + // `Self` has a different upper bound dependent on the containing class, + // so pointing to the definition of the symbol `typing.Self` itself is + // not useful here. We could point to the class definition, but the full + // range of the class definition is much larger than the full range of a + // TypeVar would usually be, which leads to bugs like + // https://github.com/astral-sh/ty/issues/2514. So we just pass `None` + // for the definition field here. + None, TypeVarKind::TypingSelf, ); let bounds = TypeVarBoundOrConstraints::UpperBound(Type::instance(