From 26d6203d1b7ba3262177f2fc282645f9ce88f62c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 11 Nov 2020 11:14:44 +0100 Subject: [PATCH 1/2] Fix #10116: Fix adaptConstant to that it survives Ycheck --- .../src/dotty/tools/dotc/typer/Typer.scala | 2 +- tests/pos/i10116.scala | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i10116.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 3f8759028542..71dad7958032 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -3425,7 +3425,7 @@ class Typer extends Namer // try converting a constant to the target type val folded = ConstFold(tree, pt) if (folded ne tree) - return adaptConstant(folded, folded.tpe.asInstanceOf[ConstantType]) + return adaptConstant(tree, folded.tpe.asInstanceOf[ConstantType]) val captured = captureWildcards(wtp) if (captured `ne` wtp) diff --git a/tests/pos/i10116.scala b/tests/pos/i10116.scala new file mode 100644 index 000000000000..f6764b8c6433 --- /dev/null +++ b/tests/pos/i10116.scala @@ -0,0 +1,18 @@ +object OverloadedWithLong { + def overloaded(x: Long): Any = + x + + def overloaded(x: Any): Unit = + ??? +} + +object Test { + def main(args: Array[String]): Unit = + import OverloadedWithLong._ + + val l: Any = 0 :: Nil + val r = overloaded(l match { + case x :: xs => 5 + }) + assert(r == 5L) +} \ No newline at end of file From 2be0ecaf5496918ba9813c82b312729e644e5a23 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 11 Nov 2020 13:27:49 +0100 Subject: [PATCH 2/2] Address review comments --- compiler/src/dotty/tools/dotc/typer/ConstFold.scala | 9 --------- compiler/src/dotty/tools/dotc/typer/Typer.scala | 9 ++++++--- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/ConstFold.scala b/compiler/src/dotty/tools/dotc/typer/ConstFold.scala index 954935c0a74e..958aba7eaf9b 100644 --- a/compiler/src/dotty/tools/dotc/typer/ConstFold.scala +++ b/compiler/src/dotty/tools/dotc/typer/ConstFold.scala @@ -59,15 +59,6 @@ object ConstFold: tree.withFoldedType(Constant(targ.tpe)) case _ => tree - /** If tree is a constant value that can be converted to type `pt`, perform - * the conversion. - */ - def apply[T <: Tree](tree: T, pt: Type)(using Context): T = - val tree1 = apply(tree) - tree.tpe.widenTermRefExpr.normalized match - case ConstantType(x) => tree1.withFoldedType(x.convertTo(pt)) - case _ => tree1 - extension [T <: Tree](tree: T)(using Context) private def withFoldedType(c: Constant | Null): T = if c == null then tree else tree.withType(ConstantType(c)).asInstanceOf[T] diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 71dad7958032..75c5dd1dbb70 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -3423,9 +3423,12 @@ class Typer extends Namer def adaptToSubType(wtp: Type): Tree = { // try converting a constant to the target type - val folded = ConstFold(tree, pt) - if (folded ne tree) - return adaptConstant(tree, folded.tpe.asInstanceOf[ConstantType]) + ConstFold(tree).tpe.widenTermRefExpr.normalized match + case ConstantType(x) => + val converted = x.convertTo(pt) + if converted != null && (converted ne x) then + return adaptConstant(tree, ConstantType(converted)) + case _ => val captured = captureWildcards(wtp) if (captured `ne` wtp)