Compare commits
1 Commits
konsti/bet
...
dhruv/rena
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e383bed889 |
@@ -285,7 +285,7 @@ pub(crate) fn binding_type<'db>(db: &'db dyn Db, definition: Definition<'db>) ->
|
||||
}
|
||||
|
||||
/// Infer the type of a declaration.
|
||||
fn declaration_type<'db>(db: &'db dyn Db, definition: Definition<'db>) -> TypeAndQualifiers<'db> {
|
||||
fn declaration_type<'db>(db: &'db dyn Db, definition: Definition<'db>) -> DeclaredType<'db> {
|
||||
let inference = infer_definition_types(db, definition);
|
||||
inference.declaration_type(definition)
|
||||
}
|
||||
@@ -434,7 +434,7 @@ impl<'db> From<Type<'db>> for SymbolAndQualifiers<'db> {
|
||||
|
||||
/// The result of looking up a declared type from declarations; see [`symbol_from_declarations`].
|
||||
type SymbolFromDeclarationsResult<'db> =
|
||||
Result<SymbolAndQualifiers<'db>, (TypeAndQualifiers<'db>, Box<[Type<'db>]>)>;
|
||||
Result<SymbolAndQualifiers<'db>, (DeclaredType<'db>, Box<[Type<'db>]>)>;
|
||||
|
||||
/// Build a declared type from a [`DeclarationsIterator`].
|
||||
///
|
||||
@@ -492,7 +492,7 @@ fn symbol_from_declarations<'db>(
|
||||
builder = builder.add(other_ty);
|
||||
qualifiers = qualifiers.union(other.qualifiers());
|
||||
}
|
||||
TypeAndQualifiers::new(builder.build(), qualifiers)
|
||||
DeclaredType::new(builder.build(), qualifiers)
|
||||
} else {
|
||||
first
|
||||
};
|
||||
@@ -2583,20 +2583,29 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
/// When inferring the type of an annotation expression, we can also encounter type qualifiers
|
||||
/// such as `ClassVar` or `Final`. These do not affect the inferred type itself, but rather
|
||||
/// control how a particular symbol can be accessed or modified. This struct holds a type and
|
||||
/// a set of type qualifiers.
|
||||
/// Represents a declared type.
|
||||
///
|
||||
/// Example: `Annotated[ClassVar[tuple[int]], "metadata"]` would have type `tuple[int]` and the
|
||||
/// qualifier `ClassVar`.
|
||||
/// This is a wrapper around [`Type`] that adds other information that's relevant for a declared
|
||||
/// type like type qualifiers (e.g. `ClassVar`, `Final`), etc.
|
||||
#[derive(Clone, Debug, Copy, Eq, PartialEq)]
|
||||
pub(crate) struct TypeAndQualifiers<'db> {
|
||||
pub(crate) struct DeclaredType<'db> {
|
||||
inner: Type<'db>,
|
||||
|
||||
/// When inferring the type of an annotation expression, we can also encounter type qualifiers
|
||||
/// such as `ClassVar` or `Final`. These do not affect the inferred type itself, but rather
|
||||
/// control how a particular symbol can be accessed or modified. This struct holds a type and a
|
||||
/// set of type qualifiers.
|
||||
///
|
||||
/// For example:
|
||||
/// ```py
|
||||
/// Annotated[ClassVar[tuple[int]], "metadata"]
|
||||
/// ```
|
||||
///
|
||||
/// In this case, the inner type would be `tuple[int]`, and the qualifiers would be `ClassVar`.
|
||||
qualifiers: TypeQualifiers,
|
||||
}
|
||||
|
||||
impl<'db> TypeAndQualifiers<'db> {
|
||||
impl<'db> DeclaredType<'db> {
|
||||
pub(crate) fn new(inner: Type<'db>, qualifiers: TypeQualifiers) -> Self {
|
||||
Self { inner, qualifiers }
|
||||
}
|
||||
@@ -2617,7 +2626,7 @@ impl<'db> TypeAndQualifiers<'db> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'db> From<Type<'db>> for TypeAndQualifiers<'db> {
|
||||
impl<'db> From<Type<'db>> for DeclaredType<'db> {
|
||||
fn from(inner: Type<'db>) -> Self {
|
||||
Self {
|
||||
inner,
|
||||
|
||||
@@ -66,11 +66,11 @@ use crate::types::unpacker::{UnpackResult, Unpacker};
|
||||
use crate::types::{
|
||||
builtins_symbol, global_symbol, symbol, symbol_from_bindings, symbol_from_declarations,
|
||||
todo_type, typing_extensions_symbol, Boundness, CallDunderResult, Class, ClassLiteralType,
|
||||
DynamicType, FunctionType, InstanceType, IntersectionBuilder, IntersectionType,
|
||||
DeclaredType, DynamicType, FunctionType, InstanceType, IntersectionBuilder, IntersectionType,
|
||||
IterationOutcome, KnownClass, KnownFunction, KnownInstanceType, MetaclassCandidate,
|
||||
MetaclassErrorKind, SliceLiteralType, SubclassOfType, Symbol, SymbolAndQualifiers, Truthiness,
|
||||
TupleType, Type, TypeAliasType, TypeAndQualifiers, TypeArrayDisplay, TypeQualifiers,
|
||||
TypeVarBoundOrConstraints, TypeVarInstance, UnionBuilder, UnionType,
|
||||
TupleType, Type, TypeAliasType, TypeArrayDisplay, TypeQualifiers, TypeVarBoundOrConstraints,
|
||||
TypeVarInstance, UnionBuilder, UnionType,
|
||||
};
|
||||
use crate::unpack::Unpack;
|
||||
use crate::util::subscript::{PyIndex, PySlice};
|
||||
@@ -246,7 +246,7 @@ pub(crate) struct TypeInference<'db> {
|
||||
bindings: FxHashMap<Definition<'db>, Type<'db>>,
|
||||
|
||||
/// The types and type qualifiers of every declaration in this region.
|
||||
declarations: FxHashMap<Definition<'db>, TypeAndQualifiers<'db>>,
|
||||
declarations: FxHashMap<Definition<'db>, DeclaredType<'db>>,
|
||||
|
||||
/// The definitions that are deferred.
|
||||
deferred: FxHashSet<Definition<'db>>,
|
||||
@@ -285,7 +285,7 @@ impl<'db> TypeInference<'db> {
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub(crate) fn declaration_type(&self, definition: Definition<'db>) -> TypeAndQualifiers<'db> {
|
||||
pub(crate) fn declaration_type(&self, definition: Definition<'db>) -> DeclaredType<'db> {
|
||||
self.declarations[&definition]
|
||||
}
|
||||
|
||||
@@ -330,7 +330,7 @@ enum DeclaredAndInferredType<'db> {
|
||||
AreTheSame(Type<'db>),
|
||||
/// Declared and inferred types might be different, we need to check assignability.
|
||||
MightBeDifferent {
|
||||
declared_ty: TypeAndQualifiers<'db>,
|
||||
declared_ty: DeclaredType<'db>,
|
||||
inferred_ty: Type<'db>,
|
||||
},
|
||||
}
|
||||
@@ -907,7 +907,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
&mut self,
|
||||
node: AnyNodeRef,
|
||||
declaration: Definition<'db>,
|
||||
ty: TypeAndQualifiers<'db>,
|
||||
ty: DeclaredType<'db>,
|
||||
) {
|
||||
debug_assert!(declaration.is_declaration(self.db()));
|
||||
let use_def = self.index.use_def_map(declaration.file_scope(self.db()));
|
||||
@@ -4805,7 +4805,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
&mut self,
|
||||
annotation: &ast::Expr,
|
||||
deferred_state: DeferredExpressionState,
|
||||
) -> TypeAndQualifiers<'db> {
|
||||
) -> DeclaredType<'db> {
|
||||
let previous_deferred_state = std::mem::replace(&mut self.deferred_state, deferred_state);
|
||||
let annotation_ty = self.infer_annotation_expression_impl(annotation);
|
||||
self.deferred_state = previous_deferred_state;
|
||||
@@ -4820,17 +4820,14 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
&mut self,
|
||||
annotation: Option<&ast::Expr>,
|
||||
deferred_state: DeferredExpressionState,
|
||||
) -> Option<TypeAndQualifiers<'db>> {
|
||||
) -> Option<DeclaredType<'db>> {
|
||||
annotation.map(|expr| self.infer_annotation_expression(expr, deferred_state))
|
||||
}
|
||||
|
||||
/// Implementation of [`infer_annotation_expression`].
|
||||
///
|
||||
/// [`infer_annotation_expression`]: TypeInferenceBuilder::infer_annotation_expression
|
||||
fn infer_annotation_expression_impl(
|
||||
&mut self,
|
||||
annotation: &ast::Expr,
|
||||
) -> TypeAndQualifiers<'db> {
|
||||
fn infer_annotation_expression_impl(&mut self, annotation: &ast::Expr) -> DeclaredType<'db> {
|
||||
// https://typing.readthedocs.io/en/latest/spec/annotations.html#grammar-token-expression-grammar-annotation_expression
|
||||
let annotation_ty = match annotation {
|
||||
// String annotations: https://typing.readthedocs.io/en/latest/spec/annotations.html#string-annotations
|
||||
@@ -4863,10 +4860,10 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
let name_expr_ty = self.infer_name_expression(name);
|
||||
match name_expr_ty {
|
||||
Type::KnownInstance(KnownInstanceType::ClassVar) => {
|
||||
TypeAndQualifiers::new(Type::unknown(), TypeQualifiers::CLASS_VAR)
|
||||
DeclaredType::new(Type::unknown(), TypeQualifiers::CLASS_VAR)
|
||||
}
|
||||
Type::KnownInstance(KnownInstanceType::Final) => {
|
||||
TypeAndQualifiers::new(Type::unknown(), TypeQualifiers::FINAL)
|
||||
DeclaredType::new(Type::unknown(), TypeQualifiers::FINAL)
|
||||
}
|
||||
_ => name_expr_ty
|
||||
.in_type_expression(self.db())
|
||||
@@ -4974,7 +4971,7 @@ impl<'db> TypeInferenceBuilder<'db> {
|
||||
fn infer_string_annotation_expression(
|
||||
&mut self,
|
||||
string: &ast::ExprStringLiteral,
|
||||
) -> TypeAndQualifiers<'db> {
|
||||
) -> DeclaredType<'db> {
|
||||
match parse_string_annotation(&self.context, string) {
|
||||
Some(parsed) => {
|
||||
// String annotations are always evaluated in the deferred context.
|
||||
|
||||
Reference in New Issue
Block a user