Skip to content

Structural types should conform with more Java types #6599

Open
@scabug

Description

@scabug

When using structural type scala sometimes successfully matches java class with it, and sometimes doesn't - see below:

Directory structure is as follows:

foo
foo/Incomp.java
baz
baz/UsesBar.scala
bar
bar/Bar.scala

where classes Incomp, Bar, UsesBar sources are:

// Incomp.java
package foo;

import java.util.List;
import java.util.ArrayList;

public class Incomp {
    
    public List returnsJavaList() {
        return new ArrayList();
    }
    
}
// Bar.scala
package bar

import foo.Incomp

object Bar {

        def useBogus(bogus: BogusType) {
            println("Hello, " + bogus.returnsJavaList().size().toString + "-element list!")
        }

        type BogusType = {
            def returnsJavaList(): java.util.List[_]
        }

        def useIncomp = useBogus(new Incomp)
}
// UsesBar.scala
package baz

import foo.Incomp
import bar.Bar

class UsesBar {

    Bar.useBogus(new Incomp)

}

There is a structural type defined in Bar.scala which Incomp is compatible with. Despite that, when I tried to compile Bar.scala along with Incomp.java I got this error:

maciej@maciej-laptop:~/tmp/scala-java$ ~/opt/scala-2.10.0-RC1/bin/scalac foo/Incomp.java bar/Bar.scala 
bar/Bar.scala:15: error: type mismatch;
 found   : foo.Incomp
 required: bar.Bar.BogusType
    (which expands to)  AnyRef{def returnsJavaList(): java.util.List[_]}
        def useIncomp = useBogus(new Incomp)
                                 ^
one error found

Now, everything compiles fine, when scalac has Incomp.class at its disposal:

maciej@maciej-laptop:~/tmp/scala-java$ javac foo/Incomp.java 
maciej@maciej-laptop:~/tmp/scala-java$ ~/opt/scala-2.10.0-RC1/bin/scalac bar/Bar.scala 
warning: there were 1 feature warnings; re-run with -feature for details
one warning found

I believe this incosistency alone would justify filing a bug report. But then, as it turns out, even having Incomp.class is not enough sometimes:

maciej@maciej-laptop:~/tmp/scala-java$ ~/opt/scala-2.10.0-RC1/bin/scalac baz/UsesBar.scala 
baz/UsesBar.scala:8: error: type mismatch;
 found   : foo.Incomp
 required: bar.Bar.BogusType
    (which expands to)  AnyRef{def returnsJavaList(): java.util.List[_]}
    Bar.useBogus(new Incomp)
                 ^
one error found

So I can't compile UsesBar neither with Incomp.java nor Incomp.class

maciej@maciej-laptop:~/tmp/scala-java$ ~/opt/scala-2.10.0-RC1/bin/scalac foo/Incomp.java baz/UsesBar.scala 
baz/UsesBar.scala:8: error: type mismatch;
 found   : foo.Incomp
 required: bar.Bar.BogusType
    (which expands to)  AnyRef{def returnsJavaList(): java.util.List[_]}
    Bar.useBogus(new Incomp)
                 ^
one error found

To compile UsesBar I had to compile it with Bar.scala

maciej@maciej-laptop:~/tmp/scala-java$ ~/opt/scala-2.10.0-RC1/bin/scalac bar/Bar.scala baz/UsesBar.scala 
warning: there were 1 feature warnings; re-run with -feature for details
one warning found

But adding Incomp.java would result in error again:

maciej@maciej-laptop:~/tmp/scala-java$ ~/opt/scala-2.10.0-RC1/bin/scalac foo/Incomp.java bar/Bar.scala baz/UsesBar.scala 
bar/Bar.scala:15: error: type mismatch;
 found   : foo.Incomp
 required: bar.Bar.BogusType
    (which expands to)  AnyRef{def returnsJavaList(): java.util.List[_]}
        def useIncomp = useBogus(new Incomp)
                                 ^
baz/UsesBar.scala:8: error: type mismatch;
 found   : foo.Incomp
 required: bar.Bar.BogusType
    (which expands to)  AnyRef{def returnsJavaList(): java.util.List[_]}
    Bar.useBogus(new Incomp)
                 ^
two errors found

This seems quite unpredictable - and while you can eventually compile what you want, provided that you compile all scala sources at once, this for example disrupts maven configuration, where test sources are compiled independently from the main source tree, resulting in errors similar to those shown above.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions