Skip to content

Commit 0555be1

Browse files
committed
Allow aliasing with less precise type parameter
1 parent 43f396c commit 0555be1

File tree

7 files changed

+79
-51
lines changed

7 files changed

+79
-51
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4551,7 +4551,7 @@ object Types {
45514551
// the param itself is annotated as precise or the param is first introduced
45524552
// in a precise position of an applied type argument
45534553
binder.paramPrecises(paramNum) ||
4554-
(binder.resType match
4554+
(binder.resType.dealiasKeepOpaques match
45554555
//givens just return an applied type which we use
45564556
case at: AppliedType => isPreciseRecur(at, false)
45574557
//for method types we go over the arguments

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
405405
Checking.checkGoodBounds(tree.symbol)
406406
(tree.rhs, sym.info) match
407407
case (rhs: LambdaTypeTree, bounds: TypeBounds) =>
408-
PreciseChecker.checkLambda(rhs)
408+
PreciseChecker.checkLambda(rhs, sym.isOpaqueAlias)
409409
VarianceChecker.checkLambda(rhs, bounds)
410410
if sym.isOpaqueAlias then
411411
VarianceChecker.checkLambda(rhs, TypeBounds.upper(sym.opaqueAlias))

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,13 @@ object PreciseChecker:
3636

3737
def checkClass(tree: tpd.Template)(using Context): Unit =
3838
val tparams = tree.constr.leadingTypeParams
39-
tree.parents.view.map(_.tpe).foreach(check(tparams, _, Mode.AllowMorePrecise))
39+
tree.parents.view.map(_.tpe.dealias).foreach(check(tparams, _, Mode.AllowMorePrecise))
4040

41-
def checkLambda(tree: tpd.LambdaTypeTree)(using Context): Unit =
42-
tree.body.tpe match
41+
def checkLambda(tree: tpd.LambdaTypeTree, isOpaque: Boolean)(using Context): Unit =
42+
tree.body.tpe.dealiasKeepOpaques match
4343
case at: AppliedType =>
44-
check(tree.tparams, at, Mode.SamePrecise)
44+
val mode = if (isOpaque) Mode.SamePrecise else Mode.AllowLessPrecise
45+
check(tree.tparams, at, mode)
4546
case tb: TypeBounds =>
4647
check(tree.tparams, tb.hi, Mode.AllowMorePrecise)
4748
check(tree.tparams, tb.lo, Mode.AllowLessPrecise)

tests/neg/precise-alias-extends.check

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,68 @@
1-
-- Error: tests/neg/precise-alias-extends.scala:23:28 ------------------------------------------------------------------
2-
23 | type FooInvAlias[@precise A] = FooInv[A] // error
1+
-- Error: tests/neg/precise-alias-extends.scala:26:28 ------------------------------------------------------------------
2+
26 | type FooInvAlias[@precise A] = FooInv[A] // error
33
| ^^^^^^^^^^
44
| precise type parameter A occurs in imprecise position in preciseTypeAliasExtendMorePrecise.FooInv[A]
5-
-- Error: tests/neg/precise-alias-extends.scala:28:29 ------------------------------------------------------------------
6-
28 | type FooCovAlias[@precise +A] = FooCov[A] // error
5+
-- Error: tests/neg/precise-alias-extends.scala:27:36 ------------------------------------------------------------------
6+
27 | opaque type FooInvOpaque[@precise A] = FooInv[A] // error
7+
| ^^^^^^^^^^
8+
| precise type parameter A occurs in imprecise position in preciseTypeAliasExtendMorePrecise.FooInv[A]
9+
-- Error: tests/neg/precise-alias-extends.scala:32:29 ------------------------------------------------------------------
10+
32 | type FooCovAlias[@precise +A] = FooCov[A] // error
711
| ^^^^^^^^^^^
812
| precise type parameter A occurs in imprecise position in preciseTypeAliasExtendMorePrecise.FooCov[A]
9-
-- Error: tests/neg/precise-alias-extends.scala:32:29 ------------------------------------------------------------------
10-
32 | type FooConAlias[@precise -A] = FooCon[A] // error
13+
-- Error: tests/neg/precise-alias-extends.scala:33:37 ------------------------------------------------------------------
14+
33 | opaque type FooCovOpaque[@precise +A] = FooCov[A] // error
15+
| ^^^^^^^^^^^
16+
| precise type parameter A occurs in imprecise position in preciseTypeAliasExtendMorePrecise.FooCov[A]
17+
-- Error: tests/neg/precise-alias-extends.scala:37:29 ------------------------------------------------------------------
18+
37 | type FooConAlias[@precise -A] = FooCon[A] // error
1119
| ^^^^^^^^^^^
1220
| precise type parameter A occurs in imprecise position in preciseTypeAliasExtendMorePrecise.FooCon[A]
13-
-- Error: tests/neg/precise-alias-extends.scala:38:21 ------------------------------------------------------------------
14-
38 | class FooInvExtend[A](val value : A) extends FooInv[A] // error
21+
-- Error: tests/neg/precise-alias-extends.scala:38:37 ------------------------------------------------------------------
22+
38 | opaque type FooConOpaque[@precise -A] = FooCon[A] // error
23+
| ^^^^^^^^^^^
24+
| precise type parameter A occurs in imprecise position in preciseTypeAliasExtendMorePrecise.FooCon[A]
25+
-- Error: tests/neg/precise-alias-extends.scala:44:21 ------------------------------------------------------------------
26+
44 | class FooInvExtend[A](val value : A) extends FooInv[A] // error
1527
| ^
1628
| imprecise type parameter A occurs in precise position in preciseTypeAliasExtendLessPrecise.FooInv[A]
17-
-- Error: tests/neg/precise-alias-extends.scala:39:19 ------------------------------------------------------------------
18-
39 | type FooInvAlias[A] = FooInv[A] // error
19-
| ^
29+
-- Error: tests/neg/precise-alias-extends.scala:46:27 ------------------------------------------------------------------
30+
46 | opaque type FooInvOpaque[A] = FooInv[A] // error
31+
| ^
2032
| imprecise type parameter A occurs in precise position in preciseTypeAliasExtendLessPrecise.FooInv[A]
21-
-- Error: tests/neg/precise-alias-extends.scala:43:22 ------------------------------------------------------------------
22-
43 | class FooCovExtend[+A](val value : A) extends FooCov[A] // error
33+
-- Error: tests/neg/precise-alias-extends.scala:50:22 ------------------------------------------------------------------
34+
50 | class FooCovExtend[+A](val value : A) extends FooCov[A] // error
2335
| ^^
2436
| imprecise type parameter A occurs in precise position in preciseTypeAliasExtendLessPrecise.FooCov[A]
25-
-- Error: tests/neg/precise-alias-extends.scala:44:20 ------------------------------------------------------------------
26-
44 | type FooCovAlias[+A] = FooCov[A] // error
27-
| ^^
37+
-- Error: tests/neg/precise-alias-extends.scala:52:28 ------------------------------------------------------------------
38+
52 | opaque type FooCovOpaque[+A] = FooCov[A] // error
39+
| ^^
2840
| imprecise type parameter A occurs in precise position in preciseTypeAliasExtendLessPrecise.FooCov[A]
29-
-- Error: tests/neg/precise-alias-extends.scala:47:22 ------------------------------------------------------------------
30-
47 | class FooConExtend[-A] extends FooCon[A] // error
41+
-- Error: tests/neg/precise-alias-extends.scala:55:22 ------------------------------------------------------------------
42+
55 | class FooConExtend[-A] extends FooCon[A] // error
3143
| ^^
3244
| imprecise type parameter A occurs in precise position in preciseTypeAliasExtendLessPrecise.FooCon[A]
33-
-- Error: tests/neg/precise-alias-extends.scala:48:20 ------------------------------------------------------------------
34-
48 | type FooConAlias[-A] = FooCon[A] // error
35-
| ^^
45+
-- Error: tests/neg/precise-alias-extends.scala:57:28 ------------------------------------------------------------------
46+
57 | opaque type FooConOpaque[-A] = FooCon[A] // error
47+
| ^^
3648
| imprecise type parameter A occurs in precise position in preciseTypeAliasExtendLessPrecise.FooCon[A]
37-
-- Error: tests/neg/precise-alias-extends.scala:55:17 ------------------------------------------------------------------
38-
55 | type FooAlias1[A] = Box[Foo[A]] // error
39-
| ^
40-
| imprecise type parameter A occurs in precise position in preciseTypeAliasComposition.Foo[A]
41-
-- Error: tests/neg/precise-alias-extends.scala:59:26 ------------------------------------------------------------------
42-
59 | type BoxAlias2[@precise A] = Foo[Box[A]] // error
49+
-- Error: tests/neg/precise-alias-extends.scala:68:26 ------------------------------------------------------------------
50+
68 | type BoxAlias2[@precise A] = Foo[Box[A]] // error
4351
| ^^^^^^^^^^
4452
| precise type parameter A occurs in imprecise position in preciseTypeAliasComposition.Box[A]
45-
-- Error: tests/neg/precise-alias-extends.scala:69:16 ------------------------------------------------------------------
46-
69 | type Less[T] <: PBox[T] // error
53+
-- Error: tests/neg/precise-alias-extends.scala:78:16 ------------------------------------------------------------------
54+
78 | type Less[T] <: PBox[T] // error
4755
| ^
4856
| imprecise type parameter T occurs in precise position in preciseTypeBounds.PBox[T]
49-
-- Error: tests/neg/precise-alias-extends.scala:74:25 ------------------------------------------------------------------
50-
74 | type More[@precise T] >: Box[T] // error
57+
-- Error: tests/neg/precise-alias-extends.scala:83:25 ------------------------------------------------------------------
58+
83 | type More[@precise T] >: Box[T] // error
5159
| ^^^^^^^^^^
5260
| precise type parameter T occurs in imprecise position in preciseTypeBounds.Box[T]
53-
-- Error: tests/neg/precise-alias-extends.scala:78:21 ------------------------------------------------------------------
54-
78 | opaque type Less[T] <: PBox[T] = PBox[T] // error
61+
-- Error: tests/neg/precise-alias-extends.scala:87:21 ------------------------------------------------------------------
62+
87 | opaque type Less[T] <: PBox[T] = PBox[T] // error
5563
| ^
5664
| imprecise type parameter T occurs in precise position in preciseTypeBounds.PBox[T]
57-
-- Error: tests/neg/precise-alias-extends.scala:79:30 ------------------------------------------------------------------
58-
79 | opaque type More[@precise T] <: Box[T] = Box[T] // error
65+
-- Error: tests/neg/precise-alias-extends.scala:88:30 ------------------------------------------------------------------
66+
88 | opaque type More[@precise T] <: Box[T] = Box[T] // error
5967
| ^^^^^^^^^^
6068
| precise type parameter T occurs in imprecise position in preciseTypeBounds.Box[T]

tests/neg/precise-alias-extends.scala

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,54 +5,63 @@ object preciseTypeAliasExtendSamePrecise:
55
val value: T
66
class FooInvExtend[@precise A](val value : A) extends FooInv[A]
77
type FooInvAlias[@precise A] = FooInv[A]
8+
opaque type FooInvOpaque[@precise A] = FooInv[A]
89

910
trait FooCov[@precise +T]:
1011
val value: T
1112
class FooCovExtend[@precise +A](val value : A) extends FooCov[A]
1213
type FooCovAlias[@precise +A] = FooCov[A]
14+
opaque type FooCovOpaque[@precise +A] = FooCov[A]
1315

1416
trait FooCon[@precise -T]
1517
class FooConExtend[@precise -A] extends FooCon[A]
1618
type FooConAlias[@precise -A] = FooCon[A]
19+
opaque type FooConOpaque[@precise -A] = FooCon[A]
1720

1821

1922
object preciseTypeAliasExtendMorePrecise:
2023
trait FooInv[T]:
2124
val value: T
2225
class FooInvExtend[@precise A](val value : A) extends FooInv[A]
2326
type FooInvAlias[@precise A] = FooInv[A] // error
27+
opaque type FooInvOpaque[@precise A] = FooInv[A] // error
2428

2529
trait FooCov[+T]:
2630
val value: T
2731
class FooCovExtend[@precise +A](val value : A) extends FooCov[A]
2832
type FooCovAlias[@precise +A] = FooCov[A] // error
33+
opaque type FooCovOpaque[@precise +A] = FooCov[A] // error
2934

3035
trait FooCon[-T]
3136
class FooConExtend[@precise -A] extends FooCon[A]
3237
type FooConAlias[@precise -A] = FooCon[A] // error
38+
opaque type FooConOpaque[@precise -A] = FooCon[A] // error
3339

3440

3541
object preciseTypeAliasExtendLessPrecise:
3642
trait FooInv[@precise T]:
3743
val value: T
3844
class FooInvExtend[A](val value : A) extends FooInv[A] // error
39-
type FooInvAlias[A] = FooInv[A] // error
45+
type FooInvAlias[A] = FooInv[A]
46+
opaque type FooInvOpaque[A] = FooInv[A] // error
4047

4148
trait FooCov[@precise +T]:
4249
val value: T
4350
class FooCovExtend[+A](val value : A) extends FooCov[A] // error
44-
type FooCovAlias[+A] = FooCov[A] // error
51+
type FooCovAlias[+A] = FooCov[A]
52+
opaque type FooCovOpaque[+A] = FooCov[A] // error
4553

4654
trait FooCon[@precise -T]
4755
class FooConExtend[-A] extends FooCon[A] // error
48-
type FooConAlias[-A] = FooCon[A] // error
56+
type FooConAlias[-A] = FooCon[A]
57+
opaque type FooConOpaque[-A] = FooCon[A] // error
4958

5059

5160
object preciseTypeAliasComposition:
5261
trait Foo[@precise T]
5362
trait Box[T]
5463

55-
type FooAlias1[A] = Box[Foo[A]] // error
64+
type FooAlias1[A] = Box[Foo[A]]
5665
type FooAlias2[A] = Foo[Box[A]]
5766

5867
type BoxAlias1[@precise A] = Box[Foo[A]]

tests/neg/precise-typecheck.check

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
-- Error: tests/neg/precise-typecheck.scala:381:16 ---------------------------------------------------------------------
2-
381 | val x = id(2L) // error
1+
-- Error: tests/neg/precise-typecheck.scala:391:16 ---------------------------------------------------------------------
2+
391 | val x = id(2L) // error
33
| ^
44
| Cannot prove that (2L : Long) =:= (1L : Long).
5-
-- [E007] Type Mismatch Error: tests/neg/precise-typecheck.scala:450:45 ------------------------------------------------
6-
450 | val id1Check: Id1 = [T] => (t: T) => Box(t) // error
5+
-- [E007] Type Mismatch Error: tests/neg/precise-typecheck.scala:460:45 ------------------------------------------------
6+
460 | val id1Check: Id1 = [T] => (t: T) => Box(t) // error
77
| ^
88
| Found: [T] => (t: T) => Box[T]
99
| Required: precisePolymorphicTypesAndValues.Id1
1010
|
1111
| longer explanation available when compiling with `-explain`
12-
-- [E007] Type Mismatch Error: tests/neg/precise-typecheck.scala:453:54 ------------------------------------------------
13-
453 | val id2Check: Id2 = [@precise T] => (t: T) => Box(t) // error
12+
-- [E007] Type Mismatch Error: tests/neg/precise-typecheck.scala:463:54 ------------------------------------------------
13+
463 | val id2Check: Id2 = [@precise T] => (t: T) => Box(t) // error
1414
| ^
1515
| Found: [@precise T] => (t: T) => Box[T]
1616
| Required: precisePolymorphicTypesAndValues.Id2

tests/neg/precise-typecheck.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,16 @@ object preciseCovariance:
180180
val fbic12Test: Inv[Int, 2] = fbic12
181181

182182

183+
object preciseTypeAlias:
184+
case class BoxC[@precise +A](x: A)
185+
type BoxCC[A] = BoxC[A]
186+
def fromBox[B](x: BoxCC[B]): BoxCC[B] = x
187+
final val b1 = BoxC(1)
188+
val b11 = fromBox(b1)
189+
val b11Test: BoxCC[1] = b11
190+
val b11CovTest: BoxCC[Int] = b11
191+
192+
183193
object preciseCovariantComposition:
184194
object direct:
185195
class BoxC[@precise +A]

0 commit comments

Comments
 (0)