summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 2fa39bc453..ef9a76f9c4 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -844,13 +844,26 @@ trait Definitions extends api.StandardDefinitions {
* has a public no-arg primary constructor.
*/
def samOf(tp: Type): Symbol = {
- // if tp has a constructor, it must be public and must not take any arguments
- // (not even an implicit argument list -- to keep it simple for now)
- val tpSym = tp.typeSymbol
- val ctor = tpSym.primaryConstructor
- val ctorOk = !ctor.exists || (!ctor.isOverloaded && ctor.isPublic && ctor.info.params.isEmpty && ctor.info.paramSectionCount <= 1)
+ // look at erased type because we (only) care about what ends up in bytecode
+ // (e.g., an alias type or intersection type is fine as long as the intersection dominator compiles to an interface)
+ val tpSym = erasure.javaErasure(tp).typeSymbol
+
+ if (tpSym.exists
+ // We use Java's MetaLambdaFactory, which requires an interface for the sam's owner
+ // (TODO: Can't use isInterface, yet, as it hasn't been updated for the new trait encoding)
+ && (tpSym.isJavaInterface || tpSym.isTrait)
+ // explicit outer precludes no-arg ctor
+ && tpSym.isStatic
+ // impl restriction -- we currently use the boxed apply, so not really useful to allow specialized sam types (https://github.com/scala/scala/pull/4971#issuecomment-198119167)
+ && !tpSym.isSpecialized) {
+
+ // this does not apply yet, since traits don't have constructors during type checking
+ // if tp has a constructor, it must be public and must not take any arguments
+ // (not even an implicit argument list -- to keep it simple for now)
+ // && { val ctor = tpSym.primaryConstructor
+ // !ctor.exists || (!ctor.isOverloaded && ctor.isPublic && ctor.info.params.isEmpty && ctor.info.paramSectionCount <= 1)
+ // }
- if (tpSym.exists && ctorOk) {
// find the single abstract member, if there is one
// don't go out requiring DEFERRED members, as you will get them even if there's a concrete override:
// scala> abstract class X { def m: Int }