Skip to content

Commit b4bbae4

Browse files
author
Oron Port
authored
Merge pull request #131 from soronpo/macro_removal
Improvements under 2.13.x and some global conversions removal
2 parents 50670b9 + 1cab791 commit b4bbae4

File tree

11 files changed

+96
-144
lines changed

11 files changed

+96
-144
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,5 @@ project/plugins/project/
1818

1919
# IDEA specific
2020
.idea*/
21+
/.bloop/
22+
/.metals/
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package singleton.ops
2+
3+
object OpContainer {
4+
//Create an equivalence implicit rule with this `Eq` type
5+
//F - from type
6+
//T - to type
7+
//Wide - the T and F wide representation
8+
type Eq[F, T, Wide] = Require[ITE[IsNonLiteral[T], ImplicitFound[T =:= Wide], F == T]]
9+
10+
//For an op container with a single argument, extend the companion object using this trait.
11+
//For example:
12+
//class Vec[Size]
13+
//object Vec extends OpContainer.Eq1[Vec, Int]
14+
//val v1 : Vec[2] = new Vec[1 + 1]
15+
//val vInt : Vec[Int] = new Vec[1 + 1]
16+
trait Eq1[C[F1], Wide1] {
17+
implicit def argCast[F1,T1](c : C[F1])(implicit eq : Eq[F1,T1,Wide1]) : C[T1] = c.asInstanceOf[C[T1]]
18+
}
19+
}

