From 20896646122fa82dc81f1405173b09eac37ae7cc Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Tue, 4 Oct 2016 12:48:30 -0500 Subject: SI-9943 final/sealed class does not yield SAM type Cannot subclass such a class. (Well, we could subclass a sealed class in the same compilation unit. We ignore this for simplicity.) This is a bit of a sneaky fix for this bug, but our hand is pretty much forced by other constraints, in this intersection of overload resolution involving built-in function types and SAMs, and type inference for higher-order function literals (#5307). Luckily, in this particular issue, the overloading clash seems accidental. The `sealed` `<:<` class is not a SAM type as it cannot be subclassed outside of `Predef`. For simplicity, we don't consider where the SAM conversion occurs and exclude all sealed classes from yielding SAM types. Thanks to Miles for pointing out that `final` was missing in my first iteration of this fix. --- src/reflect/scala/reflect/internal/Definitions.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 0f7cf07f08..fc7e184918 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -840,14 +840,14 @@ trait Definitions extends api.StandardDefinitions { * * The method must be monomorphic and have exactly one parameter list. * The class defining the method is a supertype of `tp` that - * has a public no-arg primary constructor. + * has a public no-arg primary constructor and it can be subclassed (not final or sealed). */ def samOf(tp: Type): Symbol = if (!doSam) NoSymbol else if (!isNonRefinementClassType(unwrapToClass(tp))) NoSymbol else { // look at erased type because we (only) care about what ends up in bytecode // (e.g., an alias type is fine as long as is compiles to a single-abstract-method) val tpSym: Symbol = erasure.javaErasure(tp).typeSymbol - if (tpSym.exists && tpSym.isClass + if (tpSym.exists && tpSym.isClass && !(tpSym hasFlag (FINAL | SEALED)) // 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 -- cgit v1.2.3