Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Found side effects: incomplete pattern match; but it is complete? #424

Open
Timmmm opened this issue Jan 23, 2024 · 2 comments · May be fixed by #647
Open

Found side effects: incomplete pattern match; but it is complete? #424

Timmmm opened this issue Jan 23, 2024 · 2 comments · May be fixed by #647

Comments

@Timmmm
Copy link
Contributor

Timmmm commented Jan 23, 2024

Consider the following code:

default Order dec

$include <prelude.sail>

enum ExecutionMode = {
  Legacy,
  PureCap,
}

mapping execution_mode_encdec : ExecutionMode <-> bits(1) = {
  Legacy <-> 0b0,
  PureCap <-> 0b1,
}

struct Capability = {
  mode : ExecutionMode,
}

function bitsToCap(cap_bits : bits(1)) -> Capability = {
  struct {
    mode = execution_mode_encdec(cap_bits),
  }
}

let null_cap : Capability = bitsToCap(0b0)

It gives this error:

25 |let null_cap : Capability = bitsToCap(0b0)
   |    ^------^
   | Top-level let statement must not have any side effects. Found side effects: incomplete pattern match

But execution_mode_encdec is complete, unless I'm missing something.

@Timmmm
Copy link
Contributor Author

Timmmm commented Jan 25, 2024

Much simpler example:

default Order dec

$include <prelude.sail>

mapping bool_bit : bool <-> bit = {
  true <-> bitone,
  false <-> bitzero,
}

let x : bool = bool_bit(bitzero)

I believe the error originates with this line in src/lib/effects.ml:221:

    | DEF_aux (DEF_mapdef _, _) -> effects := EffectSet.add IncompleteMatch !effects

If I comment it out then it compiles without any issues, though presumably this isn't sound. It looks like although match is checked for completeness, mapping isn't, so the code just assumes it might be incomplete. This probably also explains why this doesn't produce a The following expression is unmatched warning:

mapping bool_bit : bool <-> bit = {
  true <-> bitone,
}

@trdthg
Copy link
Contributor

trdthg commented Jul 15, 2024

Hi, I have some idea about this:

  • reuse match's complete check on mapping's both sides

    • there would be something like this:
      mapping Foo : bits(2) <-> int = {
        0b00 <-> 10,
        0b01 <-> 1,
        forwards _ => 5,
        backwards _ => 0b11
      }
      
      commit
    • and type_check ignore guard now, but this is acceptable? rustc can't do it either
      image
  • add $[complete] addribute for mapping

    • which can be very easy here
      image
  • add something like $[allow(incomplete)] for let exp, like #[allow(xxx)] in rust

I personally like the first


Update: trying to implement the first method. add something like PC.is_complete_mapcls_wildcarded.

@trdthg trdthg linked a pull request Jul 26, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants