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] = ???
In this article