-
Notifications
You must be signed in to change notification settings - Fork 21
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
Abstract type members are incorrectly forbidden in objects (unless inherited) #8217
Comments
Imported From: https://issues.scala-lang.org/browse/SI-8217?orig=1 |
@retronym said: Previous discussion: https://groups.google.com/forum/#!topic/scala-user/MiKsvizQBd4 |
@Blaisorblade said: class A { type T } is intentionally allowed. But what about objects? Why is the following forbidden? object WTF_A0 {
type T //Error: only classes can have declared but undefined members
} I don't think that objects were indeed meant to be special. Otherwise, the following should be also forbidden: trait A {
type T
}
object A extends A If this inconsistency is by design, I'd demand more explanation than this:
Additionally, on the implementation level, the mere fact that the the check for undefined members is different from the check for undefined inherited members seem debatable — I guess the former can be done earlier, but it seems the two checks should still share logic. |
@retronym said: |
@Blaisorblade said (edited on Jan 31, 2014 7:06:26 PM UTC): $ scala
Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51).
scala> object Foo {type A}
<console>:7: error: only classes can have declared but undefined members
object Foo {type A}
^ After: $ ./qbin/scala
Welcome to Scala version 2.11.0-20140131-194308-ea897b018a (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51).
scala> object Foo {type A}
defined object Foo Fix: --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1617,6 +1617,7 @@ trait Namers extends MethodSynthesis {
def symbolAllowsDeferred = (
sym.isValueParameter
|| sym.isTypeParameterOrSkolem
+ || sym.isAbstractType
|| context.tree.isInstanceOf[ExistentialTypeTree]
)
// Does the symbol owner require no undefined members? I'm also wondering about extending the check to concrete classes, while at it, since the reimplementation of these checks in refchecks is not run by the presentation compiler: @@ -1623,7 +1624,8 @@ trait Namers extends MethodSynthesis {
def ownerRequiresConcrete = (
!sym.owner.isClass
|| sym.owner.isModuleClass
|| sym.owner.isAnonymousClass
+ || sym.owner.isConcreteClass
)
if (sym hasAnnotation NativeAttr)
sym resetFlag DEFERRED |
@Blaisorblade said: |
@paulp said:
You and your wild ambitions. Once you're properly calibrated you will see that is an unusually clear and complete specification. |
@Blaisorblade said: Now, it would be cool if somebody would explain the world the point of undefined type members more clearly (answer: they encode existentials), but I certainly can't explain that undefined type members are allowed as long as this bug is not fixed. |
@adriaanm said: |
@Blaisorblade said: |
The behavior of Scalac (2.10.3) is inconsistent between objects WTF_A0 and A below: in one case an undefined type member is forbidden, in the other case it is allowed just because it is inherited.
-I speculate that forbidding abstract type members is not needed to ensure soundness, and allowing them also seems of dubious utility (but empty and distinct types are useful in Haskell in type-level programming).-
After clarifications: undefined type members can encode existential types, so they are allowed on purpose. The handling of
WTF_A0
is a mistake.I searched JIRA for "undefined type members" and found no relevant report. I can't find any applicable part of the spec describing the expected behavior.
The behavior also seems unintentional: The code producing this warning (src/compiler/scala/tools/nsc/typechecker/Namers.scala:Namer.validate) does not seem to be specific to type members — it is generally related to contained symbol, and there is no comment describing why undefined inherited members should be allowed while they should be forbidden if declared inline.
The text was updated successfully, but these errors were encountered: