@@ -1513,16 +1513,29 @@ object SymDenotations {
15131513 * See tests/pos/i10769.scala
15141514 */
15151515 def reachableTypeRef (using Context ) =
1516- TypeRef (owner.reachableThisType , symbol)
1516+ TypeRef (owner.reachablePrefix , symbol)
15171517
1518- /** Like termRef, but objects in the prefix are represented by their singleton type,
1518+ /** The reachable typeRef with wildcard arguments for each type parameter */
1519+ def reachableRawTypeRef (using Context ) =
1520+ reachableTypeRef.appliedTo(typeParams.map(_ => TypeBounds .emptyPolyKind))
1521+
1522+ /** Like termRef, if it is addressable from the current context,
1523+ * but objects in the prefix are represented by their singleton type,
15191524 * this means we output `pre.O.member` rather than `pre.O$.this.member`.
15201525 *
15211526 * This is required to avoid owner crash in ExplicitOuter.
15221527 * See tests/pos/i10769.scala
1528+ *
1529+ * If the reference is to an object that is not accessible from the
1530+ * current context since the object is nested in a class that is not an outer
1531+ * class of the current context, fall back to a TypeRef to the module class.
1532+ * Test case is tests/pos/i17556.scala.
1533+ * If the reference is to some other inaccessible object, throw an AssertionError.
15231534 */
1524- def reachableTermRef (using Context ) =
1525- TermRef (owner.reachableThisType, symbol)
1535+ def reachableTermRef (using Context ): Type = owner.reachablePrefix match
1536+ case pre : SingletonType => TermRef (pre, symbol)
1537+ case pre if symbol.is(ModuleVal ) => TypeRef (pre, symbol.moduleClass)
1538+ case _ => throw AssertionError (i " cannot compute path to TermRef $this from ${ctx.owner}" )
15261539
15271540 /** Like thisType, but objects in the type are represented by their singleton type,
15281541 * this means we output `pre.O.member` rather than `pre.O$.this.member`.
@@ -1537,6 +1550,18 @@ object SymDenotations {
15371550 else
15381551 ThisType .raw(TypeRef (owner.reachableThisType, symbol.asType))
15391552
1553+ /** Like `reachableThisType`, except if that would refer to a class where
1554+ * the `this` cannot be accessed. In that case, fall back to the
1555+ * rawTypeRef of the class. E.g. instead of `A.this.X` where `A.this`
1556+ * is inaccessible, use `A#X`.
1557+ */
1558+ def reachablePrefix (using Context ): Type = reachableThisType match
1559+ case pre : ThisType
1560+ if ! pre.cls.isStaticOwner && ! ctx.owner.isContainedIn(pre.cls) =>
1561+ pre.cls.reachableRawTypeRef
1562+ case pre =>
1563+ pre
1564+
15401565 /** The variance of this type parameter or type member as a subset of
15411566 * {Covariant, Contravariant}
15421567 */
0 commit comments