E021: Proper Definition Not Found

This error is emitted when a @usecase annotation in a Scaladoc comment does not contain a proper def definition.

Usecases are only supported for defs. They exist because with Scala's advanced type-system, we sometimes end up with seemingly scary signatures. The usage of these methods, however, needs not be scary.

For instance, the map function:

List(1, 2, 3).map(2 * _) // res: List(2, 4, 6)

is easy to understand and use - but has a rather bulky signature:

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That

The @usecase annotation allows documenting a simplified signature:

/** Map from List[A] => List[B]
 *
 * @usecase def map[B](f: A => B): List[B]
 */
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That

Example

//> using options -Xcook-comments

class Example:
  /**
   * @usecase val x: Int
   */
  def complexMethod[A, B](f: A => B)(implicit ev: Ordering[A]): B = ???

Error

-- [E021] Doc Comment Error: example.scala:5:14 --------------------------------
5 |   * @usecase val x: Int
  |              ^
  |              Proper definition was not found in @usecase
  |
6 |   */
7 |  def complexMethod[A, B](f: A => B)(implicit ev: Ordering[A]): B = ???
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | Usecases are only supported for defs. They exist because with Scala's
  | advanced type-system, we sometimes end up with seemingly scary signatures.
  | The usage of these methods, however, needs not be - for instance the map
  | function
  |
  | List(1, 2, 3).map(2 * _) // res: List(2, 4, 6)
  |
  | is easy to understand and use - but has a rather bulky signature:
  |
  | def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That
  |
  | to mitigate this and ease the usage of such functions we have the @usecase
  | annotation for docstrings. Which can be used like this:
  |
  | /** Map from List[A] => List[B]
  |   *
  |   * @usecase def map[B](f: A => B): List[B]
  |   */
  | def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That
  |
  |
  | When creating the docs, the signature of the method is substituted by the
  | usecase and the compiler makes sure that it is valid. Because of this, you're
  | only allowed to use defs when defining usecases.
   -----------------------------------------------------------------------------

Solution

//> using options -Xcook-comments

class Example:
  /**
   * Transforms elements.
   * @usecase def transform(f: Int => Int): List[Int]
   */
  def transform[A, B](f: A => B)(implicit ev: Ordering[A]): List[B] = ???