From 6a8c29a78e9eaeb9176fce75549133389324c443 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Tue, 9 Jan 2018 17:47:11 +0100 Subject: [PATCH] Fix #3782: Fix type parameter inference with scala.Singleton The fix in ec539184f388649163013ef62d4ec49835933fcc was incomplete: we need to check if the upper bound is a subtype and not just a reference to scala.Singleton --- compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala | 4 ++-- compiler/src/dotty/tools/dotc/core/Definitions.scala | 1 + tests/pos/singletontrait.scala | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala index fba306b49fe0..3d3a6f36ef51 100644 --- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -272,10 +272,10 @@ trait ConstraintHandling { // Then, approximate by (1.) - (3.) and simplify as follows. // 1. If instance is from below and is a singleton type, yet upper bound is - // not a singleton type or a reference to `scala.Singleton`, widen the + // not a singleton type or a subtype of `scala.Singleton`, widen the // instance. if (fromBelow && isMultiSingleton(inst) && !isMultiSingleton(upperBound) - && !upperBound.isRef(defn.SingletonClass)) + && !isSubTypeWhenFrozen(upperBound, defn.SingletonType)) inst = inst.widen // 2. If instance is from below and is a fully-defined union type, yet upper bound diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 84c89f727255..c792e1466d9b 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -384,6 +384,7 @@ class Definitions { enterCompleteClassSymbol( ScalaPackageClass, tpnme.Singleton, PureInterfaceCreationFlags | Final, List(AnyClass.typeRef), EmptyScope) + lazy val SingletonType: TypeRef = SingletonClass.typeRef lazy val SeqType: TypeRef = ctx.requiredClassRef("scala.collection.Seq") def SeqClass(implicit ctx: Context) = SeqType.symbol.asClass diff --git a/tests/pos/singletontrait.scala b/tests/pos/singletontrait.scala index 6b282a610cee..90da9c50a82a 100644 --- a/tests/pos/singletontrait.scala +++ b/tests/pos/singletontrait.scala @@ -1,5 +1,7 @@ object Test { def foo[T <: Singleton](x: T): T = x + def bar[T <: Int with Singleton](x: T): T = x val a: 1 = foo(1) + val b: 1 = bar(1) }