aboutsummaryrefslogtreecommitdiffstats
path: root/src/unify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/unify.cpp')
-rw-r--r--src/unify.cpp38
1 files changed, 24 insertions, 14 deletions
diff --git a/src/unify.cpp b/src/unify.cpp
index 1b25861..aadc032 100644
--- a/src/unify.cpp
+++ b/src/unify.cpp
@@ -61,7 +61,7 @@ Constraints::constrain(TEnv& tenv, const AST* o, const AType* t)
assert(o);
assert(t);
assert(!o->to<const AType*>());
- push_back(Constraint(tenv.var(o), t, o->loc));
+ push_back(Constraint(tenv.var(o), t));
}
template<typename T, typename E>
@@ -73,7 +73,9 @@ substitute(const T* tup, const E* from, const E* to)
typename T::iterator ri = ret->begin();
FOREACHP(typename T::const_iterator, i, tup) {
if (**i == *from) {
- *ri++ = const_cast<E*>(to);
+ T* type = new T(*to);
+ type->loc = (*i)->loc;
+ *ri++ = type;
} else if (static_cast<const E*>(*i) != static_cast<const E*>(to)) {
const T* subTup = dynamic_cast<const T*>(*i);
if (subTup)
@@ -104,17 +106,24 @@ Subst::compose(const Subst& delta, const Subst& gamma)
}
/// Replace all occurrences of @a s with @a t
-Constraints
+Constraints&
Constraints::replace(const AType* s, const AType* t)
{
- Constraints cp(*this);
- for (Constraints::iterator c = begin(); c != end();) {
- Constraints::iterator next = c; ++next;
- if (*c->first == *s) c->first = t;
- if (*c->second == *s) c->second = t;
- c->first = substitute(c->first, s, t);
- c->second = substitute(c->second, s, t);
- c = next;
+ for (Constraints::iterator c = begin(); c != end(); ++c) {
+ if (*c->first == *s) {
+ AType* type = new AType(*t);
+ type->loc = c->first->loc;
+ c->first = type;
+ } else {
+ c->first = substitute(c->first, s, t);
+ }
+ if (*c->second == *s) {
+ AType* type = new AType(*t);
+ type->loc = c->second->loc;
+ c->second = type;
+ } else {
+ c->second = substitute(c->second, s, t);
+ }
}
return *this;
}
@@ -146,12 +155,13 @@ unify(const Constraints& constraints)
if (st->kind == AType::DOTS || tt->kind == AType::DOTS)
return unify(cp);
else
- cp.push_back(Constraint(st, tt, st->loc));
+ cp.push_back(Constraint(st, tt));
}
if (si == s->end() && (ti == t->end() || (*ti)->as<AType*>()->kind == AType::DOTS)
|| ti == t->end() && (*si)->as<AType*>()->kind == AType::DOTS)
return unify(cp);
}
- throw Error(s->loc ? s->loc : t->loc,
- (format("type is `%1%' but should be `%2%'") % s->str() % t->str()).str());
+ throw Error(s->loc,
+ (format("type is `%1%' but should be `%2%'\n%3%: error: to match `%4%' here")
+ % s->str() % t->str() % t->loc.str() % t->str()).str());
}