Uses of Type Projection Operator Marked as Errors
Hi,
I'm transcribing some code from a paper into IDEA and it uses the type projection operator (the # sign). So far, two uses, both of them accepted by the compiler, are marked with red with the message "; or newline expected"
IDEA: 8.1.2 (#9852)
Scala plug-in: 0.2.24703
JDK / JVM: 1.6.0_13
OS: Linux (openSUSE 11.1, kernel 2.6.27.21-0.1-pae)
Arch: x86 (32-bits)
Randall Schulz
Please sign in to leave a comment.
Hi, Randall.
Could you provide any code example to reproduce this bug or point to paper you've tried to implement?
With best regards,
Ilya
Ilya,
I've attached the source file. It compiles (from within IDEA).
The header comment includes the title and Google Scholar cluster page URL for the paper from which I derived the code.
Randall Schulz
Attachment(s):
VisitorsOWG.scala
Heres a cut down example:
object TypeProjectionBug {
trait X {
type A <: {type X}
type B = (A)#X // fails, remove parens around A and it works.
}
}
My reading of the Scala spec suggests that this should actually be a compile error, although not a parse error. (A)#X is shorthand for Tuple1[A]#X. Maybe the scala compiler has a special case to allow the sort of thing in that paper.
I think the IntelliJ plugin incorrectly parses the parenthesised lists of types in Type.scala. If this is removed (see patch), the parse errors are gone.
Type ::= InfixType ‘=>’ Type
| ‘(’ [‘=>’ Type] ‘)’ ‘=>’ Type
| InfixType [ExistentialClause]
ExistentialClause ::= ‘forSome’ ‘{’ ExistentialDcl {semi ExistentialDcl} ‘}’
ExistentialDcl ::= ‘type’ TypeDcl
| ‘val’ ValDcl
InfixType ::= CompoundType {id [nl] CompoundType}
CompoundType ::= AnnotType {‘with’ AnnotType} [Refinement]
| Refinement
AnnotType ::= SimpleType {Annotation}
SimpleType ::= SimpleType TypeArgs
| SimpleType ‘#’ id
| StableId
| Path ‘.’ ‘type’
| ‘(’ Types [‘,’] ’)’
TypeArgs ::= ‘[’ Types ‘]’
Types ::= Type {‘,’ Type}
Attachment(s):
type-projection-parens.patch
A better read of the spec reveals that: "A tuple type (T1 , . . . , Tn ) is an alias for the class scala.Tuplen[T1 , . . . , Tn ], where n ≥ 2"
So if n=1, the parens are just for grouping. Makes sense, I guess, my confusion is a consequence of the overloaded meaning of parentheses.
In light of this, I think my patch in the previous post makes sense.
-jason
scala> object A { type T = (Int, Int)}
defined module A
scala> var at: A.T = (0, 0)
at: (Int, Int) = (0,0)
scala> object A { type T = (Int)}
defined module A
scala> var at: A.T = 0
at: A.T = 0
scala> object A { type T = ((Int))}
defined module A
scala> var at: A.T = 0
at: A.T = 0