diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2016-03-23 10:52:57 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2016-03-26 22:55:10 -0700 |
commit | 608ac2c2b9e3f6f46489e20830d8949ee7d506cf (patch) | |
tree | 8d995139a8a66f56fed90bf65f7ece5bf26d55d7 /src/reflect/scala/reflect/internal/Definitions.scala | |
parent | 878e20a5243383300d3b4990146d260409bf5dfd (diff) | |
download | scala-608ac2c2b9e3f6f46489e20830d8949ee7d506cf.tar.gz scala-608ac2c2b9e3f6f46489e20830d8949ee7d506cf.tar.bz2 scala-608ac2c2b9e3f6f46489e20830d8949ee7d506cf.zip |
Soften sam restrictions
Some of the earlier proposals were too strongly linked to the
requirements of the Java 8 platform, which was problematic for
scala.js & friends.
Instead of ruling out SAM types that we can't compile to use
LambdaMetaFactory, expand those during compilation to anonymous
subclasses, instead of invokedynamic + LMF.
Also, self types rear their ugly heads again. Align `hasSelfType`
with the implementation suggested in `thisSym`'s docs.
Diffstat (limited to 'src/reflect/scala/reflect/internal/Definitions.scala')
-rw-r--r-- | src/reflect/scala/reflect/internal/Definitions.scala | 24 |
1 files changed, 9 insertions, 15 deletions
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index ef9a76f9c4..81071e763d 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -848,21 +848,15 @@ trait Definitions extends api.StandardDefinitions { // (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 && tpSym.isClass + // if tp has a constructor (its class is not a trait), it must be public and must not take any arguments + // (implementation restriction: implicit argument lists are excluded to simplify type inference in adaptToSAM) + && { val ctor = tpSym.primaryConstructor + !ctor.exists || (!ctor.isOverloaded && ctor.isPublic && ctor.info.params.isEmpty && ctor.info.paramSectionCount <= 1)} + // we won't be able to create an instance of tp if it doesn't correspond to its self type + // (checking conformance gets complicated when tp is not fully defined, so let's just rule out self types entirely) + && !tpSym.hasSelfType + ) { // 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: |