File tree 5 files changed +21
-3
lines changed
compiler/src/dotty/tools/dotc
library/src/scala/annotation
tests/pos-custom-args/captures
5 files changed +21
-3
lines changed Original file line number Diff line number Diff line change @@ -1056,6 +1056,7 @@ class Definitions {
1056
1056
@ tu lazy val RetainsAnnot : ClassSymbol = requiredClass(" scala.annotation.retains" )
1057
1057
@ tu lazy val RetainsCapAnnot : ClassSymbol = requiredClass(" scala.annotation.retainsCap" )
1058
1058
@ tu lazy val RetainsByNameAnnot : ClassSymbol = requiredClass(" scala.annotation.retainsByName" )
1059
+ @ tu lazy val RetainsArgAnnot : ClassSymbol = requiredClass(" scala.annotation.retainsArg" )
1059
1060
@ tu lazy val PublicInBinaryAnnot : ClassSymbol = requiredClass(" scala.annotation.publicInBinary" )
1060
1061
1061
1062
@ 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
4047
4047
true
4048
4048
}
4049
4049
4050
+ def isRetainsArg (pt : Type ) = pt match
4051
+ case AnnotatedType (arg, annot) => annot.symbol == defn.RetainsArgAnnot
4052
+ case _ => false
4053
+
4050
4054
if (implicitFun || caseCompanion)
4051
4055
&& ! isApplyProto(pt)
4052
4056
&& pt != SingletonTypeProto
4053
4057
&& pt != LhsProto
4058
+ && ! isRetainsArg(pt)
4054
4059
&& ! ctx.mode.is(Mode .Pattern )
4055
4060
&& ! tree.isInstanceOf [SplicePattern ]
4056
4061
&& ! ctx.isAfterTyper
Original file line number Diff line number Diff line change @@ -12,12 +12,20 @@ package scala.annotation
12
12
* non-standard capturing type syntax.
13
13
*/
14
14
@ experimental
15
- class retains (xs : Any * ) extends annotation.StaticAnnotation
15
+ class retains (xs : ( Any @ retainsArg) * ) extends annotation.StaticAnnotation
16
16
17
- /** Equivalent in meaning to `@retains(cap)`, but consumes less bytecode.
17
+ /** Equivalent in meaning to `@retains(cap)`, but consumes less bytecode.
18
18
*/
19
19
@ experimental
20
20
class retainsCap () extends annotation.StaticAnnotation
21
21
// This special case is needed to be able to load standard library modules without
22
22
// cyclic reference errors. Specifically, load sequences involving IterableOnce.
23
23
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
2
2
3
3
/** An annotation that indicates capture of an enclosing by-name type
4
4
*/
5
- @ experimental class retainsByName (xs : Any * ) extends annotation.StaticAnnotation
5
+ @ experimental class retainsByName (xs : ( Any @ retainsArg) * ) extends annotation.StaticAnnotation
6
6
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