Merge: Handle gracefuly multi-varargs
authorJean Privat <jean@pryen.org>
Thu, 12 Nov 2015 01:43:38 +0000 (20:43 -0500)
committerJean Privat <jean@pryen.org>
Thu, 12 Nov 2015 01:43:38 +0000 (20:43 -0500)
This solve a very borderline issue when a signature contains more than one vararg parameter.
They are still refused in the common case but can occurs when multiple initializers are combined into a single constructor.

The implemented semantic is the following:

* vararg parameters remains varag
* if more than one vararg parameter exists in a signature, then the signature does not accepts additional arguments, it means that each vararg is associated to a single argument (a discarded alternative was to only keep the first/last parameter as the main vararg one)
* the associated argument can be either a single value, of a reverse vararg with an ellipsis.

~~~nit
class A
   fun x(i: Int...) is autoinit do end
   fun y(j: Int...) is autoinit do end
end
var a
a = new A(10, 20) # OK: i=[10], j=[20]
a = new A(10, 11, 20) # Refused
a = new A([10, 11]..., 20) # OK: i=[10, 11], j=[20]
a = new A([10, 11]..., [20, 21, 22]...) # OK: i=[10, 11], j=[20, 21, 22]
a = new A([10, 11], [20, 21, 22]) # Refused but a hint is given that `...` may be missing
~~~

Pull-Request: #1825
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>

1  2 
src/compiler/abstract_compiler.nit

@@@ -853,14 -853,12 +853,14 @@@ extern void nitni_global_ref_decr( stru
                        v.add_decl("int main(int argc, char** argv) \{")
                end
  
 +              v.add "#ifndef ANDROID"
                v.add("signal(SIGABRT, sig_handler);")
                v.add("signal(SIGFPE, sig_handler);")
                v.add("signal(SIGILL, sig_handler);")
                v.add("signal(SIGINT, sig_handler);")
                v.add("signal(SIGTERM, sig_handler);")
                v.add("signal(SIGSEGV, sig_handler);")
 +              v.add "#endif"
                v.add("signal(SIGPIPE, SIG_IGN);")
  
                v.add("glob_argc = argc; glob_argv = argv;")
@@@ -1224,8 -1222,8 +1224,8 @@@ abstract class AbstractCompilerVisito
                                res.add(null_instance)
                                continue
                        end
-                       if param.is_vararg and map.vararg_decl > 0 then
-                               var vararg = exprs.sub(j, map.vararg_decl)
+                       if param.is_vararg and args[i].vararg_decl > 0 then
+                               var vararg = exprs.sub(j, args[i].vararg_decl)
                                var elttype = param.mtype
                                var arg = self.vararg_instance(mpropdef, recv, vararg, elttype)
                                res.add(arg)