Skip to content

Commit 0f19b67

Browse files
committed
remove support for SAM types in ImplicitFunctionParams rule and enhance tests for function type restrictions
1 parent fbafdfb commit 0f19b67

File tree

2 files changed

+83
-2
lines changed

2 files changed

+83
-2
lines changed

analyzer/src/main/scala/com/avsystem/commons/analyzer/ImplicitFunctionParams.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class ImplicitFunctionParams(g: Global) extends AnalyzerRule(g, "implicitFunctio
1313
if (paramList.nonEmpty && paramList.head.mods.hasFlag(Flag.IMPLICIT)) {
1414
paramList.foreach { param =>
1515
val paramTpe = param.tpt.tpe
16-
if (paramTpe != null && (definitions.isFunctionProto(paramTpe) || definitions.isPartialFunctionType(paramTpe))) {
16+
if (paramTpe != null && (definitions.isFunctionType(paramTpe) || definitions.isPartialFunctionType(paramTpe))) {
1717
report(param.pos, "Implicit parameters should not have any function type")
1818
}
1919
}

analyzer/src/test/scala/com/avsystem/commons/analyzer/ImplicitFunctionParamsTest.scala

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,85 @@ class ImplicitFunctionParamsTest extends AnyFunSuite with AnalyzerTest {
5353
|}
5454
""".stripMargin)
5555
}
56-
}
56+
57+
test("implicit parameters with SAM types should pass") {
58+
assertCompiles(
59+
//language=Scala
60+
"""
61+
|object whatever {
62+
| // Define a SAM type (Single Abstract Method)
63+
| trait IntToString {
64+
| def apply(i: Int): String
65+
| }
66+
|
67+
| // This should pass - regular parameter with SAM type
68+
| def goodMethod1(f: IntToString): Unit = ???
69+
|
70+
| // This should pass - implicit parameter with SAM type
71+
| def goodMethod2(implicit f: IntToString): Unit = ???
72+
|
73+
| // This should pass - implicit parameter with SAM type in second parameter list
74+
| def goodMethod3(x: Int)(implicit f: IntToString): Unit = ???
75+
|
76+
| // This should pass - regular class parameter with SAM type
77+
| class GoodClass1(f: IntToString)
78+
|
79+
| // This should pass - implicit class parameter with SAM type
80+
| class GoodClass2(implicit f: IntToString)
81+
|
82+
| // This should pass - implicit class parameter with SAM type in second parameter list
83+
| class GoodClass3(x: Int)(implicit f: IntToString)
84+
|}
85+
""".stripMargin)
86+
}
87+
88+
test("implicit parameters should not be function types with multiple parameters") {
89+
assertErrors(8,
90+
//language=Scala
91+
"""
92+
|object whatever {
93+
| // This should pass - regular parameter with Function2 type
94+
| def goodMethod1(f: (Int, String) => Boolean): Unit = ???
95+
|
96+
| // This should pass - regular parameter with Function3 type
97+
| def goodMethod2(f: (Int, String, Double) => Boolean): Unit = ???
98+
|
99+
| // This should pass - implicit parameter with non-function type
100+
| def goodMethod3(implicit s: String): Unit = ???
101+
|
102+
| // This should fail - implicit parameter with Function2 type
103+
| def badMethod1(implicit f: (Int, String) => Boolean): Unit = ???
104+
|
105+
| // This should fail - implicit parameter with Function2 type in second parameter list
106+
| def badMethod2(x: Int)(implicit f: (Int, String) => Boolean): Unit = ???
107+
|
108+
| // This should fail - implicit parameter with Function3 type
109+
| def badMethod3(implicit f: (Int, String, Double) => Boolean): Unit = ???
110+
|
111+
| // This should fail - implicit parameter with Function3 type in second parameter list
112+
| def badMethod4(x: Int)(implicit f: (Int, String, Double) => Boolean): Unit = ???
113+
|
114+
| // This should pass - regular class parameter with Function2 type
115+
| class GoodClass1(f: (Int, String) => Boolean)
116+
|
117+
| // This should pass - regular class parameter with Function3 type
118+
| class GoodClass2(f: (Int, String, Double) => Boolean)
119+
|
120+
| // This should pass - implicit class parameter with non-function type
121+
| class GoodClass3(implicit s: String)
122+
|
123+
| // This should fail - implicit class parameter with Function2 type
124+
| class BadClass1(implicit f: (Int, String) => Boolean)
125+
|
126+
| // This should fail - implicit class parameter with Function2 type in second parameter list
127+
| class BadClass2(x: Int)(implicit f: (Int, String) => Boolean)
128+
|
129+
| // This should fail - implicit class parameter with Function3 type
130+
| class BadClass3(implicit f: (Int, String, Double) => Boolean)
131+
|
132+
| // This should fail - implicit class parameter with Function3 type in second parameter list
133+
| class BadClass4(x: Int)(implicit f: (Int, String, Double) => Boolean)
134+
|}
135+
""".stripMargin)
136+
}
137+
}

0 commit comments

Comments
 (0)