From 377703a3b9a38af07f0cfc92cc9b7071291226a4 Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Fri, 24 May 2024 23:00:10 +0300 Subject: [PATCH] Unify error messages between Scala 2 and Scala 3 (#546) --- .../cats/tagless/macros/DeriveMacros.scala | 2 +- .../cats/tagless/macros/MacroApply.scala | 2 +- .../cats/tagless/macros/MacroBifunctor.scala | 2 +- .../cats/tagless/macros/MacroFlatMap.scala | 4 +-- .../scala-2/cats/tagless/DeriveMacros.scala | 30 +++++++++++++------ 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/core/src/main/scala-3/cats/tagless/macros/DeriveMacros.scala b/core/src/main/scala-3/cats/tagless/macros/DeriveMacros.scala index d083b657..722f4b4b 100644 --- a/core/src/main/scala-3/cats/tagless/macros/DeriveMacros.scala +++ b/core/src/main/scala-3/cats/tagless/macros/DeriveMacros.scala @@ -201,7 +201,7 @@ private class DeriveMacros[Q <: Quotes](using val q: Q): def summon: Term = Implicits.search(tpe) match case success: ImplicitSearchSuccess => success.tree case failure: ImplicitSearchFailure => report.errorAndAbort(failure.explanation) - case _ => report.errorAndAbort(s"Failed to summon: ${tpe.show}") + case _ => report.errorAndAbort(s"Not found: given ${tpe.show}") def lambda(args: List[Symbol]): TypeLambda = val n = args.length diff --git a/core/src/main/scala-3/cats/tagless/macros/MacroApply.scala b/core/src/main/scala-3/cats/tagless/macros/MacroApply.scala index 8cb7e6f5..312b6cac 100644 --- a/core/src/main/scala-3/cats/tagless/macros/MacroApply.scala +++ b/core/src/main/scala-3/cats/tagless/macros/MacroApply.scala @@ -47,7 +47,7 @@ object MacroApply: List(ff, fa).combineTo[F[B]]( args = List.fill(2): case (method, tpe, _) if tpe.contains(B) => - report.errorAndAbort(s"Type parameter ${A.show} appears in contravariant position in $method"), + report.errorAndAbort(s"Type parameter ${A.show} occurs in contravariant position in $method"), body = { case (_, tpe, ff :: fa :: Nil) if tpe.contains(B) => Select diff --git a/core/src/main/scala-3/cats/tagless/macros/MacroBifunctor.scala b/core/src/main/scala-3/cats/tagless/macros/MacroBifunctor.scala index 00e84ca4..8012dc6e 100644 --- a/core/src/main/scala-3/cats/tagless/macros/MacroBifunctor.scala +++ b/core/src/main/scala-3/cats/tagless/macros/MacroBifunctor.scala @@ -48,7 +48,7 @@ object MacroBifunctor: fab.transformTo[F[C, D]]( args = { case (method, tpe, _) if tpe.containsAll(C, D) => - val msg = s"Both type parameters ${A.show} and ${B.show} appear in contravariant position in $method" + val msg = s"Both type parameters ${A.show} and ${B.show} occur in contravariant position in $method" report.errorAndAbort(msg) case (_, tpe, arg) if tpe.contains(C) => Select diff --git a/core/src/main/scala-3/cats/tagless/macros/MacroFlatMap.scala b/core/src/main/scala-3/cats/tagless/macros/MacroFlatMap.scala index ab249f1a..fada922d 100644 --- a/core/src/main/scala-3/cats/tagless/macros/MacroFlatMap.scala +++ b/core/src/main/scala-3/cats/tagless/macros/MacroFlatMap.scala @@ -50,7 +50,7 @@ object MacroFlatMap: fa.transformTo[F[B]]( args = { case (method, tpe, _) if tpe.contains(B) => - report.errorAndAbort(s"Type parameter ${A.show} appears in contravariant position in $method") + report.errorAndAbort(s"Type parameter ${A.show} occurs in contravariant position in $method") }, body = { case (_, tpe, body) if tpe =:= B => @@ -73,7 +73,7 @@ object MacroFlatMap: '{ $f($a) }.transformTo[F[B]]( args = { case (method, tpe, _) if tpe.contains(B) => - report.errorAndAbort(s"Type parameter ${A.show} appears in contravariant position in $method") + report.errorAndAbort(s"Type parameter ${A.show} occurs in contravariant position in $method") }, body = { case (method, tpe, body) if tpe =:= B => diff --git a/macros/src/main/scala-2/cats/tagless/DeriveMacros.scala b/macros/src/main/scala-2/cats/tagless/DeriveMacros.scala index 65cd74d3..72917bc8 100644 --- a/macros/src/main/scala-2/cats/tagless/DeriveMacros.scala +++ b/macros/src/main/scala-2/cats/tagless/DeriveMacros.scala @@ -110,7 +110,7 @@ class DeriveMacros(val c: blackbox.Context) { /** Summon an implicit instance of `A` applied to `typeArgs` if one exists in scope, otherwise abort. */ def summon[A: TypeTag](typeArgs: Type*): Tree = - summonOr[A](typeArgs*)(tpe => abort(s"could not find implicit value of type $tpe in method $displayName")) + summonOr[A](typeArgs*)(tpe => abort(s"Not found: implicit $tpe in method $displayName")) /** Summon an implicit instance of `F[a =>> returnType]` if one exists in scope. */ def summonF[F[_[_]]](a: Symbol, returnType: Type)(implicit tag: TypeTag[F[Any]]): Tree = @@ -523,9 +523,12 @@ class DeriveMacros(val c: blackbox.Context) { case method if method.returnType.typeSymbol == a => val body = method.delegate(q"$f(${method.body})") method.copy(returnType = b.asType.toType, body = body) + case method if method.occursOnlyInReturn(a) => + val A = a.asType.toType + abort(s"Expected method ${method.displayName} to return $A but found ${method.returnType}") case method if method.occursInSignature(a) => val A = a.asType.toType - abort(s"Type parameter $A can only occur as a top level return type in method ${method.displayName}") + abort(s"Type parameter $A occurs in contravariant position in method ${method.returnType}") } implement(algebra)(b)(types ++ methods) @@ -550,9 +553,12 @@ class DeriveMacros(val c: blackbox.Context) { }""" method.copy(returnType = b.asType.toType, body = body) + case method if method.occursOnlyInReturn(a) => + val A = a.asType.toType + abort(s"Expected method ${method.displayName} to return $A but found ${method.returnType}") case method if method.occursInSignature(a) => val A = a.asType.toType - abort(s"Type parameter $A can only occur as a top level return type in method ${method.displayName}") + abort(s"Type parameter $A occurs in contravariant position in method ${method.displayName}") case method => method.copy(body = method.delegate(q"$f($x)")) } @@ -644,8 +650,10 @@ class DeriveMacros(val c: blackbox.Context) { val body = q"${reify(aop.Instrumentation)}(${method.body}, $algebraName, ${method.displayName})" val returnType = appliedType(Instrumentation, F :: method.returnType.typeArgs) method.copy(body = body, returnType = returnType) + case method if method.occursOnlyInReturn(f) => + abort(s"Expected method ${method.displayName} to return $F[?] but found ${method.returnType}") case method if method.occursInSignature(f) => - abort(s"Type parameter $F can only occur as a top level return type in method ${method.displayName}") + abort(s"Type parameter $F occurs in contravariant position in method ${method.displayName}") } val InstrumentationType = appliedType(Instrumentation, F :: F.typeParams.map(_.asType.toType)) @@ -678,8 +686,10 @@ class DeriveMacros(val c: blackbox.Context) { val body = q"${reify(Aspect.Weave)}[$F, $Dom, $Cod, ..$typeArgs]($algebraName, $domain, $codomain)" val returnType = appliedType(AspectWeave, F :: Dom :: Cod :: typeArgs) method.copy(body = body, returnType = returnType) + case method if method.occursOnlyInReturn(f) => + abort(s"Expected method ${method.displayName} to return $F[?] but found ${method.returnType}") case method if method.occursInSignature(f) => - abort(s"Type parameter $F can only occur as a top level return type in method ${method.displayName}") + abort(s"Type parameter $F occurs in contravariant position in method ${method.displayName}") } val WeaveType = appliedType(AspectWeave, F :: Dom :: Cod :: F.typeParams.map(_.asType.toType)) @@ -697,10 +707,10 @@ class DeriveMacros(val c: blackbox.Context) { val methods = delegateMethods(Af, abstractMembers, NoSymbol) { case method if method.returnType.typeSymbol == f => method.copy(returnType = weakTypeOf[A], body = q"$tmp") - case method if method.occursInSignature(f) => - abort(s"Type parameter $F can only occur as a top level return type in method ${method.displayName}") + case method if method.occursInSignature(f) && !method.occursOnlyInReturn(f) => + abort(s"Type parameter $F occurs in contravariant position in method ${method.displayName}") case method => - abort(s"Abstract method ${method.displayName} cannot be derived because it does not return in $F") + abort(s"Expected method ${method.displayName} to return $F[?] but found ${method.returnType}") } val Const = weakTypeOf[Const[A]].member(TypeName("λ")).typeSignature @@ -730,8 +740,10 @@ class DeriveMacros(val c: blackbox.Context) { val typeArgs = F :: Af :: method.returnType.typeArgs q"${reify(cats.data.ReaderT)}[..$typeArgs](($af: $Af) => $delegate)" } + case method if method.occursInSignature(f) && !method.occursOnlyInReturn(f) => + abort(s"Type parameter $F occurs in contravariant position in method ${method.displayName}") case method => - abort(s"Abstract method ${method.displayName} cannot be derived because it does not return in $F") + abort(s"Expected method ${method.displayName} to return $F[?] but found ${method.returnType}") } val b = ReaderT.typeParams.last.asType