Skip to content

Exports: Refine canForward for selections on this #22503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1175,11 +1175,23 @@ class Namer { typer: Typer =>
def canForward(mbr: SingleDenotation, alias: TermName): CanForward = {
import CanForward.*
val sym = mbr.symbol
/**
* Check the export selects an abstract member (issue #22147).
*/
def isAbstractMember: Boolean = sym.is(Deferred) && (expr match
case ths: This if ths.qual.isEmpty => true
case _ => false
)
if !sym.isAccessibleFrom(pathType) then
No("is not accessible")
else if sym.isConstructor || sym.is(ModuleClass) || sym.is(Bridge) || sym.is(ConstructorProxy) || sym.isAllOf(JavaModule) then
Skip
else if cls.derivesFrom(sym.owner) && (sym.owner == cls || !sym.is(Deferred)) then
// if the cls is a subclass of the owner of the symbol
// and either
// * the symbols owner is the cls itself
// * the symbol is not a deferred symbol
// * the symbol is an abstract member #22147
else if cls.derivesFrom(sym.owner) && (sym.owner == cls || !sym.is(Deferred) || isAbstractMember) then
No(i"is already a member of $cls")
else if pathMethod.exists && mbr.isType then
No("is a type, so it cannot be exported as extension method")
Expand Down
5 changes: 5 additions & 0 deletions tests/neg/exports3.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
trait P:
def foo: Int

class A extends P:
export this.foo // error