File tree Expand file tree Collapse file tree 5 files changed +21
-3
lines changed
compiler/src/dotty/tools/dotc
library/src/scala/annotation
tests/pos-custom-args/captures Expand file tree Collapse file tree 5 files changed +21
-3
lines changed Original file line number Diff line number Diff 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" )
Original file line number Diff line number Diff 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
Original file line number Diff line number Diff 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
2020class 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.
Original file line number Diff line number Diff 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 number Diff line number Diff line change 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)
You can’t perform that action at this time.
0 commit comments