File tree 4 files changed +87
-2
lines changed
compiler/src/dotty/tools/dotc/core 4 files changed +87
-2
lines changed Original file line number Diff line number Diff line change @@ -3835,7 +3835,7 @@ object Types {
3835
3835
* A type is a SAM type if it is a reference to a class or trait, which
3836
3836
*
3837
3837
* - has a single abstract method with a method type (ExprType
3838
- * and PolyType not allowed!)
3838
+ * and PolyType not allowed!) which result type is not an implicit function type
3839
3839
* - can be instantiated without arguments or with just () as argument.
3840
3840
*
3841
3841
* The pattern `SAMType(sam)` matches a SAM type, where `sam` is the
@@ -3877,7 +3877,8 @@ object Types {
3877
3877
// println(s"absMems: ${absMems map (_.show) mkString ", "}")
3878
3878
if (absMems.size == 1 )
3879
3879
absMems.head.info match {
3880
- case mt : MethodType if ! mt.isParamDependent =>
3880
+ case mt : MethodType if ! mt.isParamDependent &&
3881
+ ! defn.isImplicitFunctionType(mt.resultType) =>
3881
3882
val cls = tp.classSymbol
3882
3883
3883
3884
// Given a SAM type such as:
Original file line number Diff line number Diff line change
1
+ // Don't qualify as SAM type because result type is an implicit function type
2
+ trait Foo {
3
+ def foo (x : Int ): implicit Int => Int
4
+ }
5
+
6
+ class Test {
7
+ val good = new Foo {
8
+ def foo (x : Int ) = 1
9
+ }
10
+
11
+ val bad : Foo = (x : Int ) => 1 // error
12
+ }
Original file line number Diff line number Diff line change
1
+ import scala .concurrent .Future
2
+
3
+ class Response
4
+ class Request
5
+ object Request {
6
+ type To [T ] = implicit Request => T
7
+ }
8
+
9
+ // Don't qualify as SAM type because result type is an implicit function type
10
+ trait Responder [T ] {
11
+ def responseFor (value : T ): Request .To [Future [Response ]]
12
+ }
13
+
14
+ object Responder {
15
+ // with SAM
16
+ val responseResponder : Responder [Response ] =
17
+ response => Future .successful(response) // error
18
+
19
+ // with anonymous class
20
+ val futureResponseResponder : Responder [Future [Response ]] = new Responder [Future [Response ]] {
21
+ override def responseFor (value : Future [Response ]): Request .To [Future [Response ]] =
22
+ value
23
+ }
24
+ }
Original file line number Diff line number Diff line change
1
+ class A
2
+ class B
3
+
4
+ trait Foo {
5
+ def foo : implicit A => implicit B => Int
6
+ }
7
+
8
+ class Foo1 extends Foo {
9
+ def foo : implicit A => implicit B => Int = 1
10
+ }
11
+
12
+ class Foo2 extends Foo1 {
13
+ override def foo : implicit A => implicit B => Int = 2
14
+ }
15
+
16
+ trait Foo3 extends Foo {
17
+ override def foo : implicit A => implicit B => Int = 3
18
+ }
19
+
20
+ class Bar [T ] {
21
+ def bar : implicit A => T = null .asInstanceOf [T ]
22
+ }
23
+
24
+ class Bar1 extends Bar [implicit B => Int ] {
25
+ override def bar : implicit A => implicit B => Int = 1
26
+ }
27
+
28
+ object Test {
29
+ def testFoo () = {
30
+ implicit val a = new A
31
+ implicit val b = new B
32
+ assert((new Foo1 ).foo == 1 )
33
+ assert((new Foo2 ).foo == 2 )
34
+ assert(new Foo3 {}.foo == 3 )
35
+ }
36
+
37
+ def testBar () = {
38
+ implicit val a = new A
39
+ implicit val b = new B
40
+ assert((new Bar ).bar == null )
41
+ assert((new Bar1 ).bar == 1 )
42
+ }
43
+
44
+ def main (args : Array [String ]): Unit = {
45
+ testFoo()
46
+ testBar()
47
+ }
48
+ }
You can’t perform that action at this time.
0 commit comments