This plugin removes some of the redundancy of the compiler output and prints additional info for implicit resolution errors.
addCompilerPlugin("io.tryp" %% "splain" % "0.2.4")The plugin can be configured via compiler plugin parameters with the format:
-P:splain:<param>[:<value>]
param can be one of the following:
allinfixfoundreqimplicitsbounds(default off)colorbreakinfix(default 0)treecompact(default off)boundsimplicitstruncrefined(default 0)
value can either be true or false. If omitted, the default is true for
both value and parameter.
The parameter all can be used to deactivate all features.
The parameters can be applied like this:
scalacOptions += "-P:splain:implicits:false"Instead of shapeless.::[A, HNil], prints A :: HNil.
Rather than printing up to four types, only the dealiased types are shown as a colored diff:
special consideration for shapeless.Record:
When an implicit is not found, only the outermost error at the invocation point
is printed. 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:

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 tree is set, the candidates will be indented according to their nesting level:
If the parameter compact is set, only the first and last implicit in a chain will be printed.
If the parameter boundsimplicits is set to false, any nonconformant bounds errors will be suppressed.
For comparison, this is the regular compiler output for this case (with formatted types):
[info] unit/src/basic.scala:35: f is not a valid implicit value for
splain.ImplicitChain.T2 because:
[info] hasMatchingSymbol reported error: could not find implicit value for
parameter impPar2: (D *** (C *** String)) >:< ((C,D,C) *** D)
[info] implicitly[T1]
[info] ^
[info] unit/src/basic.scala:35: g is not a valid implicit value for
splain.ImplicitChain.T1 because:
[info] hasMatchingSymbol reported error: could not find implicit value for
parameter impPar1: D *** ((C >:< C) *** (D => Unit))
[info] implicitly[T1]
[info] ^
[error] unit/src/basic.scala:35: could not find implicit value for
parameter e: (C *** D) >:< C with D {type A = D; type B = C}
[error] implicitly[T1]
If the parameter breakinfix is given and greater than 0, types longer than
that number 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
]
A type of the shape T { type A = X; type B = Y } will be displayed as T {...} if the parameter truncrefined is set
to a value /= 0 and the refinement's length is greater than the value.


