Skip to content

Commit 4d2dadc

Browse files
committed
Fix #3005: Treat singleton ExprTypes as stable values
Two main changes: - values with type => T are stable if T is stable - types deriving from scala.Singleton are considered stable The two changes together allow to declare by-name-parameters to be stable by declaring them to have a Singleton type.
1 parent 7e402a7 commit 4d2dadc

File tree

4 files changed

+23
-4
lines changed

4 files changed

+23
-4
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,8 +595,11 @@ object SymDenotations {
595595
)
596596

597597
/** Is this a denotation of a stable term (or an arbitrary type)? */
598-
final def isStable(implicit ctx: Context) =
599-
isType || is(Stable) || !(is(UnstableValue) || info.isInstanceOf[ExprType])
598+
final def isStable(implicit ctx: Context) = {
599+
def isUnstable =
600+
is(UnstableValue) || info.isInstanceOf[ExprType] && !info.isStable
601+
isType || is(Stable) || !isUnstable
602+
}
600603

601604
/** Is this a "real" method? A real method is a method which is:
602605
* - not an accessor

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ object Types {
115115
case tp: RefinedOrRecType => tp.parent.isStable
116116
case tp: ExprType => tp.resultType.isStable
117117
case tp: AnnotatedType => tp.tpe.isStable
118-
case _ => false
118+
case tp => tp.derivesFrom(defn.SingletonClass)
119119
}
120120

121121
/** Is this type a (possibly refined or applied or aliased) type reference

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ object ProtoTypes {
417417

418418
/** Create a new TypeVar that represents a dependent method parameter singleton */
419419
def newDepTypeVar(tp: Type)(implicit ctx: Context): TypeVar =
420-
newTypeVar(TypeBounds.upper(AndType(tp, defn.SingletonClass.typeRef)))
420+
newTypeVar(TypeBounds.upper(AndType(tp.widenExpr, defn.SingletonClass.typeRef)))
421421

422422
/** The result type of `mt`, where all references to parameters of `mt` are
423423
* replaced by either wildcards (if typevarsMissContext) or TypeParamRefs.

tests/pos-special/i3005.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
trait Foo {
2+
type Out
3+
def out: Out
4+
}
5+
6+
object Test extends App {
7+
8+
implicit def bar(implicit foo: => Foo & Singleton): foo.Out = foo.out
9+
10+
var x = new Foo { type Out = String; def out = "hello" }
11+
12+
implicit val y: Foo = x
13+
14+
assert(bar(y) == "hello")
15+
assert(bar == "hello")
16+
}

0 commit comments

Comments
 (0)