Skip to content

Commit

Permalink
better refinment of maps: implementation
Browse files Browse the repository at this point in the history
Summary:
under the hood, occurrence typing properly refines the map `#{required := _R1}`, however it is also aliased as `Foo` and occurrence typing doesn't handle such aliasing properly (yet).

Aliasing is somewhat handled in narrowing. This diff slightly improves narrowing of map types: if a particular required key doesn't exist among *all* keys - then the narrowing would be an empty type `none()`.

Reviewed By: VLanvin

Differential Revision: D53179541

fbshipit-source-id: 4161da9276a0340cf0908fe2e997bb09aed08491
  • Loading branch information
ilya-klyuchnikov authored and facebook-github-bot committed Jan 29, 2024
1 parent 761c4ca commit 5da3a99
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ class Narrow(pipelineContext: PipelineContext) {
t
case BoundedDynamicType(bound) =>
BoundedDynamicType(withRequiredProp(k, bound))
case ShapeMap(props) =>
case ShapeMap(props) if props.exists(_.key == k) =>
ShapeMap(props.map {
case OptProp(`k`, v) =>
ReqProp(k, v)
Expand Down
19 changes: 2 additions & 17 deletions eqwalizer/test_projects/eqwater/src/eqwater_maps.erl.check
Original file line number Diff line number Diff line change
Expand Up @@ -72,22 +72,7 @@ map_occ_07_neg(M) -> M. | | M.
-type foo() :: #{} | #{required := binary(…… |
| |
-spec add_optional(foo(), binary()) -> foo…… |
add_optional(Foo = #{required := _R1}, Opt…… ERROR |
Foo#{optional => Optional}; | | ..#{..}.
| | Expression has type: #S{optional := binary()} | #S{optional := binary(), required := binary()}
| | Context expected type: foo()
| |
| | #S{optional := binary()} | #S{optional := binary(), required := binary()} is not compatible with foo()
| | because
| | #S{optional := binary()} | #S{optional := binary(), required := binary()} is not compatible with #S{} | #S{optional => binary(), required := binary()}
| | because
| | #S{optional := binary()} is not compatible with #S{} | #S{optional => binary(), required := binary()}
| | because
| | #S{optional := binary()} is not compatible with #S{}
| | These associations do not match:
| |
| | #S{
| | + optional := ...
| | }
add_optional(Foo = #{required := _R1}, Opt…… OK |
Foo#{optional => Optional}; | |
add_optional(Z, _) -> | |
Z. | |

0 comments on commit 5da3a99

Please sign in to comment.