forked from M-Labs/artiq
1
0
Fork 0

Use a single type printer for inference errors.

This way, type variable names will be consistent among all
printed diagnostics.
This commit is contained in:
whitequark 2015-06-04 14:46:43 +03:00
parent c9623a106e
commit 1a08b50f0a
1 changed files with 18 additions and 9 deletions

View File

@ -135,35 +135,34 @@ class Inferencer(algorithm.Transformer):
try: try:
typea.unify(typeb) typea.unify(typeb)
except types.UnificationError as e: except types.UnificationError as e:
printer = types.TypePrinter()
if kind == 'generic': if kind == 'generic':
note1 = diagnostic.Diagnostic('note', note1 = diagnostic.Diagnostic('note',
"expression of type {typea}", "expression of type {typea}",
{"typea": types.TypePrinter().name(typea)}, {"typea": printer.name(typea)},
loca) loca)
elif kind == 'expects': elif kind == 'expects':
note1 = diagnostic.Diagnostic('note', note1 = diagnostic.Diagnostic('note',
"expression expecting an operand of type {typea}", "expression expecting an operand of type {typea}",
{"typea": types.TypePrinter().name(typea)}, {"typea": printer.name(typea)},
loca) loca)
note2 = diagnostic.Diagnostic('note', note2 = diagnostic.Diagnostic('note',
"expression of type {typeb}", "expression of type {typeb}",
{"typeb": types.TypePrinter().name(typeb)}, {"typeb": printer.name(typeb)},
locb) locb)
if e.typea.find() == typea.find() and e.typeb.find() == typeb.find(): if e.typea.find() == typea.find() and e.typeb.find() == typeb.find():
diag = diagnostic.Diagnostic('fatal', diag = diagnostic.Diagnostic('fatal',
"cannot unify {typea} with {typeb}", "cannot unify {typea} with {typeb}",
{"typea": types.TypePrinter().name(typea), {"typea": printer.name(typea), "typeb": printer.name(typeb)},
"typeb": types.TypePrinter().name(typeb)},
loca, [locb], notes=[note1, note2]) loca, [locb], notes=[note1, note2])
else: # give more detail else: # give more detail
diag = diagnostic.Diagnostic('fatal', diag = diagnostic.Diagnostic('fatal',
"cannot unify {typea} with {typeb}: {fraga} is incompatible with {fragb}", "cannot unify {typea} with {typeb}: {fraga} is incompatible with {fragb}",
{"typea": types.TypePrinter().name(typea), {"typea": printer.name(typea), "typeb": printer.name(typeb),
"typeb": types.TypePrinter().name(typeb), "fraga": printer.name(e.typea), "fragb": printer.name(e.typeb)},
"fraga": types.TypePrinter().name(e.typea),
"fragb": types.TypePrinter().name(e.typeb),},
loca, [locb], notes=[note1, note2]) loca, [locb], notes=[note1, note2])
self.engine.process(diag) self.engine.process(diag)
@ -230,6 +229,16 @@ class Inferencer(algorithm.Transformer):
node.loc, elt.loc, kind='expects') node.loc, elt.loc, kind='expects')
return node return node
def visit_Subscript(self, node):
node = self.generic_visit(node)
node = asttyped.SubscriptT(type=types.TVar(),
value=node.value, slice=node.slice, ctx=node.ctx,
loc=node.loc)
# TODO: support more than just lists
self._unify(types.TList(node.type), node.value.type,
node.loc, node.value.loc, kind='expects')
return node
# Visitors that just unify types # Visitors that just unify types
# #
def visit_Assign(self, node): def visit_Assign(self, node):