Skip to content

Commit 75f38b5

Browse files
authored
Allow @retains arguments to be context functions (#20232)
Suppress the creation of apply method selections for these arguments Fixes #20231
2 parents fe3f8ef + 829e84a commit 75f38b5

File tree

6 files changed

+22
-3
lines changed

6 files changed

+22
-3
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,7 @@ class Definitions {
10561056
@tu lazy val RetainsAnnot: ClassSymbol = requiredClass("scala.annotation.retains")
10571057
@tu lazy val RetainsCapAnnot: ClassSymbol = requiredClass("scala.annotation.retainsCap")
10581058
@tu lazy val RetainsByNameAnnot: ClassSymbol = requiredClass("scala.annotation.retainsByName")
1059+
@tu lazy val RetainsArgAnnot: ClassSymbol = requiredClass("scala.annotation.retainsArg")
10591060
@tu lazy val PublicInBinaryAnnot: ClassSymbol = requiredClass("scala.annotation.publicInBinary")
10601061

10611062
@tu lazy val JavaRepeatableAnnot: ClassSymbol = requiredClass("java.lang.annotation.Repeatable")

compiler/src/dotty/tools/dotc/typer/Typer.scala

+5
Original file line numberDiff line numberDiff line change
@@ -4047,10 +4047,15 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
40474047
true
40484048
}
40494049

4050+
def isRetainsArg(pt: Type) = pt match
4051+
case AnnotatedType(arg, annot) => annot.symbol == defn.RetainsArgAnnot
4052+
case _ => false
4053+
40504054
if (implicitFun || caseCompanion)
40514055
&& !isApplyProto(pt)
40524056
&& pt != SingletonTypeProto
40534057
&& pt != LhsProto
4058+
&& !isRetainsArg(pt)
40544059
&& !ctx.mode.is(Mode.Pattern)
40554060
&& !tree.isInstanceOf[SplicePattern]
40564061
&& !ctx.isAfterTyper

library/src/scala/annotation/retains.scala

+10-2
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,20 @@ package scala.annotation
1212
* non-standard capturing type syntax.
1313
*/
1414
@experimental
15-
class retains(xs: Any*) extends annotation.StaticAnnotation
15+
class retains(xs: (Any@retainsArg)*) extends annotation.StaticAnnotation
1616

17-
/** Equivalent in meaning to `@retains(cap)`, but consumes less bytecode.
17+
/** Equivalent in meaning to `@retains(cap)`, but consumes less bytecode.
1818
*/
1919
@experimental
2020
class retainsCap() extends annotation.StaticAnnotation
2121
// This special case is needed to be able to load standard library modules without
2222
// cyclic reference errors. Specifically, load sequences involving IterableOnce.
2323

24+
/** Internal use, only for parameters of `retains` and `retainsByName`.
25+
*/
26+
@experimental
27+
class retainsArg extends annotation.StaticAnnotation
28+
// This annotation prevents argument references to retains and retainsByName from being
29+
// augmented with explicit arguments. That's unsound in general, but necessary
30+
// since a captureRef could have an impure context function type, A ?=> B, but
31+
// we still need to have the unapplied captureRef in the annotation.

library/src/scala/annotation/retainsByName.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ package scala.annotation
22

33
/** An annotation that indicates capture of an enclosing by-name type
44
*/
5-
@experimental class retainsByName(xs: Any*) extends annotation.StaticAnnotation
5+
@experimental class retainsByName(xs: (Any@retainsArg)*) extends annotation.StaticAnnotation
66

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Async
2+
class C(val x: Async ?=> Unit)
3+
def foo(x: Async ?=> Unit): C^{x} = C(x)
4+
def foo(x: Async ?=> Unit)(using Async): C^{x} = C(x)

tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ val experimentalDefinitionInLibrary = Set(
3030
"scala.annotation.retains",
3131
"scala.annotation.retainsByName",
3232
"scala.annotation.retainsCap",
33+
"scala.annotation.retainsArg",
3334
"scala.Pure",
3435
"scala.caps",
3536
"scala.caps$",

0 commit comments

Comments
 (0)