diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2016-07-14 11:50:22 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2016-07-14 12:04:21 +1000 |
commit | f806073d32a476d156f1b3ec24c17f35ed65b4c3 (patch) | |
tree | 2a1389a194bdcc7153eae8c0bb0dd1951721b3e4 /test | |
parent | 4e564efb04e508ccc0f479cf1a25331501927d88 (diff) | |
download | scala-f806073d32a476d156f1b3ec24c17f35ed65b4c3.tar.gz scala-f806073d32a476d156f1b3ec24c17f35ed65b4c3.tar.bz2 scala-f806073d32a476d156f1b3ec24c17f35ed65b4c3.zip |
SD-183 Make refinement classes ineligible as SAMs
Only non-refinement class types need apply, which is the same
restriction that we levy on parent types of a class.
```
scala> class C; class D extends C; type CD = C with D; class E extends CD
<console>:11: error: class type required but C with D found
class C; class D extends C; type CD = C with D; class E extends CD
^
scala> class C; class D extends C; type DC = D with C; class E extends DC
<console>:11: error: class type required but D with C found
class C; class D extends C; type DC = D with C; class E extends DC
^
```
Prior to this change:
```
scala> trait T { def t(a: Any): Any }; trait U; abstract class C extends T
defined trait T
defined trait U
defined class C
````
For indy-based lambdas:
```
scala> val tu: T with U = x => x
tu: T with U = $$Lambda$1812/317644782@3c3c4a71
scala> tu: U
java.lang.ClassCastException: $$Lambda$1812/317644782 cannot be cast to U
... 30 elided
```
For anon class based lambdas:
```
scala> ((x => x): C with U)
<console>:14: error: class type required but C with U found
((x => x): C with U)
^
scala> implicit def anyToCWithU(a: Any): C with U = new C with U { def t(a: Any) = a }
warning: there was one feature warning; re-run with -feature for details
anyToCWithU: (a: Any)C with U
scala> (((x: Any) => x): C with U) // SAM chosen but fails to typecheck the expansion uncurry
<console>:17: error: class type required but C with U found
(((x: Any) => x): C with U) // SAM chosen but fails to typecheck the expansion uncurry
^
```
Fixes https://github.com/scala/scala-dev/issues/183
While it is tempting to special case refinement classes with no decls by
flattening their parents into the parents of the lambda. But there are
some subtle issues at play with lineriazation order, as Martin pointed out
when I brought this up before: http://www.scala-lang.org/old/node/6817.html
Diffstat (limited to 'test')
-rw-r--r-- | test/files/neg/sammy_restrictions.check | 33 | ||||
-rw-r--r-- | test/files/neg/sammy_restrictions.scala | 7 |
2 files changed, 28 insertions, 12 deletions
diff --git a/test/files/neg/sammy_restrictions.check b/test/files/neg/sammy_restrictions.check index 09579cbe21..0225c61ac1 100644 --- a/test/files/neg/sammy_restrictions.check +++ b/test/files/neg/sammy_restrictions.check @@ -1,51 +1,62 @@ -sammy_restrictions.scala:35: error: type mismatch; +sammy_restrictions.scala:38: error: type mismatch; found : () => Int required: NoAbstract (() => 0) : NoAbstract ^ -sammy_restrictions.scala:36: error: type mismatch; +sammy_restrictions.scala:39: error: type mismatch; found : Int => Int required: TwoAbstract ((x: Int) => 0): TwoAbstract ^ -sammy_restrictions.scala:37: error: type mismatch; +sammy_restrictions.scala:40: error: type mismatch; found : Int => Int required: NoEmptyConstructor ((x: Int) => 0): NoEmptyConstructor ^ -sammy_restrictions.scala:38: error: type mismatch; +sammy_restrictions.scala:41: error: type mismatch; found : Int => Int required: MultipleConstructorLists ((x: Int) => 0): MultipleConstructorLists ^ -sammy_restrictions.scala:39: error: type mismatch; +sammy_restrictions.scala:42: error: type mismatch; found : Int => Int required: OneEmptySecondaryConstructor ((x: Int) => 0): OneEmptySecondaryConstructor // derived class must have an empty *primary* to call. ^ -sammy_restrictions.scala:40: error: type mismatch; +sammy_restrictions.scala:43: error: type mismatch; found : Int => Int required: MultipleMethodLists ((x: Int) => 0): MultipleMethodLists ^ -sammy_restrictions.scala:41: error: type mismatch; +sammy_restrictions.scala:44: error: type mismatch; found : Int => Int required: ImplicitConstructorParam ((x: Int) => 0): ImplicitConstructorParam ^ -sammy_restrictions.scala:42: error: type mismatch; +sammy_restrictions.scala:45: error: type mismatch; found : Int => Int required: ImplicitMethodParam ((x: Int) => 0): ImplicitMethodParam ^ -sammy_restrictions.scala:43: error: type mismatch; +sammy_restrictions.scala:46: error: type mismatch; found : Int => Int required: PolyMethod ((x: Int) => 0): PolyMethod ^ -sammy_restrictions.scala:44: error: type mismatch; +sammy_restrictions.scala:47: error: type mismatch; found : Int => Int required: SelfTp ((x: Int) => 0): SelfTp ^ -10 errors found +sammy_restrictions.scala:48: error: type mismatch; + found : Int => Int + required: T1 with U1 + ((x: Int) => 0): T1 with U1 + ^ +sammy_restrictions.scala:49: error: type mismatch; + found : Int => Int + required: Test.NonClassTypeRefinement + (which expands to) DerivedOneAbstract with OneAbstract + ((x: Int) => 0): NonClassTypeRefinement + ^ +12 errors found diff --git a/test/files/neg/sammy_restrictions.scala b/test/files/neg/sammy_restrictions.scala index ff2c16b679..dee4f1f247 100644 --- a/test/files/neg/sammy_restrictions.scala +++ b/test/files/neg/sammy_restrictions.scala @@ -27,9 +27,12 @@ abstract class DerivedOneAbstract extends OneAbstract abstract class SelfTp { self: NoAbstract => def ap(a: Int): Any } abstract class SelfVar { self => def ap(a: Int): Any } +trait T1 { def t(a: Int): Int }; trait U1 + object Test { implicit val s: String = "" - type NonClassType = DerivedOneAbstract with OneAbstract + type NonClassTypeRefinement = DerivedOneAbstract with OneAbstract + type NonClassType = DerivedOneAbstract // errors: (() => 0) : NoAbstract @@ -42,6 +45,8 @@ object Test { ((x: Int) => 0): ImplicitMethodParam ((x: Int) => 0): PolyMethod ((x: Int) => 0): SelfTp + ((x: Int) => 0): T1 with U1 + ((x: Int) => 0): NonClassTypeRefinement // allowed: ((x: Int) => 0): OneEmptyConstructor |