mirror of https://github.com/astral-sh/ruff
debug
This commit is contained in:
parent
336d01957d
commit
6a448e1623
|
|
@ -2891,9 +2891,16 @@ impl<'a, 'db> ArgumentTypeChecker<'a, 'db> {
|
||||||
// should prefer the tighter specialization.
|
// should prefer the tighter specialization.
|
||||||
|
|
||||||
// XXX: Determine typevar variance per argument
|
// XXX: Determine typevar variance per argument
|
||||||
|
eprintln!(
|
||||||
|
"--> arg {} {} {}",
|
||||||
|
argument_index,
|
||||||
|
argument_constraints.display(self.db),
|
||||||
|
valid_argument_constraints.display(self.db),
|
||||||
|
);
|
||||||
constraints.intersect(self.db, valid_argument_constraints);
|
constraints.intersect(self.db, valid_argument_constraints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
eprintln!("--> constraints {}", constraints.display(self.db));
|
||||||
|
|
||||||
// Attempt to promote any literal types assigned to the specialization.
|
// Attempt to promote any literal types assigned to the specialization.
|
||||||
let maybe_promote = |identity, typevar, ty: Type<'db>| {
|
let maybe_promote = |identity, typevar, ty: Type<'db>| {
|
||||||
|
|
@ -2949,15 +2956,23 @@ impl<'a, 'db> ArgumentTypeChecker<'a, 'db> {
|
||||||
generic_context.specialize_constrained_mapped(self.db, constraints, maybe_promote)
|
generic_context.specialize_constrained_mapped(self.db, constraints, maybe_promote)
|
||||||
else {
|
else {
|
||||||
// XXX: better error
|
// XXX: better error
|
||||||
|
eprintln!("--> X1");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
// XXX: maybe_promote
|
// XXX: maybe_promote
|
||||||
let isolated_return_ty = self
|
let isolated_return_ty = self
|
||||||
.return_ty
|
.return_ty
|
||||||
.apply_specialization(self.db, isolated_specialization);
|
.apply_specialization(self.db, isolated_specialization);
|
||||||
|
eprintln!("--> spec {}", isolated_specialization.display_full(self.db));
|
||||||
|
eprintln!("--> rty {}", isolated_return_ty.display(self.db));
|
||||||
|
|
||||||
let mut try_infer_tcx = || {
|
let mut try_infer_tcx = || {
|
||||||
let (return_ty, call_expression_tcx) = return_with_tcx?;
|
let (return_ty, call_expression_tcx) = return_with_tcx?;
|
||||||
|
eprintln!(
|
||||||
|
"--> infer tcx {} {}",
|
||||||
|
return_ty.display(self.db),
|
||||||
|
call_expression_tcx.display(self.db)
|
||||||
|
);
|
||||||
|
|
||||||
// A type variable is not a useful type-context for expression inference, and applying it
|
// A type variable is not a useful type-context for expression inference, and applying it
|
||||||
// to the return type can lead to confusing unions in nested generic calls.
|
// to the return type can lead to confusing unions in nested generic calls.
|
||||||
|
|
@ -2968,6 +2983,7 @@ impl<'a, 'db> ArgumentTypeChecker<'a, 'db> {
|
||||||
// If the return type is already assignable to the annotated type, we ignore the rest of
|
// If the return type is already assignable to the annotated type, we ignore the rest of
|
||||||
// the type context and prefer the narrower inferred type.
|
// the type context and prefer the narrower inferred type.
|
||||||
if isolated_return_ty.is_assignable_to(self.db, call_expression_tcx) {
|
if isolated_return_ty.is_assignable_to(self.db, call_expression_tcx) {
|
||||||
|
eprintln!("--> X2");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2977,6 +2993,7 @@ impl<'a, 'db> ArgumentTypeChecker<'a, 'db> {
|
||||||
.when_assignable_to(self.db, call_expression_tcx, self.inferable_typevars)
|
.when_assignable_to(self.db, call_expression_tcx, self.inferable_typevars)
|
||||||
.and(self.db, || valid_specializations);
|
.and(self.db, || valid_specializations);
|
||||||
if return_constraints.is_never_satisfied(self.db) {
|
if return_constraints.is_never_satisfied(self.db) {
|
||||||
|
eprintln!("--> X3");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2987,6 +3004,7 @@ impl<'a, 'db> ArgumentTypeChecker<'a, 'db> {
|
||||||
maybe_promote,
|
maybe_promote,
|
||||||
) else {
|
) else {
|
||||||
// XXX: better return
|
// XXX: better return
|
||||||
|
eprintln!("--> X4");
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
// XXX: maybe_promote
|
// XXX: maybe_promote
|
||||||
|
|
@ -3009,13 +3027,37 @@ impl<'a, 'db> ArgumentTypeChecker<'a, 'db> {
|
||||||
let parameters = self.signature.parameters();
|
let parameters = self.signature.parameters();
|
||||||
let parameter = ¶meters[parameter_index];
|
let parameter = ¶meters[parameter_index];
|
||||||
if let Some(mut expected_ty) = parameter.annotated_type() {
|
if let Some(mut expected_ty) = parameter.annotated_type() {
|
||||||
|
eprintln!(
|
||||||
|
"--> before {:?} {} {}",
|
||||||
|
adjusted_argument_index,
|
||||||
|
argument_type.display(self.db),
|
||||||
|
expected_ty.display(self.db),
|
||||||
|
);
|
||||||
if let Some(specialization) = self.specialization {
|
if let Some(specialization) = self.specialization {
|
||||||
argument_type = argument_type.apply_specialization(self.db, specialization);
|
argument_type = argument_type.apply_specialization(self.db, specialization);
|
||||||
expected_ty = expected_ty.apply_specialization(self.db, specialization);
|
expected_ty = expected_ty.apply_specialization(self.db, specialization);
|
||||||
|
eprintln!(
|
||||||
|
"--> after {:?} {} {}",
|
||||||
|
adjusted_argument_index,
|
||||||
|
argument_type.display(self.db),
|
||||||
|
expected_ty.display(self.db),
|
||||||
|
);
|
||||||
|
eprintln!(" {:?}", argument_type);
|
||||||
|
eprintln!(" {:?}", expected_ty);
|
||||||
}
|
}
|
||||||
// TODO: Soon we will go further, and build the actual specializations from the
|
// TODO: Soon we will go further, and build the actual specializations from the
|
||||||
// constraint set that we get from this assignability check, instead of inferring and
|
// constraint set that we get from this assignability check, instead of inferring and
|
||||||
// building them in an earlier separate step.
|
// building them in an earlier separate step.
|
||||||
|
let when =
|
||||||
|
argument_type.when_assignable_to(self.db, expected_ty, self.inferable_typevars);
|
||||||
|
eprintln!("===> check argument");
|
||||||
|
eprintln!(" --> arg {}", argument_type.display(self.db));
|
||||||
|
eprintln!(" --> param {}", expected_ty.display(self.db));
|
||||||
|
eprintln!(" --> when {}", when.display(self.db));
|
||||||
|
eprintln!(
|
||||||
|
" --> sat {}",
|
||||||
|
when.satisfied_by_all_typevars(self.db, self.inferable_typevars)
|
||||||
|
);
|
||||||
if !argument_type
|
if !argument_type
|
||||||
.when_assignable_to(self.db, expected_ty, self.inferable_typevars)
|
.when_assignable_to(self.db, expected_ty, self.inferable_typevars)
|
||||||
.satisfied_by_all_typevars(self.db, self.inferable_typevars)
|
.satisfied_by_all_typevars(self.db, self.inferable_typevars)
|
||||||
|
|
|
||||||
|
|
@ -1432,6 +1432,7 @@ impl<'db> SpecializationBuilder<'db> {
|
||||||
mut f: &mut dyn FnMut(TypeVarAssignment<'db>) -> Option<Type<'db>>,
|
mut f: &mut dyn FnMut(TypeVarAssignment<'db>) -> Option<Type<'db>>,
|
||||||
) -> Result<(), SpecializationError<'db>> {
|
) -> Result<(), SpecializationError<'db>> {
|
||||||
if formal == actual {
|
if formal == actual {
|
||||||
|
eprintln!(" --> AAA");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1510,6 +1511,7 @@ impl<'db> SpecializationBuilder<'db> {
|
||||||
.satisfied_by_all_typevars(self.db, InferableTypeVars::None)
|
.satisfied_by_all_typevars(self.db, InferableTypeVars::None)
|
||||||
});
|
});
|
||||||
if assignable_elements.exactly_one().is_ok() {
|
if assignable_elements.exactly_one().is_ok() {
|
||||||
|
eprintln!(" --> BBB");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -876,19 +876,22 @@ impl<'db> Signature<'db> {
|
||||||
let mut check_types = |type1: Option<Type<'db>>, type2: Option<Type<'db>>| {
|
let mut check_types = |type1: Option<Type<'db>>, type2: Option<Type<'db>>| {
|
||||||
let type1 = type1.unwrap_or(Type::unknown());
|
let type1 = type1.unwrap_or(Type::unknown());
|
||||||
let type2 = type2.unwrap_or(Type::unknown());
|
let type2 = type2.unwrap_or(Type::unknown());
|
||||||
!result
|
eprintln!(" --> check param");
|
||||||
.intersect(
|
eprintln!(" {}", type1.display(db));
|
||||||
db,
|
eprintln!(" {}", type2.display(db));
|
||||||
type1.has_relation_to_impl(
|
let x = type1.has_relation_to_impl(
|
||||||
db,
|
db,
|
||||||
type2,
|
type2,
|
||||||
inferable,
|
inferable,
|
||||||
relation,
|
relation,
|
||||||
relation_visitor,
|
relation_visitor,
|
||||||
disjointness_visitor,
|
disjointness_visitor,
|
||||||
),
|
);
|
||||||
)
|
eprintln!(" x {}", x.display(db),);
|
||||||
.is_never_satisfied(db)
|
let y = result.intersect(db, x);
|
||||||
|
eprintln!(" y {}", y.display(db),);
|
||||||
|
eprintln!(" ? {}", !y.is_never_satisfied(db));
|
||||||
|
!y.is_never_satisfied(db)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return types are covariant.
|
// Return types are covariant.
|
||||||
|
|
@ -932,6 +935,7 @@ impl<'db> Signature<'db> {
|
||||||
let Some(next_parameter) = parameters.next() else {
|
let Some(next_parameter) = parameters.next() else {
|
||||||
// All parameters have been checked or both the parameter lists were empty. In
|
// All parameters have been checked or both the parameter lists were empty. In
|
||||||
// either case, `self` is a subtype of `other`.
|
// either case, `self` is a subtype of `other`.
|
||||||
|
eprintln!(" --> X1 {}", result.display(db));
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -952,6 +956,7 @@ impl<'db> Signature<'db> {
|
||||||
// `other`, then the non-variadic parameters in `self` must have a default
|
// `other`, then the non-variadic parameters in `self` must have a default
|
||||||
// value.
|
// value.
|
||||||
if default_type.is_none() {
|
if default_type.is_none() {
|
||||||
|
eprintln!(" --> X2");
|
||||||
return ConstraintSet::from(false);
|
return ConstraintSet::from(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -964,6 +969,7 @@ impl<'db> Signature<'db> {
|
||||||
EitherOrBoth::Right(_) => {
|
EitherOrBoth::Right(_) => {
|
||||||
// If there are more parameters in `other` than in `self`, then `self` is not a
|
// If there are more parameters in `other` than in `self`, then `self` is not a
|
||||||
// subtype of `other`.
|
// subtype of `other`.
|
||||||
|
eprintln!(" --> X3");
|
||||||
return ConstraintSet::from(false);
|
return ConstraintSet::from(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -984,12 +990,14 @@ impl<'db> Signature<'db> {
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
if self_default.is_none() && other_default.is_some() {
|
if self_default.is_none() && other_default.is_some() {
|
||||||
|
eprintln!(" --> X4");
|
||||||
return ConstraintSet::from(false);
|
return ConstraintSet::from(false);
|
||||||
}
|
}
|
||||||
if !check_types(
|
if !check_types(
|
||||||
other_parameter.annotated_type(),
|
other_parameter.annotated_type(),
|
||||||
self_parameter.annotated_type(),
|
self_parameter.annotated_type(),
|
||||||
) {
|
) {
|
||||||
|
eprintln!(" --> X5");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1005,16 +1013,19 @@ impl<'db> Signature<'db> {
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
if self_name != other_name {
|
if self_name != other_name {
|
||||||
|
eprintln!(" --> X6");
|
||||||
return ConstraintSet::from(false);
|
return ConstraintSet::from(false);
|
||||||
}
|
}
|
||||||
// The following checks are the same as positional-only parameters.
|
// The following checks are the same as positional-only parameters.
|
||||||
if self_default.is_none() && other_default.is_some() {
|
if self_default.is_none() && other_default.is_some() {
|
||||||
|
eprintln!(" --> X7");
|
||||||
return ConstraintSet::from(false);
|
return ConstraintSet::from(false);
|
||||||
}
|
}
|
||||||
if !check_types(
|
if !check_types(
|
||||||
other_parameter.annotated_type(),
|
other_parameter.annotated_type(),
|
||||||
self_parameter.annotated_type(),
|
self_parameter.annotated_type(),
|
||||||
) {
|
) {
|
||||||
|
eprintln!(" --> X8");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1028,6 +1039,7 @@ impl<'db> Signature<'db> {
|
||||||
other_parameter.annotated_type(),
|
other_parameter.annotated_type(),
|
||||||
self_parameter.annotated_type(),
|
self_parameter.annotated_type(),
|
||||||
) {
|
) {
|
||||||
|
eprintln!(" --> X9");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1068,6 +1080,7 @@ impl<'db> Signature<'db> {
|
||||||
other_parameter.annotated_type(),
|
other_parameter.annotated_type(),
|
||||||
self_parameter.annotated_type(),
|
self_parameter.annotated_type(),
|
||||||
) {
|
) {
|
||||||
|
eprintln!(" --> X10");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
parameters.next_other();
|
parameters.next_other();
|
||||||
|
|
@ -1079,6 +1092,7 @@ impl<'db> Signature<'db> {
|
||||||
other_parameter.annotated_type(),
|
other_parameter.annotated_type(),
|
||||||
self_parameter.annotated_type(),
|
self_parameter.annotated_type(),
|
||||||
) {
|
) {
|
||||||
|
eprintln!(" --> X11");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1094,12 +1108,16 @@ impl<'db> Signature<'db> {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => return ConstraintSet::from(false),
|
_ => {
|
||||||
|
eprintln!(" --> X12");
|
||||||
|
return ConstraintSet::from(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eprintln!(" --> YYY");
|
||||||
// At this point, the remaining parameters in `other` are keyword-only or keyword variadic.
|
// At this point, the remaining parameters in `other` are keyword-only or keyword variadic.
|
||||||
// But, `self` could contain any unmatched positional parameters.
|
// But, `self` could contain any unmatched positional parameters.
|
||||||
let (self_parameters, other_parameters) = parameters.into_remaining();
|
let (self_parameters, other_parameters) = parameters.into_remaining();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue