Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-10250

Erroneous type inference of closure in STC

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 3.0.9
    • 4.0.0-beta-2
    • Static Type Checker
    • None

    Description

      Sorry if this is a duplicate, but I couldn't identify it. I'm using the Vavr Option and Either types here:

      repository.findOne(id) // <- Option<Foo>
        .toEither(config.&defaultUri) // <- Either<URI, Foo>
        .map(linkProvider.&forFoo) // <- Either<URI, URI>
        ...
      

      This is the signature of the method being called:

      <L> Either<L, T> toEither(Supplier<? extends L> leftSupplier)
      

      At the invocation of toEither, the STC appears to correctly recognize that config.&defaultUri is a valid match for Supplier<URI> and approves the call. However, instead of inferring L=URI it infers L=Closure<URI>, apparently failing to "dereference" the closure into the functional interface, so that later calls expecting <URI, URI> fail because the STC thinks that Left is a closure.

      Inserting a type witness at toEither does seem to work, which I think is new with 3.0.9.

      *Update:* Optimism apparently premature. The problem appears to be that in fact toEither is overloaded, and the static compiler is selecting the immediate-value override instead of the Supplier override.

      Bizarrely (I would open a second ticket on this but have no idea how to cleanly repro), when I changed .& to :: just to see what would happen, I get a ClassFormatError under GRECLIPSE 4.3.0.v202108132133-e2106 (attached) and a stack overflow under groovyc 3.0.9:

          at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.inferMethodReferenceType (StaticTypeCheckingVisitor.java:3615)    at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitMethodCallArguments (StaticTypeCheckingVisitor.java:2750)    at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.inferMethodReferenceType (StaticTypeCheckingVisitor.java:3646)    at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.visitMethodCallArguments (StaticTypeCheckingVisitor.java:2750)    at org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor.inferMethodReferenceType (StaticTypeCheckingVisitor.java:3646)
      

      Explicitly providing this form does work, and appears to be a substantial improvement in 3.0.9's generics handling (is this the partial backport you meant?), because now the entire generic chain infers properly. I note that previously, the STC ignored generics in the as clause and always treated types as raw, but now it observes them, and I didn't gather this from the release notes.

      Attachments

        1. SubscriptionClickController.class
          6 kB
          Christopher Smith

        Activity

          People

            emilles Eric Milles
            chrylis Christopher Smith
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: