Skip to content

Commit a06264d

Browse files
committed
Fix mapping TypeMaps over annotations
Avoids orphan parameters when pickling Fixes #15922 I am not sure about the status of the test in custome-args/captures. Should it pass or be rejected? But in any case it does not crash anymore.
1 parent bf03086 commit a06264d

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

compiler/src/dotty/tools/dotc/core/Annotations.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
package dotty.tools.dotc
1+
package dotty.tools
2+
package dotc
23
package core
34

45
import Symbols._, Types._, Contexts._, Constants._
@@ -58,7 +59,7 @@ object Annotations {
5859
if tm.isRange(x) then x
5960
else
6061
val tp1 = tm(tree.tpe)
61-
foldOver(if tp1 =:= tree.tpe then x else tp1, tree)
62+
foldOver(if tp1 frozen_=:= tree.tpe then x else tp1, tree)
6263
val diff = findDiff(NoType, args)
6364
if tm.isRange(diff) then EmptyAnnotation
6465
else if diff.exists then derivedAnnotation(tm.mapOver(tree))
@@ -69,7 +70,7 @@ object Annotations {
6970
val args = arguments
7071
if args.isEmpty then false
7172
else tree.existsSubTree {
72-
case id: Ident => id.tpe match
73+
case id: Ident => id.tpe.stripped match
7374
case TermParamRef(tl1, _) => tl eq tl1
7475
case _ => false
7576
case _ => false
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
trait Cap { def use(): Int }
2+
type Id[X] = [T] -> (op: X => T) -> T
3+
def mkId[X](x: X): Id[X] = [T] => (op: X => T) => op(x)
4+
5+
def withCap[X](op: ({*} Cap) => X): X = {
6+
val cap: {*} Cap = new Cap { def use() = { println("cap is used"); 0 } }
7+
val result = op(cap)
8+
result
9+
}
10+
11+
def leaking(c: {*} Cap): Id[{c} Cap] = mkId(c)
12+
13+
def test =
14+
val bad = withCap(leaking)

tests/pos/i15922.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
trait Cap:
2+
type M
3+
class Id[X]
4+
5+
object Test:
6+
def withCap[X](op: Cap => X): X = ???
7+
8+
class retains1(xs: Any*) extends annotation.StaticAnnotation
9+
10+
def leaking1(c: Cap): Id[Cap @retains1(c)] = ??? // used to crash with orphan parameter on pickling
11+
def leaking2(c: Cap): Id[c.type] = ???
12+
13+
val bad1 = withCap(leaking1)
14+
val bad2 = withCap(leaking2)

0 commit comments

Comments
 (0)