From e0edb2f9dc478b4a492a84ea900e813266798cf5 Mon Sep 17 00:00:00 2001 From: Matt Bovel Date: Mon, 4 Nov 2024 14:48:28 +0100 Subject: [PATCH] Use previous type of Apply.fun when copying if none available --- compiler/src/dotty/tools/dotc/ast/tpd.scala | 6 +++++ tests/pos/dependent-annot-2.scala | 30 +++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/pos/dependent-annot-2.scala diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index f97baa7f7889..0d193db2f21b 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -661,6 +661,12 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { case tree: Apply if (fun.tpe eq tree.fun.tpe) && sameTypes(args, tree.args) => tree1.withTypeUnchecked(tree.tpe) + case tree: Apply if fun.tpe.underlyingIfProxy == NoType => + // The function type is not yet known. This happens for example if its + // type refers to a previous parameter in the same parameters list. In + // this case, we use the previously known type of the function. + // See tests/pos/dependent-annot-2.scala for an example. + ta.assignType(tree1, fun.withType(tree.fun.tpe), args) case _ => ta.assignType(tree1, fun, args) } } diff --git a/tests/pos/dependent-annot-2.scala b/tests/pos/dependent-annot-2.scala new file mode 100644 index 000000000000..9bfa8b594c2b --- /dev/null +++ b/tests/pos/dependent-annot-2.scala @@ -0,0 +1,30 @@ +class dummy(b: Any) extends annotation.StaticAnnotation + +class X: + def foo() = 1 + def bar() = 2 + def eq(x: X) = true + def id(): this.type = this + +class Y extends X: + override def bar() = 2 + override def eq(x: X) = true + +def f(x: Int) = x +def g(x: String) = x +def g(x: Int) = x + +object AnnotationTests: + def foo1(elem: Int, bla: Int @dummy(Array(elem))) = bla + def foo2(elem: X, bla: Int @dummy(elem.foo())) = bla + def foo3(elem: Y, bla: Int @dummy(elem.foo())) = bla + def foo4(elem: X, bla: Int @dummy(elem.bar())) = bla + def foo5(elem: Y, bla: Int @dummy(elem.bar())) = bla + def foo6(elem: X, bla: Int @dummy(elem.eq(X()))) = bla + def foo7(elem: Y, bla: Int @dummy(elem.eq(Y()))) = bla + def foo8(elem: X, bla: Int @dummy(elem.id().foo())) = bla + def foo9(elem: Y, bla: Int @dummy(elem.id().foo())) = bla + def foo10(elem: Int, bla: Int @dummy(f(elem))) = bla + def foo11(elem: Int, bla: Int @dummy(g(elem))) = bla + def foo12(elem: Int, bla: Int @dummy(0 == elem)) = bla + def foo13(elem: Int, bla: Int @dummy(elem == 0)) = bla