@@ -1509,16 +1509,29 @@ object SymDenotations {
15091509 * See tests/pos/i10769.scala
15101510 */
15111511 def reachableTypeRef (using Context ) =
1512- TypeRef (owner.reachableThisType , symbol)
1512+ TypeRef (owner.reachablePrefix , symbol)
15131513
1514- /** Like termRef, but objects in the prefix are represented by their singleton type,
1514+ /** The reachable typeRef with wildcard arguments for each type parameter */
1515+ def reachableRawTypeRef (using Context ) =
1516+ reachableTypeRef.appliedTo(typeParams.map(_ => TypeBounds .emptyPolyKind))
1517+
1518+ /** Like termRef, if it is addressable from the current context,
1519+ * but objects in the prefix are represented by their singleton type,
15151520 * this means we output `pre.O.member` rather than `pre.O$.this.member`.
15161521 *
15171522 * This is required to avoid owner crash in ExplicitOuter.
15181523 * See tests/pos/i10769.scala
1524+ *
1525+ * If the reference is to an object that is not accessible from the
1526+ * current context since the object is nested in a class that is not an outer
1527+ * class of the current context, fall back to a TypeRef to the module class.
1528+ * Test case is tests/pos/i17556.scala.
1529+ * If the reference is to some other inaccessible object, throw an AssertionError.
15191530 */
1520- def reachableTermRef (using Context ) =
1521- TermRef (owner.reachableThisType, symbol)
1531+ def reachableTermRef (using Context ): Type = owner.reachablePrefix match
1532+ case pre : SingletonType => TermRef (pre, symbol)
1533+ case pre if symbol.is(ModuleVal ) => TypeRef (pre, symbol.moduleClass)
1534+ case _ => throw AssertionError (i " cannot compute path to TermRef $this from ${ctx.owner}" )
15221535
15231536 /** Like thisType, but objects in the type are represented by their singleton type,
15241537 * this means we output `pre.O.member` rather than `pre.O$.this.member`.
@@ -1533,6 +1546,18 @@ object SymDenotations {
15331546 else
15341547 ThisType .raw(TypeRef (owner.reachableThisType, symbol.asType))
15351548
1549+ /** Like `reachableThisType`, except if that would refer to a class where
1550+ * the `this` cannot be accessed. In that case, fall back to the
1551+ * rawTypeRef of the class. E.g. instead of `A.this.X` where `A.this`
1552+ * is inaccessible, use `A#X`.
1553+ */
1554+ def reachablePrefix (using Context ): Type = reachableThisType match
1555+ case pre : ThisType
1556+ if ! pre.cls.isStaticOwner && ! ctx.owner.isContainedIn(pre.cls) =>
1557+ pre.cls.reachableRawTypeRef
1558+ case pre =>
1559+ pre
1560+
15361561 /** The variance of this type parameter or type member as a subset of
15371562 * {Covariant, Contravariant}
15381563 */
0 commit comments