forked from M-Labs/artiq
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:
parent
c9623a106e
commit
1a08b50f0a
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue