Skip to content

Commit

Permalink
improve error messages around constraint resolution failure, fix old …
Browse files Browse the repository at this point in the history
…fileref hacks
  • Loading branch information
Kalani Thielen committed Nov 22, 2018
1 parent 2f4388e commit 6c4b5ec
Show file tree
Hide file tree
Showing 17 changed files with 94 additions and 64 deletions.
7 changes: 7 additions & 0 deletions bin/hi/evaluator.C
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,13 @@ void evaluator::resetREPLCycle() {
hobbes::resetMemoryPool();
}

bool evaluator::satisfied(const hobbes::ConstraintPtr& c) {
hobbes::Definitions ds;
bool result = hobbes::satisfied(this->ctx.typeEnv(), c, &ds);
this->ctx.drainUnqualifyDefs(ds);
return result;
}

void showSearchResults(const std::string& expr, const hobbes::SearchEntries& ses) {
if (ses.size() > 0) {
std::map<std::string, std::string> stbl;
Expand Down
1 change: 1 addition & 0 deletions bin/hi/evaluator.H
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public:
void breakdownEvalExpr(const std::string& expr);
void searchDefs(const std::string& expr_to_type);
void resetREPLCycle();
bool satisfied(const hobbes::ConstraintPtr&);
private:
hobbes::cc ctx;
bool silent;
Expand Down
38 changes: 23 additions & 15 deletions bin/hi/main.C
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ namespace str = hobbes::str;

namespace hi {

// the one evaluator for this process
evaluator* eval = 0;

// control color options (these can be tweaked by ~/.hirc)
ConsoleColors colors;

Expand All @@ -47,7 +50,7 @@ void setDefaultColorScheme() {
colors.oddlinebg = 238;
}

bool consoleCmdsEnabled = true;
bool consoleCmdsEnabled = false;
bool extConsoleCmdsEnabled() {
return consoleCmdsEnabled;
}
Expand Down Expand Up @@ -97,9 +100,14 @@ void printAnnotatedText(const hobbes::LexicalAnnotation& la) {
std::cout << resetfmt() << std::endl;
}

void printAnnotatedError(const hobbes::annotated_error& ae) {
void printAnnotatedError(const hobbes::annotated_error& ae, const hobbes::Constraints& cs) {
for (const auto& m : ae.messages()) {
std::cout << setbold() << setfgc(colors.errorfg) << m.second.lineDesc() << ": " << m.first << "\n";
for (const auto& c : cs) {
if (eval && !eval->satisfied(c)) {
std::cout << " " << hobbes::show(c) << std::endl;
}
}
printAnnotatedText(m.second);
}
}
Expand Down Expand Up @@ -176,9 +184,6 @@ std::string prompttext() {
return ss.str();
}

// the one evaluator for this process
evaluator* eval = 0;

// provide possibilities for autocompletion
str::seq completionMatches;

Expand Down Expand Up @@ -206,8 +211,6 @@ char** completions(const char* pfx, int start, int end) {
void evalLine(char*);

void repl(evaluator* ev) {
eval = ev;

// set up stdin to be read incrementally
std::ostringstream prompt;
prompt << resetfmt() << setbold() << setfgc(colors.promptfg) << "> " << setfgc(colors.stdtextfg) << std::flush;
Expand Down Expand Up @@ -331,8 +334,10 @@ void evalLine(char* x) {
}

eval->resetREPLCycle();
} catch (hobbes::unsolved_constraints& cs) {
printAnnotatedError(cs, cs.constraints());
} catch (hobbes::annotated_error& ae) {
printAnnotatedError(ae);
printAnnotatedError(ae, hobbes::Constraints());
} catch (std::exception& ex) {
std::cout << setfgc(colors.errorfg) << setbold() << ex.what() << std::endl;
}
Expand Down Expand Up @@ -594,8 +599,8 @@ int main(int argc, char** argv) {

// start an evaluator and process ~/.hirc if it exists
// (this should apply whatever settings the user prefers)
evaluator eval(args);
initHI(&eval, args.useDefColors);
eval = new evaluator(args);
initHI(eval, args.useDefColors);

// show the repl header
if (!args.silent) {
Expand All @@ -618,25 +623,28 @@ int main(int argc, char** argv) {
// load any modules passed in
if (args.mfiles.size() > 0) {
for (ModuleFiles::const_iterator m = args.mfiles.begin(); m != args.mfiles.end(); ++m) {
eval.loadModule(str::expandPath(*m));
eval->loadModule(str::expandPath(*m));
}
}

// should we evaluate some given expression?
if (!args.evalExpr.empty()) {
eval.evalExpr(args.evalExpr);
eval->evalExpr(args.evalExpr);
}

// finally, run some kind of REPL if requested
if (args.machineREPL) {
eval.runMachineREPL();
eval->runMachineREPL();
} else if (!args.exitAfterEval) {
repl(&eval);
repl(eval);
}
std::cout << resetfmt();
return 0;
} catch (hobbes::unsolved_constraints& cs) {
printAnnotatedError(cs, cs.constraints());
return -1;
} catch (hobbes::annotated_error& ae) {
printAnnotatedError(ae);
printAnnotatedError(ae, hobbes::Constraints());
return -1;
} catch (std::exception& ex) {
std::cout << "Fatal error: " << ex.what() << resetfmt() << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion bin/hog/session.C
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ ProcessTxnF initStorageSession(Session* s, const std::string& dirPfx, storage::P
s->streams[stmt.id] = ss;
s->writeFns[stmt.id] = c->compileFn<void(storage::Transaction*)>("txn", "either(hstoreRead(txn), (), " + writefn + ")");

txnEntries.push_back(Variant::Member(stmt.name, filerefty(ss->storageType()), stmt.id));
txnEntries.push_back(Variant::Member(stmt.name, fileRefTy(ss->storageType()), stmt.id));
}

if (sm != hobbes::StoredSeries::Compressed) {
Expand Down
4 changes: 2 additions & 2 deletions include/hobbes/db/file.H
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ template <typename T>
template <typename T, bool InStruct>
struct lift< fileref<T>, InStruct > {
static MonoTypePtr type(typedb& tenv) {
return MonoTypePtr(TApp::make(MonoTypePtr(Prim::make("fileref")), list(lift<T, false>::type(tenv))));
return fileRefTy(lift<T, false>::type(tenv));
}
};

Expand All @@ -66,7 +66,7 @@ template <typename T, bool InStruct>
struct lift<dbseq<T>*, InStruct> {
static MonoTypePtr type(typedb& tenv) {
// ^x.()+T*x@n
MonoTypePtr tlink = MonoTypePtr(TApp::make(MonoTypePtr(Prim::make("fileref")), list(tvar("x"))));
MonoTypePtr tlink = fileRefTy(tvar("x"));
MonoTypePtr tcons = tuplety(list(lift<T, true>::type(tenv), tlink));

return MonoTypePtr(Recursive::make("x", MonoTypePtr(Variant::make(list(Variant::Member(".f0", primty("unit"), 0), Variant::Member(".f1", tcons, 1))))));
Expand Down
4 changes: 0 additions & 4 deletions include/hobbes/db/series.H
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,6 @@ template <typename T>
StoredSeries storage;
};

inline MonoTypePtr filerefty(const MonoTypePtr& t) {
return tapp(primty("fileref"), list(t));
}

}

#endif
Expand Down
11 changes: 11 additions & 0 deletions include/hobbes/lang/expr.H
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,17 @@ private:
Case::Bindings switchOf(const Case::Bindings& bs, const switchExpr<ExprPtr>& f);
Switch::Bindings switchOf(const Switch::Bindings& bs, const switchExpr<ExprPtr>& f);

// when asserting that an expression has a monotype, we might find an exceptional circumstance where some type constraints remain unsolved
class unsolved_constraints : public annotated_error {
public:
unsolved_constraints(const LexicalAnnotation&, const std::string&, const Constraints&);
unsolved_constraints(const LexicallyAnnotated&, const std::string&, const Constraints&);

const Constraints& constraints() const;
private:
Constraints cs;
};

// require that a mono-type can be extracted from an expression
const MonoTypePtr& requireMonotype(const TEnvPtr&, const ExprPtr&);
MonoTypes requireMonotype(const TEnvPtr&, const Exprs&);
Expand Down
4 changes: 4 additions & 0 deletions include/hobbes/lang/type.H
Original file line number Diff line number Diff line change
Expand Up @@ -1255,6 +1255,10 @@ inline MonoTypePtr fnresult(const MonoTypePtr& fty) {

void compactMTypeMemory();

// shorthand for making file ref types
MonoTypePtr fileRefTy(const MonoTypePtr&, const MonoTypePtr&);
MonoTypePtr fileRefTy(const MonoTypePtr&);

// hash record and variant members
template <>
struct genHash<Record::Member> {
Expand Down
23 changes: 11 additions & 12 deletions lib/hobbes/db/bindings.C
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ struct injFileReferencesF : public switchTyFn {
if (const Prim* tfn = is<Prim>(tf)) {
if (tfn->name() == "fileref") {
if (targs.size() == 1) {
targs.resize(2);
targs[1] = texpr(this->f);
return fileRefTy(targs[0], texpr(this->f));
}
}
}
Expand Down Expand Up @@ -289,7 +288,7 @@ struct dbloadF : public op {
PolyTypePtr type(typedb&) const {
static MonoTypePtr tg0(TGen::make(0));
static MonoTypePtr tg1(TGen::make(1));
static PolyTypePtr npty(new PolyType(2, qualtype(Func::make(tuplety(list(tapp(primty("fileref"), list(tg0, tg1)))), tg0))));
static PolyTypePtr npty(new PolyType(2, qualtype(Func::make(tuplety(list(fileRefTy(tg0, tg1))), tg0))));
return npty;
}
};
Expand Down Expand Up @@ -333,7 +332,7 @@ struct dbloadPF : public op {
static MonoTypePtr tg0(TGen::make(0));
static MonoTypePtr tg1(TGen::make(1));
static MonoTypePtr tg2(TGen::make(2));
static PolyTypePtr npty(new PolyType(3, qualtype(Func::make(tuplety(list(tapp(primty("file"), list(tg0, tg1)), tapp(primty("fileref"), list(tg2)))), tg2))));
static PolyTypePtr npty(new PolyType(3, qualtype(Func::make(tuplety(list(tapp(primty("file"), list(tg0, tg1)), fileRefTy(tg2))), tg2))));
return npty;
}
};
Expand All @@ -356,7 +355,7 @@ struct dbRefFileF : public op {
MonoTypePtr tg1(TGen::make(1));
MonoTypePtr tg2(TGen::make(2));
MonoTypePtr tg3(TGen::make(3));
PolyTypePtr npty(new PolyType(4, qualtype(Func::make(tuplety(list(tapp(primty("fileref"), list(tg0, tg1)))), tapp(primty("file"), list(tg2, tg3))))));
PolyTypePtr npty(new PolyType(4, qualtype(Func::make(tuplety(list(fileRefTy(tg0, tg1))), tapp(primty("file"), list(tg2, tg3))))));
return npty;
}
};
Expand Down Expand Up @@ -433,7 +432,7 @@ struct dballocF : public op {
}

PolyTypePtr type(typedb&) const {
return PolyTypePtr(new PolyType(2, qualtype(Func::make(tuplety(list(primty("unit"))), tapp(primty("fileref"), list(tgen(0), tgen(1)))))));
return PolyTypePtr(new PolyType(2, qualtype(Func::make(tuplety(list(primty("unit"))), fileRefTy(tgen(0), tgen(1))))));
}
};

Expand Down Expand Up @@ -469,7 +468,7 @@ struct dbstoreF : public op {
PolyTypePtr type(typedb&) const {
static MonoTypePtr tg0(TGen::make(0));
static MonoTypePtr tg1(TGen::make(1));
static PolyTypePtr npty(new PolyType(2, qualtype(Func::make(tuplety(list(tg0)), tapp(primty("fileref"), list(tg0, tg1))))));
static PolyTypePtr npty(new PolyType(2, qualtype(Func::make(tuplety(list(tg0)), fileRefTy(tg0, tg1)))));
return npty;
}
};
Expand Down Expand Up @@ -503,7 +502,7 @@ struct dbstorePF : public op {
PolyTypePtr type(typedb&) const {
static MonoTypePtr tg0(TGen::make(0));
static MonoTypePtr tg1(TGen::make(1));
static PolyTypePtr npty(new PolyType(2, qualtype(Func::make(tuplety(list(tapp(primty("file"), list(tlong(1), tg0)), tg1)), tapp(primty("fileref"), list(tg1))))));
static PolyTypePtr npty(new PolyType(2, qualtype(Func::make(tuplety(list(tapp(primty("file"), list(tlong(1), tg0)), tg1)), fileRefTy(tg1)))));
return npty;
}
};
Expand All @@ -530,7 +529,7 @@ struct dballocArrF : public op {
PolyTypePtr type(typedb&) const {
static MonoTypePtr tg0(TGen::make(0));
static MonoTypePtr tg1(TGen::make(1));
static PolyTypePtr npty(new PolyType(2, qualtype(Func::make(tuplety(list(primty("long"))), tapp(primty("fileref"), list(arrayty(tg0), tg1))))));
static PolyTypePtr npty(new PolyType(2, qualtype(Func::make(tuplety(list(primty("long"))), fileRefTy(arrayty(tg0), tg1)))));
return npty;
}
};
Expand All @@ -550,7 +549,7 @@ struct dballocArrPF : public op {
PolyTypePtr type(typedb&) const {
static MonoTypePtr tg0(TGen::make(0));
static MonoTypePtr tg1(TGen::make(1));
static PolyTypePtr npty(new PolyType(2, qualtype(Func::make(tuplety(list(tapp(primty("file"), list(tlong(1), tg0)), primty("long"))), tapp(primty("fileref"), list(arrayty(tg1)))))));
static PolyTypePtr npty(new PolyType(2, qualtype(Func::make(tuplety(list(tapp(primty("file"), list(tlong(1), tg0)), primty("long"))), fileRefTy(arrayty(tg1))))));
return npty;
}
};
Expand All @@ -577,7 +576,7 @@ struct dbarrCapacityF : public op {
PolyTypePtr type(typedb&) const {
static MonoTypePtr tg0(TGen::make(0));
static MonoTypePtr tg1(TGen::make(1));
static PolyTypePtr npty(new PolyType(3, qualtype(Func::make(tuplety(list(tapp(primty("fileref"), list(darrayty(tg0), tg1)))), primty("long")))));
static PolyTypePtr npty(new PolyType(3, qualtype(Func::make(tuplety(list(fileRefTy(darrayty(tg0), tg1))), primty("long")))));
return npty;
}
};
Expand All @@ -598,7 +597,7 @@ struct dbarrCapacityPF : public op {
static MonoTypePtr tg0(TGen::make(0));
static MonoTypePtr tg1(TGen::make(1));
static MonoTypePtr tg2(TGen::make(2));
static PolyTypePtr npty(new PolyType(3, qualtype(Func::make(tuplety(list(tapp(primty("file"), list(tg0, tg1)), tapp(primty("fileref"), list(darrayty(tg2))))), primty("long")))));
static PolyTypePtr npty(new PolyType(3, qualtype(Func::make(tuplety(list(tapp(primty("file"), list(tg0, tg1)), fileRefTy(darrayty(tg2)))), primty("long")))));
return npty;
}
};
Expand Down
8 changes: 2 additions & 6 deletions lib/hobbes/db/file.C
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct mapFileRefs : public switchTyFn {
if (ap->args().size() == 2) {
if (const Prim* f = is<Prim>(ap->fn())) {
if (f->name() == "fileref") {
return MonoTypePtr(TApp::make(ap->fn(), list(switchOf(ap->args()[1], *this))));
return fileRefTy(switchOf(ap->args()[1], *this));
}
}
}
Expand All @@ -64,7 +64,7 @@ struct mapStoredArrays : public switchTyFn {

// translate a stored type by file version
static MonoTypePtr v0_to_v1(const MonoTypePtr& t) {
return tapp(primty("fileref"), list(switchOf(t, mapFileRefs())));
return fileRefTy(switchOf(t, mapFileRefs()));
}

static MonoTypePtr v1_to_v2(const MonoTypePtr& t) {
Expand Down Expand Up @@ -257,10 +257,6 @@ void reader::unsafeUnloadArray(void* p, size_t sz) {
}

// change any file ref types to point to this reader because they must be out of this file (this is a bit of a hack)
MonoTypePtr mkFR(const MonoTypePtr& t) {
return tapp(primty("fileref"), list(t));
}

void reader::showFileSummary(std::ostream& out) const {
out << this->fdata->path << " : " << str::showDataSize(this->fdata->file_size) << std::endl;
}
Expand Down
9 changes: 2 additions & 7 deletions lib/hobbes/db/series.C
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,6 @@ static MonoTypePtr entuple(const MonoTypePtr& ty) {
return MonoTypePtr(Record::make(ms));
}

// A -> A@?
static MonoTypePtr filerefTy(const MonoTypePtr& ty) {
return tapp(primty("fileref"), list(ty));
}

// A N -> carray A N
static MonoTypePtr carrayty(const MonoTypePtr& ty, size_t n) {
Record::Members ms;
Expand All @@ -139,7 +134,7 @@ static MonoTypePtr carrayty(const MonoTypePtr& ty, size_t n) {
static MonoTypePtr storedListOf(const MonoTypePtr& ty) {
Record::Members pms;
pms.push_back(Record::Member(".f0", ty));
pms.push_back(Record::Member(".f1", filerefTy(tvar("x"))));
pms.push_back(Record::Member(".f1", fileRefTy(tvar("x"))));
MonoTypePtr pty(Record::make(pms));

Variant::Members ms;
Expand All @@ -150,7 +145,7 @@ static MonoTypePtr storedListOf(const MonoTypePtr& ty) {

// A -> ^x.(()+([A]@?*x@?))@?
static MonoTypePtr storedStreamOf(const MonoTypePtr& ty, size_t n) {
return filerefTy(storedListOf(filerefTy(carrayty(ty, n))));
return fileRefTy(storedListOf(fileRefTy(carrayty(ty, n))));
}

// A -- StoredAs A B --> B
Expand Down
2 changes: 1 addition & 1 deletion lib/hobbes/db/signals.C
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ struct addFileSignalF : public op {
PolyTypePtr type(typedb&) const {
MonoTypePtr tg0(TGen::make(0));
MonoTypePtr tg1(TGen::make(1));
MonoTypePtr fr = tapp(primty("fileref"), list(tg0, tg1));
MonoTypePtr fr = fileRefTy(tg0, tg1);
PolyTypePtr npty(new PolyType(3, qualtype(functy(list(fr, functy(list(fr), primty("bool"))), primty("unit")))));
return npty;
}
Expand Down
8 changes: 6 additions & 2 deletions lib/hobbes/eval/cc.C
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ ExprPtr cc::unsweetenExpression(const TEnvPtr& te, const std::string& vname, con
return result;
}

void raiseUnsolvedCsts(cc& c, const std::string& vname, const ExprPtr& e, const PolyTypePtr& t) {
throw unsolved_constraints(*e, "Constraints left unresolved in residual expression", expandHiddenTCs(c.typeEnv(), simplifyVarNames(e->type())->constraints()));
}

void cc::drainUnqualifyDefs(const Definitions& ds) {
hlock _;
bool finaldef = !this->drainingDefs;
Expand All @@ -261,7 +265,7 @@ void cc::drainUnqualifyDefs(const Definitions& ds) {
} else {
if (forwardDeclared) {
if (vname.substr(0, 4) == ".rfn" || isMonotype(this->tenv->lookup(vname))) {
throw annotated_error(*xe, "Internal error, residual instance function '" + vname + "' should have had monotype '" + show(this->tenv->lookup(vname)) + "' but instead inferred '" + show(xety) + "' in:\n " + showAnnotated(xe));
raiseUnsolvedCsts(*this, vname, xe, this->tenv->lookup(vname));
}
this->tenv->unbind(vname);
}
Expand Down Expand Up @@ -304,7 +308,7 @@ void cc::define(const std::string& vname, const ExprPtr& e) {
} else {
if (forwardDeclared) {
if (isMonotype(this->tenv->lookup(vname))) {
throw annotated_error(*xe, "Internal error, residual instance function '" + vname + "' should have had monotype '" + show(this->tenv->lookup(vname)) + "' but instead inferred '" + show(xety) + "'");
raiseUnsolvedCsts(*this, vname, xe, this->tenv->lookup(vname));
}
this->tenv->unbind(vname);
}
Expand Down
Loading

0 comments on commit 6c4b5ec

Please sign in to comment.