From 342ebf38f455fb23c71b447434a6d625240af12f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 20 Dec 2022 16:06:59 +0000 Subject: [PATCH] Tweak AvoidMap's derivedSelect Using the example from `pos/i16435.avoid`: class Foo: type Value def test: Option[Value] = val scr = { val self: Foo.this.type = this None: Option[self.Value] } scr We want avoidance to return `Option[Value]`, aka `Option[Foo.this.Value]`, rather than widening to `Option[Any]`. Using test cases i16105,i16435,i2945,i8900,i8861 we don't tryWiden if the derived prefix is a singleton. And fix some kind of race condition in creating files/directories. --- compiler/src/dotty/tools/dotc/core/TypeOps.scala | 2 +- compiler/src/dotty/tools/io/AbstractFile.scala | 6 ++++-- tests/pos/i16435.TreeUnpickler.scala | 13 +++++++++++++ tests/pos/i16435.avoid.scala | 8 ++++++++ tests/pos/i16435.scala | 11 +++++++++++ 5 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 tests/pos/i16435.TreeUnpickler.scala create mode 100644 tests/pos/i16435.avoid.scala create mode 100644 tests/pos/i16435.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index ffcdcbe9e869..65143b3bdb75 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -504,7 +504,7 @@ object TypeOps: override def derivedSelect(tp: NamedType, pre: Type) = if (pre eq tp.prefix) tp - else tryWiden(tp, tp.prefix).orElse { + else (if pre.isSingleton then NoType else tryWiden(tp, tp.prefix)).orElse { if (tp.isTerm && variance > 0 && !pre.isSingleton) apply(tp.info.widenExpr) else if (upper(pre).member(tp.name).exists) diff --git a/compiler/src/dotty/tools/io/AbstractFile.scala b/compiler/src/dotty/tools/io/AbstractFile.scala index 29bc764dcd7b..f34fe6f40b9c 100644 --- a/compiler/src/dotty/tools/io/AbstractFile.scala +++ b/compiler/src/dotty/tools/io/AbstractFile.scala @@ -260,8 +260,10 @@ abstract class AbstractFile extends Iterable[AbstractFile] { // a race condition in creating the entry after the failed lookup may throw val path = jpath.resolve(name) - if (isDir) Files.createDirectory(path) - else Files.createFile(path) + try + if (isDir) Files.createDirectory(path) + else Files.createFile(path) + catch case _: FileAlreadyExistsException => () new PlainFile(new File(path)) case lookup => lookup } diff --git a/tests/pos/i16435.TreeUnpickler.scala b/tests/pos/i16435.TreeUnpickler.scala new file mode 100644 index 000000000000..b6b5d54f775e --- /dev/null +++ b/tests/pos/i16435.TreeUnpickler.scala @@ -0,0 +1,13 @@ +// Derived from the CI failure in compiling TreeUnpickler.scala +class Foo +class Bar extends Foo: + type Self >: this.type <: Bar + final def meth(): Self = this + +class Test: + def test(cond: Boolean, bar: Bar): Foo = + val res = bar + if cond then + res.meth() + else + res diff --git a/tests/pos/i16435.avoid.scala b/tests/pos/i16435.avoid.scala new file mode 100644 index 000000000000..6fca050bd40b --- /dev/null +++ b/tests/pos/i16435.avoid.scala @@ -0,0 +1,8 @@ +class Foo: + type Value + def test: Option[Value] = + val scr = { + val self: Foo.this.type = this + None: Option[self.Value] + } + scr diff --git a/tests/pos/i16435.scala b/tests/pos/i16435.scala new file mode 100644 index 000000000000..3fb36efc55c9 --- /dev/null +++ b/tests/pos/i16435.scala @@ -0,0 +1,11 @@ +// scalac: -Werror +trait Base: + type Value + inline def oov: Option[Option[Value]] = None + def get: Option[Value] + +trait X extends Base: + override def get: Option[Value] = + oov match // was: match may not be exhaustive + case Some(ov) => ov + case None => None