diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala index 9156b6c1971b..e033d7f44b8c 100644 --- a/compiler/src/dotty/tools/dotc/core/Denotations.scala +++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala @@ -653,15 +653,18 @@ object Denotations { case ExprType(rtp1) => tp2 match { case ExprType(rtp2) => ExprType(rtp1 & rtp2) - case _ => rtp1 & tp2 + case _ => infoMeet(rtp1, tp2, sym1, sym2, safeIntersection) } case _ => - try tp1 & tp2.widenExpr - catch { - case ex: Throwable => - println(i"error for meet: $tp1 &&& $tp2, ${tp1.getClass}, ${tp2.getClass}") - throw ex - } + tp2 match + case _: MethodType | _: PolyType => + mergeConflict(sym1, sym2, tp1, tp2) + case _ => + try tp1 & tp2.widenExpr + catch + case ex: Throwable => + println(i"error for meet: $tp1 &&& $tp2, ${tp1.getClass}, ${tp2.getClass}") + throw ex } /** Normally, `tp1 | tp2`. diff --git a/tests/neg/i7425.scala b/tests/neg/i7425.scala new file mode 100644 index 000000000000..dae559b48f24 --- /dev/null +++ b/tests/neg/i7425.scala @@ -0,0 +1,12 @@ +class C { def f: Int = 0 } + +trait D { def f(): Int = 0 } + +def foo1(x: C & D) = x.f // error: method f must be called with () argument +def foo2(x: C | D) = x.f // error: value f is not a member of C | D +def foo3(x: D & C) = x.f // ok +def foo4(x: D | C) = x.f // error: value f is not a member of D | C +def foo5(x: C & D) = x.f() // ok +def foo6(x: C | D) = x.f() // error: value f is not a member of C | D +def foo7(x: D & C) = x.f() // error: method f in class C does not take parameters +def foo8(x: D | C) = x.f() // error: value f is not a member of D | C diff --git a/tests/pos/i7175.scala b/tests/pos/i7175.scala new file mode 100644 index 000000000000..859acfa43300 --- /dev/null +++ b/tests/pos/i7175.scala @@ -0,0 +1,59 @@ +object foo { + def main(args: Array[String]): Unit = println("Dotty") + + import java.net.URL + import java.util.List + + trait ConfigOrigin { + def description: String + def filename: String + def url: URL + def resource: String + def lineNumber: Int + def comments: List[String] + def withComments(comments: List[String]): ConfigOrigin + def withLineNumber(lineNumber: Int): ConfigOrigin + } + + + trait ConfigValue extends ConfigMergeable { + def origin: ConfigOrigin + //def valueType: ConfigValueType + def unwrapped: AnyRef + def render: String + //def render(options: ConfigRenderOptions): String + override def withFallback(other: ConfigMergeable): ConfigValue + //def atPath(path: String): Config + //def atKey(key: String): Config + def withOrigin(origin: ConfigOrigin): ConfigValue + } + + + trait ConfigMergeable { + def withFallback(other: ConfigMergeable): ConfigMergeable + } + + trait MergeableValue extends ConfigMergeable { + def toFallbackValue(): ConfigValue + } + + // no impl + final class SimpleConfigOrigin extends ConfigOrigin { + def comments: java.util.List[String] = ??? + def description: String = ??? + def filename: String = ??? + def lineNumber: Int = ??? + def resource: String = ??? + def url: java.net.URL = ??? + def withComments(comments: java.util.List[String]): foo.ConfigOrigin = ??? + def withLineNumber(lineNumber: Int): foo.ConfigOrigin = ??? + } + + abstract class AbstractConfigValue (val _origin: ConfigOrigin) + extends ConfigValue + with MergeableValue { + + override def origin: SimpleConfigOrigin = + this._origin.asInstanceOf[SimpleConfigOrigin] + } +} \ No newline at end of file