From ebc316272deb2e2c3cd00659af453d5ac6a9a6ee Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 8 Mar 2017 14:01:29 +0100 Subject: Fix #2064: Avoid illegal types in OrDominator Need to skip type bounds in `underlying` chain, since TypeBounds is not a legal operand type for OrType. --- compiler/src/dotty/tools/dotc/core/TypeOps.scala | 2 +- tests/pos/i2064.scala | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i2064.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index 6c40794e3..6e9e1f2e5 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -239,7 +239,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object. case tp1: RecType => tp1.rebind(approximateOr(tp1.parent, tp2)) case tp1: TypeProxy if !isClassRef(tp1) => - orDominator(tp1.superType | tp2) + orDominator(tp1.superType.bounds.hi | tp2) case _ => tp2 match { case tp2: RecType => diff --git a/tests/pos/i2064.scala b/tests/pos/i2064.scala new file mode 100644 index 000000000..909923372 --- /dev/null +++ b/tests/pos/i2064.scala @@ -0,0 +1,15 @@ +object p { + +class Foo[T] { + // Crashes: + def f(): Foo[T] = (if (true) this else this).bar + + // Works: + // def f(): Foo[T] = new Bar(if (true) this else this).bar +} + +implicit class Bar[A](val self: A) { + def bar(): A = self +} + +} -- cgit v1.2.3 From c6685d520df9cd428019f741f2eeb153af02ac2b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 8 Mar 2017 17:11:54 +0100 Subject: Better fix `superType` should never return a `TypeBounds` in the first place. This commit makes sure it doesn't. --- compiler/src/dotty/tools/dotc/core/TypeOps.scala | 2 +- compiler/src/dotty/tools/dotc/core/Types.scala | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index 6e9e1f2e5..6c40794e3 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -239,7 +239,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object. case tp1: RecType => tp1.rebind(approximateOr(tp1.parent, tp2)) case tp1: TypeProxy if !isClassRef(tp1) => - orDominator(tp1.superType.bounds.hi | tp2) + orDominator(tp1.superType | tp2) case _ => tp2 match { case tp2: RecType => diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 9dd767a8e..6aa77de52 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1276,7 +1276,10 @@ object Types { * except for TypeRefs where the upper bound is returned, and HKApplys, * where the upper bound of the constructor is re-applied to the arguments. */ - def superType(implicit ctx: Context): Type = underlying + def superType(implicit ctx: Context): Type = underlying match { + case TypeBounds(_, hi) => hi + case st => st + } } // Every type has to inherit one of the following four abstract type classes., @@ -1762,11 +1765,6 @@ object Types { type ThisType = TypeRef override def underlying(implicit ctx: Context): Type = info - - override def superType(implicit ctx: Context): Type = info match { - case TypeBounds(_, hi) => hi - case _ => info - } } final class TermRefWithSignature(prefix: Type, name: TermName, override val sig: Signature) extends TermRef(prefix, name) { -- cgit v1.2.3 From 57e449ed18bc4643871e5e84ddf2c9d334d12acb Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 8 Mar 2017 17:29:35 +0100 Subject: Fix comment --- compiler/src/dotty/tools/dotc/core/Types.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 6aa77de52..070a6ea83 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1273,8 +1273,9 @@ object Types { def underlying(implicit ctx: Context): Type /** The closest supertype of this type. This is the same as `underlying`, - * except for TypeRefs where the upper bound is returned, and HKApplys, - * where the upper bound of the constructor is re-applied to the arguments. + * except that + * - instead of a TyperBounds type it returns its upper bound, and + * - for HKApplys it returns the upper bound of the constructor re-applied to the arguments. */ def superType(implicit ctx: Context): Type = underlying match { case TypeBounds(_, hi) => hi -- cgit v1.2.3