s/ConstraintGraph::Node/ConstraintGraphNode

Swift SVN r11002
This commit is contained in:
Doug Gregor
2013-12-09 03:48:12 +00:00
parent 0d2074994e
commit 2dbc5018ae
3 changed files with 153 additions and 150 deletions

View File

@@ -104,7 +104,7 @@ gatherReferencedTypeVars(ConstraintSystem &cs,
#pragma mark Graph accessors #pragma mark Graph accessors
std::pair<ConstraintGraph::Node &, unsigned> std::pair<ConstraintGraphNode &, unsigned>
ConstraintGraph::lookupNode(TypeVariableType *typeVar) { ConstraintGraph::lookupNode(TypeVariableType *typeVar) {
// Check whether we've already created a node for this type variable. // Check whether we've already created a node for this type variable.
auto known = Nodes.find(typeVar); auto known = Nodes.find(typeVar);
@@ -115,7 +115,7 @@ ConstraintGraph::lookupNode(TypeVariableType *typeVar) {
// Allocate the new node. // Allocate the new node.
StoredNode &stored = Nodes[typeVar]; StoredNode &stored = Nodes[typeVar];
stored.NodePtr = new Node(typeVar); stored.NodePtr = new ConstraintGraphNode(typeVar);
stored.Index = TypeVariables.size(); stored.Index = TypeVariables.size();
// Record this type variable. // Record this type variable.
@@ -138,27 +138,27 @@ ConstraintGraph::lookupNode(TypeVariableType *typeVar) {
return { *stored.NodePtr, stored.Index }; return { *stored.NodePtr, stored.Index };
} }
ArrayRef<TypeVariableType *> ConstraintGraph::Node::getEquivalenceClass() const{ ArrayRef<TypeVariableType *> ConstraintGraphNode::getEquivalenceClass() const{
assert(TypeVar == TypeVar->getImpl().getRepresentative(nullptr) && assert(TypeVar == TypeVar->getImpl().getRepresentative(nullptr) &&
"Can't request equivalence class from non-representative type var"); "Can't request equivalence class from non-representative type var");
return getEquivalenceClassUnsafe(); return getEquivalenceClassUnsafe();
} }
ArrayRef<TypeVariableType *> ArrayRef<TypeVariableType *>
ConstraintGraph::Node::getEquivalenceClassUnsafe() const{ ConstraintGraphNode::getEquivalenceClassUnsafe() const{
if (EquivalenceClass.empty()) if (EquivalenceClass.empty())
EquivalenceClass.push_back(TypeVar); EquivalenceClass.push_back(TypeVar);
return EquivalenceClass; return EquivalenceClass;
} }
#pragma mark Node mutation #pragma mark Node mutation
void ConstraintGraph::Node::addConstraint(Constraint *constraint) { void ConstraintGraphNode::addConstraint(Constraint *constraint) {
assert(ConstraintIndex.count(constraint) == 0 && "Constraint re-insertion"); assert(ConstraintIndex.count(constraint) == 0 && "Constraint re-insertion");
ConstraintIndex[constraint] = Constraints.size(); ConstraintIndex[constraint] = Constraints.size();
Constraints.push_back(constraint); Constraints.push_back(constraint);
} }
void ConstraintGraph::Node::removeConstraint(Constraint *constraint) { void ConstraintGraphNode::removeConstraint(Constraint *constraint) {
auto pos = ConstraintIndex.find(constraint); auto pos = ConstraintIndex.find(constraint);
assert(pos != ConstraintIndex.end()); assert(pos != ConstraintIndex.end());
@@ -183,8 +183,8 @@ void ConstraintGraph::Node::removeConstraint(Constraint *constraint) {
Constraints.pop_back(); Constraints.pop_back();
} }
ConstraintGraph::Node::Adjacency & ConstraintGraphNode::Adjacency &
ConstraintGraph::Node::getAdjacency(TypeVariableType *typeVar) { ConstraintGraphNode::getAdjacency(TypeVariableType *typeVar) {
assert(typeVar != TypeVar && "Cannot be adjacent to oneself"); assert(typeVar != TypeVar && "Cannot be adjacent to oneself");
// Look for existing adjacency information. // Look for existing adjacency information.
@@ -202,7 +202,7 @@ ConstraintGraph::Node::getAdjacency(TypeVariableType *typeVar) {
return pos->second; return pos->second;
} }
void ConstraintGraph::Node::modifyAdjacency( void ConstraintGraphNode::modifyAdjacency(
TypeVariableType *typeVar, TypeVariableType *typeVar,
std::function<void(Adjacency& adj)> modify) { std::function<void(Adjacency& adj)> modify) {
// Find the adjacency information. // Find the adjacency information.
@@ -237,21 +237,21 @@ void ConstraintGraph::Node::modifyAdjacency(
Adjacencies.pop_back(); Adjacencies.pop_back();
} }
void ConstraintGraph::Node::addAdjacency(TypeVariableType *typeVar) { void ConstraintGraphNode::addAdjacency(TypeVariableType *typeVar) {
auto &adjacency = getAdjacency(typeVar); auto &adjacency = getAdjacency(typeVar);
// Bump the degree of the adjacency. // Bump the degree of the adjacency.
++adjacency.NumConstraints; ++adjacency.NumConstraints;
} }
void ConstraintGraph::Node::removeAdjacency(TypeVariableType *typeVar) { void ConstraintGraphNode::removeAdjacency(TypeVariableType *typeVar) {
modifyAdjacency(typeVar, [](Adjacency &adj) { modifyAdjacency(typeVar, [](Adjacency &adj) {
assert(adj.NumConstraints > 0 && "No adjacency to remove?"); assert(adj.NumConstraints > 0 && "No adjacency to remove?");
--adj.NumConstraints; --adj.NumConstraints;
}); });
} }
void ConstraintGraph::Node::addToEquivalenceClass( void ConstraintGraphNode::addToEquivalenceClass(
ArrayRef<TypeVariableType *> typeVars) { ArrayRef<TypeVariableType *> typeVars) {
assert(TypeVar == TypeVar->getImpl().getRepresentative(nullptr) && assert(TypeVar == TypeVar->getImpl().getRepresentative(nullptr) &&
"Can't extend equivalence class of non-representative type var"); "Can't extend equivalence class of non-representative type var");
@@ -260,14 +260,14 @@ void ConstraintGraph::Node::addToEquivalenceClass(
EquivalenceClass.append(typeVars.begin(), typeVars.end()); EquivalenceClass.append(typeVars.begin(), typeVars.end());
} }
void ConstraintGraph::Node::addFixedBinding(TypeVariableType *typeVar) { void ConstraintGraphNode::addFixedBinding(TypeVariableType *typeVar) {
auto &adjacency = getAdjacency(typeVar); auto &adjacency = getAdjacency(typeVar);
assert(!adjacency.FixedBinding && "Already marked as a fixed binding?"); assert(!adjacency.FixedBinding && "Already marked as a fixed binding?");
adjacency.FixedBinding = true; adjacency.FixedBinding = true;
} }
void ConstraintGraph::Node::removeFixedBinding(TypeVariableType *typeVar) { void ConstraintGraphNode::removeFixedBinding(TypeVariableType *typeVar) {
modifyAdjacency(typeVar, [](Adjacency &adj) { modifyAdjacency(typeVar, [](Adjacency &adj) {
assert(adj.FixedBinding && "Not a fixed binding?"); assert(adj.FixedBinding && "Not a fixed binding?");
adj.FixedBinding = false; adj.FixedBinding = false;
@@ -358,7 +358,7 @@ void ConstraintGraph::Change::undo(ConstraintGraph &cg) {
break; break;
case ChangeKind::ExtendedEquivalenceClass: { case ChangeKind::ExtendedEquivalenceClass: {
Node &node = cg[EquivClass.TypeVar]; auto &node = cg[EquivClass.TypeVar];
node.EquivalenceClass.erase( node.EquivalenceClass.erase(
node.EquivalenceClass.begin() + EquivClass.PrevSize, node.EquivalenceClass.begin() + EquivClass.PrevSize,
node.EquivalenceClass.end()); node.EquivalenceClass.end());
@@ -398,7 +398,7 @@ void ConstraintGraph::addConstraint(Constraint *constraint) {
// For the nodes corresponding to each type variable... // For the nodes corresponding to each type variable...
for (auto typeVar : referencedTypeVars) { for (auto typeVar : referencedTypeVars) {
// Find the node for this type variable. // Find the node for this type variable.
Node &node = (*this)[typeVar]; auto &node = (*this)[typeVar];
// Note the constraint within the node for that type variable. // Note the constraint within the node for that type variable.
node.addConstraint(constraint); node.addConstraint(constraint);
@@ -427,7 +427,7 @@ void ConstraintGraph::removeConstraint(Constraint *constraint) {
// For the nodes corresponding to each type variable... // For the nodes corresponding to each type variable...
for (auto typeVar : referencedTypeVars) { for (auto typeVar : referencedTypeVars) {
// Find the node for this type variable. // Find the node for this type variable.
Node &node = (*this)[typeVar]; auto &node = (*this)[typeVar];
// Remove the constraint. // Remove the constraint.
node.removeConstraint(constraint); node.removeConstraint(constraint);
@@ -481,7 +481,7 @@ void ConstraintGraph::bindTypeVariable(TypeVariableType *typeVar, Type fixed) {
SmallVector<TypeVariableType *, 4> typeVars; SmallVector<TypeVariableType *, 4> typeVars;
llvm::SmallPtrSet<TypeVariableType *, 4> knownTypeVars; llvm::SmallPtrSet<TypeVariableType *, 4> knownTypeVars;
fixed->getTypeVariables(typeVars); fixed->getTypeVariables(typeVars);
Node &node = (*this)[typeVar]; auto &node = (*this)[typeVar];
for (auto otherTypeVar : typeVars) { for (auto otherTypeVar : typeVars) {
if (knownTypeVars.insert(otherTypeVar)) { if (knownTypeVars.insert(otherTypeVar)) {
(*this)[otherTypeVar].addFixedBinding(typeVar); (*this)[otherTypeVar].addFixedBinding(typeVar);
@@ -504,7 +504,7 @@ void ConstraintGraph::unbindTypeVariable(TypeVariableType *typeVar, Type fixed){
SmallVector<TypeVariableType *, 4> typeVars; SmallVector<TypeVariableType *, 4> typeVars;
llvm::SmallPtrSet<TypeVariableType *, 4> knownTypeVars; llvm::SmallPtrSet<TypeVariableType *, 4> knownTypeVars;
fixed->getTypeVariables(typeVars); fixed->getTypeVariables(typeVars);
Node &node = (*this)[typeVar]; auto &node = (*this)[typeVar];
for (auto otherTypeVar : typeVars) { for (auto otherTypeVar : typeVars) {
if (knownTypeVars.insert(otherTypeVar)) { if (knownTypeVars.insert(otherTypeVar)) {
(*this)[otherTypeVar].removeFixedBinding(typeVar); (*this)[otherTypeVar].removeFixedBinding(typeVar);
@@ -528,7 +528,7 @@ void ConstraintGraph::gatherConstraints(
/// Depth-first search for connected components /// Depth-first search for connected components
static void connectedComponentsDFS(ConstraintGraph &cg, static void connectedComponentsDFS(ConstraintGraph &cg,
ConstraintGraph::Node &node, ConstraintGraphNode &node,
unsigned component, unsigned component,
SmallVectorImpl<unsigned> &components) { SmallVectorImpl<unsigned> &components) {
// Local function that recurses on the given set of type variables. // Local function that recurses on the given set of type variables.
@@ -644,7 +644,7 @@ unsigned ConstraintGraph::computeConnectedComponents(
#pragma mark Debugging output #pragma mark Debugging output
void ConstraintGraph::Node::print(llvm::raw_ostream &out, unsigned indent) { void ConstraintGraphNode::print(llvm::raw_ostream &out, unsigned indent) {
out.indent(indent); out.indent(indent);
TypeVar->print(out); TypeVar->print(out);
out << ":\n"; out << ":\n";
@@ -708,7 +708,7 @@ void ConstraintGraph::Node::print(llvm::raw_ostream &out, unsigned indent) {
} }
} }
void ConstraintGraph::Node::dump() { void ConstraintGraphNode::dump() {
print(llvm::dbgs(), 0); print(llvm::dbgs(), 0);
} }
@@ -762,7 +762,7 @@ void ConstraintGraph::dumpConnectedComponents() {
/// provide extra, contextual information about the failure. /// provide extra, contextual information about the failure.
static void _require(bool condition, const Twine &complaint, static void _require(bool condition, const Twine &complaint,
ConstraintGraph &cg, ConstraintGraph &cg,
ConstraintGraph::Node *node, ConstraintGraphNode *node,
const std::function<void()> &extraContext = nullptr) { const std::function<void()> &extraContext = nullptr) {
if (condition) if (condition)
return; return;
@@ -794,7 +794,7 @@ static void printValue(llvm::raw_ostream &os, unsigned value) {
os << value; os << value;
} }
void ConstraintGraph::Node::verify(ConstraintGraph &cg) { void ConstraintGraphNode::verify(ConstraintGraph &cg) {
#define require(condition, complaint) _require(condition, complaint, cg, this) #define require(condition, complaint) _require(condition, complaint, cg, this)
#define requireWithContext(condition, complaint, context) \ #define requireWithContext(condition, complaint, context) \
_require(condition, complaint, cg, this, context) _require(condition, complaint, cg, this, context)
@@ -835,7 +835,8 @@ void ConstraintGraph::Node::verify(ConstraintGraph &cg) {
llvm::DenseMap<TypeVariableType *, unsigned> expectedAdjacencies; llvm::DenseMap<TypeVariableType *, unsigned> expectedAdjacencies;
for (auto constraint : Constraints) { for (auto constraint : Constraints) {
SmallVector<TypeVariableType *, 4> referencedTypeVars; SmallVector<TypeVariableType *, 4> referencedTypeVars;
gatherReferencedTypeVars(cg.CS, constraint, referencedTypeVars); gatherReferencedTypeVars(cg.getConstraintSystem(), constraint,
referencedTypeVars);
for (auto adjTypeVar : referencedTypeVars) { for (auto adjTypeVar : referencedTypeVars) {
if (adjTypeVar == TypeVar) if (adjTypeVar == TypeVar)
@@ -974,7 +975,7 @@ void ConstraintGraph::verify() {
llvm::dbgs() << "\n"; llvm::dbgs() << "\n";
}); });
Node &node = *nodePos->second.NodePtr; auto &node = *nodePos->second.NodePtr;
auto constraintPos = node.ConstraintIndex.find(&constraint); auto constraintPos = node.ConstraintIndex.find(&constraint);
requireWithContext(constraintPos != node.ConstraintIndex.end(), requireWithContext(constraintPos != node.ConstraintIndex.end(),
"type variable doesn't know about constraint", "type variable doesn't know about constraint",

View File

@@ -35,9 +35,130 @@ class TypeVariableType;
namespace constraints { namespace constraints {
class Constraint; class Constraint;
class ConstraintGraph;
class ConstraintGraphScope; class ConstraintGraphScope;
class ConstraintSystem; class ConstraintSystem;
/// A single node in the constraint graph, which represents a type variable.
class ConstraintGraphNode {
/// Describes information about an adjacency between two type variables.
struct Adjacency {
/// Index into the vector of adjacent type variables, \c Adjacencies.
unsigned Index : 31;
/// Whether a fixed type binding relates the two type variables.
unsigned FixedBinding : 1;
/// The number of constraints that link this type variable to the
/// enclosing node.
unsigned NumConstraints;
bool empty() const {
return !FixedBinding && !NumConstraints;
}
};
public:
explicit ConstraintGraphNode(TypeVariableType *typeVar) : TypeVar(typeVar) { }
ConstraintGraphNode(const ConstraintGraphNode&) = delete;
ConstraintGraphNode &operator=(const ConstraintGraphNode&) = delete;
/// Retrieve the type variable this node represents.
TypeVariableType *getTypeVariable() const { return TypeVar; }
/// Retrieve the set of constraints that mention this type variable.
///
/// These are the hyperedges of the graph, connecting this node to
/// various other nodes.
ArrayRef<Constraint *> getConstraints() const { return Constraints; }
/// Retrieve the set of type variables to which this node is adjacent.
ArrayRef<TypeVariableType *> getAdjacencies() const {
return Adjacencies;
}
/// Retrieve all of the type variables in the same equivalence class
/// as this type variable.
ArrayRef<TypeVariableType *> getEquivalenceClass() const;
private:
/// Retrieve all of the type variables in the same equivalence class
/// as this type variable.
ArrayRef<TypeVariableType *> getEquivalenceClassUnsafe() const;
/// Add a constraint to the list of constraints.
void addConstraint(Constraint *constraint);
/// Remove a constraint from the list of constraints.
///
/// Note that this only removes the constraint itself; it does not
/// remove the corresponding adjacencies.
void removeConstraint(Constraint *constraint);
/// Retrieve adjacency information for the given type variable.
Adjacency &getAdjacency(TypeVariableType *typeVar);
/// Modify the adjacency information for the given type variable
/// directly. If the adjacency becomes empty afterward, it will be
/// removed.
void modifyAdjacency(TypeVariableType *typeVar,
std::function<void(Adjacency& adj)> modify);
/// Add an adjacency to the list of adjacencies.
void addAdjacency(TypeVariableType *typeVar);
/// Remove an adjacency from the list of adjacencies.
void removeAdjacency(TypeVariableType *typeVar);
/// Add the given type variables to this node's equivalence class.
void addToEquivalenceClass(ArrayRef<TypeVariableType *> typeVars);
/// Add a type variable related to this type variable through fixed
/// bindings.
void addFixedBinding(TypeVariableType *typeVar);
/// Remove a type variable from the fixed-binding relationship.
void removeFixedBinding(TypeVariableType *typeVar);
/// The type variable this node represents.
TypeVariableType *TypeVar;
/// The vector of constraints that mention this type variable, in a stable
/// order for iteration.
SmallVector<Constraint *, 2> Constraints;
/// A mapping from the set of constraints that mention this type variable
/// to the index within the vector of constraints.
llvm::SmallDenseMap<Constraint *, unsigned, 2> ConstraintIndex;
/// The set of adjacent type variables, in a stable order.
SmallVector<TypeVariableType *, 2> Adjacencies;
/// A mapping from each of the type variables adjacent to this
/// type variable to the index of the adjacency information in
/// \c Adjacencies.
llvm::SmallDenseMap<TypeVariableType *, Adjacency, 2> AdjacencyInfo;
/// All of the type variables in the same equivalence class as this
/// representative type variable.
///
/// Note that this field is only valid for type variables that
/// are representatives of their equivalence classes.
mutable SmallVector<TypeVariableType *, 2> EquivalenceClass;
/// Print this graph node.
void print(llvm::raw_ostream &out, unsigned indent);
LLVM_ATTRIBUTE_DEPRECATED(void dump() LLVM_ATTRIBUTE_USED,
"only for use within the debugger");
/// Verify the invariants of this node within the given constraint graph.
void verify(ConstraintGraph &cg);
friend class ConstraintGraph;
};
/// A graph that describes the relationships among the various type variables /// A graph that describes the relationships among the various type variables
/// and constraints within a constraint system. /// and constraints within a constraint system.
/// ///
@@ -49,126 +170,6 @@ class ConstraintSystem;
/// its adjacencies (the type variables) separately. /// its adjacencies (the type variables) separately.
class ConstraintGraph { class ConstraintGraph {
public: public:
/// A single node in the constraint graph, which represents a type variable.
class Node {
/// Describes information about an adjacency between two type variables.
struct Adjacency {
/// Index into the vector of adjacent type variables, \c Adjacencies.
unsigned Index : 31;
/// Whether a fixed type binding relates the two type variables.
unsigned FixedBinding : 1;
/// The number of constraints that link this type variable to the
/// enclosing node.
unsigned NumConstraints;
bool empty() const {
return !FixedBinding && !NumConstraints;
}
};
public:
explicit Node(TypeVariableType *typeVar) : TypeVar(typeVar) { }
Node(const Node&) = delete;
Node &operator=(const Node&) = delete;
/// Retrieve the type variable this node represents.
TypeVariableType *getTypeVariable() const { return TypeVar; }
/// Retrieve the set of constraints that mention this type variable.
///
/// These are the hyperedges of the graph, connecting this node to
/// various other nodes.
ArrayRef<Constraint *> getConstraints() const { return Constraints; }
/// Retrieve the set of type variables to which this node is adjacent.
ArrayRef<TypeVariableType *> getAdjacencies() const {
return Adjacencies;
}
/// Retrieve all of the type variables in the same equivalence class
/// as this type variable.
ArrayRef<TypeVariableType *> getEquivalenceClass() const;
private:
/// Retrieve all of the type variables in the same equivalence class
/// as this type variable.
ArrayRef<TypeVariableType *> getEquivalenceClassUnsafe() const;
/// Add a constraint to the list of constraints.
void addConstraint(Constraint *constraint);
/// Remove a constraint from the list of constraints.
///
/// Note that this only removes the constraint itself; it does not
/// remove the corresponding adjacencies.
void removeConstraint(Constraint *constraint);
/// Retrieve adjacency information for the given type variable.
Adjacency &getAdjacency(TypeVariableType *typeVar);
/// Modify the adjacency information for the given type variable
/// directly. If the adjacency becomes empty afterward, it will be
/// removed.
void modifyAdjacency(TypeVariableType *typeVar,
std::function<void(Adjacency& adj)> modify);
/// Add an adjacency to the list of adjacencies.
void addAdjacency(TypeVariableType *typeVar);
/// Remove an adjacency from the list of adjacencies.
void removeAdjacency(TypeVariableType *typeVar);
/// Add the given type variables to this node's equivalence class.
void addToEquivalenceClass(ArrayRef<TypeVariableType *> typeVars);
/// Add a type variable related to this type variable through fixed
/// bindings.
void addFixedBinding(TypeVariableType *typeVar);
/// Remove a type variable from the fixed-binding relationship.
void removeFixedBinding(TypeVariableType *typeVar);
/// The type variable this node represents.
TypeVariableType *TypeVar;
/// The vector of constraints that mention this type variable, in a stable
/// order for iteration.
SmallVector<Constraint *, 2> Constraints;
/// A mapping from the set of constraints that mention this type variable
/// to the index within the vector of constraints.
llvm::SmallDenseMap<Constraint *, unsigned, 2> ConstraintIndex;
/// The set of adjacent type variables, in a stable order.
SmallVector<TypeVariableType *, 2> Adjacencies;
/// A mapping from each of the type variables adjacent to this
/// type variable to the index of the adjacency information in
/// \c Adjacencies.
llvm::SmallDenseMap<TypeVariableType *, Adjacency, 2> AdjacencyInfo;
/// All of the type variables in the same equivalence class as this
/// representative type variable.
///
/// Note that this field is only valid for type variables that
/// are representatives of their equivalence classes.
mutable SmallVector<TypeVariableType *, 2> EquivalenceClass;
/// Print this graph node.
void print(llvm::raw_ostream &out, unsigned indent);
LLVM_ATTRIBUTE_DEPRECATED(void dump() LLVM_ATTRIBUTE_USED,
"only for use within the debugger");
/// Verify the invariants of this node within the given constraint graph.
void verify(ConstraintGraph &cg);
friend class ConstraintGraph;
};
/// Constraint a constraint graph for the given constraint system. /// Constraint a constraint graph for the given constraint system.
ConstraintGraph(ConstraintSystem &cs); ConstraintGraph(ConstraintSystem &cs);
@@ -183,12 +184,13 @@ public:
ConstraintSystem &getConstraintSystem() const { return CS; } ConstraintSystem &getConstraintSystem() const { return CS; }
/// Access the node corresponding to the given type variable. /// Access the node corresponding to the given type variable.
Node &operator[](TypeVariableType *typeVar) { ConstraintGraphNode &operator[](TypeVariableType *typeVar) {
return lookupNode(typeVar).first; return lookupNode(typeVar).first;
} }
/// Retrieve the node and index corresponding to the given type variable. /// Retrieve the node and index corresponding to the given type variable.
std::pair<Node &, unsigned> lookupNode(TypeVariableType *typeVar); std::pair<ConstraintGraphNode &, unsigned>
lookupNode(TypeVariableType *typeVar);
/// Add a new constraint to the graph. /// Add a new constraint to the graph.
void addConstraint(Constraint *constraint); void addConstraint(Constraint *constraint);
@@ -278,7 +280,7 @@ private:
struct StoredNode { struct StoredNode {
/// \brief The node itself, stored as a pointer so we can efficiently /// \brief The node itself, stored as a pointer so we can efficiently
/// copy/move \c StoredNodes. /// copy/move \c StoredNodes.
Node *NodePtr; ConstraintGraphNode *NodePtr;
/// \brief The index in the \c TypeVariables vector where the corresponding /// \brief The index in the \c TypeVariables vector where the corresponding
/// type variable is stored. /// type variable is stored.

View File

@@ -92,7 +92,7 @@ ConstraintSystem::ConstraintSystem(TypeChecker &tc, DeclContext *dc)
// Create the constraint graph. // Create the constraint graph.
// FIXME: Enable this by default. // FIXME: Enable this by default.
// CG = new ConstraintGraph(*this); CG = new ConstraintGraph(*this);
} }
ConstraintSystem::~ConstraintSystem() { ConstraintSystem::~ConstraintSystem() {