Checking ill-typed constraint guards for exhaustivity can cause Cryptol to
panic. If we detect any type errors after type-checking the guards, we now
abort early and report any recorded errors instead of proceeding to check
exhaustivity.
Fixes#1593. Fixes#1693.
Numeric constraint guards have very particular syntactic requirements:
* They must always be used in top-level definitions.
* Their definitions must always be accompanied by a top-level type signature.
Previously, we checked these requirements in a combination of places in the
parser and the typechecker. The checks in the typechecker weren't very
thorough, however, and they failed to catch local definitions without type
signatures that use constraint guards, as seen in #1685.
This patch moves all of these syntactic checks to the parser (in
`Cryptol.Parser.ExpandPropGuards`). We now recurse into expressions to check
for local definition that use constraint guards and error if we encounter one.
This ensures that by the time we reach the typechecker, all constraint guard
expressions are at least syntactically valid.
Fixes#1685.
This synchronizes the implementation of `roundAway` in the reference evaluator
with the implementation of `Cryptol.Backend.FloatHelpers.floatToInteger`, which
expects `NearAway` rather than `Away`.
Fixes#1663.
This ensures that the constraints and right-hand side expressions in each guard
are well formed. This check suffices to catch the bug in
https://github.com/GaloisInc/saw-script/issues/2043, which was fixed separately
in a previous commit.
I have also updated the `tests/constraint-guards/type-sig-constraint.icry` test
to use `coreLint=on` rather than checking `debug` output, as the former is more
resilient to internal changes in Cryptol's pretty-printer.
Fixes#1647.
Previously, `checkPropGuardCase` would not consider type signature constraints
when determining how many proof applications to generate, which ultimately led
to the issues observed in https://github.com/GaloisInc/saw-script/issues/2043.
This is relatively easy to fix by ensuring that we pass these constraints as an
additional argument to `checkPropGuardCase`.
It is difficult to fully validate that this fix works without SAW, but I have
checked in a smoke test that checks if the guards in a numeric constraint guard
definition have the expected number of proof applications.
We must treat built-in abstract types slightly differently from user-defined
abstract types.
Also fix a bug in the way that the return kind of primitive types are computed:
we previously said that they all return `*`, but this is not necessarily the
case.
Previously, `parmap` could incorrectly return a `VWord` when the element type
was not `Bit`, and it could also return a `VSeq` when the element type was
`Bit`. This changes the implementation of `parmap` to use the `mkSeq` smart
constructor, which properly chooses what sort of `GenValue` to return depending
on the element type.
Fixes#1578.