Skip to content

Commit 18ce106

Browse files
committed
Reject various handle types in 'map' value type
1 parent d095e2f commit 18ce106

5 files changed

Lines changed: 95 additions & 1 deletion

File tree

‎design/mvp/Binary.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ Notes:
260260
rejects any transitive use of `borrow` in an exported value type.
261261
* Validation of `stream` and `future` rejects element types that transitively
262262
contain a `borrow`.
263+
* Validation of `map` rejects value types that transitively contain an `own`,
264+
`borrow`, `future`, `stream` or `error-context`.
263265
* Validation of `stream` rejects `(stream char)` as a temporary
264266
[TODO](Concurrency.md#TODO).
265267
* Validation of `resourcetype` requires the destructor (if present) to have

‎design/mvp/Explainer.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,11 @@ original list defines the final value of the key. However, bindings generators
862862
are not *required* to deduplicate keys and may instead simply present the
863863
original list to guest code. To simplify bindings generation, `<keytype>` is a
864864
conservative subset of `<valtype>`, but this subset could be expanded over time
865-
based on use cases.
865+
based on use cases. Similarly, validation currently rejects `(map K V)` when `V`
866+
transitively contains an `own`, `borrow`, `future`, `stream` or
867+
`error-context`, since dropping the value of a duplicate key would otherwise
868+
require bindings generators to correctly dispose of the contained handles. This
869+
restriction could be relaxed in the future.
866870

867871
Note that, at least initially, variants must have a non-empty list of
868872
cases. This could be relaxed in the future to allow an empty list of cases, with

‎design/mvp/WIT.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,6 +1963,8 @@ meanings though so they're also provided as first-class types.
19631963
values but is meant to be represented by bindings generators in the source
19641964
language as a mapping from keys to values (e.g., as an associative array or or
19651965
hash table) where, in the case of duplicate keys, the last key's value is used.
1966+
Currently, the value type of a `map` may not transitively contain an owned or
1967+
borrowed handle, `future`, `stream` or `error-context`.
19661968

19671969
The `future` and `stream` types are described as part of the [concurrency
19681970
explainer](Concurrency.md#streams-and-futures).

‎test/nyi.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
./values/post-return.wast
44
./async/big-interleaving-test.wast
55
./async/forward.wast
6+
./validation/map.wast

‎test/validation/map.wast‎

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
;; (map K V) validation
2+
3+
(component definition
4+
(type (map bool u8))
5+
(type (map s8 u8))
6+
(type (map u8 u8))
7+
(type (map s16 u8))
8+
(type (map u16 u8))
9+
(type (map s32 u8))
10+
(type (map u32 u8))
11+
(type (map s64 u8))
12+
(type (map u64 u8))
13+
(type (map char u8))
14+
(type (map string u8))
15+
(type (map string f64))
16+
(type (map string string))
17+
(type (map string (list u8)))
18+
(type (map string (tuple u8 string)))
19+
(type (map string (record (field "a" u32) (field "b" string))))
20+
(type (map string (variant (case "a") (case "b" u32))))
21+
(type (map string (enum "x" "y")))
22+
(type (map string (flags "p" "q")))
23+
(type (map string (option string)))
24+
(type (map string (result u32 (error string))))
25+
(type (map string (map u32 (list string))))
26+
(type (list (map string u32)))
27+
(type (option (map u32 string)))
28+
(type (stream (map string u32)))
29+
(type (future (map string u32)))
30+
(type (func (param "m" (map string u32)) (result (map u32 string))))
31+
)
32+
33+
(assert_invalid
34+
(component (type (map f32 u8)))
35+
"invalid map key type")
36+
(assert_invalid
37+
(component (type (map (list u8) u8)))
38+
"invalid map key type")
39+
(assert_invalid
40+
(component (type (map (tuple u8 u8) u8)))
41+
"invalid map key type")
42+
(assert_invalid
43+
(component
44+
(type $R (resource (rep i32)))
45+
(type (map (own $R) u8)))
46+
"invalid map key type")
47+
(assert_invalid
48+
(component
49+
(type $R (resource (rep i32)))
50+
(type (map u32 (own $R))))
51+
"map value type cannot contain a handle")
52+
(assert_invalid
53+
(component
54+
(type $R (resource (rep i32)))
55+
(type (map string (option (borrow $R)))))
56+
"map value type cannot contain a handle")
57+
(assert_invalid
58+
(component
59+
(type (map string (record (field "f" (future u8))))))
60+
"map value type cannot contain a handle")
61+
(assert_invalid
62+
(component
63+
(type (map u8 (list (stream u8)))))
64+
"map value type cannot contain a handle")
65+
(assert_invalid
66+
(component
67+
(type $FT (future))
68+
(type (map char (variant (case "a") (case "b" $FT)))))
69+
"map value type cannot contain a handle")
70+
(assert_invalid
71+
(component
72+
(type $R (resource (rep i32)))
73+
(type $Rec (record (field "r" (own $R))))
74+
(type (map u32 $Rec)))
75+
"map value type cannot contain a handle")
76+
(assert_invalid
77+
(component
78+
(type $R (resource (rep i32)))
79+
(type (map string (map string (tuple u32 (own $R))))))
80+
"map value type cannot contain a handle")
81+
(assert_invalid
82+
(component
83+
(import "r" (type $R (sub resource)))
84+
(import "f" (func (param "m" (map string (own $R))))))
85+
"map value type cannot contain a handle")

0 commit comments

Comments
 (0)