GaloisInc / saw-script

The SAW scripting language.
BSD 3-Clause "New" or "Revised" License
442 stars 63 forks source link

Support importing Cryptol enums into SAWCore #2052

Open RyanGlScott opened 7 months ago

RyanGlScott commented 7 months ago

Since https://github.com/GaloisInc/saw-script/pull/2020, SAW bundles a version of Cryptol that includes support for Cryptol's enum declarations. It it still not possible to import Cryptol files that define enums into SAWCore, however. For example, given this Cryptol and SAW file:

// Test.cry
enum Foo = MkFoo
// test.saw
import "Test.cry";

If you run test.saw, it will throw an error message:

$ ~/Software/saw-1.1/bin/saw test.saw
[13:24:15.614] Loading file "/home/ryanscott/Documents/Hacking/SAW/test.saw"
[13:24:15.634] genNominalConstrurctors: `enum` is not yet supported
CallStack (from HasCallStack):
  error, called at src/Verifier/SAW/Cryptol.hs:2034:22 in cryptol-saw-core-0.1-inplace:Verifier.SAW.Cryptol

Alternatively, you might also see this error message if you load a program which uses (but does not define) an enum:

// Test.cry

f : Option () -> ()
f x =
  case x of
    None -> ()
    Some y -> y
$ ~/Software/saw-1.1/bin/saw test.saw
[13:25:05.093] Loading file "/home/ryanscott/Documents/Hacking/SAW/test.saw"
[13:25:05.113] importType: `enum` is not yet supported
CallStack (from HasCallStack):
  error, called at src/Verifier/SAW/Cryptol.hs:274:25 in cryptol-saw-core-0.1-inplace:Verifier.SAW.Cryptol

This issue tracks lifting this restriction. (A further step would be to allow using Cryptol enums in MIR specifications, as proposed in https://github.com/GaloisInc/saw-script/issues/1976.)


In order to import an enum into SAWCore, we need to have a corresponding SAWCore representation. Two possible representations that we could pick are:

  1. Map each Cryptol enum declaration to a SAWCore data declaration with the same field types.
  2. Map each Cryptol enum declaration to a value defined in terms of Eithers, which provides an "anonymous sum" representation.
RyanGlScott commented 7 months ago

It is also possible to make SAW outright panic by using an enum in the return type of a function:

// Test.cry

f : Option ()
f = None
$ ~/Software/saw-1.1/bin/saw test.saw
[13:33:52.133] Loading file "/home/ryanscott/Documents/Hacking/SAW/test.saw"
[13:33:52.155] You have encountered a bug in cryptol-saw-core's implementation.
*** Please create an issue at https://github.com/GaloisInc/saw-script/issues

%< --------------------------------------------------- 
  Revision:  5c16c876f35f0abdf0b412a5387e220b15b7f990
  Branch:    release-1.1 (uncommited files present)
  Location:  importExpr
  Message:   unknown variable: Name {nUnique = 4188, nInfo = GlobalName UserName (OrigName {ogNamespace = NSConstructor, ogModule = TopModule (ModName "Cryptol" NormalName), ogSource = FromDefinition, ogName = Ident False NormalName "None", ogFromParam = Nothing}), nFixity = Nothing, nLoc = Range {from = Position {line = 645, col = 17}, to = Position {line = 645, col = 21}, source = "/home/ryanscott/Software/saw-1.1/lib/Cryptol.cry"}}
CallStack (from HasCallStack):
  panic, called at src/Verifier/SAW/Cryptol/Panic.hs:13:9 in cryptol-saw-core-0.1-inplace:Verifier.SAW.Cryptol.Panic
  panic, called at src/Verifier/SAW/Cryptol.hs:1081:25 in cryptol-saw-core-0.1-inplace:Verifier.SAW.Cryptol
%< ---------------------------------------------------

It's not obvious to me if it is straightforward to fix this panic without doing all of the necessary legwork to support enums wholesale, but I thought I'd mention it here as well.