diff --git a/docs/BUILT.md b/docs/BUILT.md index 866bf4b..5f33f1a 100644 --- a/docs/BUILT.md +++ b/docs/BUILT.md @@ -5393,9 +5393,10 @@ to name and nothing to choose between, so the abstract pass could not build the pair would have been worse than refusing: it would hash a string's pointer and a struct's padding. **What closes it is deferral, and what makes deferral safe is the `where` clause.** `put`, `get`, `has-key?`, -`reserve` and `clone` — the five arms that reach `key_fns` — now check their arguments and then, when the key is a -type variable, return a placeholder of the operation's own type: `Unit` for `put` and `reserve`, `None` for `get` -so the `(Option V)` around it still checks, `false` for `has-key?`, a zeroed map for `clone`. The whole node is +`map-remove!`, `reserve` and `clone` — the arms that reach `key_fns` — now check their arguments and then, when the +key is a type variable, return a placeholder of the operation's own type: `Unit` for `put` and `reserve`, `None` for +`get` and for `map-remove!` so the `(Option V)` around either still checks, `false` for `has-key?`, a zeroed map for +`clone`. The whole node is thrown away with the rest of the abstract pass, exactly as `println`'s is, and the real one is built when the copy is checked with `$t` concrete. diff --git a/test/test_flan.ml b/test/test_flan.ml index 73c4091..e8215a8 100644 --- a/test/test_flan.ml +++ b/test/test_flan.ml @@ -2676,6 +2676,12 @@ let () = accepts "get over a type-variable key answers an (Option V)" "(defn f [m (Map $t i32) k $t] i32 {:where (hashable? $t)} \ (match (get m k) (Some v) v _ 0))"; + (* And so does the removal, whose placeholder is [get]'s for the same reason: + it answers an (Option V), so the match around it still has to check while + the key is a variable. *) + accepts "map-remove! over a type-variable key answers an (Option V)" + "(defn f [m (Map $t i32) k $t] i32 {:where (hashable? $t)} \ + (match (map-remove! m k) (Some v) v _ 0))"; accepts "and so do has-key?, reserve and clone" "(defn f [m (Map $t i32) k $t] bool {:where (hashable? $t)} \ (do (reserve m 8) (let [c (clone m)] (free c) (has-key? m k))))";