Skip to content

Commit 0606cb9

Browse files
authored
Merge pull request #109 from scala/backport-lts-3.3-21941
Backport "Rename `InlineCopier` to `ConservativeTreeCopier`, use it in `TypeMap`s" to 3.3 LTS
2 parents c891ee5 + 6cb2d01 commit 0606cb9

File tree

5 files changed

+58
-11
lines changed

5 files changed

+58
-11
lines changed

Diff for: compiler/src/dotty/tools/dotc/ast/tpd.scala

+8
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,14 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
817817
Closure(tree: Tree)(env, meth, tpt)
818818
}
819819

820+
// This is a more fault-tolerant copier that does not cause errors when
821+
// function types in applications are undefined.
822+
// This was called `Inliner.InlineCopier` before 3.6.3.
823+
class ConservativeTreeCopier() extends TypedTreeCopier:
824+
override def Apply(tree: Tree)(fun: Tree, args: List[Tree])(using Context): Apply =
825+
if fun.tpe.widen.exists then super.Apply(tree)(fun, args)
826+
else untpd.cpy.Apply(tree)(fun, args).withTypeUnchecked(tree.tpe)
827+
820828
override def skipTransform(tree: Tree)(using Context): Boolean = tree.tpe.isError
821829

822830
implicit class TreeOps[ThisTree <: tpd.Tree](private val tree: ThisTree) extends AnyVal {

Diff for: compiler/src/dotty/tools/dotc/core/Types.scala

+8-1
Original file line numberDiff line numberDiff line change
@@ -5936,7 +5936,14 @@ object Types extends TypeUtils {
59365936
}
59375937
}
59385938

5939-
private def treeTypeMap = new TreeTypeMap(typeMap = this)
5939+
private def treeTypeMap = new TreeTypeMap(
5940+
typeMap = this,
5941+
// Using `ConservativeTreeCopier` is needed when copying dependent annoted
5942+
// types, where we can refer to a previous parameter represented as
5943+
// `TermParamRef` that has no underlying type yet.
5944+
// See tests/pos/annot-17242.scala.
5945+
cpy = ConservativeTreeCopier()
5946+
)
59405947

59415948
def mapOver(syms: List[Symbol]): List[Symbol] = mapSymbols(syms, treeTypeMap)
59425949

Diff for: compiler/src/dotty/tools/dotc/inlines/Inliner.scala

+7-10
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,6 @@ object Inliner:
9696
}
9797
end isElideableExpr
9898

99-
// InlineCopier is a more fault-tolerant copier that does not cause errors when
100-
// function types in applications are undefined. This is necessary since we copy at
101-
// the same time as establishing the proper context in which the copied tree should
102-
// be evaluated. This matters for opaque types, see neg/i14653.scala.
103-
private class InlineCopier() extends TypedTreeCopier:
104-
override def Apply(tree: Tree)(fun: Tree, args: List[Tree])(using Context): Apply =
105-
if fun.tpe.widen.exists then super.Apply(tree)(fun, args)
106-
else untpd.cpy.Apply(tree)(fun, args).withTypeUnchecked(tree.tpe)
107-
10899
// InlinerMap is a TreeTypeMap with special treatment for inlined arguments:
109100
// They are generally left alone (not mapped further, and if they wrap a type
110101
// the type Inlined wrapper gets dropped
@@ -116,7 +107,13 @@ object Inliner:
116107
substFrom: List[Symbol],
117108
substTo: List[Symbol])(using Context)
118109
extends TreeTypeMap(
119-
typeMap, treeMap, oldOwners, newOwners, substFrom, substTo, InlineCopier()):
110+
typeMap, treeMap, oldOwners, newOwners, substFrom, substTo,
111+
// It is necessary to use the `ConservativeTreeCopier` since we copy at
112+
// the same time as establishing the proper context in which the copied
113+
// tree should be evaluated. This matters for opaque types, see
114+
// neg/i14653.scala.
115+
ConservativeTreeCopier()
116+
):
120117

121118
override def copy(
122119
typeMap: Type => Type,

Diff for: tests/pos/annot-17242.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// See also tests/pos/annot-21595.scala
2+
3+
class local(predicate: Int) extends annotation.StaticAnnotation
4+
5+
def failing1(x: Int, z: Int @local(x + x)) = ()

Diff for: tests/pos/dependent-annot2.scala

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
class dummy(b: Any) extends annotation.StaticAnnotation
2+
3+
class X:
4+
def foo() = 1
5+
def bar() = 2
6+
def eq(x: X) = true
7+
def id(): this.type = this
8+
9+
class Y extends X:
10+
override def bar() = 2
11+
override def eq(x: X) = true
12+
13+
def f(x: Int) = x
14+
def g(x: String) = x
15+
def g(x: Int) = x
16+
17+
object AnnotationTests:
18+
def foo1(elem: Int, bla: Int @dummy(Array(elem))) = bla
19+
def foo2(elem: X, bla: Int @dummy(elem.foo())) = bla
20+
def foo3(elem: Y, bla: Int @dummy(elem.foo())) = bla
21+
def foo4(elem: X, bla: Int @dummy(elem.bar())) = bla
22+
def foo5(elem: Y, bla: Int @dummy(elem.bar())) = bla
23+
def foo6(elem: X, bla: Int @dummy(elem.eq(X()))) = bla
24+
def foo7(elem: Y, bla: Int @dummy(elem.eq(Y()))) = bla
25+
def foo8(elem: X, bla: Int @dummy(elem.id().foo())) = bla
26+
def foo9(elem: Y, bla: Int @dummy(elem.id().foo())) = bla
27+
def foo10(elem: Int, bla: Int @dummy(f(elem))) = bla
28+
def foo11(elem: Int, bla: Int @dummy(g(elem))) = bla
29+
def foo12(elem: Int, bla: Int @dummy(0 == elem)) = bla
30+
def foo13(elem: Int, bla: Int @dummy(elem == 0)) = bla

0 commit comments

Comments
 (0)