File tree 4 files changed +96
-2
lines changed
compiler/src/dotty/tools/dotc/core
4 files changed +96
-2
lines changed Original file line number Diff line number Diff line change @@ -3868,7 +3868,7 @@ object Types {
3868
3868
* A type is a SAM type if it is a reference to a class or trait, which
3869
3869
*
3870
3870
* - has a single abstract method with a method type (ExprType
3871
- * and PolyType not allowed!)
3871
+ * and PolyType not allowed!) whose result type is not an implicit function type
3872
3872
* - can be instantiated without arguments or with just () as argument.
3873
3873
*
3874
3874
* The pattern `SAMType(sam)` matches a SAM type, where `sam` is the
@@ -3910,7 +3910,8 @@ object Types {
3910
3910
// println(s"absMems: ${absMems map (_.show) mkString ", "}")
3911
3911
if (absMems.size == 1 )
3912
3912
absMems.head.info match {
3913
- case mt : MethodType if ! mt.isParamDependent =>
3913
+ case mt : MethodType if ! mt.isParamDependent &&
3914
+ ! defn.isImplicitFunctionType(mt.resultType) =>
3914
3915
val cls = tp.classSymbol
3915
3916
3916
3917
// 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
+ trait Bar [T ] {
7
+ def bar (x : Int ): T
8
+ }
9
+
10
+ class Test {
11
+ val good1 = new Foo {
12
+ def foo (x : Int ) = 1
13
+ }
14
+
15
+ val good2 = new Bar [implicit Int => Int ] {
16
+ def bar (x : Int ) = 1
17
+ }
18
+
19
+ val bad1 : Foo = (x : Int ) => 1 // error
20
+ val bad2 : Bar [implicit Int => Int ] = (x : Int ) => 1 // error
21
+ }
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