src/main/scala/singleton/ops/impl/GeneralMacros.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,7 @@ trait GeneralMacros {
605605

606606

607607
def abort(msg: String, annotatedSym : Option[TypeSymbol] = defaultAnnotatedSym): Nothing = {
608+
// println(s"!!!!!!aborted with: $msg at $annotatedSym, $defaultAnnotatedSym")
608609
if (annotatedSym.isDefined) setAnnotation(msg, annotatedSym.get)
609610
c.abort(c.enclosingPosition, msg)
610611
}
@@ -736,7 +737,7 @@ trait GeneralMacros {
736737
case t : CalcLit => t
737738
case t : CalcType => CalcNLit(t, q"$tfTree.getValue")
738739
case t =>
739-
println(t)
740+
// println(t)
740741
extractionFailed(typedTree.tpe)
741742
}
742743
}
@@ -769,9 +770,12 @@ trait GeneralMacros {
769770
object GetArgTree {
770771
def isMethodMacroCall : Boolean = c.enclosingImplicits.last.sym.isMacro
771772
def getAllArgs(tree : Tree, lhs : Boolean) : List[Tree] = tree match {
772-
case Apply(Select(q,n), args) => if (isMethodMacroCall || lhs) args else List(tree)
773+
case ValDef(_,_,_,Apply(_, t)) => t
774+
case Apply(Apply(_,_), _) => getAllArgsRecur(tree)
775+
case Apply(_, args) => if (isMethodMacroCall || lhs) args else List(tree)
773776
case t : Select => List(t)
774777
case t : Literal => List(t)
778+
case t : Ident => List(t)
775779
case _ => getAllArgsRecur(tree)
776780
}
777781

src/main/scala/singleton/ops/package.scala

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -196,49 +196,4 @@ package object ops {
196196
check : Require[OP_OUTA == OP_OUTB]
197197
) : OpMacro[NB, SB1, SB2, SB3] = opB
198198
/////////////////////////////////////////////////
199-
200-
201-
/////////////////////////////////////////////////
202-
//Implicit proof for type class containers of
203-
//singleton type operations & literals
204-
/////////////////////////////////////////////////
205-
implicit def opContainer1[
206-
F,
207-
T,
208-
C[_]
209-
](cf : C[F])
210-
(implicit
211-
ct : C[T],
212-
check : Require[
213-
F == T
214-
])
215-
: C[T] = ct
216-
217-
implicit def opContainer2[
218-
F1, F2,
219-
T1, T2,
220-
C[_,_]
221-
](cf : C[F1, F2])
222-
(implicit
223-
ct : C[T1, T2],
224-
check : Require[
225-
(F1 == T1) &&
226-
(F2 == T2)
227-
]
228-
) : C[T1, T2] = ct
229-
230-
implicit def opContainer3[
231-
F1, F2, F3,
232-
T1, T2, T3,
233-
C[_,_,_]
234-
](cf : C[F1, F2, F3])
235-
(implicit
236-
ct : C[T1, T2, T3],
237-
check : Require[
238-
(F1 == T1) &&
239-
(F2 == T2) &&
240-
(F3 == T3)
241-
]
242-
) : C[T1, T2, T3] = ct
243-
/////////////////////////////////////////////////
244199
}

src/main/scala_2.13+/singleton/twoface/impl/Checked0ParamAny.scala

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,19 @@ trait Checked0ParamAny[Chk[Cond0[_], Msg0[_], T0], Cond[_], Msg[_], Face, T] ext
1414

1515
object Checked0ParamAny {
1616
trait LP[Chk[Cond0[_], Msg0[_], T0], Face] {
17-
implicit def fromNum[Cond[_], Msg[_], T >: Face, Out <: T](value : T)
17+
def create[Cond[_], Msg[_], T](value : Face) : Chk[Cond, Msg, T]
18+
19+
//This is a hack to force Scalac to actually display the constructed error message in all cases
20+
//From some weird reason only direct macro calls displays the error in a case of an implicit conversion
21+
implicit def requireMsg[Cond[_], Msg[_], T >: Face, Out <: T](value : T)
1822
: Chk[Cond, Msg, Out] = macro Builder.Macro.fromNumValue[Chk[Cond,Msg,_], Cond[_], Msg[_], T]
23+
24+
//from non-singleton values
25+
implicit def fromNumNonSing[Cond[_], Msg[_]](value : Face)(
26+
implicit req : ITE[IsNonLiteral[GetArg0], true, RequireMsg[Cond[GetArg0], Msg[GetArg0]]], di : DummyImplicit
27+
) : Chk[Cond, Msg, Face] = create[Cond, Msg, Face](value)
1928
}
29+
2030
trait Builder[Chk[Cond0[_], Msg0[_], T0], Face] extends LP[Chk, Face] {
2131
trait Alias {
2232
type Cond[T]
@@ -25,48 +35,35 @@ object Checked0ParamAny {
2535
final type CheckedShell[T] = CheckedShellSym[NoSym, T]
2636
final type CheckedShellSym[Sym, T] = CheckedShell1[Cond, Msg, Sym, T, Face]
2737
}
28-
def create[Cond[_], Msg[_], T](value : Face) : Chk[Cond, Msg, T]
2938

3039
////////////////////////////////////////////////////////////////////////////////////////
3140
// Generic Implicit Conversions
3241
// Currently triggers good-code-red IntelliJ issue
3342
// https://youtrack.jetbrains.com/issue/SCL-13089
3443
////////////////////////////////////////////////////////////////////////////////////////
35-
implicit def ev[Cond[_], Msg[_], T](implicit value : AcceptNonLiteral[Id[T]])
36-
: Chk[Cond, Msg, T] = macro Builder.Macro.fromOpImpl[Chk[Cond,Msg,_], Cond[_], Msg[_], T]
44+
implicit def ev[Cond[_], Msg[_], T](implicit req : RequireMsg[Cond[T], Msg[T]], value : AcceptNonLiteral[Id[T]])
45+
: Chk[Cond, Msg, T] = create[Cond, Msg, T](value.valueWide.asInstanceOf[Face])
3746

38-
implicit def fromNumSing[Cond[_], Msg[_], T <: Face with Singleton](value : T)(implicit req : RequireMsg[Cond[T], Msg[T]])
39-
: Chk[Cond, Msg, T] = create[Cond, Msg, T](value)
47+
implicit def fromNumSing[Cond[_], Msg[_], T <: Face with Singleton](value : T)(
48+
implicit req : RequireMsg[Cond[T], Msg[T]]
49+
) : Chk[Cond, Msg, T] = create[Cond, Msg, T](value)
4050

41-
implicit def fromTF[Cond[_], Msg[_], T >: Face, Out <: T](value : TwoFaceAny[Face, T])
42-
: Chk[Cond, Msg, Out] = macro Builder.Macro.fromTF[Chk[Cond,Msg,_], Cond[_], Msg[_], T]
51+
implicit def fromTF[Cond[_], Msg[_], T](tfValue : TwoFaceAny[Face, T])(
52+
implicit req : RequireMsg[IsNonLiteral[T] || Cond[T], Msg[T]], di : DummyImplicit
53+
) : Chk[Cond, Msg, T] = create[Cond, Msg, T](tfValue.getValue)
4354

44-
implicit def widen[Cond[_], Msg[_], T](value : Chk[Cond, Msg, T])
45-
: Chk[Cond, Msg, Face] = value.asInstanceOf[Chk[Cond, Msg, Face]]
55+
implicit def argCast[Cond[_], Msg[_], F, T](c : Chk[Cond, Msg, F])(
56+
implicit eq : OpContainer.Eq[F, T, Face]
57+
) : Chk[Cond, Msg, T] = c.asInstanceOf[Chk[Cond, Msg, T]]
4658
////////////////////////////////////////////////////////////////////////////////////////
4759
}
4860

4961
object Builder {
5062
final class Macro(val c: whitebox.Context) extends GeneralMacros {
51-
def fromOpImpl[Chk, Cond, Msg, T](value : c.Tree)(
52-
implicit
53-
chk : c.WeakTypeTag[Chk], cond : c.WeakTypeTag[Cond], msg : c.WeakTypeTag[Msg], t : c.WeakTypeTag[T]
54-
): c.Tree = Checked0ParamMaterializer[Chk, Cond, Msg, T].fromOpImpl(value)
55-
5663
def fromNumValue[Chk, Cond, Msg, T](value : c.Tree)(
5764
implicit
5865
chk : c.WeakTypeTag[Chk], cond : c.WeakTypeTag[Cond], msg : c.WeakTypeTag[Msg], t : c.WeakTypeTag[T]
5966
): c.Tree = Checked0ParamMaterializer[Chk, Cond, Msg, T].fromNumValue(value)
60-
61-
def fromTF[Chk, Cond, Msg, T](value : c.Tree)(
62-
implicit
63-
chk : c.WeakTypeTag[Chk], cond : c.WeakTypeTag[Cond], msg : c.WeakTypeTag[Msg], t : c.WeakTypeTag[T]
64-
): c.Tree = Checked0ParamMaterializer[Chk, Cond, Msg, T].fromTF(value)
65-
66-
def widen[Chk, Cond, Msg, T](value : c.Tree)(
67-
implicit
68-
chk : c.WeakTypeTag[Chk], cond : c.WeakTypeTag[Cond], msg : c.WeakTypeTag[Msg], t : c.WeakTypeTag[T]
69-
): c.Tree = Checked0ParamMaterializer[Chk, Cond, Msg, T].widen(value)
7067
}
7168
}
7269

@@ -78,6 +75,7 @@ object Checked0ParamAny {
7875
def create[Cond[_], Msg[_], T](value: std.Char): Char[Cond, Msg, T] = new Char[Cond, Msg, T](value)
7976
}
8077

78+
@scala.annotation.implicitNotFound("haha")
8179
final class Int[Cond[_], Msg[_], T](val value : std.Int) extends
8280
Checked0ParamAny[Int, Cond, Msg, std.Int, T] with TwoFaceAny.Int[T] {
8381
@inline def getValue : std.Int = value

src/main/scala_2.13+/singleton/twoface/impl/Checked1ParamAny.scala

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,17 @@ trait Checked1ParamAny[Chk[Cond0[_,_], Msg0[_,_], T0, ParamFace0, Param0], Cond[
1515

1616
object Checked1ParamAny {
1717
trait LP[Chk[Cond0[_,_], Msg0[_,_], T0, ParamFace0, Param0], Face] {
18-
implicit def fromNum[Cond[_,_], Msg[_,_], T >: Face, ParamFace, Param, Out <: T](value : T)
19-
: Chk[Cond, Msg, Out, ParamFace, Param] = macro Builder.Macro.fromNumValue[Chk[Cond,Msg,_,_,_], Cond[_,_], Msg[_,_], T, ParamFace, Param]
18+
def create[Cond[_,_], Msg[_,_], T, ParamFace, Param](value : Face) : Chk[Cond, Msg, T, ParamFace, Param]
19+
20+
//This is a hack to force Scalac to actually display the constructed error message in all cases
21+
//From some weird reason only direct macro calls displays the error in a case of an implicit conversion
22+
implicit def requireMsg[Cond[_,_], Msg[_,_], T >: Face, ParamFace, Param, Out <: T](value : T)
23+
: Chk[Cond, Msg, Out, ParamFace, Param] = macro Builder.Macro.requireMsg[Chk[Cond,Msg,_,_,_], Cond[_,_], Msg[_,_], T, ParamFace, Param]
24+
25+
//from non-singleton values
26+
implicit def fromNumNonSing[Cond[_,_], Msg[_,_], ParamFace, Param](value : Face)(
27+
implicit req : RequireMsg[IsNonLiteral[GetArg0] || IsNonLiteral[Param] || Cond[GetArg0, Param], Msg[GetArg0, Param]],
28+
) : Chk[Cond, Msg, Face, ParamFace, Param] = create[Cond, Msg, Face, ParamFace, Param](value)
2029
}
2130
trait Builder[Chk[Cond0[_,_], Msg0[_,_], T0, ParamFace0, Param0], Face] extends LP[Chk, Face]{
2231
trait Alias {
@@ -27,49 +36,36 @@ object Checked1ParamAny {
2736
final type CheckedShell[T, Param] = CheckedShellSym[NoSym, T, Param]
2837
final type CheckedShellSym[Sym, T, Param] = CheckedShell2[Cond, Msg, Sym, T, Face, Param, ParamFace]
2938
}
30-
31-
def create[Cond[_,_], Msg[_,_], T, ParamFace, Param](value : Face) : Chk[Cond, Msg, T, ParamFace, Param]
3239

3340
////////////////////////////////////////////////////////////////////////////////////////
3441
// Generic Implicit Conversions
3542
// Currently triggers good-code-red IntelliJ issue
3643
// https://youtrack.jetbrains.com/issue/SCL-13089
3744
////////////////////////////////////////////////////////////////////////////////////////
38-
implicit def ev[Cond[_,_], Msg[_,_], ParamFace, T, Param](implicit value : AcceptNonLiteral[Id[T]])
39-
: Chk[Cond, Msg, T, ParamFace, Param] = macro Builder.Macro.fromOpImpl[Chk[Cond,Msg,_,_,_], Cond[_,_], Msg[_,_], T, ParamFace, Param]
45+
implicit def ev[Cond[_,_], Msg[_,_], ParamFace, T, Param](
46+
implicit req : RequireMsg[IsNonLiteral[Param] || Cond[T, Param], Msg[T, Param]], value : AcceptNonLiteral[Id[T]]
47+
) : Chk[Cond, Msg, T, ParamFace, Param] = create[Cond, Msg, T, ParamFace, Param](value.valueWide.asInstanceOf[Face])
4048

41-
implicit def fromNumSing[Cond[_,_], Msg[_,_], T <: Face with Singleton, ParamFace, Param](value : T)(implicit req : RequireMsg[Cond[T, Param], Msg[T, Param]])
42-
: Chk[Cond, Msg, T, ParamFace, Param] = create[Cond, Msg, T, ParamFace, Param](value)
49+
implicit def fromNumSing[Cond[_,_], Msg[_,_], T <: Face with Singleton, ParamFace, Param](value : T)(
50+
implicit req : RequireMsg[IsNonLiteral[Param] || Cond[T, Param], Msg[T, Param]]
51+
) : Chk[Cond, Msg, T, ParamFace, Param] = create[Cond, Msg, T, ParamFace, Param](value)
4352

44-
implicit def fromTF[Cond[_,_], Msg[_,_], T >: Face, ParamFace, Param, Out <: T](value : TwoFaceAny[Face, T])
45-
: Chk[Cond, Msg, Out, ParamFace, Param] = macro Builder.Macro.fromTF[Chk[Cond,Msg,_,_,_], Cond[_,_], Msg[_,_], T, ParamFace, Param]
53+
implicit def fromTF[Cond[_,_], Msg[_,_], T, ParamFace, Param](tfValue : TwoFaceAny[Face, T])(
54+
implicit req : RequireMsg[IsNonLiteral[T] || IsNonLiteral[Param] || Cond[T, Param], Msg[T, Param]], di : DummyImplicit
55+
) : Chk[Cond, Msg, T, ParamFace, Param] = create[Cond, Msg, T, ParamFace, Param](tfValue.getValue)
4656

47-
implicit def widen[Cond[_,_], Msg[_,_], T, ParamFace, Param](value : Chk[Cond, Msg, T, ParamFace, Param])
48-
: Chk[Cond, Msg, Face, ParamFace, Param] = value.asInstanceOf[Chk[Cond, Msg, Face, ParamFace, Param]]
57+
implicit def argCast[Cond[_,_], Msg[_,_], F, T, ParamFace, Param](c : Chk[Cond, Msg, F, ParamFace, Param])(
58+
implicit eq : OpContainer.Eq[F, T, Face]
59+
) : Chk[Cond, Msg, T, ParamFace, Param] = c.asInstanceOf[Chk[Cond, Msg, T, ParamFace, Param]]
4960
////////////////////////////////////////////////////////////////////////////////////////
5061
}
5162

5263
object Builder {
5364
final class Macro(val c: whitebox.Context) extends GeneralMacros {
54-
def fromOpImpl[Chk, Cond, Msg, T, ParamFace, Param](value : c.Tree)(
55-
implicit
56-
chk : c.WeakTypeTag[Chk], cond : c.WeakTypeTag[Cond], msg : c.WeakTypeTag[Msg], t : c.WeakTypeTag[T], paramFace : c.WeakTypeTag[ParamFace], p : c.WeakTypeTag[Param]
57-
): c.Tree = Checked1ParamMaterializer[Chk, Cond, Msg, T, ParamFace, Param].fromOpImpl(value)
58-
59-
def fromNumValue[Chk, Cond, Msg, T, ParamFace, Param](value : c.Tree)(
65+
def requireMsg[Chk, Cond, Msg, T, ParamFace, Param](value : c.Tree)(
6066
implicit
6167
chk : c.WeakTypeTag[Chk], cond : c.WeakTypeTag[Cond], msg : c.WeakTypeTag[Msg], t : c.WeakTypeTag[T], paramFace : c.WeakTypeTag[ParamFace], p : c.WeakTypeTag[Param]
6268
): c.Tree = Checked1ParamMaterializer[Chk, Cond, Msg, T, ParamFace, Param].fromNumValue(value)
63-
64-
def fromTF[Chk, Cond, Msg, T, ParamFace, Param](value : c.Tree)(
65-
implicit
66-
chk : c.WeakTypeTag[Chk], cond : c.WeakTypeTag[Cond], msg : c.WeakTypeTag[Msg], t : c.WeakTypeTag[T], paramFace : c.WeakTypeTag[ParamFace], p : c.WeakTypeTag[Param]
67-
): c.Tree = Checked1ParamMaterializer[Chk, Cond, Msg, T, ParamFace, Param].fromTF(value)
68-
69-
def widen[Chk, Cond, Msg, T, ParamFace, Param](value : c.Tree)(
70-
implicit
71-
chk : c.WeakTypeTag[Chk], cond : c.WeakTypeTag[Cond], msg : c.WeakTypeTag[Msg], t : c.WeakTypeTag[T], paramFace : c.WeakTypeTag[ParamFace], p : c.WeakTypeTag[Param]
72-
): c.Tree = Checked1ParamMaterializer[Chk, Cond, Msg, T, ParamFace, Param].widen(value)
7369
}
7470
}
7571

0 commit comments

Comments
 (0)