Skip to content

[CSBindings] Inference cannot fail #35529

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/swift/Sema/CSBindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ struct PotentialBindings {
Optional<PotentialBinding> inferFromRelational(Constraint *constraint);

public:
bool infer(Constraint *constraint);
void infer(Constraint *constraint);

/// Finalize binding computation for this type variable by
/// inferring bindings from context e.g. transitive bindings.
Expand Down
34 changes: 13 additions & 21 deletions lib/Sema/CSBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,13 +812,8 @@ PotentialBindings ConstraintSystem::inferBindingsFor(TypeVariableType *typeVar,
auto constraints = CG.gatherConstraints(
typeVar, ConstraintGraph::GatheringKind::EquivalenceClass);

for (auto *constraint : constraints) {
bool failed = bindings.infer(constraint);

// Upon inference failure let's produce an empty set of bindings.
if (failed)
return {*this, typeVar};
}
for (auto *constraint : constraints)
bindings.infer(constraint);

if (finalize) {
llvm::SmallDenseMap<TypeVariableType *, PotentialBindings> inferred;
Expand Down Expand Up @@ -1068,7 +1063,7 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
/// Retrieve the set of potential type bindings for the given
/// representative type variable, along with flags indicating whether
/// those types should be opened.
bool PotentialBindings::infer(Constraint *constraint) {
void PotentialBindings::infer(Constraint *constraint) {
switch (constraint->getKind()) {
case ConstraintKind::Bind:
case ConstraintKind::Equal:
Expand Down Expand Up @@ -1152,8 +1147,10 @@ bool PotentialBindings::infer(Constraint *constraint) {
// [existential] metatype.
auto dynamicType = constraint->getFirstType();
if (auto *tv = dynamicType->getAs<TypeVariableType>()) {
if (tv->getImpl().getRepresentative(nullptr) == TypeVar)
return true;
if (tv->getImpl().getRepresentative(nullptr) == TypeVar) {
DelayedBy.push_back(constraint);
break;
}
}

// This is right-hand side, let's continue.
Expand All @@ -1174,19 +1171,14 @@ bool PotentialBindings::infer(Constraint *constraint) {
// associated with closure literal (e.g. coercion to some other
// type) let's delay resolving the closure until the disjunction
// is attempted.
if (TypeVar->getImpl().isClosureType())
return true;

DelayedBy.push_back(constraint);
break;

case ConstraintKind::ConformsTo:
case ConstraintKind::SelfObjectOfProtocol: {
auto protocolTy = constraint->getSecondType();
if (!protocolTy->is<ProtocolType>())
return false;

Protocols.push_back(constraint);
if (protocolTy->is<ProtocolType>())
Protocols.push_back(constraint);
break;
}

Expand Down Expand Up @@ -1247,15 +1239,15 @@ bool PotentialBindings::infer(Constraint *constraint) {
// side of a one-way binding.
auto firstType = constraint->getFirstType();
if (auto *tv = firstType->getAs<TypeVariableType>()) {
if (tv->getImpl().getRepresentative(nullptr) == TypeVar)
return true;
if (tv->getImpl().getRepresentative(nullptr) == TypeVar) {
DelayedBy.push_back(constraint);
break;
}
}

break;
}
}

return false;
}

LiteralBindingKind PotentialBindings::getLiteralKind() const {
Expand Down