mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[ConstraintSystem] Use originating constraint as a source for a binding
Unify all of the fields of `PotentialBinding` which have to do with location information into a single field with is either a constraint (for regular bindings) or constraint locator (for "holes"). This helps to reduce the amount of space used by `PotentialBinding` as well as propagate more contextual information when binding gets attempted.
This commit is contained in:
@@ -3288,28 +3288,72 @@ private:
|
||||
/// The kind of bindings permitted.
|
||||
AllowedBindingKind Kind;
|
||||
|
||||
/// The kind of the constraint this binding came from.
|
||||
ConstraintKind BindingSource;
|
||||
|
||||
/// The defaulted protocol associated with this binding.
|
||||
ProtocolDecl *DefaultedProtocol;
|
||||
|
||||
/// If this is a binding that comes from a \c Defaultable constraint,
|
||||
/// the locator of that constraint.
|
||||
ConstraintLocator *DefaultableBinding = nullptr;
|
||||
protected:
|
||||
/// The source of the type information.
|
||||
///
|
||||
/// Determines whether this binding represents a "hole" in
|
||||
/// constraint system. Such bindings have no originating constraint
|
||||
/// because they are synthetic, they have a locator instead.
|
||||
PointerUnion<Constraint *, ConstraintLocator *> BindingSource;
|
||||
|
||||
PotentialBinding(Type type, AllowedBindingKind kind,
|
||||
ConstraintKind bindingSource,
|
||||
ProtocolDecl *defaultedProtocol = nullptr,
|
||||
ConstraintLocator *defaultableBinding = nullptr)
|
||||
PointerUnion<Constraint *, ConstraintLocator *> source)
|
||||
: BindingType(type->getWithoutParens()), Kind(kind),
|
||||
BindingSource(bindingSource), DefaultedProtocol(defaultedProtocol),
|
||||
DefaultableBinding(defaultableBinding) {}
|
||||
BindingSource(source) {}
|
||||
|
||||
bool isDefaultableBinding() const { return DefaultableBinding != nullptr; }
|
||||
public:
|
||||
PotentialBinding(Type type, AllowedBindingKind kind, Constraint *source)
|
||||
: BindingType(type->getWithoutParens()), Kind(kind),
|
||||
BindingSource(source) {}
|
||||
|
||||
bool isDefaultableBinding() const {
|
||||
if (auto *constraint = BindingSource.dyn_cast<Constraint *>())
|
||||
return constraint->getKind() == ConstraintKind::Defaultable;
|
||||
// If binding source is not constraint - it's a hole, which is
|
||||
// a last resort default binding for a type variable.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hasDefaultedLiteralProtocol() const {
|
||||
return bool(getDefaultedLiteralProtocol());
|
||||
}
|
||||
|
||||
ProtocolDecl *getDefaultedLiteralProtocol() const {
|
||||
auto *constraint = BindingSource.dyn_cast<Constraint *>();
|
||||
if (!constraint)
|
||||
return nullptr;
|
||||
|
||||
return constraint->getKind() == ConstraintKind::LiteralConformsTo
|
||||
? constraint->getProtocol()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
ConstraintKind getSourceKind() const {
|
||||
if (auto *constraint = BindingSource.dyn_cast<Constraint *>())
|
||||
return constraint->getKind();
|
||||
// If binding source is not constraint - it's a hole which is
|
||||
// always a `Bind` constraint.
|
||||
return ConstraintKind::Bind;
|
||||
}
|
||||
|
||||
ConstraintLocator *getLocator() const {
|
||||
if (auto *constraint = BindingSource.dyn_cast<Constraint *>())
|
||||
return constraint->getLocator();
|
||||
return BindingSource.get<ConstraintLocator *>();
|
||||
}
|
||||
|
||||
PotentialBinding withType(Type type) const {
|
||||
return {type, Kind, BindingSource, DefaultedProtocol, DefaultableBinding};
|
||||
return {type, Kind, BindingSource};
|
||||
}
|
||||
|
||||
PotentialBinding withSameSource(Type type, AllowedBindingKind kind) {
|
||||
return {type, Kind, BindingSource};
|
||||
}
|
||||
|
||||
static PotentialBinding forHole(ASTContext &ctx,
|
||||
ConstraintLocator *locator) {
|
||||
return {ctx.TheUnresolvedType, AllowedBindingKind::Exact,
|
||||
/*source=*/locator};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3464,9 +3508,8 @@ private:
|
||||
out << "(supertypes of) ";
|
||||
break;
|
||||
}
|
||||
if (binding.DefaultedProtocol)
|
||||
out << "(default from "
|
||||
<< binding.DefaultedProtocol->getName() << ") ";
|
||||
if (auto *literal = binding.getDefaultedLiteralProtocol())
|
||||
out << "(default from " << literal->getName() << ") ";
|
||||
out << type.getString(PO);
|
||||
},
|
||||
[&]() { out << "; "; });
|
||||
@@ -4196,7 +4239,9 @@ public:
|
||||
|
||||
bool isDefaultable() const { return Binding.isDefaultableBinding(); }
|
||||
|
||||
bool hasDefaultedProtocol() const { return Binding.DefaultedProtocol; }
|
||||
bool hasDefaultedProtocol() const {
|
||||
return Binding.hasDefaultedLiteralProtocol();
|
||||
}
|
||||
|
||||
bool attempt(ConstraintSystem &cs) const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user