Compare commits

...

5 Commits

Author SHA1 Message Date
Douglas Creager
832131f382 wohops 2026-01-05 10:12:14 -05:00
Douglas Creager
7da9a8ebcf add tracing 2026-01-05 10:12:14 -05:00
Douglas Creager
10c910b5ac some vacuous implications 2026-01-05 10:12:14 -05:00
Douglas Creager
dc3e36fb06 this extra ordering is counterproductive 2026-01-05 10:12:14 -05:00
Douglas Creager
42aabc8b99 separate lower and upper bounds 2026-01-05 10:12:14 -05:00
5 changed files with 506 additions and 451 deletions

View File

@@ -1226,7 +1226,10 @@ impl<'db> Bindings<'db> {
else {
return;
};
let constraints = ConstraintSet::range(db, *lower, *typevar, *upper);
// XXX: Replace this with lower, upper, and equality
let lower = ConstraintSet::lower_bound_constraint(db, *typevar, *lower);
let upper = ConstraintSet::upper_bound_constraint(db, *typevar, *upper);
let constraints = lower.and(db, || upper);
let tracked = TrackedConstraintSet::new(db, constraints);
overload.set_return_type(Type::KnownInstance(
KnownInstanceType::ConstraintSet(tracked),

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,7 @@ use crate::semantic_index::scope::{FileScopeId, NodeWithScopeKind, ScopeId};
use crate::semantic_index::{SemanticIndex, semantic_index};
use crate::types::class::ClassType;
use crate::types::class_base::ClassBase;
use crate::types::constraints::{ConstraintSet, IteratorConstraintsExtension};
use crate::types::constraints::{ConstraintBound, ConstraintSet, IteratorConstraintsExtension};
use crate::types::instance::{Protocol, ProtocolInstanceType};
use crate::types::relation::{
HasRelationToVisitor, IsDisjointVisitor, IsEquivalentVisitor, TypeRelation,
@@ -1643,20 +1643,23 @@ impl<'db> SpecializationBuilder<'db> {
mappings.clear();
for (constraint, _) in path {
let typevar = constraint.typevar(self.db);
let lower = constraint.lower(self.db);
let upper = constraint.upper(self.db);
let bound = constraint.bound(self.db);
let bounds = mappings.entry(typevar).or_default();
bounds.lower.insert(lower);
bounds.upper.insert(upper);
if let Type::TypeVar(lower_bound_typevar) = lower {
let bounds = mappings.entry(lower_bound_typevar).or_default();
bounds.upper.insert(Type::TypeVar(typevar));
}
if let Type::TypeVar(upper_bound_typevar) = upper {
let bounds = mappings.entry(upper_bound_typevar).or_default();
bounds.lower.insert(Type::TypeVar(typevar));
match bound {
ConstraintBound::Lower(lower) => {
bounds.lower.insert(lower);
if let Type::TypeVar(lower_bound_typevar) = lower {
let bounds = mappings.entry(lower_bound_typevar).or_default();
bounds.upper.insert(Type::TypeVar(typevar));
}
}
ConstraintBound::Upper(upper) => {
bounds.upper.insert(upper);
if let Type::TypeVar(upper_bound_typevar) = upper {
let bounds = mappings.entry(upper_bound_typevar).or_default();
bounds.lower.insert(Type::TypeVar(typevar));
}
}
}
}

View File

@@ -350,9 +350,9 @@ impl<'db> Type<'db> {
// only has to hold when the typevar has a valid specialization (i.e., one that
// satisfies the upper bound/constraints).
if let Type::TypeVar(bound_typevar) = self {
return ConstraintSet::constrain_typevar(db, bound_typevar, Type::Never, target);
return ConstraintSet::upper_bound_constraint(db, bound_typevar, target);
} else if let Type::TypeVar(bound_typevar) = target {
return ConstraintSet::constrain_typevar(db, bound_typevar, self, Type::object());
return ConstraintSet::lower_bound_constraint(db, bound_typevar, self);
}
}

View File

@@ -405,11 +405,10 @@ impl<'db> CallableSignature<'db> {
Some((self_bound_typevar, self_return_type)),
Some((other_bound_typevar, other_return_type)),
) => {
let param_spec_matches = ConstraintSet::constrain_typevar(
let param_spec_matches = ConstraintSet::equality_constraint(
db,
self_bound_typevar,
Type::TypeVar(other_bound_typevar),
Type::TypeVar(other_bound_typevar),
);
let return_types_match = self_return_type.zip(other_return_type).when_some_and(
|(self_return_type, other_return_type)| {
@@ -435,12 +434,8 @@ impl<'db> CallableSignature<'db> {
)),
CallableTypeKind::ParamSpecValue,
));
let param_spec_matches = ConstraintSet::constrain_typevar(
db,
self_bound_typevar,
Type::Never,
upper,
);
let param_spec_matches =
ConstraintSet::upper_bound_constraint(db, self_bound_typevar, upper);
let return_types_match = self_return_type.when_some_and(|self_return_type| {
other_signatures
.iter()
@@ -468,12 +463,8 @@ impl<'db> CallableSignature<'db> {
)),
CallableTypeKind::ParamSpecValue,
));
let param_spec_matches = ConstraintSet::constrain_typevar(
db,
other_bound_typevar,
lower,
Type::object(),
);
let param_spec_matches =
ConstraintSet::lower_bound_constraint(db, other_bound_typevar, lower);
let return_types_match = other_return_type.when_some_and(|other_return_type| {
self_signatures
.iter()
@@ -1120,7 +1111,7 @@ impl<'db> Signature<'db> {
CallableTypeKind::ParamSpecValue,
));
let param_spec_matches =
ConstraintSet::constrain_typevar(db, self_bound_typevar, Type::Never, upper);
ConstraintSet::upper_bound_constraint(db, self_bound_typevar, upper);
let return_types_match = self.return_ty.when_some_and(|self_return_type| {
other
.overloads
@@ -1362,11 +1353,10 @@ impl<'db> Signature<'db> {
// the other signature.
match (self_is_paramspec, other_is_paramspec) {
(Some(self_bound_typevar), Some(other_bound_typevar)) => {
let param_spec_matches = ConstraintSet::constrain_typevar(
let param_spec_matches = ConstraintSet::equality_constraint(
db,
self_bound_typevar,
Type::TypeVar(other_bound_typevar),
Type::TypeVar(other_bound_typevar),
);
result.intersect(db, param_spec_matches);
return result;
@@ -1378,12 +1368,8 @@ impl<'db> Signature<'db> {
CallableSignature::single(Signature::new(other.parameters.clone(), None)),
CallableTypeKind::ParamSpecValue,
));
let param_spec_matches = ConstraintSet::constrain_typevar(
db,
self_bound_typevar,
Type::Never,
upper,
);
let param_spec_matches =
ConstraintSet::upper_bound_constraint(db, self_bound_typevar, upper);
result.intersect(db, param_spec_matches);
return result;
}
@@ -1394,12 +1380,8 @@ impl<'db> Signature<'db> {
CallableSignature::single(Signature::new(self.parameters.clone(), None)),
CallableTypeKind::ParamSpecValue,
));
let param_spec_matches = ConstraintSet::constrain_typevar(
db,
other_bound_typevar,
lower,
Type::object(),
);
let param_spec_matches =
ConstraintSet::lower_bound_constraint(db, other_bound_typevar, lower);
result.intersect(db, param_spec_matches);
return result;
}