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

STC: Wrong return value type inferred for generic method with upper bound without parameters

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 3.0.8, 4.0.0-alpha-3
    • 4.0.0-beta-1
    • Static Type Checker
    • None
    • OpenJDK8

    Description

      When static compilation is enabled, and we have a method call for a generic method that returns a generic value with an upper bound, and the method does not have any parameters, the inferred return type is the upper bound instead of the type of the variable to which that value is assigned. To better illustrate the issue, here's an example of what doesn't work and some work-arounds:

      class Test {
      
      	<T extends Number> T getValue() {
      		return null;
      	}
      	
      	void methodWithIntParam(Integer param) {
      		// do nothing
      	}
      	
      	void test() {
      		// not working
      		Integer int1 = getValue();
      		methodWithIntParam(getValue());
      		
      		// working
      		Integer int2 = this.<Integer>getValue();
      		Integer int3 = (Integer) getValue();
      		methodWithIntParam(this.<Integer>getValue());
      		methodWithIntParam((Integer) getValue());
      	}
      }
      

      Compiling this code with static type checking enabled causes the following errors:

      Script_e94ec281a61eb83bce1a38580b498a48.groovy: 13: [Static type checking] - Cannot assign value of type java.lang.Number to variable of type java.lang.Integer
       @ line 13, column 18.
         		Integer int1 = getValue();
      
      Script_e94ec281a61eb83bce1a38580b498a48.groovy: 14: [Static type checking] - Cannot find matching method Test#methodWithIntParam(java.lang.Number). Please check if the declared type is correct and if the method exists.
       @ line 14, column 3.
         		methodWithIntParam(getValue());
      

      Note that if we just a define a generic method without any upper bounds to the generic value, type checking works as expected:

      <T> T getNumber() {
          return null;
      }
      
      Integer myInt = getNumber(); // this works!
      

      Attachments

        Issue Links

          Activity

            People

              emilles Eric Milles
              latanasov Lyuben Atanasov
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: