Use weaker version of updateRoutCtx in merge. All tests pass.
Cat's Eye Technologies
8 years ago
126 | 126 | -- Take 2 routine contexts -- one from each branch of an `if` -- and merge |
127 | 127 | -- them to create a new context for the remainder of the routine. |
128 | 128 | -- |
129 | -- TODO: this merge is "too sensitive" in a way that needs to be better | |
130 | -- understood and documented. It is that it is using updateRoutCtx to | |
131 | -- make the merged resultant context, but that routine raises an error | |
132 | -- if the new usage is replacing a poisoned entry. It should be "more OK" | |
133 | -- with replacing a poisoned entry, here. | |
129 | -- We use a weaker version of updateRoutCtx to build the merged context. | |
130 | -- We do this because accessing a poisoned storage location from either | |
131 | -- of the branch contexts is not an error at the merge point -- we simply | |
132 | -- make the storage location poisoned in the resulting context. (If the | |
133 | -- poisoned location is accessed subsequently to the merge point, that is | |
134 | -- of course still an error.) | |
134 | 135 | -- |
135 | 136 | mergeAlternateRoutCtxs nm routCtx1 routCtx2 = |
136 | 137 | let |
153 | 154 | updateRoutCtx nm location newUsage routCtxAccum |
154 | 155 | in |
155 | 156 | Map.foldrWithKey (poison) routCtx1 routCtx2 |
157 | where | |
158 | -- a weaker version of updateRoutCtx, which does not error if | |
159 | -- we access a poisoned source | |
160 | updateRoutCtx nm dst (UpdatedWith src) routCtx = | |
161 | let | |
162 | s = untypedLocation src | |
163 | d = untypedLocation dst | |
164 | in | |
165 | Map.insert d (UpdatedWith s) routCtx | |
166 | updateRoutCtx nm dst (PoisonedWith src) routCtx = | |
167 | Map.insert (untypedLocation dst) (PoisonedWith $ untypedLocation src) routCtx |