# If `sub` is a safe subtype of `sup` then return `sub`.
# If `sub` is an unsafe subtype (ie an implicit cast is required), then return `sup`.
#
- # The point of the return type is to determinate the usable type on an expression:
+ # The point of the return type is to determinate the usable type on an expression when `autocast` is true:
# If the suptype is safe, then the return type is the one on the expression typed by `sub`.
# Is the subtype is unsafe, then the return type is the one of an implicit cast on `sup`.
- fun check_subtype(node: ANode, sub, sup: MType): nullable MType
+ fun check_subtype(node: ANode, sub, sup: MType, autocast: Bool): nullable MType
do
if self.is_subtype(sub, sup) then return sub
- if self.is_subtype(sub, self.anchor_to(sup)) then
+ if autocast and self.is_subtype(sub, self.anchor_to(sup)) then
# FIXME workaround to the current unsafe typing policy. To remove once fixed virtual types exists.
#node.debug("Unsafe typing: expected {sup}, got {sub}")
return sup
if sup == null then return null # Forward error
- var res = check_subtype(nexpr, sub, sup)
+ var res = check_subtype(nexpr, sub, sup, true)
if res != sub then
nexpr.implicit_cast_to = res
end
# Return the static type of the value to store.
private fun resolve_reassignment(v: TypeVisitor, readtype, writetype: MType): nullable MType
do
- var reassign_name: String
- if self.n_assign_op isa APlusAssignOp then
- reassign_name = "+"
- else if self.n_assign_op isa AMinusAssignOp then
- reassign_name = "-"
- else
- abort
- end
+ var reassign_name = self.n_assign_op.operator
self.read_type = readtype
var value_type = v.visit_expr_subtype(self.n_value, msignature.mparameters.first.mtype)
if value_type == null then return null # Skip error
- v.check_subtype(self, rettype, writetype)
+ v.check_subtype(self, rettype, writetype, false)
return rettype
end
end
end
set_comprehension(e)
if mtype != null then
- if v.check_subtype(e, t, mtype) == null then return # Skip error
+ if v.check_subtype(e, t, mtype, false) == null then return # Forward error
if t == mtype then useless = true
else
mtypes.add(t)
redef class ABinopExpr
redef fun compute_raw_arguments do return [n_expr2]
+ redef fun property_name do return operator
+ redef fun property_node do return n_op
end
redef class AEqExpr
- redef fun property_name do return "=="
redef fun accept_typing(v)
do
super
end
end
redef class ANeExpr
- redef fun property_name do return "!="
redef fun accept_typing(v)
do
super
v.null_test(self)
end
end
-redef class ALtExpr
- redef fun property_name do return "<"
-end
-redef class ALeExpr
- redef fun property_name do return "<="
-end
-redef class ALlExpr
- redef fun property_name do return "<<"
-end
-redef class AGtExpr
- redef fun property_name do return ">"
-end
-redef class AGeExpr
- redef fun property_name do return ">="
-end
-redef class AGgExpr
- redef fun property_name do return ">>"
-end
-redef class APlusExpr
- redef fun property_name do return "+"
-end
-redef class AMinusExpr
- redef fun property_name do return "-"
-end
-redef class AStarshipExpr
- redef fun property_name do return "<=>"
-end
-redef class AStarExpr
- redef fun property_name do return "*"
-end
-redef class AStarstarExpr
- redef fun property_name do return "**"
-end
-redef class ASlashExpr
- redef fun property_name do return "/"
-end
-redef class APercentExpr
- redef fun property_name do return "%"
-end
redef class AUplusExpr
redef fun property_name do return "unary +"