File tree Expand file tree Collapse file tree 7 files changed +72
-3
lines changed
compiler/src/dotty/tools/dotc/ast Expand file tree Collapse file tree 7 files changed +72
-3
lines changed Original file line number Diff line number Diff line change @@ -1022,13 +1022,23 @@ object desugar {
1022
1022
else Apply (ref(tupleTypeRef.classSymbol.companionModule.termRef), ts)
1023
1023
}
1024
1024
1025
- /** Group all patterm, value and method definitions and all non-class type definitions
1026
- * in an object named `<source>#object` where `<source>` is the name of the source file.
1025
+ /** Group all definitions that can't be at the toplebel in
1026
+ * an object named `<source>#object` where `<source>` is the name of the source file.
1027
+ * Definitions that can't be at the toplevel are:
1028
+ *
1029
+ * - all pattern, value and method definitions
1030
+ * - non-class type definitions
1031
+ * - implicit classes and objects
1032
+ * - companion objects of opaque types
1027
1033
*/
1028
1034
def packageDef (pdef : PackageDef )(implicit ctx : Context ): PackageDef = {
1035
+ val opaqueNames = pdef.stats.collect {
1036
+ case stat : TypeDef if stat.mods.is(Opaque ) => stat.name
1037
+ }
1029
1038
def needsObject (stat : Tree ) = stat match {
1030
1039
case _ : ValDef | _ : PatDef | _ : DefDef => true
1031
- case stat : ModuleDef => stat.mods.is(Implicit )
1040
+ case stat : ModuleDef =>
1041
+ stat.mods.is(Implicit ) || opaqueNames.contains(stat.name.stripModuleClassSuffix.toTypeName)
1032
1042
case stat : TypeDef => ! stat.isClassDef || stat.mods.is(Implicit )
1033
1043
case _ => false
1034
1044
}
Original file line number Diff line number Diff line change
1
+ object Test {
2
+ val x : T [Int ] = 2 // error
3
+ val y : Int = x // error
4
+ val a : Int = T .f(x) // ok
5
+ val b : T [Int ] = T .g(y) // ok
6
+ }
Original file line number Diff line number Diff line change
1
+ opaque type T [X ] = X
2
+ object T {
3
+ def f (x : T [Int ]): Int = x // OK
4
+ def g (x : Int ): T [Int ] = x // OK
5
+ }
Original file line number Diff line number Diff line change
1
+ package logs
2
+
3
+ opaque type Logarithm = Double
4
+
5
+ implicit object Logarithm {
6
+
7
+ // These are the ways to lift to the logarithm type
8
+ def apply (d : Double ): Logarithm = math.log(d)
9
+
10
+ def safe (d : Double ): Option [Logarithm ] =
11
+ if (d > 0.0 ) Some (math.log(d)) else None
12
+
13
+ // This is the first way to unlift the logarithm type
14
+ def exponent (l : Logarithm ): Double = l
15
+
16
+ // Extension methods define opaque types' public APIs
17
+
18
+ // This is the second way to unlift the logarithm type
19
+ def (x : Logarithm ) toDouble : Double = math.exp(x)
20
+ def (x : Logarithm ) + (y : Logarithm ) = Logarithm (math.exp(x) + math.exp(y))
21
+ def (x : Logarithm ) * (y : Logarithm ): Logarithm = Logarithm (x + y)
22
+ }
Original file line number Diff line number Diff line change
1
+ package logs
2
+
3
+ import Predef .{any2stringadd => _ , _ }
4
+
5
+ object Test {
6
+ val l = Logarithm (1.0 )
7
+ val l2 = Logarithm (2.0 )
8
+ val l3 = l * l2
9
+ val l4 = l + l2 // currently requires any2stringadd to be disabled because
10
+ // as a contextual implicit this takes precedence over the
11
+ // implicit scope implicit LogarithmOps.
12
+ // TODO: Remove any2stringadd
13
+ val d = Logarithm .toDouble(l3)
14
+ val l5 : Logarithm = (1.0 ).asInstanceOf [Logarithm ]
15
+ }
Original file line number Diff line number Diff line change
1
+ object Test {
2
+ val x : T [Int ] = ??? // 2 // error
3
+ val y : Int = 1 // x // error
4
+ val a : Int = T .f(x) // ok
5
+ val b : T [Int ] = T .g(y) // ok
6
+ }
Original file line number Diff line number Diff line change
1
+ opaque type T [X ] = X
2
+ object T {
3
+ def f (x : T [Int ]): Int = x // OK
4
+ def g (x : Int ): T [Int ] = x // OK
5
+ }
You can’t perform that action at this time.
0 commit comments