Uses of Type Projection Operator Marked as Errors


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
Arch: x86 (32-bits)

Randall Schulz

Comment actions Permalink

Hi, Randall.

Could you provide any code example to reproduce this bug or point to paper you've tried to implement?

With best regards,

Comment actions Permalink


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

Comment actions Permalink

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}

Comment actions Permalink

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.


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


Please sign in to leave a comment.