Skip to content

Commit

Permalink
[hack] fix capture error on splated arguments
Browse files Browse the repository at this point in the history
Summary:
We already support splated args, but only when they are given to a variadic function. Now they can also be given to a non-variadic function, without capture failure.

The precise static analysis of such situation is left for further work.

Reviewed By: ngorogiannis

Differential Revision:
D55359346

Privacy Context Container: L1208441

fbshipit-source-id: 3d7bd1fca86935d926cc0fa39048747bd725c559
  • Loading branch information
davidpichardie authored and facebook-github-bot committed Mar 26, 2024
1 parent be6d9bd commit 8f535ef
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 2 deletions.
22 changes: 22 additions & 0 deletions infer/src/textual/TextualDecls.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ module ProcEntry = struct
let desc = function Decl _ -> None | Desc p -> Some p

let signature t lang = ProcDecl.to_sig (decl t) lang

let remove_formals_types = function
| Decl pdecl ->
Decl {pdecl with formals_types= None}
| Desc pdesc ->
let procdecl = {pdesc.procdecl with formals_types= None} in
Desc {pdesc with procdecl}
end

type t =
Expand Down Expand Up @@ -107,10 +114,25 @@ let declare_variadic_proc_if_necessary decls = function
()


(* every declared/implemented function is also given a default proc entry without
formals types. This is useful to avoid capture errors with variadic function and/or
splated arguments. *)
let declare_default_if_necessary decls proc =
let procsig = ProcEntry.signature proc decls.lang in
match procsig with
| ProcSig.Hack {qualified_name; arity= Some _} ->
let procsig_default = ProcSig.Hack {qualified_name; arity= None} in
if not (ProcSig.Hashtbl.mem decls.procs procsig_default) then
ProcSig.Hashtbl.add decls.procs procsig_default (ProcEntry.remove_formals_types proc)
| _ ->
()


let declare_proc decls (proc : ProcEntry.t) =
let procsig = ProcEntry.signature proc decls.lang in
let existing_proc = ProcSig.Hashtbl.find_opt decls.procs procsig in
declare_variadic_proc_if_necessary decls proc ;
declare_default_if_necessary decls proc ;
match (existing_proc, proc) with
| Some (Desc _), Decl _ ->
()
Expand Down
4 changes: 4 additions & 0 deletions infer/src/textual/unit/TextualSilTest.ml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ let%expect_test "undefined types are included in tenv" =
supers: {}
objc_protocols: {}
methods: {
Foo.f
Foo.f#2
}
exported_obj_methods: {}
Expand Down Expand Up @@ -83,6 +84,7 @@ let%expect_test "undefined types are included in tenv" =
supers: {}
objc_protocols: {}
methods: {
Bar.f
Bar.f#0
}
exported_obj_methods: {}
Expand Down Expand Up @@ -217,6 +219,7 @@ let%expect_test "overloads in tenv" =
supers: {}
objc_protocols: {}
methods: {
C.f
C.f#1
C.f#2
}
Expand Down Expand Up @@ -284,6 +287,7 @@ let%expect_test "undefined + overloads in merged tenv" =
supers: {}
objc_protocols: {}
methods: {
Dep.f
Dep.f#1
Dep.f#2
}
Expand Down
7 changes: 7 additions & 0 deletions infer/tests/codetoanalyze/hack/capture/snippets/variadic.hack
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,10 @@ trait T {
public function foo2<reify T>(int $x = 0, int ...$rest): void {}
public static function static_foo2<reify T>(int $x, int ...$rest): void {}
}

function arity3(int $arg1, int $arg2, int $arg3): void {}

function call_not_really_variadic_with_splat(): void {
$args = tuple(1, 2, 3);
arity3(...$args);
}
2 changes: 0 additions & 2 deletions infer/tests/codetoanalyze/sil/verif/issues.exp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ basic.sil, line 88, column 4: textual type error: expression 0 has type int, whi
basic.sil, line 106, column 4: textual type error: expression n1 has type float, while a subtype of int was expected
basic.sil, line 108, column 4: textual type error: expression n1 has type float, while a subtype of int was expected
basic.sil, line 110, column 9: textual type error: expression [&y:float] has type float, while a subtype of int was expected
basic_error_argnum.sil, line 12, column 7: SIL consistency error: function $builtins.bar which can be called with 0 arguments is not declared
error1.sil, line 12, column 4: SIL syntax error: unexpected token x
error2.sil, line 19, column 9: SIL consistency error: function g which can be called with 0 arguments is not declared
error2.sil, line 18, column 13: SIL consistency error: field cell.n is not declared
Expand Down Expand Up @@ -49,4 +48,3 @@ variadic.sil, line 50, column 7: SIL consistency error: variadic parameter is no
variadic.sil, line 40, column 7: SIL consistency error: variadic parameter is not in penultimate position in trait function T.bad
variadic.sil, line 28, column 7: SIL consistency error: variadic parameter is not in penultimate position in function with_generics_bad which has a reified generics parameter
variadic.sil, line 18, column 7: SIL consistency error: variadic parameter is not in last position in function f3
variadic.sil, line 10, column 8: SIL consistency error: function f2 which can be called with 1 arguments is not declared

0 comments on commit 8f535ef

Please sign in to comment.