Skip to content

Commit

Permalink
Update meet for dynamic case
Browse files Browse the repository at this point in the history
Summary:
Use `BoundedDynamic(t)` as the meet of `Dynamic` and `t`, instead of just `Dynamic`.

This gives more info with types-on-hover.

Record type-checking becomes slightly more lenient with underspecced functions, because extracting a field from a record of type `BoundedDynamic(#rec{})` produces a value of type `BoundedDynamic(field_ty)`.

See tests for details about newly accepted code.

Reviewed By: ilya-klyuchnikov

Differential Revision: D57624187

fbshipit-source-id: 5e9bad73405058fd7e6aad93415cc8830f3f7082
  • Loading branch information
VLanvin authored and facebook-github-bot committed May 22, 2024
1 parent 9f90e9d commit 9362404
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class Narrow(pipelineContext: PipelineContext) {
BoundedDynamicType(b1)
case (DynamicType, BoundedDynamicType(b2)) =>
BoundedDynamicType(b2)
case (DynamicType, _) => DynamicType
case (_, DynamicType) => DynamicType
case (DynamicType, t) => BoundedDynamicType(t)
case (t, DynamicType) => BoundedDynamicType(t)
case (BoundedDynamicType(b1), BoundedDynamicType(b2)) =>
BoundedDynamicType(meetAux(b1, b2, seen))
case (BoundedDynamicType(b1), _) =>
Expand Down
16 changes: 6 additions & 10 deletions eqwalizer/test_projects/check_gradual/src/dynamic_refine.erl.check
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ refine_todo1_neg() -> | ERROR |
% It would be better to have | |
% Dyn refined as [dynamic()] here | |
is_list(Dyn) -> {Dyn} | | {Dyn}.
| | Expression has type: {dynamic()}
| | Expression has type: {dynamic([term()])}
| | Context expected type: 'ok'
end. | |
| |
Expand All @@ -115,7 +115,7 @@ refine_todo2_neg() -> | ERROR |
% It would be better to have | |
% Dyn refined as binary here | |
is_binary(Dyn) -> {Dyn}; | | {Dyn}.
| | Expression has type: {dynamic()}
| | Expression has type: {dynamic(binary())}
| | Context expected type: 'ok'
true -> ok | |
end. | |
Expand Down Expand Up @@ -247,12 +247,10 @@ dyn_refine_union_neg(D) -> D. | | D.
| |
-record(foo, {id :: integer()}). | |
| |
with_rec_neg(undefined) -> | ERROR |
with_rec_neg(undefined) -> | OK |
undefined; | |
with_rec_neg(#foo{id = Id}) -> | |
atom_to_binary(Id). | | Id.
| | Expression has type: number()
| | Context expected type: atom()
atom_to_binary(Id). | |
| |
-spec with_rec_neg2( | |
eqwalizer:dynamic() | #foo{} | |
Expand Down Expand Up @@ -339,10 +337,8 @@ refine_dyn_record(R = #ref_rec{a = I}) | OK |
-spec refine_dyn_select( | |
dyn_alias() | |
) -> integer(). | |
refine_dyn_select(R = #ref_rec{a = I}) | ERROR |
when is_integer(I) -> R#ref_rec.a. | | ...#ref_rec.a.
| | Expression has type: term()
| | Context expected type: number()
refine_dyn_select(R = #ref_rec{a = I}) | OK |
when is_integer(I) -> R#ref_rec.a. | |
| |
% Testing interaction between generics and…… |
filter_none(D) -> | OK |
Expand Down
6 changes: 2 additions & 4 deletions eqwalizer/test_projects/check_gradual/src/unspecced.erl.check
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,5 @@ get_id_neg1(Rec) -> | ERROR |
| | Expression has type: number()
| | Context expected type: atom()
| |
get_id_neg2(#rec{id = Id}) -> | ERROR |
atom_to_binary(Id). | | Id.
| | Expression has type: number()
| | Context expected type: atom()
get_id_neg2(#rec{id = Id}) -> | OK |
atom_to_binary(Id). | |

0 comments on commit 9362404

Please sign in to comment.