Skip to content

Commit 41c05bd

Browse files
committed
[TODO EXPLAIN] Add capture checking to Mirror and TupleMirror
We need to split the files here, because... ?
1 parent 254a0b3 commit 41c05bd

File tree

8 files changed

+129
-14
lines changed

8 files changed

+129
-14
lines changed

TODO.md

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
- [x] library/src/scala/CanEqual.scala
2+
- [x] library/src/scala/CanThrow.scala
3+
- [x] library/src/scala/Conversion.scala
4+
- [x] library/src/scala/IArray.scala
5+
- [x] library/src/scala/NamedTuple.scala
6+
- [x] library/src/scala/PolyFunction.scala
7+
- [x] library/src/scala/Precise.scala
8+
- [x] library/src/scala/Pure.scala
9+
- [x] library/src/scala/Selectable.scala
10+
- [x] library/src/scala/Tuple.scala
111
- [ ] library/src/scala/annotation/MacroAnnotation.scala
212
- [ ] library/src/scala/annotation/RefiningAnnotation.scala
313
- [ ] library/src/scala/annotation/alpha.scala
@@ -10,6 +20,7 @@
1020
- [ ] library/src/scala/annotation/internal/AnnotationDefault.scala
1121
- [ ] library/src/scala/annotation/internal/AssignedNonLocally.scala
1222
- [ ] library/src/scala/annotation/internal/Body.scala
23+
- [ ] library/src/scala/annotation/internal/CaptureChecked.scala
1324
- [ ] library/src/scala/annotation/internal/Child.scala
1425
- [ ] library/src/scala/annotation/internal/ContextResultCount.scala
1526
- [ ] library/src/scala/annotation/internal/ErasedParam.scala
@@ -38,6 +49,7 @@
3849
- [ ] library/src/scala/annotation/unchecked/uncheckedCapabilityLeaks.scala
3950
- [ ] library/src/scala/annotation/unchecked/uncheckedCaptures.scala
4051
- [ ] library/src/scala/annotation/unroll.scala
52+
- [ ] library/src/scala/caps/package.scala
4153
- [ ] library/src/scala/compiletime/ops/any.scala
4254
- [ ] library/src/scala/compiletime/ops/boolean.scala
4355
- [ ] library/src/scala/compiletime/ops/double.scala
@@ -46,10 +58,10 @@
4658
- [ ] library/src/scala/compiletime/ops/long.scala
4759
- [ ] library/src/scala/compiletime/ops/string.scala
4860
- [ ] library/src/scala/compiletime/package.scala
49-
- [ ] library/src/scala/compiletime/testing/Error.scala
50-
- [ ] library/src/scala/compiletime/testing/ErrorKind.scala
51-
- [ ] library/src/scala/compiletime/testing/package.scala
52-
- [ ] library/src/scala/deriving/Mirror.scala
61+
- [x] library/src/scala/compiletime/testing/Error.scala
62+
- [x] library/src/scala/compiletime/testing/ErrorKind.scala
63+
- [x] library/src/scala/compiletime/testing/package.scala
64+
- [x] library/src/scala/main.scala
5365
- [ ] library/src/scala/quoted/Expr.scala
5466
- [ ] library/src/scala/quoted/ExprMap.scala
5567
- [ ] library/src/scala/quoted/Exprs.scala
@@ -64,3 +76,28 @@
6476
- [ ] library/src/scala/quoted/runtime/QuoteUnpickler.scala
6577
- [ ] library/src/scala/quoted/runtime/SplicedType.scala
6678
- [ ] library/src/scala/quoted/runtime/StopMacroExpansion.scala
79+
- [x] library/src/scala/reflect/Enum.scala
80+
- [x] library/src/scala/reflect/Selectable.scala
81+
- [x] library/src/scala/reflect/TypeTest.scala
82+
- [x] library/src/scala/reflect/Typeable.scala
83+
- [x] library/src/scala/runtime/$throws.scala
84+
- [x] library/src/scala/runtime/Arrays.scala
85+
- [x] library/src/scala/runtime/EnumValue.scala
86+
- [x] library/src/scala/runtime/FunctionXXL.scala
87+
- [x] library/src/scala/runtime/LazyVals.scala
88+
- [x] library/src/scala/runtime/MatchCase.scala
89+
- [x] library/src/scala/runtime/Scala3RunTime.scala
90+
- [x] library/src/scala/runtime/TupleMirror.scala
91+
- [x] library/src/scala/runtime/TupleXXL.scala
92+
- [x] library/src/scala/runtime/TupledFunctions.scala
93+
- [x] library/src/scala/runtime/Tuples.scala
94+
- [x] library/src/scala/runtime/TypeBox.scala
95+
- [x] library/src/scala/runtime/coverage/Invoker.scala
96+
- [ ] library/src/scala/runtime/stdLibPatches/Predef.scala
97+
- [ ] library/src/scala/runtime/stdLibPatches/language.scala
98+
- [x] library/src/scala/util/CommandLineParser.scala
99+
- [x] library/src/scala/util/FromDigits.scala
100+
- [x] library/src/scala/util/NotGiven.scala
101+
- [x] library/src/scala/util/TupledFunction.scala
102+
- [x] library/src/scala/util/boundary.scala
103+
- [x] library/src/scala/util/control/NonLocalReturns.scala

compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import util.Spans.Span
1717
import config.Printers.derive
1818
import NullOpsDecorator.*
1919
import scala.runtime.Statics
20+
import dotty.tools.dotc.config.Feature
21+
import dotty.tools.dotc.cc.CapturingType
2022

2123
object SyntheticMembers {
2224

@@ -688,7 +690,12 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
688690
addParent(defn.Mirror_SingletonClass.typeRef)
689691
def makeProductMirror(cls: Symbol, optInfo: Option[MirrorImpl.OfProduct]) = {
690692
addParent(defn.Mirror_ProductClass.typeRef)
691-
addMethod(nme.fromProduct, MethodType(defn.ProductClass.typeRef :: Nil, monoType.typeRef), cls,
693+
// fromProduct
694+
val productParamType =
695+
if Feature.ccEnabled then
696+
CapturingType(defn.ProductClass.typeRef, cc.CaptureSet.universal)
697+
else defn.ProductClass.typeRef
698+
addMethod(nme.fromProduct, MethodType(productParamType :: Nil, monoType.typeRef), cls,
692699
fromProductBody(_, _, optInfo).ensureConforms(monoType.typeRef)) // t4758.scala or i3381.scala are examples where a cast is needed
693700
}
694701
def makeSumMirror(cls: Symbol, optInfo: Option[MirrorImpl.OfSum]) = {
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package scala.deriving
2+
3+
import language.experimental.captureChecking
4+
5+
/** Mirrors allows typelevel access to enums, case classes and objects, and their sealed parents.
6+
*/
7+
sealed trait Mirror {
8+
9+
/** The mirrored *-type */
10+
type MirroredMonoType
11+
12+
/** The name of the type */
13+
type MirroredLabel <: String
14+
15+
/** The names of the product elements */
16+
type MirroredElemLabels <: Tuple
17+
}
18+
19+
object Mirror {
20+
21+
/** The Mirror for a sum type */
22+
trait Sum extends Mirror { self =>
23+
/** The ordinal number of the case class of `x`. For enums, `ordinal(x) == x.ordinal` */
24+
def ordinal(x: MirroredMonoType): Int
25+
}
26+
27+
/** The Mirror for a product type */
28+
trait Product extends Mirror {
29+
30+
/** Create a new instance of type `T` with elements taken from product `p`. */
31+
def fromProduct(p: scala.Product^): MirroredMonoType & AnyRef^{p, this}
32+
}
33+
34+
trait Singleton extends Product {
35+
type MirroredMonoType = this.type
36+
type MirroredType = this.type
37+
type MirroredElemTypes = EmptyTuple
38+
type MirroredElemLabels = EmptyTuple
39+
def fromProduct(p: scala.Product^): this.type = this
40+
}
41+
42+
/** A proxy for Scala 2 singletons, which do not inherit `Singleton` directly */
43+
class SingletonProxy(val value: AnyRef^) extends Product {
44+
type MirroredMonoType = value.type
45+
type MirroredType = value.type
46+
type MirroredElemTypes = EmptyTuple
47+
type MirroredElemLabels = EmptyTuple
48+
def fromProduct(p: scala.Product^): value.type = value
49+
}
50+
51+
type Of[T] = Mirror { type MirroredType = T; type MirroredMonoType = T ; type MirroredElemTypes <: Tuple }
52+
type ProductOf[T] = Mirror.Product { type MirroredType = T; type MirroredMonoType = T ; type MirroredElemTypes <: Tuple }
53+
type SumOf[T] = Mirror.Sum { type MirroredType = T; type MirroredMonoType = T; type MirroredElemTypes <: Tuple }
54+
55+
extension [T](p: ProductOf[T]^)
56+
/** Create a new instance of type `T` with elements taken from product `a`. */
57+
def fromProductTyped[A <: scala.Product, Elems <: p.MirroredElemTypes](a: A)(using ProductOf[A] { type MirroredElemTypes = Elems }): T =
58+
p.fromProduct(a)
59+
60+
/** Create a new instance of type `T` with elements taken from tuple `t`. */
61+
def fromTuple(t: p.MirroredElemTypes): T =
62+
p.fromProduct(t)
63+
}

library/src/scala/deriving/Mirror.scala renamed to library/src-non-bootstrapped/scala/deriving/Mirror.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package scala.deriving
22

3+
import language.experimental.captureChecking
4+
35
/** Mirrors allows typelevel access to enums, case classes and objects, and their sealed parents.
46
*/
57
sealed trait Mirror {
@@ -26,31 +28,31 @@ object Mirror {
2628
trait Product extends Mirror {
2729

2830
/** Create a new instance of type `T` with elements taken from product `p`. */
29-
def fromProduct(p: scala.Product): MirroredMonoType
31+
def fromProduct(p: scala.Product): MirroredMonoType & AnyRef^{this}
3032
}
3133

3234
trait Singleton extends Product {
3335
type MirroredMonoType = this.type
3436
type MirroredType = this.type
3537
type MirroredElemTypes = EmptyTuple
3638
type MirroredElemLabels = EmptyTuple
37-
def fromProduct(p: scala.Product): MirroredMonoType = this
39+
def fromProduct(p: scala.Product): this.type = this
3840
}
3941

4042
/** A proxy for Scala 2 singletons, which do not inherit `Singleton` directly */
41-
class SingletonProxy(val value: AnyRef) extends Product {
43+
class SingletonProxy(val value: AnyRef^) extends Product {
4244
type MirroredMonoType = value.type
4345
type MirroredType = value.type
4446
type MirroredElemTypes = EmptyTuple
4547
type MirroredElemLabels = EmptyTuple
46-
def fromProduct(p: scala.Product): MirroredMonoType = value
48+
def fromProduct(p: scala.Product): value.type = value
4749
}
4850

4951
type Of[T] = Mirror { type MirroredType = T; type MirroredMonoType = T ; type MirroredElemTypes <: Tuple }
5052
type ProductOf[T] = Mirror.Product { type MirroredType = T; type MirroredMonoType = T ; type MirroredElemTypes <: Tuple }
5153
type SumOf[T] = Mirror.Sum { type MirroredType = T; type MirroredMonoType = T; type MirroredElemTypes <: Tuple }
5254

53-
extension [T](p: ProductOf[T])
55+
extension [T](p: ProductOf[T]^)
5456
/** Create a new instance of type `T` with elements taken from product `a`. */
5557
def fromProductTyped[A <: scala.Product, Elems <: p.MirroredElemTypes](a: A)(using ProductOf[A] { type MirroredElemTypes = Elems }): T =
5658
p.fromProduct(a)

library/src/scala/runtime/TupleMirror.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ final class TupleMirror(arity: Int) extends scala.deriving.Mirror.Product with S
1010

1111
override type MirroredMonoType <: Tuple
1212

13-
final def fromProduct(product: Product): MirroredMonoType =
13+
final def fromProduct(product: Product^): MirroredMonoType^{product} =
1414
if product.productArity != arity then
1515
throw IllegalArgumentException(s"expected Product with $arity elements, got ${product.productArity}")
1616
runtime.Tuples.fromProduct(product).asInstanceOf[MirroredMonoType]

library/src/scala/runtime/Tuples.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ object Tuples {
5959
if (xs.length <= 22) fromArray(xs.asInstanceOf[Array[Object]])
6060
else TupleXXL.fromIArray(xs).asInstanceOf[Tuple]
6161

62-
def fromProduct(xs: Product): Tuple = (xs.productArity match {
62+
def fromProduct(xs: Product^): Tuple^{xs} = (xs.productArity match {
6363
case 0 => EmptyTuple
6464
case 1 =>
6565
xs match {

mk_todo.fish

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env fish
2+
3+
for file in (ls library/src/**.scala | sort)
4+
set checkbox (if rg -Fq "import language.experimental.captureChecking" $file; echo "[x]"; else; echo "[ ]"; end)
5+
printf "- %s %s\n" $checkbox $file
6+
end

project/Build.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,7 +1143,7 @@ object Build {
11431143
file(s"${baseDirectory.value}/src/scala/annotation/unroll.scala"),
11441144
file(s"${baseDirectory.value}/src/scala/annotation/targetName.scala"),
11451145
file(s"${baseDirectory.value}/src/scala/annotation/stableNull.scala"),
1146-
file(s"${baseDirectory.value}/src/scala/deriving/Mirror.scala"),
1146+
file(s"${baseDirectory.value}/src-non-bootstrapped/scala/deriving/Mirror.scala"),
11471147
file(s"${baseDirectory.value}/src/scala/compiletime/package.scala"),
11481148
file(s"${baseDirectory.value}/src/scala/quoted/Type.scala"),
11491149
file(s"${baseDirectory.value}/src/scala/quoted/Varargs.scala"),
@@ -1281,7 +1281,7 @@ object Build {
12811281
file(s"${baseDirectory.value}/src/scala/annotation/unroll.scala"),
12821282
file(s"${baseDirectory.value}/src/scala/annotation/targetName.scala"),
12831283
file(s"${baseDirectory.value}/src/scala/annotation/stableNull.scala"),
1284-
file(s"${baseDirectory.value}/src/scala/deriving/Mirror.scala"),
1284+
file(s"${baseDirectory.value}/src-bootstrapped/scala/deriving/Mirror.scala"),
12851285
file(s"${baseDirectory.value}/src/scala/compiletime/package.scala"),
12861286
file(s"${baseDirectory.value}/src/scala/quoted/Type.scala"),
12871287
file(s"${baseDirectory.value}/src/scala/quoted/Varargs.scala"),

0 commit comments

Comments
 (0)