@@ -27,43 +27,42 @@ class CaptureMacros(val c: whitebox.Context) extends OpenImplicitMacros {
2727
2828 def materializeCapture [A : WeakTypeTag ]: Tree = {
2929 val A = openImplicitTpeParam.getOrElse(weakTypeOf[A ])
30-
3130 q """ _root_.shims.util.Capture[ $A]( ${reconstructImplicit(A )}) """
3231 }
3332
3433 def materializeEitherCapture [A : WeakTypeTag , B : WeakTypeTag ]: Tree = {
35- val A = openImplicitTpeParam.getOrElse(weakTypeOf[A ])
36- val B = openImplicitTpeParam.getOrElse(weakTypeOf[B ])
37-
3834 val treeAM = try {
39- Right (q " _root_.scala.util.Left( ${reconstructImplicit(A )}) " )
35+ val A = leftImplicitTpeParam.getOrElse(weakTypeOf[A ])
36+ val B = weakTypeOf[B ]
37+ Right (q """ _root_.shims.util.EitherCapture[ $A, $B](_root_.scala.util.Left[ $A, $B]( ${reconstructImplicit(A )})) """ )
4038 } catch {
41- case e : Exception => Left (e)
39+ // ok it's actually an Error, not an Exception 🤦♀️
40+ case t : Throwable => Left (t)
4241 }
4342
4443 val treeBM = try {
45- Right (q " _root_.scala.util.Right( ${reconstructImplicit(B )}) " )
44+ val A = weakTypeOf[A ]
45+ val B = rightImplicitTpeParam.getOrElse(weakTypeOf[B ])
46+ Right (q """ _root_.shims.util.EitherCapture[ $A, $B](_root_.scala.util.Right[ $A, $B]( ${reconstructImplicit(B )})) """ )
4647 } catch {
47- case e : Exception => Left (e)
48+ // ok it's actually an Error, not an Exception 🤦♀️
49+ case t : Throwable => Left (t)
4850 }
4951
50- val result = treeAM.right.map( Right (_)).right.getOrElse(treeBM ).fold(
52+ treeAM.fold(_ => treeBM, Right (_)).fold(
5153 throw _, // it's so great how scalac uses exceptions...
5254 identity)
53-
54- q """ _root_.shims.util.EitherCapture[ $A, $B]( $result) """
5555 }
5656
5757 def materializeOptionCapture [A : WeakTypeTag ]: Tree = {
58- val A = openImplicitTpeParam.getOrElse(weakTypeOf[A ])
59-
60- val result = try {
61- q " _root_.scala.Some( ${reconstructImplicit(A )}) "
58+ try {
59+ val A = openImplicitTpeParam.getOrElse(weakTypeOf[A ])
60+ q """ _root_.shims.util.OptionCapture[ $A](_root_.scala.Some( ${reconstructImplicit(A )})) """
6261 } catch {
63- case e : Exception => q " _root_.scala.None "
62+ // ok it's actually an Error, not an Exception 🤦♀️
63+ case t : Throwable =>
64+ q """ _root_.shims.util.OptionCapture[ ${weakTypeOf[A ]}](_root_.scala.None) """
6465 }
65-
66- q """ _root_.shims.util.OptionCapture[ $A]( $result) """
6766 }
6867
6968 private def reconstructImplicit (A : Type ): Tree = {
@@ -73,16 +72,16 @@ class CaptureMacros(val c: whitebox.Context) extends OpenImplicitMacros {
7372 try {
7473 c.inferImplicitValue(A )
7574 } catch {
76- case e : Exception => c.abort(c.enclosingPosition, s " Implicit $A not found " )
75+ case t : Throwable => c.abort(c.enclosingPosition, s " implicit $A not found " )
7776 }
7877 }
7978
8079 if (tree0 == EmptyTree ) {
81- c.abort(c.enclosingPosition, s " Implicit $A not found " )
80+ c.abort(c.enclosingPosition, s " implicit $A not found " )
8281 }
8382
8483 if (tree0.tpe <:< Synthetic ) {
85- c.abort(c.enclosingPosition, s " Cannot capture subtype of Synthetic" )
84+ c.abort(c.enclosingPosition, s " cannot capture subtype of Synthetic" )
8685 }
8786
8887 tree0
@@ -109,7 +108,7 @@ private[util] object CaptureMacros {
109108
110109 // simple divergence check
111110 if (vs.exists(tpe <:< _.asInstanceOf [c.universe.Type ])) {
112- c.abort(c.enclosingPosition, s " Implicit $tpe not found " )
111+ c.abort(c.enclosingPosition, s " implicit $tpe not found " )
113112 } else {
114113 val vs2 = tpe :: vs
115114
@@ -133,17 +132,29 @@ private[shims] trait OpenImplicitMacros {
133132 c.openImplicits.headOption.map(_.pt)
134133
135134 def openImplicitTpeParam : Option [Type ] =
136- openImplicitTpe. map {
135+ openImplicitTpe map {
137136 case TypeRef (_, _, List (tpe)) =>
138137 tpe.map(_.dealias)
138+
139+ case other =>
140+ c.abort(c.enclosingPosition, s " bad materialization: $other" )
141+ }
142+
143+ def leftImplicitTpeParam : Option [Type ] =
144+ openImplicitTpe map {
145+ case TypeRef (_, _, List (tpe, _)) =>
146+ tpe.map(_.dealias)
147+
139148 case other =>
140- c.abort(c.enclosingPosition, s " Bad materialization: $other" )
149+ c.abort(c.enclosingPosition, s " bad materialization (left) : $other" )
141150 }
142151
143- def secondOpenImplicitTpe : Option [Type ] =
144- c.openImplicits match {
145- case (List (_, second, _ @ _* )) =>
146- Some (second.pt)
147- case _ => None
152+ def rightImplicitTpeParam : Option [Type ] =
153+ openImplicitTpe map {
154+ case TypeRef (_, _, List (_, tpe)) =>
155+ tpe.map(_.dealias)
156+
157+ case other =>
158+ c.abort(c.enclosingPosition, s " bad materialization (right): $other" )
148159 }
149160}
0 commit comments