Skip to content

confusing "Not found" error when I change "def foo()" to "val foo()" #18684

Closed
@som-snytt

Description

@som-snytt

Compiler version

3.3/3.4

Minimized example

Welcome to Scala 3.4.0-RC1-bin-SNAPSHOT-git-d788ef2 (21, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala> val s(): String = "hello, world"
-- [E006] Not Found Error: ---------------------------------------------------------------------------------------------
1 |val s(): String = "hello, world"
  |    ^
  |    Not found: s
  |
  | longer explanation available when compiling with `-explain`
1 error found
Welcome to Scala 3.3.1 (21, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala> def s(): String = "hello, world"
def s(): String

scala> val s(): String = "hello, world"
-- [E100] Syntax Error: ------------------------------------------------------------------------------------------------
1 |val s(): String = "hello, world"
  |    ^
  |    method s must be called with () argument
  |
  | longer explanation available when compiling with `-explain`
-- Warning: ------------------------------------------------------------------------------------------------------------
1 |val s(): String = "hello, world"
  |                  ^^^^^^^^^^^^^^
  |          pattern's type Int does not match the right hand side expression's type String
  |
  |          If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression,
  |          which may result in a MatchError at runtime.
1 warning found
1 error found

Output Error/Warning message

-- [E006] Not Found Error: ---------------------------------------------------------------------------------------------
1 |val s(): String = "hello, world"
  |    ^
  |    Not found: s

Why this Error/Warning was not helpful

As explained at scala/bug#6564, when refactoring a def to a val, this is an easy mistake to make.

In addition, someone on chat suggested they weren't aware that "applies" in patterns did not require backquotes, so that it is not apparent (without research) that the error pertains to a pattern. That is, there is no distinguishing visual marker.

The confusion is even more confounding in REPL, as shown.

Suggested improvement

Mention that it is a pattern context. Or use pink squiggles instead of red. If you can notice that my val doesn't look like a pattern def, then say so.

Relatedly, I am unlikely to use a boolean extractor in a valdef, so that is an example of a pattern def that looks wrong.

scala> object s { def unapply(x: Any): Boolean = false }
// defined object s

scala> val s(): String = "hello, world"
1 warning found
-- Warning: ------------------------------------------------------------------------------------------------------------
1 |val s(): String = "hello, world"
  |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |    pattern binding uses refutable extractor `s`
  |
  |    If this usage is intentional, this can be communicated by adding `: @unchecked` after the expression,
  |    which may result in a MatchError at runtime.
scala.MatchError: hello, world (of class java.lang.String)
  ... 27 elided

At least it mentions here that it was a pattern.

Metadata

Metadata

Assignees

Labels

area:reportingError reporting including formatting, implicit suggestions, etcbetter-errorsIssues concerned with improving confusing/unhelpful diagnostic messagesitype:enhancement

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions