forked from M-Labs/artiq
inferencer: significantly improve the op-assignment diagnostic.
Before this commit, it displayed incorrect output if an error appeared on 2nd run and beyond, and displayed messages for trying to do "num32 -= num64" that made very little sense.
This commit is contained in:
parent
3485c83429
commit
35f4449ef2
@ -1043,22 +1043,10 @@ class Inferencer(algorithm.Visitor):
|
|||||||
if coerced:
|
if coerced:
|
||||||
return_type, target_type, value_type = coerced
|
return_type, target_type, value_type = coerced
|
||||||
|
|
||||||
try:
|
if isinstance(node.value, asttyped.CoerceT):
|
||||||
node.target.type.unify(target_type)
|
orig_value_type = node.value.value.type
|
||||||
except types.UnificationError as e:
|
else:
|
||||||
printer = types.TypePrinter()
|
orig_value_type = node.value.type
|
||||||
note = diagnostic.Diagnostic("note",
|
|
||||||
"expression of type {typec}",
|
|
||||||
{"typec": printer.name(node.value.type)},
|
|
||||||
node.value.loc)
|
|
||||||
diag = diagnostic.Diagnostic("error",
|
|
||||||
"expression of type {typea} has to be coerced to {typeb}, "
|
|
||||||
"which makes assignment invalid",
|
|
||||||
{"typea": printer.name(node.target.type),
|
|
||||||
"typeb": printer.name(target_type)},
|
|
||||||
node.op.loc, [node.target.loc], [note])
|
|
||||||
self.engine.process(diag)
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
node.target.type.unify(return_type)
|
node.target.type.unify(return_type)
|
||||||
@ -1066,17 +1054,34 @@ class Inferencer(algorithm.Visitor):
|
|||||||
printer = types.TypePrinter()
|
printer = types.TypePrinter()
|
||||||
note = diagnostic.Diagnostic("note",
|
note = diagnostic.Diagnostic("note",
|
||||||
"expression of type {typec}",
|
"expression of type {typec}",
|
||||||
{"typec": printer.name(node.value.type)},
|
{"typec": printer.name(orig_value_type)},
|
||||||
node.value.loc)
|
node.value.loc)
|
||||||
diag = diagnostic.Diagnostic("error",
|
diag = diagnostic.Diagnostic("error",
|
||||||
"the result of this operation has type {typeb}, "
|
"the result of this operation has type {typeb}, "
|
||||||
"which makes assignment to a slot of type {typea} invalid",
|
"which cannot be assigned to a left-hand side of type {typea}",
|
||||||
{"typea": printer.name(node.target.type),
|
{"typea": printer.name(node.target.type),
|
||||||
"typeb": printer.name(return_type)},
|
"typeb": printer.name(return_type)},
|
||||||
node.op.loc, [node.target.loc], [note])
|
node.op.loc, [node.target.loc], [note])
|
||||||
self.engine.process(diag)
|
self.engine.process(diag)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
node.target.type.unify(target_type)
|
||||||
|
except types.UnificationError as e:
|
||||||
|
printer = types.TypePrinter()
|
||||||
|
note = diagnostic.Diagnostic("note",
|
||||||
|
"expression of type {typec}",
|
||||||
|
{"typec": printer.name(orig_value_type)},
|
||||||
|
node.value.loc)
|
||||||
|
diag = diagnostic.Diagnostic("error",
|
||||||
|
"this operation requires the left-hand side of type {typea} "
|
||||||
|
"to be coerced to {typeb}, which cannot be done",
|
||||||
|
{"typea": printer.name(node.target.type),
|
||||||
|
"typeb": printer.name(target_type)},
|
||||||
|
node.op.loc, [node.target.loc], [note])
|
||||||
|
self.engine.process(diag)
|
||||||
|
return
|
||||||
|
|
||||||
node.value = self._coerce_one(value_type, node.value, other_node=node.target)
|
node.value = self._coerce_one(value_type, node.value, other_node=node.target)
|
||||||
|
|
||||||
def visit_ForT(self, node):
|
def visit_ForT(self, node):
|
||||||
|
@ -28,10 +28,10 @@
|
|||||||
# CHECK-L: ${LINE:+1}: error: cannot coerce list(elt='a) to a numeric type
|
# CHECK-L: ${LINE:+1}: error: cannot coerce list(elt='a) to a numeric type
|
||||||
[] - 1.0
|
[] - 1.0
|
||||||
|
|
||||||
# CHECK-L: ${LINE:+2}: error: expression of type numpy.int? has to be coerced to float, which makes assignment invalid
|
# CHECK-L: ${LINE:+2}: error: the result of this operation has type float, which cannot be assigned to a left-hand side of type numpy.int?
|
||||||
# CHECK-L: ${LINE:+1}: note: expression of type float
|
# CHECK-L: ${LINE:+1}: note: expression of type float
|
||||||
a = 1; a += 1.0
|
a = 1; a += 1.0
|
||||||
|
|
||||||
# CHECK-L: ${LINE:+2}: error: the result of this operation has type (numpy.int?, float), which makes assignment to a slot of type (numpy.int?,) invalid
|
# CHECK-L: ${LINE:+2}: error: the result of this operation has type (numpy.int?, float), which cannot be assigned to a left-hand side of type (numpy.int?,)
|
||||||
# CHECK-L: ${LINE:+1}: note: expression of type (float,)
|
# CHECK-L: ${LINE:+1}: note: expression of type (float,)
|
||||||
b = (1,); b += (1.0,)
|
b = (1,); b += (1.0,)
|
||||||
|
Loading…
Reference in New Issue
Block a user