The removal joins the deferred map operations in the test and in the note
The arm was written with the others and through the same deferral, and neither the generics row in test_flan.ml nor the paragraph in BUILT.md that enumerates what defers had it. Its placeholder is get's, for get's reason: it answers an (Option V), so the match around it still has to check while the key is a variable.
This commit is contained in:
parent
9f85139f1f
commit
c59cc95679
@ -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.
|
||||
|
||||
|
||||
@ -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))))";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user