-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
"cannot resolve reference to type" when type member of self-type appears in method type #11226
Comments
Minimized: trait ActorRef
trait ActorEventBus {
type Subscriber = ActorRef
}
trait ManagedActorClassification { this: ActorEventBus =>
def unsubscribe(subscriber: Subscriber, from: Any): Unit
def unsubscribe(subscriber: Subscriber): Unit
}
class Unsubscriber(bus: ManagedActorClassification) {
def test(a: ActorRef): Unit = bus.unsubscribe(a)
} Output from Scala compiler version 3.0.0-RC1-bin-SNAPSHOT-git-8d3275c: cannot take signature of MethodType(List(subscriber), List(TypeRef(TermRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),class Unsubscriber)),val bus),Subscriber)), TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),class Unit))
-- Error: i11226.scala:13:32 ---------------------------------------------------
13 | def test(a: ActorRef): Unit = bus.unsubscribe(a)
| ^
|cannot resolve reference to type (Unsubscriber.this.bus : ManagedActorClassification).Subscriber
|the classfile defining the type might be missing from the classpath |
@odersky Should we disallow references to members of the self-type in the types of public methods? |
Without the overload, the error is -- [E007] Type Mismatch Error: i11226.scala:12:48 ------------------------------
12 | def test(a: ActorRef): Unit = bus.unsubscribe(a)
| ^
| Found: (a : ActorRef)
| Required: Unsubscriber.this.bus.Subscriber |
I came across this bug today, here is the minimization I came up with: trait A {
class T()
}
trait B {
this: A =>
def f(a: Int = 0): Any
}
trait C extends B {
this: A =>
def f(t: T): Any
} Interestingly, removing the default value solves the problem. |
This might be the same bug as #15030 |
The issue seems still there is one form or another.
The following declaration seems like a possible workaround. private[api] trait GenericCollectionWithCommands[P <: SerializationPack] {
//self: GenericCollection[P] =>
// Workaround for self-type issue with Scala 3
// https://github.com/scala/scala3/issues/11226
protected def selfCollection: GenericCollection[P] |
We run into problems when referring to a member of a self type of a class that it not also a member of the class from outside via an asSeenFrom. One example is in 11226.scala where we see: ```scala trait ManagedActorClassification { this: ActorEventBus => def unsubscribe(subscriber: Subscriber): Unit } class Unsubscriber(bus: ManagedActorClassification) { def test(a: ActorRef): Unit = bus.unsubscribe(a) // error } ``` The problem is that `unsubscribe` refers to the type `Subscriber` which is not resolvable as a member of `bus`. one idea could be to rule out type signatures like `unsubscribe`, similar how we rule out public signatures referring to private members. But this could rule out existing valid programs. For instance, the `unsubscribe` signature is unproblematic if it gets only called with prefixes that inherit `ActorEventBus`. You could say that the problem was instead that the type of `bus` was not specific enough. In the long term, maybe restructing the signature is the right move. But for now, we just try to give better error messages in the case of existing failures. Fixes scala#11226
It's different from #15030. |
See #20477 for an attempt to give better error messages for these failures. It turns out the program in #11226 (comment) compiles in main, so I added a pos test for it. |
We run into problems when referring to a member of a self type of a class that it not also a member of the class from outside via an asSeenFrom. One example is in 11226.scala where we see: ```scala trait ManagedActorClassification { this: ActorEventBus => def unsubscribe(subscriber: Subscriber): Unit } class Unsubscriber(bus: ManagedActorClassification) { def test(a: ActorRef): Unit = bus.unsubscribe(a) // error } ``` The problem is that `unsubscribe` refers to the type `Subscriber` which is not resolvable as a member of `bus`. one idea could be to rule out type signatures like `unsubscribe`, similar how we rule out public signatures referring to private members. But this could rule out existing valid programs. For instance, the `unsubscribe` signature is unproblematic if it gets only called with prefixes that inherit `ActorEventBus`. You could say that the problem was instead that the type of `bus` was not specific enough. In the long term, maybe restructing the signature is the right move. But for now, we just try to give better error messages in the case of existing failures. Fixes scala#11226
We run into problems when referring to a member of a self type of a class that it not also a member of the class from outside via an asSeenFrom. One example is in 11226.scala where we see: ```scala trait ManagedActorClassification { this: ActorEventBus => def unsubscribe(subscriber: Subscriber): Unit } class Unsubscriber(bus: ManagedActorClassification) { def test(a: ActorRef): Unit = bus.unsubscribe(a) // error } ``` The problem is that `unsubscribe` refers to the type `Subscriber` which is not resolvable as a member of `bus`. one idea could be to rule out type signatures like `unsubscribe`, similar how we rule out public signatures referring to private members. But this could rule out existing valid programs. For instance, the `unsubscribe` signature is unproblematic if it gets only called with prefixes that inherit `ActorEventBus`. You could say that the problem was instead that the type of `bus` was not specific enough. In the long term, maybe restricting the signature is the right move. But for now, we just try to give better error messages in the case of existing failures. Fixes #11226
We run into problems when referring to a member of a self type of a class that it not also a member of the class from outside via an asSeenFrom. One example is in 11226.scala where we see: ```scala trait ManagedActorClassification { this: ActorEventBus => def unsubscribe(subscriber: Subscriber): Unit } class Unsubscriber(bus: ManagedActorClassification) { def test(a: ActorRef): Unit = bus.unsubscribe(a) // error } ``` The problem is that `unsubscribe` refers to the type `Subscriber` which is not resolvable as a member of `bus`. one idea could be to rule out type signatures like `unsubscribe`, similar how we rule out public signatures referring to private members. But this could rule out existing valid programs. For instance, the `unsubscribe` signature is unproblematic if it gets only called with prefixes that inherit `ActorEventBus`. You could say that the problem was instead that the type of `bus` was not specific enough. In the long term, maybe restructing the signature is the right move. But for now, we just try to give better error messages in the case of existing failures. Fixes #11226 [Cherry-picked 21261c0]
Compiler version
3.0.0-M3
Minimized code
I haven't managed to minimize the problem but is reproducible here:
https://github.com/akka/akka/tree/repro-scala3
sbt -Dakka.build.scalaVersion=3.0 akka-actor/compile
Output
Expectation
Compiles as with scalac 2.12 - 2.13
The text was updated successfully, but these errors were encountered: