Skip to content

Workaround #4819: Avoid creating incorrect JointRefDenotations #4829

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

Merged
merged 1 commit into from
Jul 25, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,9 @@ object Denotations {
* 4. The access boundary of sym2 is properly contained in the access
* boundary of sym1. For protected access, we count the enclosing
* package as access boundary.
* 5. sym1 a method but sym2 is not.
* 5. sym1 is a method but sym2 is not.
* 6. sym1 is a non-polymorphic method but sym2 is a polymorphic method.
* (to be consistent with infoMeet, see #4819)
* The aim of these criteria is to give some disambiguation on access which
* - does not depend on textual order or other arbitrary choices
* - minimizes raising of doubleDef errors
Expand All @@ -505,6 +507,7 @@ object Denotations {
accessBoundary(sym2).isProperlyContainedIn(accessBoundary(sym1)) ||
sym2.is(Bridge) && !sym1.is(Bridge) ||
sym1.is(Method) && !sym2.is(Method)) ||
sym1.info.isInstanceOf[MethodType] && sym2.info.isInstanceOf[PolyType] ||
sym1.info.isErroneous)

/** Sym preference provided types also override */
Expand Down
16 changes: 16 additions & 0 deletions tests/neg/i4819.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
trait One[X] {
def concat(suffix: Int): X = ???
}

trait Two[Y <: Foo] {
def concat[Dummy](suffix: Int): Y = ???
}

class Foo extends One[Foo] with Two[Foo] {
concat(0) // OK

// TODO: This does not typecheck because the polymorphic overload is masked
// (we merge the denotations for both overloads into one and always prefer
// MethodType to PolyType, instead we should return a MultiDenotation). See #4819.
concat[Int](0) // error (that should actually not be an error)
}
12 changes: 12 additions & 0 deletions tests/pos/i4819.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
trait One[X] {
def concat(suffix: Int): X = ???
}

trait Two[Y <: Foo] {
def concat[Dummy](suffix: Int): Y = ???
}

class Foo extends One[Foo] with Two[Foo] {
concat(0) // OK
// See also tests/neg/i4819.scala
}