unwoof this too
This commit is contained in:
@@ -548,7 +548,7 @@ impl<'db> PropertyInstanceType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
self.is_equivalent_to_impl(db, other, inferable, &IsEquivalentVisitor::default())
|
||||
}
|
||||
@@ -557,7 +557,7 @@ impl<'db> PropertyInstanceType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
let getter_equivalence = if let Some(getter) = self.getter(db) {
|
||||
@@ -1286,7 +1286,7 @@ impl<'db> Type<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
target: Type<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
) -> Type<'db> {
|
||||
self.filter_union(db, |elem| {
|
||||
!elem
|
||||
@@ -1605,7 +1605,7 @@ impl<'db> Type<'db> {
|
||||
///
|
||||
/// See [`TypeRelation::Subtyping`] for more details.
|
||||
pub(crate) fn is_subtype_of(self, db: &'db dyn Db, target: Type<'db>) -> bool {
|
||||
self.when_subtype_of(db, target, InferableTypeVars::none())
|
||||
self.when_subtype_of(db, target, InferableTypeVars::None)
|
||||
.is_always_satisfied(db)
|
||||
}
|
||||
|
||||
@@ -1613,7 +1613,7 @@ impl<'db> Type<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
target: Type<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
self.has_relation_to(db, target, inferable, TypeRelation::Subtyping)
|
||||
}
|
||||
@@ -1627,7 +1627,7 @@ impl<'db> Type<'db> {
|
||||
db: &'db dyn Db,
|
||||
target: Type<'db>,
|
||||
constraints: ConstraintSet<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
self.has_relation_to(
|
||||
db,
|
||||
@@ -1641,7 +1641,7 @@ impl<'db> Type<'db> {
|
||||
///
|
||||
/// See [`TypeRelation::Assignability`] for more details.
|
||||
pub(crate) fn is_assignable_to(self, db: &'db dyn Db, target: Type<'db>) -> bool {
|
||||
self.when_assignable_to(db, target, InferableTypeVars::none())
|
||||
self.when_assignable_to(db, target, InferableTypeVars::None)
|
||||
.is_always_satisfied(db)
|
||||
}
|
||||
|
||||
@@ -1649,7 +1649,7 @@ impl<'db> Type<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
target: Type<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
self.has_relation_to(db, target, inferable, TypeRelation::Assignability)
|
||||
}
|
||||
@@ -1659,20 +1659,15 @@ impl<'db> Type<'db> {
|
||||
/// See [`TypeRelation::Redundancy`] for more details.
|
||||
#[salsa::tracked(cycle_initial=is_redundant_with_cycle_initial, heap_size=ruff_memory_usage::heap_size)]
|
||||
pub(crate) fn is_redundant_with(self, db: &'db dyn Db, other: Type<'db>) -> bool {
|
||||
self.has_relation_to(
|
||||
db,
|
||||
other,
|
||||
InferableTypeVars::none(),
|
||||
TypeRelation::Redundancy,
|
||||
)
|
||||
.is_always_satisfied(db)
|
||||
self.has_relation_to(db, other, InferableTypeVars::None, TypeRelation::Redundancy)
|
||||
.is_always_satisfied(db)
|
||||
}
|
||||
|
||||
fn has_relation_to(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
target: Type<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
self.has_relation_to_impl(
|
||||
@@ -1689,7 +1684,7 @@ impl<'db> Type<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
target: Type<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -2549,7 +2544,7 @@ impl<'db> Type<'db> {
|
||||
///
|
||||
/// [equivalent to]: https://typing.python.org/en/latest/spec/glossary.html#term-equivalent
|
||||
pub(crate) fn is_equivalent_to(self, db: &'db dyn Db, other: Type<'db>) -> bool {
|
||||
self.when_equivalent_to(db, other, InferableTypeVars::none())
|
||||
self.when_equivalent_to(db, other, InferableTypeVars::None)
|
||||
.is_always_satisfied(db)
|
||||
}
|
||||
|
||||
@@ -2557,7 +2552,7 @@ impl<'db> Type<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Type<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
self.is_equivalent_to_impl(db, other, inferable, &IsEquivalentVisitor::default())
|
||||
}
|
||||
@@ -2566,7 +2561,7 @@ impl<'db> Type<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Type<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
if self == other {
|
||||
@@ -2676,7 +2671,7 @@ impl<'db> Type<'db> {
|
||||
/// This function aims to have no false positives, but might return wrong
|
||||
/// `false` answers in some cases.
|
||||
pub(crate) fn is_disjoint_from(self, db: &'db dyn Db, other: Type<'db>) -> bool {
|
||||
self.when_disjoint_from(db, other, InferableTypeVars::none())
|
||||
self.when_disjoint_from(db, other, InferableTypeVars::None)
|
||||
.is_always_satisfied(db)
|
||||
}
|
||||
|
||||
@@ -2684,7 +2679,7 @@ impl<'db> Type<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Type<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
self.is_disjoint_from_impl(
|
||||
db,
|
||||
@@ -2699,7 +2694,7 @@ impl<'db> Type<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Type<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
@@ -2707,7 +2702,7 @@ impl<'db> Type<'db> {
|
||||
db: &'db dyn Db,
|
||||
protocol: ProtocolInstanceType<'db>,
|
||||
other: Type<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
@@ -10546,7 +10541,7 @@ impl<'db> BoundMethodType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -10580,7 +10575,7 @@ impl<'db> BoundMethodType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
self.function(db)
|
||||
@@ -10713,7 +10708,7 @@ impl<'db> CallableType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -10738,7 +10733,7 @@ impl<'db> CallableType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
if self == other {
|
||||
@@ -10822,7 +10817,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -10924,7 +10919,7 @@ impl<'db> KnownBoundMethodType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
match (self, other) {
|
||||
@@ -11969,7 +11964,7 @@ impl<'db> UnionType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
_inferable: InferableTypeVars<'db>,
|
||||
_inferable: InferableTypeVars<'_, 'db>,
|
||||
_visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
if self == other {
|
||||
@@ -12071,7 +12066,7 @@ impl<'db> IntersectionType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
_inferable: InferableTypeVars<'db>,
|
||||
_inferable: InferableTypeVars<'_, 'db>,
|
||||
_visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
if self == other {
|
||||
|
||||
@@ -9,6 +9,7 @@ use std::fmt;
|
||||
use itertools::{Either, Itertools};
|
||||
use ruff_db::parsed::parsed_module;
|
||||
use ruff_python_ast::name::Name;
|
||||
use rustc_hash::FxHashSet;
|
||||
use smallvec::{SmallVec, smallvec, smallvec_inline};
|
||||
|
||||
use super::{Argument, CallArguments, CallError, CallErrorKind, InferContext, Signature, Type};
|
||||
@@ -700,7 +701,7 @@ impl<'db> Bindings<'db> {
|
||||
Some(KnownFunction::IsEquivalentTo) => {
|
||||
if let [Some(ty_a), Some(ty_b)] = overload.parameter_types() {
|
||||
let constraints =
|
||||
ty_a.when_equivalent_to(db, *ty_b, InferableTypeVars::none());
|
||||
ty_a.when_equivalent_to(db, *ty_b, InferableTypeVars::None);
|
||||
let tracked = TrackedConstraintSet::new(db, constraints);
|
||||
overload.set_return_type(Type::KnownInstance(
|
||||
KnownInstanceType::ConstraintSet(tracked),
|
||||
@@ -711,7 +712,7 @@ impl<'db> Bindings<'db> {
|
||||
Some(KnownFunction::IsSubtypeOf) => {
|
||||
if let [Some(ty_a), Some(ty_b)] = overload.parameter_types() {
|
||||
let constraints =
|
||||
ty_a.when_subtype_of(db, *ty_b, InferableTypeVars::none());
|
||||
ty_a.when_subtype_of(db, *ty_b, InferableTypeVars::None);
|
||||
let tracked = TrackedConstraintSet::new(db, constraints);
|
||||
overload.set_return_type(Type::KnownInstance(
|
||||
KnownInstanceType::ConstraintSet(tracked),
|
||||
@@ -722,7 +723,7 @@ impl<'db> Bindings<'db> {
|
||||
Some(KnownFunction::IsAssignableTo) => {
|
||||
if let [Some(ty_a), Some(ty_b)] = overload.parameter_types() {
|
||||
let constraints =
|
||||
ty_a.when_assignable_to(db, *ty_b, InferableTypeVars::none());
|
||||
ty_a.when_assignable_to(db, *ty_b, InferableTypeVars::None);
|
||||
let tracked = TrackedConstraintSet::new(db, constraints);
|
||||
overload.set_return_type(Type::KnownInstance(
|
||||
KnownInstanceType::ConstraintSet(tracked),
|
||||
@@ -733,7 +734,7 @@ impl<'db> Bindings<'db> {
|
||||
Some(KnownFunction::IsDisjointFrom) => {
|
||||
if let [Some(ty_a), Some(ty_b)] = overload.parameter_types() {
|
||||
let constraints =
|
||||
ty_a.when_disjoint_from(db, *ty_b, InferableTypeVars::none());
|
||||
ty_a.when_disjoint_from(db, *ty_b, InferableTypeVars::None);
|
||||
let tracked = TrackedConstraintSet::new(db, constraints);
|
||||
overload.set_return_type(Type::KnownInstance(
|
||||
KnownInstanceType::ConstraintSet(tracked),
|
||||
@@ -1182,7 +1183,7 @@ impl<'db> Bindings<'db> {
|
||||
db,
|
||||
*ty_b,
|
||||
tracked.constraints(db),
|
||||
InferableTypeVars::none(),
|
||||
InferableTypeVars::None,
|
||||
);
|
||||
let tracked = TrackedConstraintSet::new(db, result);
|
||||
overload.set_return_type(Type::KnownInstance(
|
||||
@@ -1216,20 +1217,21 @@ impl<'db> Bindings<'db> {
|
||||
let extract_inferable = |instance: &NominalInstanceType<'db>| {
|
||||
if instance.has_known_class(db, KnownClass::NoneType) {
|
||||
// Caller explicitly passed None, so no typevars are inferable.
|
||||
return Some(InferableTypeVars::none());
|
||||
return Some(FxHashSet::default());
|
||||
}
|
||||
Some(InferableTypeVars::from_bound_typevars(
|
||||
db,
|
||||
instance.tuple_spec(db)?.fixed_elements().filter_map(|ty| {
|
||||
instance
|
||||
.tuple_spec(db)?
|
||||
.fixed_elements()
|
||||
.map(|ty| {
|
||||
ty.as_typevar()
|
||||
.map(|bound_typevar| bound_typevar.identity(db))
|
||||
}),
|
||||
))
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
let inferable = match overload.parameter_types() {
|
||||
// Caller did not provide argument, so no typevars are inferable.
|
||||
[None] => InferableTypeVars::none(),
|
||||
[None] => FxHashSet::default(),
|
||||
[Some(Type::NominalInstance(instance))] => {
|
||||
match extract_inferable(instance) {
|
||||
Some(inferable) => inferable,
|
||||
@@ -1241,7 +1243,7 @@ impl<'db> Bindings<'db> {
|
||||
|
||||
let result = tracked
|
||||
.constraints(db)
|
||||
.satisfied_by_all_typevars(db, inferable);
|
||||
.satisfied_by_all_typevars(db, InferableTypeVars::One(&inferable));
|
||||
overload.set_return_type(Type::BooleanLiteral(result));
|
||||
}
|
||||
|
||||
@@ -2690,7 +2692,7 @@ struct ArgumentTypeChecker<'a, 'db> {
|
||||
return_ty: Type<'db>,
|
||||
errors: &'a mut Vec<BindingError<'db>>,
|
||||
|
||||
inferable_typevars: InferableTypeVars<'db>,
|
||||
inferable_typevars: InferableTypeVars<'db, 'db>,
|
||||
specialization: Option<Specialization<'db>>,
|
||||
}
|
||||
|
||||
@@ -2717,7 +2719,7 @@ impl<'a, 'db> ArgumentTypeChecker<'a, 'db> {
|
||||
call_expression_tcx,
|
||||
return_ty,
|
||||
errors,
|
||||
inferable_typevars: InferableTypeVars::none(),
|
||||
inferable_typevars: InferableTypeVars::None,
|
||||
specialization: None,
|
||||
}
|
||||
}
|
||||
@@ -3039,7 +3041,7 @@ impl<'a, 'db> ArgumentTypeChecker<'a, 'db> {
|
||||
fn finish(
|
||||
self,
|
||||
) -> (
|
||||
InferableTypeVars<'db>,
|
||||
InferableTypeVars<'db, 'db>,
|
||||
Option<Specialization<'db>>,
|
||||
Type<'db>,
|
||||
) {
|
||||
@@ -3109,7 +3111,7 @@ pub(crate) struct Binding<'db> {
|
||||
return_ty: Type<'db>,
|
||||
|
||||
/// The inferable typevars in this signature.
|
||||
inferable_typevars: InferableTypeVars<'db>,
|
||||
inferable_typevars: InferableTypeVars<'db, 'db>,
|
||||
|
||||
/// The specialization that was inferred from the argument types, if the callable is generic.
|
||||
specialization: Option<Specialization<'db>>,
|
||||
@@ -3137,7 +3139,7 @@ impl<'db> Binding<'db> {
|
||||
callable_type: signature_type,
|
||||
signature_type,
|
||||
return_ty: Type::unknown(),
|
||||
inferable_typevars: InferableTypeVars::none(),
|
||||
inferable_typevars: InferableTypeVars::None,
|
||||
specialization: None,
|
||||
argument_matches: Box::from([]),
|
||||
variadic_argument_matched_to_variadic_parameter: false,
|
||||
@@ -3350,7 +3352,7 @@ impl<'db> Binding<'db> {
|
||||
/// Resets the state of this binding to its initial state.
|
||||
fn reset(&mut self) {
|
||||
self.return_ty = Type::unknown();
|
||||
self.inferable_typevars = InferableTypeVars::none();
|
||||
self.inferable_typevars = InferableTypeVars::None;
|
||||
self.specialization = None;
|
||||
self.argument_matches = Box::from([]);
|
||||
self.parameter_tys = Box::from([]);
|
||||
@@ -3361,7 +3363,7 @@ impl<'db> Binding<'db> {
|
||||
#[derive(Clone, Debug)]
|
||||
struct BindingSnapshot<'db> {
|
||||
return_ty: Type<'db>,
|
||||
inferable_typevars: InferableTypeVars<'db>,
|
||||
inferable_typevars: InferableTypeVars<'db, 'db>,
|
||||
specialization: Option<Specialization<'db>>,
|
||||
argument_matches: Box<[MatchedArgument<'db>]>,
|
||||
parameter_tys: Box<[Option<Type<'db>>]>,
|
||||
|
||||
@@ -516,7 +516,7 @@ impl<'db> ClassType<'db> {
|
||||
|
||||
/// Return `true` if `other` is present in this class's MRO.
|
||||
pub(super) fn is_subclass_of(self, db: &'db dyn Db, other: ClassType<'db>) -> bool {
|
||||
self.when_subclass_of(db, other, InferableTypeVars::none())
|
||||
self.when_subclass_of(db, other, InferableTypeVars::None)
|
||||
.is_always_satisfied(db)
|
||||
}
|
||||
|
||||
@@ -524,7 +524,7 @@ impl<'db> ClassType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: ClassType<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
self.has_relation_to_impl(
|
||||
db,
|
||||
@@ -540,7 +540,7 @@ impl<'db> ClassType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -593,7 +593,7 @@ impl<'db> ClassType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: ClassType<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
if self == other {
|
||||
|
||||
@@ -246,7 +246,7 @@ impl<'db> ConstraintSet<'db> {
|
||||
pub(crate) fn satisfied_by_all_typevars(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
) -> bool {
|
||||
self.node.satisfied_by_all_typevars(db, inferable)
|
||||
}
|
||||
@@ -843,7 +843,11 @@ impl<'db> Node<'db> {
|
||||
self.satisfies(db, constraint)
|
||||
}
|
||||
|
||||
fn satisfied_by_all_typevars(self, db: &'db dyn Db, inferable: InferableTypeVars<'db>) -> bool {
|
||||
fn satisfied_by_all_typevars(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
) -> bool {
|
||||
match self {
|
||||
Node::AlwaysTrue => return true,
|
||||
Node::AlwaysFalse => return false,
|
||||
|
||||
@@ -970,7 +970,7 @@ impl<'db> FunctionType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -1009,7 +1009,7 @@ impl<'db> FunctionType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
if self.normalized(db) == other.normalized(db) {
|
||||
|
||||
@@ -2,10 +2,9 @@ use std::cell::RefCell;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::fmt::Display;
|
||||
|
||||
use itertools::Itertools;
|
||||
use itertools::{Either, Itertools};
|
||||
use ruff_python_ast as ast;
|
||||
use rustc_hash::FxHashMap;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
use crate::semantic_index::definition::Definition;
|
||||
use crate::semantic_index::scope::{FileScopeId, NodeWithScopeKind, ScopeId};
|
||||
@@ -120,111 +119,79 @@ pub(crate) fn typing_self<'db>(
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub(crate) struct InferableTypeVars<'db> {
|
||||
inner: Option<InferableTypeVarsInner<'db>>,
|
||||
pub(crate) enum InferableTypeVars<'a, 'db> {
|
||||
None,
|
||||
One(&'a FxHashSet<BoundTypeVarIdentity<'db>>),
|
||||
Two(
|
||||
&'a InferableTypeVars<'a, 'db>,
|
||||
&'a InferableTypeVars<'a, 'db>,
|
||||
),
|
||||
}
|
||||
|
||||
#[salsa::tracked(debug, heap_size=ruff_memory_usage::heap_size)]
|
||||
struct InferableTypeVarsInner<'db> {
|
||||
// The _set_ of typevars that are inferable. This will always be sorted and deduped.
|
||||
#[returns(ref)]
|
||||
inferable: SmallVec<[BoundTypeVarIdentity<'db>; 4]>,
|
||||
}
|
||||
|
||||
// The Salsa heap is tracked separately.
|
||||
impl get_size2::GetSize for InferableTypeVarsInner<'_> {}
|
||||
|
||||
impl<'db> BoundTypeVarInstance<'db> {
|
||||
pub(crate) fn is_inferable(self, db: &'db dyn Db, inferable: InferableTypeVars<'db>) -> bool {
|
||||
match inferable.inner {
|
||||
None => false,
|
||||
Some(inner) => inner
|
||||
.inferable(db)
|
||||
.binary_search(&self.identity(db))
|
||||
.is_ok(),
|
||||
pub(crate) fn is_inferable(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
) -> bool {
|
||||
match inferable {
|
||||
InferableTypeVars::None => false,
|
||||
InferableTypeVars::One(typevars) => typevars.contains(&self.identity(db)),
|
||||
InferableTypeVars::Two(left, right) => {
|
||||
self.is_inferable(db, *left) || self.is_inferable(db, *right)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'db> InferableTypeVars<'db> {
|
||||
pub(crate) const fn none() -> Self {
|
||||
InferableTypeVars { inner: None }
|
||||
impl<'a, 'db> InferableTypeVars<'a, 'db> {
|
||||
pub(crate) fn merge(&'a self, other: &'a InferableTypeVars<'a, 'db>) -> Self {
|
||||
InferableTypeVars::Two(self, other)
|
||||
}
|
||||
|
||||
pub(crate) fn from_bound_typevars(
|
||||
db: &'db dyn Db,
|
||||
bound_typevars: impl IntoIterator<Item = BoundTypeVarIdentity<'db>>,
|
||||
) -> Self {
|
||||
InferableTypeVars {
|
||||
inner: Some(InferableTypeVarsInner::from_bound_typevars(
|
||||
db,
|
||||
bound_typevars,
|
||||
)),
|
||||
// This is not an IntoIterator implementation because I have no desire to try to name the
|
||||
// iterator type.
|
||||
pub(crate) fn iter(self) -> impl Iterator<Item = BoundTypeVarIdentity<'db>> {
|
||||
match self {
|
||||
InferableTypeVars::None => Either::Left(Either::Left(std::iter::empty())),
|
||||
InferableTypeVars::One(typevars) => Either::Right(typevars.iter().copied()),
|
||||
InferableTypeVars::Two(left, right) => {
|
||||
let chained: Box<dyn Iterator<Item = BoundTypeVarIdentity<'db>>> =
|
||||
Box::new(left.iter().chain(right.iter()));
|
||||
Either::Left(Either::Right(chained))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn merge(self, db: &'db dyn Db, other: Self) -> Self {
|
||||
match (self.inner, other.inner) {
|
||||
(None, None) => self,
|
||||
(Some(_), None) => self,
|
||||
(None, Some(_)) => other,
|
||||
(Some(self_inner), Some(other_inner)) => InferableTypeVars {
|
||||
inner: Some(self_inner.merge(db, other_inner)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn iter(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
) -> impl Iterator<Item = BoundTypeVarIdentity<'db>> + 'db {
|
||||
self.inner
|
||||
.into_iter()
|
||||
.flat_map(|inner| inner.inferable(db).iter().copied())
|
||||
}
|
||||
|
||||
// Keep this around for debugging purposes
|
||||
#[expect(dead_code)]
|
||||
pub(crate) fn display(self, db: &'db dyn Db) -> impl Display {
|
||||
let inferable = match self.inner {
|
||||
Some(inner) => inner.inferable(db),
|
||||
None => return String::from("[]"),
|
||||
};
|
||||
pub(crate) fn display(&self, db: &'db dyn Db) -> impl Display {
|
||||
fn find_typevars<'db>(
|
||||
result: &mut FxHashSet<BoundTypeVarIdentity<'db>>,
|
||||
inferable: &InferableTypeVars<'_, 'db>,
|
||||
) {
|
||||
match inferable {
|
||||
InferableTypeVars::None => {}
|
||||
InferableTypeVars::One(typevars) => result.extend(typevars.iter().copied()),
|
||||
InferableTypeVars::Two(left, right) => {
|
||||
find_typevars(result, left);
|
||||
find_typevars(result, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut typevars = FxHashSet::default();
|
||||
find_typevars(&mut typevars, self);
|
||||
format!(
|
||||
"[{}]",
|
||||
inferable
|
||||
.iter()
|
||||
typevars
|
||||
.into_iter()
|
||||
.map(|identity| identity.display(db))
|
||||
.format(", ")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl<'db> InferableTypeVarsInner<'db> {
|
||||
fn from_bound_typevars(
|
||||
db: &'db dyn Db,
|
||||
bound_typevars: impl IntoIterator<Item = BoundTypeVarIdentity<'db>>,
|
||||
) -> Self {
|
||||
let mut inferable: SmallVec<_> = bound_typevars.into_iter().collect();
|
||||
inferable.sort_unstable();
|
||||
inferable.dedup();
|
||||
InferableTypeVarsInner::new(db, inferable)
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn merge(self, db: &'db dyn Db, other: Self) -> Self {
|
||||
// The input typevar vecs are already sorted, so we can merge/dedup them instead of
|
||||
// having to do an expensive sort.
|
||||
let self_inferable = self.inferable(db);
|
||||
let self_typevars = self_inferable.iter().copied();
|
||||
let other_inferable = other.inferable(db);
|
||||
let other_typevars = other_inferable.iter().copied();
|
||||
let inferable = self_typevars.merge(other_typevars).dedup().collect();
|
||||
InferableTypeVarsInner::new(db, inferable)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, get_size2::GetSize)]
|
||||
pub struct GenericContextTypeVar<'db> {
|
||||
bound_typevar: BoundTypeVarInstance<'db>,
|
||||
@@ -329,10 +296,10 @@ impl<'db> GenericContext<'db> {
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn inferable_typevars(self, db: &'db dyn Db) -> InferableTypeVars<'db> {
|
||||
pub(crate) fn inferable_typevars(self, db: &'db dyn Db) -> InferableTypeVars<'db, 'db> {
|
||||
#[derive(Default)]
|
||||
struct CollectTypeVars<'db> {
|
||||
typevars: RefCell<SmallVec<[BoundTypeVarIdentity<'db>; 4]>>,
|
||||
typevars: RefCell<FxHashSet<BoundTypeVarIdentity<'db>>>,
|
||||
recursion_guard: TypeCollector<'db>,
|
||||
}
|
||||
|
||||
@@ -346,7 +313,9 @@ impl<'db> GenericContext<'db> {
|
||||
db: &'db dyn Db,
|
||||
bound_typevar: BoundTypeVarInstance<'db>,
|
||||
) {
|
||||
self.typevars.borrow_mut().push(bound_typevar.identity(db));
|
||||
self.typevars
|
||||
.borrow_mut()
|
||||
.insert(bound_typevar.identity(db));
|
||||
walk_bound_type_var_type(db, bound_typevar, self);
|
||||
}
|
||||
|
||||
@@ -356,29 +325,25 @@ impl<'db> GenericContext<'db> {
|
||||
}
|
||||
|
||||
#[salsa::tracked(
|
||||
returns(ref),
|
||||
cycle_initial=inferable_typevars_cycle_initial,
|
||||
heap_size=ruff_memory_usage::heap_size,
|
||||
)]
|
||||
fn inferable_typevars_inner<'db>(
|
||||
db: &'db dyn Db,
|
||||
generic_context: GenericContext<'db>,
|
||||
) -> InferableTypeVarsInner<'db> {
|
||||
) -> FxHashSet<BoundTypeVarIdentity<'db>> {
|
||||
let visitor = CollectTypeVars::default();
|
||||
for bound_typevar in generic_context.variables(db) {
|
||||
visitor.visit_bound_type_var_type(db, bound_typevar);
|
||||
}
|
||||
let mut inferable = visitor.typevars.into_inner();
|
||||
inferable.sort_unstable();
|
||||
inferable.dedup();
|
||||
InferableTypeVarsInner::new(db, inferable)
|
||||
visitor.typevars.into_inner()
|
||||
}
|
||||
|
||||
// This ensures that salsa caches the InferableTypeVarsInner, not the InferableTypeVars
|
||||
// that wraps it. (That way InferableTypeVars can contain a reference, and doesn't need to
|
||||
// impl salsa::Update.)
|
||||
InferableTypeVars {
|
||||
inner: Some(inferable_typevars_inner(db, self)),
|
||||
}
|
||||
// This ensures that salsa caches the FxHashSet, not the InferableTypeVars that wraps it.
|
||||
// (That way InferableTypeVars can contain references, and doesn't need to impl
|
||||
// salsa::Update.)
|
||||
InferableTypeVars::One(inferable_typevars_inner(db, self))
|
||||
}
|
||||
|
||||
pub(crate) fn variables(
|
||||
@@ -664,11 +629,11 @@ impl<'db> GenericContext<'db> {
|
||||
}
|
||||
|
||||
fn inferable_typevars_cycle_initial<'db>(
|
||||
db: &'db dyn Db,
|
||||
_db: &'db dyn Db,
|
||||
_id: salsa::Id,
|
||||
_self: GenericContext<'db>,
|
||||
) -> InferableTypeVarsInner<'db> {
|
||||
InferableTypeVarsInner::new(db, smallvec![])
|
||||
) -> FxHashSet<BoundTypeVarIdentity<'db>> {
|
||||
FxHashSet::default()
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
@@ -739,7 +704,7 @@ fn is_subtype_in_invariant_position<'db>(
|
||||
derived_materialization: MaterializationKind,
|
||||
base_type: &Type<'db>,
|
||||
base_materialization: MaterializationKind,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
@@ -817,7 +782,7 @@ fn has_relation_in_invariant_position<'db>(
|
||||
derived_materialization: Option<MaterializationKind>,
|
||||
base_type: &Type<'db>,
|
||||
base_materialization: Option<MaterializationKind>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -1165,7 +1130,7 @@ impl<'db> Specialization<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -1243,7 +1208,7 @@ impl<'db> Specialization<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Specialization<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
if self.materialization_kind(db) != other.materialization_kind(db) {
|
||||
@@ -1357,12 +1322,12 @@ impl<'db> PartialSpecialization<'_, 'db> {
|
||||
/// specialization of a generic function.
|
||||
pub(crate) struct SpecializationBuilder<'db> {
|
||||
db: &'db dyn Db,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'db, 'db>,
|
||||
types: FxHashMap<BoundTypeVarIdentity<'db>, Type<'db>>,
|
||||
}
|
||||
|
||||
impl<'db> SpecializationBuilder<'db> {
|
||||
pub(crate) fn new(db: &'db dyn Db, inferable: InferableTypeVars<'db>) -> Self {
|
||||
pub(crate) fn new(db: &'db dyn Db, inferable: InferableTypeVars<'db, 'db>) -> Self {
|
||||
Self {
|
||||
db,
|
||||
inferable,
|
||||
|
||||
@@ -6829,7 +6829,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
.try_to_class_literal(self.db())
|
||||
.and_then(|class| class.generic_context(self.db()))
|
||||
.map(|generic_context| generic_context.inferable_typevars(self.db()))
|
||||
.unwrap_or(InferableTypeVars::none());
|
||||
.unwrap_or(InferableTypeVars::None);
|
||||
annotation.filter_disjoint_elements(
|
||||
self.db(),
|
||||
Type::homogeneous_tuple(self.db(), Type::unknown()),
|
||||
@@ -7149,7 +7149,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
|
||||
annotation.filter_disjoint_elements(
|
||||
self.db(),
|
||||
collection_class.to_instance(self.db()),
|
||||
InferableTypeVars::none(),
|
||||
InferableTypeVars::None,
|
||||
)
|
||||
});
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ impl<'db> Type<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
protocol: ProtocolInstanceType<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -365,7 +365,7 @@ impl<'db> NominalInstanceType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -398,7 +398,7 @@ impl<'db> NominalInstanceType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
match (self.0, other.0) {
|
||||
@@ -420,7 +420,7 @@ impl<'db> NominalInstanceType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
@@ -666,7 +666,7 @@ impl<'db> ProtocolInstanceType<'db> {
|
||||
.satisfies_protocol(
|
||||
db,
|
||||
protocol,
|
||||
InferableTypeVars::none(),
|
||||
InferableTypeVars::None,
|
||||
TypeRelation::Subtyping,
|
||||
&HasRelationToVisitor::default(),
|
||||
&IsDisjointVisitor::default(),
|
||||
@@ -719,7 +719,7 @@ impl<'db> ProtocolInstanceType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
_inferable: InferableTypeVars<'db>,
|
||||
_inferable: InferableTypeVars<'_, 'db>,
|
||||
_visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
if self == other {
|
||||
@@ -741,7 +741,7 @@ impl<'db> ProtocolInstanceType<'db> {
|
||||
self,
|
||||
_db: &'db dyn Db,
|
||||
_other: Self,
|
||||
_inferable: InferableTypeVars<'db>,
|
||||
_inferable: InferableTypeVars<'_, 'db>,
|
||||
_visitor: &IsDisjointVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
ConstraintSet::from(false)
|
||||
|
||||
@@ -233,7 +233,7 @@ impl<'db> ProtocolInterface<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -608,7 +608,7 @@ impl<'a, 'db> ProtocolMember<'a, 'db> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: Type<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
@@ -633,7 +633,7 @@ impl<'a, 'db> ProtocolMember<'a, 'db> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: Type<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
|
||||
@@ -217,7 +217,7 @@ impl<'db> CallableSignature<'db> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: &Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
self.has_relation_to_impl(
|
||||
db,
|
||||
@@ -233,7 +233,7 @@ impl<'db> CallableSignature<'db> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: &Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -255,7 +255,7 @@ impl<'db> CallableSignature<'db> {
|
||||
db: &'db dyn Db,
|
||||
self_signatures: &[Signature<'db>],
|
||||
other_signatures: &[Signature<'db>],
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -321,7 +321,7 @@ impl<'db> CallableSignature<'db> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: &Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
match (self.overloads.as_slice(), other.overloads.as_slice()) {
|
||||
@@ -628,10 +628,10 @@ impl<'db> Signature<'db> {
|
||||
}
|
||||
}
|
||||
|
||||
fn inferable_typevars(&self, db: &'db dyn Db) -> InferableTypeVars<'db> {
|
||||
fn inferable_typevars(&self, db: &'db dyn Db) -> InferableTypeVars<'db, 'db> {
|
||||
match self.generic_context {
|
||||
Some(generic_context) => generic_context.inferable_typevars(db),
|
||||
None => InferableTypeVars::none(),
|
||||
None => InferableTypeVars::None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -642,7 +642,7 @@ impl<'db> Signature<'db> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: &Signature<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
let mut result = ConstraintSet::from(true);
|
||||
@@ -729,7 +729,7 @@ impl<'db> Signature<'db> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: &Signature<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -739,10 +739,8 @@ impl<'db> Signature<'db> {
|
||||
// specialization that causes the check to succeed.
|
||||
let self_inferable = self.inferable_typevars(db);
|
||||
let other_inferable = other.inferable_typevars(db);
|
||||
let new_inferable = InferableTypeVars::none()
|
||||
.merge(db, self_inferable)
|
||||
.merge(db, other_inferable);
|
||||
let inferable = inferable.merge(db, new_inferable);
|
||||
let inferable = inferable.merge(&self_inferable);
|
||||
let inferable = inferable.merge(&other_inferable);
|
||||
|
||||
// `inner` will create a constraint set that references these newly inferable typevars.
|
||||
let when = self.has_relation_to_inner(
|
||||
@@ -758,14 +756,14 @@ impl<'db> Signature<'db> {
|
||||
// we produce, we reduce it back down to the inferable set that the caller asked about.
|
||||
// If we introduced new inferable typevars, those will be existentially quantified away
|
||||
// before returning.
|
||||
when.reduce_inferable(db, new_inferable.iter(db))
|
||||
when.reduce_inferable(db, self_inferable.iter().chain(other_inferable.iter()))
|
||||
}
|
||||
|
||||
fn has_relation_to_inner(
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: &Signature<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
|
||||
@@ -136,7 +136,7 @@ impl<'db> SubclassOfType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: SubclassOfType<'db>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -174,7 +174,7 @@ impl<'db> SubclassOfType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
_inferable: InferableTypeVars<'db>,
|
||||
_inferable: InferableTypeVars<'_, 'db>,
|
||||
_visitor: &IsDisjointVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
match (self.subclass_of, other.subclass_of) {
|
||||
|
||||
@@ -259,7 +259,7 @@ impl<'db> TupleType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -278,7 +278,7 @@ impl<'db> TupleType<'db> {
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
other: Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
self.tuple(db)
|
||||
@@ -441,7 +441,7 @@ impl<'db> FixedLengthTuple<Type<'db>> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: &Tuple<Type<'db>>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -528,7 +528,7 @@ impl<'db> FixedLengthTuple<Type<'db>> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: &Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
ConstraintSet::from(self.0.len() == other.0.len()).and(db, || {
|
||||
@@ -798,7 +798,7 @@ impl<'db> VariableLengthTuple<Type<'db>> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: &Tuple<Type<'db>>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -977,7 +977,7 @@ impl<'db> VariableLengthTuple<Type<'db>> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: &Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
self.variable
|
||||
@@ -1190,7 +1190,7 @@ impl<'db> Tuple<Type<'db>> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: &Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
relation: TypeRelation<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
@@ -1219,7 +1219,7 @@ impl<'db> Tuple<Type<'db>> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: &Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
visitor: &IsEquivalentVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
match (self, other) {
|
||||
@@ -1239,7 +1239,7 @@ impl<'db> Tuple<Type<'db>> {
|
||||
&self,
|
||||
db: &'db dyn Db,
|
||||
other: &Self,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
) -> ConstraintSet<'db> {
|
||||
@@ -1259,7 +1259,7 @@ impl<'db> Tuple<Type<'db>> {
|
||||
db: &'db dyn Db,
|
||||
a: impl IntoIterator<Item = &'s Type<'db>>,
|
||||
b: impl IntoIterator<Item = &'s Type<'db>>,
|
||||
inferable: InferableTypeVars<'db>,
|
||||
inferable: InferableTypeVars<'_, 'db>,
|
||||
disjointness_visitor: &IsDisjointVisitor<'db>,
|
||||
relation_visitor: &HasRelationToVisitor<'db>,
|
||||
) -> ConstraintSet<'db>
|
||||
|
||||
Reference in New Issue
Block a user