Merge: Hint vararg
authorJean Privat <jean@pryen.org>
Fri, 24 Apr 2015 06:02:47 +0000 (13:02 +0700)
committerJean Privat <jean@pryen.org>
Fri, 24 Apr 2015 06:02:47 +0000 (13:02 +0700)
Improve the error message so that user that try to pass an array as is instead of elements is hinted about the `...` reverse-vararg operator.

~~~
fun foo(xs: Int...) do end
foo(1,2,3) # OK
var a = [1,2,3]
foo(a) # Error, expected `Int`; got `Array[Int]`. Is `...` missing?
foo(a...) # OK
~~~

![](http://i.imgur.com/zmyi8GR.jpg)

close #98 (quite old bug)

Pull-Request: #1294
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>

src/semantize/typing.nit
tests/sav/base_vararg3_alt1.res
tests/sav/base_vararg3_alt3.res

index e798ab2..df3b33a 100644 (file)
@@ -453,12 +453,26 @@ private class TypeVisitor
                if vararg_rank >= 0 then
                        var paramtype = msignature.mparameters[vararg_rank].mtype
                        var first = args[vararg_rank]
-                       if vararg_decl == 0 and first isa AVarargExpr then
+                       if vararg_decl == 0 then
                                var mclass = get_mclass(node, "Array")
                                if mclass == null then return null # Forward error
                                var array_mtype = mclass.get_mtype([paramtype])
-                               self.visit_expr_subtype(first.n_expr, array_mtype)
-                               first.mtype  = first.n_expr.mtype
+                               if first isa AVarargExpr then
+                                       self.visit_expr_subtype(first.n_expr, array_mtype)
+                                       first.mtype  = first.n_expr.mtype
+                               else
+                                       # only one vararg, maybe `...` was forgot, so be gentle!
+                                       var t = visit_expr(first)
+                                       if t == null then return null # Forward error
+                                       if not is_subtype(t, paramtype) and is_subtype(t, array_mtype) then
+                                               # Not acceptable but could be a `...`
+                                               error(first, "Type Error: expected `{paramtype}`, got `{t}`. Is an ellipsis `...` missing on the argument?")
+                                               return null
+                                       end
+                                       # Standard valid vararg, finish the job
+                                       map.vararg_decl = 1
+                                       self.visit_expr_subtype(first, paramtype)
+                               end
                        else
                                map.vararg_decl = vararg_decl + 1
                                for i in [vararg_rank..vararg_rank+vararg_decl] do
index e7cb189..9285e6f 100644 (file)
@@ -1 +1 @@
-alt/base_vararg3_alt1.nit:41,7--13: Type Error: expected `Int`, got `Array[Int]`.
+alt/base_vararg3_alt1.nit:41,7--13: Type Error: expected `Int`, got `Array[Int]`. Is an ellipsis `...` missing on the argument?
index 4ca932b..acafe02 100644 (file)
@@ -1 +1 @@
-alt/base_vararg3_alt3.nit:33,9: Type Error: expected `Int`, got `Array[Int]`.
+alt/base_vararg3_alt3.nit:33,9: Type Error: expected `Int`, got `Array[Int]`. Is an ellipsis `...` missing on the argument?