Skip to content

Commit

Permalink
Document the advanced error formatting engine
Browse files Browse the repository at this point in the history
  • Loading branch information
tek committed Apr 7, 2021
1 parent 0aa3fde commit 08e5aca
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 1 deletion.
15 changes: 14 additions & 1 deletion _data/compiler-options.yml
Expand Up @@ -611,9 +611,22 @@
- option: "-Vimplicits"
schema:
type: "Boolean"
description: "Show more detail on why some implicits are not applicable."
description: "Print dependent missing implicits."
abbreviations:
- "-Xlog-implicits"
- option: "-Vimplicits-verbose-tree"
schema:
type: "Boolean"
description: "Display all intermediate implicits in a chain."
- option: "-Vimplicits-max-refined"
schema:
type: "Int"
default: "0"
description: "max chars for printing refined types, abbreviate to `F {...}`"
- option: "-Vtype-diffs"
schema:
type: "Boolean"
description: "Print found/required error messages as colored diffs."
- option: "-Vinline"
schema:
type: "String"
Expand Down
5 changes: 5 additions & 0 deletions _data/overviews.yml
Expand Up @@ -254,6 +254,11 @@
icon: cog
url: "compiler-options/index.html"
description: "Various options to control how scalac compiles your code."
- title: Error Formatting
by: Torsten Schmits
icon: cog
url: "compiler-options/errors.html"
description: "A new engine for more user-friendly error messages, printing chains of dependent implicits and colored found/required type diffs."


- category: Legacy
Expand Down
104 changes: 104 additions & 0 deletions _overviews/compiler-options/errors.md
@@ -0,0 +1,104 @@
# Introduction

An advanced mechanism for formatting type errors and inspecting missing
implicits has been introduced in Scala 2.13.6.
It is based on the compiler plugin [splain](https://github.com/tek/splain).

This tool abstracts several classes of compiler errors with simple data types
that can be processed by a few built-in routines as well as
[user-provided analyzer plugins](/overviews/plugins/index.html).

The most significant feature is the illustration of chains of implicit instances
that allows a user to determine the root cause of an implicit error:

![implicits](/resources/img/implicits-circe.jpg)

# Basic Configuration

* `-Vimplicits` enables printing of implicit chains
* `-Vtype-diffs` enables colored diffs for found/required errors

## Additional Configuration

`-Vimplicits-verbose-tree` shows the implicits between the error site and the
root cause, see [#implicit-resolution-chains].

`-Vimplicits-max-refined` reduces the verbosity of refined types, see
[#truncating-refined-types].

# Features

The error formatting engine provides the following enhancements:

## Infix Types

Instead of `shapeless.::[A, HNil]`, prints `A :: HNil`.

## Found/Required Types

Rather than printing up to four types, only the dealiased types are shown as a colored diff:

![foundreq](/resources/img/foundreq.jpg)

## Implicit Resolution Chains

When an implicit is not found, only the outermost error at the invocation point
is printed by the regular error reporter. This can be expanded with the
compiler flag `-Xlog-implicits`, but that also shows all invalid implicits for
parameters that have been resolved successfully.

This feature prints a compact list of all involved implicits:

![compact](/resources/img/implicits-compact.jpg)

Here, `!I` stands for *could not find implicit value*, the name of the implicit
parameter is in yellow, and its type in green.

If the parameter `-Vimplicits-verbose-tree` is given, all intermediate implicits will be
printed, potentially spanning tens of lines.
An example of this is the circe error at the top of the page.

For comparison, this is the regular compiler output for this case:

```
[error] /path/Example.scala:20:5: could not find implicit value for parameter a: io.circe.Decoder[A]
[error] A.fun
[error] ^
```

## Infix Type and Type Argument Line Breaking

Types longer than 79 characters will be split into multiple lines:

```
implicit error;
!I e: String
f invalid because
!I impPar4: List[
(
VeryLongTypeName ::::
VeryLongTypeName ::::
VeryLongTypeName ::::
VeryLongTypeName
)
::::
(Short :::: Short) ::::
(
VeryLongTypeName ::::
VeryLongTypeName ::::
VeryLongTypeName ::::
VeryLongTypeName
)
::::
VeryLongTypeName ::::
VeryLongTypeName ::::
VeryLongTypeName ::::
VeryLongTypeName
]
```

## Truncating Refined Types

A type of the shape `T { type A = X; type B = Y }` will be displayed as `T
{...}` if the option `-Vimplicits-max-refined` is set to a value `/= 0` and
the refinement's length is greater than the value.
Binary file added resources/img/foundreq.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/img/foundreq_record.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/img/implicits-circe.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/img/implicits-compact.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 08e5aca

Please sign in to comment.