Skip to content

Commit e579bfa

Browse files
authored
Merge pull request #6853 from dotty-staging/fix-inline-opaque-2
Disallow inline methods and opaque types in same scope
2 parents 4385c39 + f8dded5 commit e579bfa

File tree

8 files changed

+60
-8
lines changed

8 files changed

+60
-8
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ object SymDenotations {
592592

593593
def seesOpaques(implicit ctx: Context): Boolean =
594594
containsOpaques ||
595-
is(Module, butNot = Package) && owner.containsOpaques
595+
is(Module, butNot = Package) && owner.seesOpaques
596596

597597
/** Is this the denotation of a self symbol of some class?
598598
* This is the case if one of two conditions holds:

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2463,9 +2463,9 @@ class ExplainingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
24632463
if (skipped) op
24642464
else {
24652465
indent += 2
2466-
b append "\n" append (" " * indent) append "==> " append str
2466+
b.append("\n").append(" " * indent).append("==> ").append(str)
24672467
val res = op
2468-
b append "\n" append (" " * indent) append "<== " append str append " = " append show(res)
2468+
b.append("\n").append(" " * indent).append("<== ").append(str).append(" = ").append(show(res))
24692469
indent -= 2
24702470
res
24712471
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,10 @@ object TypeErasure {
244244
!classify(tp).derivesFrom(defn.ObjectClass) &&
245245
!tp.binder.resultType.isJavaMethod
246246
case tp: TypeAlias => isUnboundedGeneric(tp.alias)
247-
case tp: TypeBounds => !classify(tp.hi).derivesFrom(defn.ObjectClass)
247+
case tp: TypeBounds =>
248+
val upper = classify(tp.hi)
249+
!upper.derivesFrom(defn.ObjectClass) &&
250+
!upper.isPrimitiveValueType
248251
case tp: TypeProxy => isUnboundedGeneric(tp.translucentSuperType)
249252
case tp: AndType => isUnboundedGeneric(tp.tp1) && isUnboundedGeneric(tp.tp2)
250253
case tp: OrType => isUnboundedGeneric(tp.tp1) || isUnboundedGeneric(tp.tp2)

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,10 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
201201

202202
private val (methPart, callTypeArgs, callValueArgss) = decomposeCall(call)
203203
private val inlinedMethod = methPart.symbol
204-
private val inlineCallPrefix = qualifier(methPart)
204+
private val inlineCallPrefix =
205+
qualifier(methPart).orElse(This(inlinedMethod.enclosingClass.asClass))
206+
207+
inlining.println("-----------------------\nInlining $call\nWith RHS $rhsToInline")
205208

206209
// Make sure all type arguments to the call are fully determined
207210
for (targ <- callTypeArgs) fullyDefinedType(targ.tpe, "inlined type argument", targ.span)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,8 @@ class Namer { typer: Typer =>
803803

804804
private def addInlineInfo(sym: Symbol) = original match {
805805
case original: untpd.DefDef if sym.isInlineMethod =>
806+
if (sym.owner.isClass && sym.owner.seesOpaques)
807+
ctx.error(em"Implementation restriction: No inline methods allowed where opaque type aliases are in scope", sym.sourcePos)
806808
PrepareInlineable.registerInlineInfo(
807809
sym,
808810
implicit ctx => typedAheadExpr(original).asInstanceOf[tpd.DefDef].rhs

library/src-bootstrapped/scala/IArray.scala

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,28 @@ implicit object arrayOps {
1515
* @param n the index of the element to select
1616
* @return the element of the array at the given index
1717
*/
18-
inline def (arr: IArray[T]) apply[T] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
18+
def (arr: IArray[Byte]) apply (n: Int): Byte = arr.asInstanceOf[Array[Byte]].apply(n)
19+
def (arr: IArray[Short]) apply (n: Int): Short = arr.asInstanceOf[Array[Short]].apply(n)
20+
def (arr: IArray[Char]) apply (n: Int): Char = arr.asInstanceOf[Array[Char]].apply(n)
21+
def (arr: IArray[Int]) apply (n: Int): Int = arr.asInstanceOf[Array[Int]].apply(n)
22+
def (arr: IArray[Long]) apply (n: Int): Long = arr.asInstanceOf[Array[Long]].apply(n)
23+
def (arr: IArray[Float]) apply (n: Int): Float = arr.asInstanceOf[Array[Float]].apply(n)
24+
def (arr: IArray[Double]) apply (n: Int): Double = arr.asInstanceOf[Array[Double]].apply(n)
25+
def (arr: IArray[T]) apply[T <: Object] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
26+
def (arr: IArray[T]) apply[T] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
1927

2028
/** The number of elements in an immutable array
2129
* @param arr the immutable array
2230
*/
23-
inline def (arr: IArray[T]) length[T] : Int = arr.asInstanceOf[Array[T]].length
31+
def (arr: IArray[Byte]) length: Int = arr.asInstanceOf[Array[Byte]].length
32+
def (arr: IArray[Short]) length: Int = arr.asInstanceOf[Array[Short]].length
33+
def (arr: IArray[Char]) length: Int = arr.asInstanceOf[Array[Char]].length
34+
def (arr: IArray[Int]) length: Int = arr.asInstanceOf[Array[Int]].length
35+
def (arr: IArray[Long]) length: Int = arr.asInstanceOf[Array[Long]].length
36+
def (arr: IArray[Float]) length: Int = arr.asInstanceOf[Array[Float]].length
37+
def (arr: IArray[Double]) length: Int = arr.asInstanceOf[Array[Double]].length
38+
def (arr: IArray[Object]) length: Int = arr.asInstanceOf[Array[Object]].length
39+
def (arr: IArray[T]) length[T] : Int = arr.asInstanceOf[Array[T]].length
2440
}
2541

2642
object IArray {

tests/neg/inline3.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
object K0 {
2+
3+
type T = String
4+
5+
opaque type ProductInstances[F[_], T] = ErasedProductInstances[F[T]]
6+
7+
inline def summonAsArray[F[_], T]: Array[Any] = ??? // error: Implementation restriction: No inline methods allowed
8+
9+
inline def mkProductInstances[F[_], T]: ProductInstances[F, T] = // error: Implementation restriction: No inline methods allowed
10+
new ErasedProductInstances(summonAsArray[F, T]).asInstanceOf[ProductInstances[F, T]]
11+
12+
val x: T = ""
13+
14+
inline def foo(x: T): T = "foo".asInstanceOf[T] // error: Implementation restriction: No inline methods allowed
15+
16+
}
17+
18+
final class ErasedProductInstances[FT](is0: => Array[Any])
19+
20+
trait Monoid[A]
21+
case class ISB(i: Int)
22+
23+
object Test {
24+
//val K0 = new K0
25+
K0.foo(K0.x)
26+
K0.mkProductInstances[Monoid, ISB]
27+
28+
}

tests/run/opaque-immutable-array-xm.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ object Test extends App {
66
opaque type IArray[A1] = Array[A1]
77

88
implicit object IArray {
9-
inline def initialize[A](body: => Array[A]): IArray[A] = body
9+
def initialize[A](body: => Array[A]): IArray[A] = body
1010
def apply[A: ClassTag](xs: A*): IArray[A] = initialize(Array(xs: _*))
1111

1212
// These should be inline but that does not work currently. Try again

0 commit comments

Comments
 (0)