mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:24:57 +00:00
More cleanup, clarification
This commit is contained in:
parent
0b99dfdb90
commit
2a2e03c3b9
3 changed files with 26 additions and 29 deletions
|
@ -376,8 +376,8 @@ pub enum ClassType<'db> {
|
|||
|
||||
#[salsa::tracked]
|
||||
impl<'db> ClassType<'db> {
|
||||
pub(super) const fn is_not_generic(self) -> bool {
|
||||
matches!(self, Self::NonGeneric(_))
|
||||
pub(super) const fn is_generic(self) -> bool {
|
||||
matches!(self, Self::Generic(_))
|
||||
}
|
||||
|
||||
pub(super) const fn into_generic_alias(self) -> Option<GenericAlias<'db>> {
|
||||
|
|
|
@ -5954,7 +5954,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
|||
// but constructor calls to `tuple[int]`, `tuple[int, ...]`, `tuple[int, *tuple[str, ...]]` (etc.)
|
||||
// are handled by the default constructor-call logic (we synthesize a `__new__` method for them
|
||||
// in `ClassType::own_class_member()`).
|
||||
class.is_known(self.db(), KnownClass::Tuple) && class.is_not_generic()
|
||||
class.is_known(self.db(), KnownClass::Tuple) && !class.is_generic()
|
||||
);
|
||||
|
||||
// temporary special-casing for all subclasses of `enum.Enum`
|
||||
|
|
|
@ -27,16 +27,16 @@ use crate::types::infer::nearest_enclosing_class;
|
|||
use crate::types::{
|
||||
ApplyTypeMappingVisitor, BindingContext, BoundTypeVarInstance, ClassType,
|
||||
FindLegacyTypeVarsVisitor, HasRelationToVisitor, IsEquivalentVisitor, KnownClass,
|
||||
MaterializationKind, NormalizedVisitor, TypeMapping, TypeRelation, TypeVarKind,
|
||||
VarianceInferable, todo_type,
|
||||
MaterializationKind, NormalizedVisitor, TypeMapping, TypeRelation, VarianceInferable,
|
||||
todo_type,
|
||||
};
|
||||
use crate::{Db, FxOrderSet};
|
||||
use ruff_python_ast::{self as ast, name::Name};
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct MethodInformation<'db> {
|
||||
method_type: FunctionType<'db>,
|
||||
class_type: ClassType<'db>,
|
||||
method: FunctionType<'db>,
|
||||
class: ClassType<'db>,
|
||||
}
|
||||
|
||||
fn infer_method_information<'db>(
|
||||
|
@ -50,7 +50,7 @@ fn infer_method_information<'db>(
|
|||
let class_scope = index.scope(class_scope_id.file_scope_id(db));
|
||||
let class_node = class_scope.node().as_class()?;
|
||||
|
||||
let method_type = infer_definition_types(db, definition)
|
||||
let method = infer_definition_types(db, definition)
|
||||
.declaration_type(definition)
|
||||
.inner_type()
|
||||
.into_function_literal()?;
|
||||
|
@ -59,12 +59,9 @@ fn infer_method_information<'db>(
|
|||
let class_literal = infer_definition_types(db, class_def)
|
||||
.declaration_type(class_def)
|
||||
.inner_type();
|
||||
let class_type = class_literal.to_class_type(db)?;
|
||||
let class = class_literal.to_class_type(db)?;
|
||||
|
||||
Some(MethodInformation {
|
||||
method_type,
|
||||
class_type,
|
||||
})
|
||||
Some(MethodInformation { method, class })
|
||||
}
|
||||
|
||||
/// The signature of a single callable. If the callable is overloaded, there is a separate
|
||||
|
@ -1260,16 +1257,12 @@ impl<'db> Parameters<'db> {
|
|||
);
|
||||
}
|
||||
let method_info = infer_method_information(db, definition);
|
||||
let is_classmethod = method_info.is_some_and(|f| f.method_type.is_classmethod(db));
|
||||
let is_staticmethod = method_info.is_some_and(|f| f.method_type.is_staticmethod(db));
|
||||
let is_static_or_classmethod = method_info
|
||||
.is_some_and(|f| f.method.is_staticmethod(db) || f.method.is_classmethod(db));
|
||||
|
||||
let positional_or_keyword = pos_or_keyword_iter.map(|arg| {
|
||||
if let Some(MethodInformation {
|
||||
method_type: method,
|
||||
class_type: class,
|
||||
}) = method_info
|
||||
&& !is_staticmethod
|
||||
&& !is_classmethod
|
||||
if let Some(MethodInformation { method, class }) = method_info
|
||||
&& !is_static_or_classmethod
|
||||
&& arg.parameter.annotation().is_none()
|
||||
&& parameters.index(arg.name().id()) == Some(0)
|
||||
{
|
||||
|
@ -1279,18 +1272,16 @@ impl<'db> Parameters<'db> {
|
|||
context
|
||||
.variables(db)
|
||||
.iter()
|
||||
.any(|v| v.typevar(db).kind(db) == TypeVarKind::TypingSelf);
|
||||
true
|
||||
.any(|v| v.typevar(db).is_self(db))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
let implicit_annotation = if !method_has_self_in_generic_context
|
||||
&& class.is_not_generic()
|
||||
&& !class.known(db).is_some_and(KnownClass::is_fallback_class)
|
||||
|
||||
let inferred_annotation = if method_has_self_in_generic_context
|
||||
|| class.is_generic()
|
||||
|| class.known(db).is_some_and(KnownClass::is_fallback_class)
|
||||
{
|
||||
Type::instance(db, class)
|
||||
} else {
|
||||
let scope_id = definition.scope(db);
|
||||
let typevar_binding_context = Some(definition);
|
||||
let index = semantic_index(db, scope_id.file(db));
|
||||
|
@ -1304,9 +1295,15 @@ impl<'db> Parameters<'db> {
|
|||
definition,
|
||||
))),
|
||||
)
|
||||
} else {
|
||||
// For methods of non-generic classes that are not otherwise generic (e.g. return `Self` or
|
||||
// have additional type parameters), the implicit `Self` type of the `self` parameter would
|
||||
// be the only type variable, so we can just use the class directly.
|
||||
Type::instance(db, class)
|
||||
};
|
||||
|
||||
Parameter {
|
||||
annotated_type: Some(implicit_annotation),
|
||||
annotated_type: Some(inferred_annotation),
|
||||
inferred_annotation: true,
|
||||
kind: ParameterKind::PositionalOrKeyword {
|
||||
name: arg.parameter.name.id.clone(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue