effekt icon indicating copy to clipboard operation
effekt copied to clipboard

Unhelpful error message on missing braces in an interface implementation

Open jiribenes opened this issue 1 year ago • 4 comments

When trying to write an instance of an interface:

interface Eff {
  def op(): Int
}

def e: Eff = new Eff {
  def op() = println("42"); 42
}

shows an error: "Operation Eff is not part of interface Eff."

Here's a screenshot: Screenshot 2024-01-23 at 17 19 27

One way to work around this is to add braces into the method body:

interface Eff {
  def op(): Int
}

def e: Eff = new Eff {
  def op() = { println("42"); 42 }
}

jiribenes avatar Jan 23 '24 16:01 jiribenes

TBH it took me quite a while to understand this error...

The parser parses it as

def e: Eff = new Eff { () =>
  def op() = println("42")
  42
}

which is our syntax for singleton operations and thus shorthand for:

def e: Eff = new Eff { 
  def Eff() = {
    def op() = println("42")
    42
  }
}

b-studios avatar Jan 27 '24 18:01 b-studios

@jiribenes what would you expect as an error message? We could also forbid parsing it as single operation in case it starts with def

b-studios avatar Jan 27 '24 18:01 b-studios

I wouldn't know an elegant way to prevent it though.

https://github.com/effekt-lang/effekt/blob/49f2166f85c228b6169d1e7d0c1f508081c5551a/effekt/shared/src/main/scala/effekt/Parser.scala#L426-L437

The parser for implementation reuses functionArg which admits the program you wrote.

b-studios avatar Jan 27 '24 18:01 b-studios

After #495, the error looks something like this: image

which means I can somewhat improve it (or at least underline the relevant part) by consuming tokens after ; until I find } or def or EOF: Screenshot 2024-06-22 at 16 36 28

jiribenes avatar Jun 22 '24 14:06 jiribenes