You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Joan Karadimov (JIRA)" <ji...@apache.org> on 2017/05/23 19:10:04 UTC

[jira] [Updated] (GROOVY-8202) void tail calls in closures break @CompileStatic type inference

     [ https://issues.apache.org/jira/browse/GROOVY-8202?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Joan Karadimov updated GROOVY-8202:
-----------------------------------
    Description: 
Consider this piece of code:

{code:java}
class Example {
	@CompileStatic
	static void test1() {
		Closure<String> x = {
			if (true) {
				"asd"
			} else {
				f()
				null
			}
		}
	}

	@CompileStatic
	static void test2() {
		Closure<String> x = { // [Static type checking] - Incompatible generic argument types. Cannot assign groovy.lang.Closure <java.lang.Object> to: groovy.lang.Closure <String>
			if (true) {
				"asd"
			} else {
				f()
			}
		}
	}

	@CompileStatic
	static String test3() {
		if (true) {
			"asd"
		} else {
			f()
		}
	}

	@CompileStatic
	static void f() {
	}
}
{code}

The code in _*test1*_ compiles correctly. The type of the closure in _*test2*_ is inferred as _*Closure<Object>*_ and that results in a static type checking error. There is an inconsistency here - in _*test3*_ the type inference yields _*String*_.

Basically - _*null*_ s are not considered when the type is inferred. Calls to void methods should not be either.

  was:
Consider this piece of code:

{code:java}
class Example {
	@CompileStatic
	static void test1() {
		Closure<String> x = {
			if (true) {
				"asd"
			} else {
				f()
				null
			}
		}
	}

	@CompileStatic
	static void test2() {
		Closure<String> x = { // [Static type checking] - Incompatible generic argument types. Cannot assign groovy.lang.Closure <java.lang.Object> to: groovy.lang.Closure <String>
			if (true) {
				"asd"
			} else {
				f()
			}
		}
	}

	@CompileStatic
	static String test3() {
		if (true) {
			"asd"
		} else {
			f()
		}
	}

	@CompileStatic
	static void f() {
	}
}
{code}

The code in _*test1*_ compiles correctly. The type of the closure in _*test2*_ is inferred as _*Closure<Object>*_. There is an inconsistency here - in _*test3*_ the type inference yields _*String*_.

Basically - _*null*_ s are not considered when the type is inferred. Calls to void methods should not be either.


> void tail calls in closures break @CompileStatic type inference
> ---------------------------------------------------------------
>
>                 Key: GROOVY-8202
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8202
>             Project: Groovy
>          Issue Type: Bug
>          Components: Static compilation
>    Affects Versions: 2.4.10
>            Reporter: Joan Karadimov
>            Priority: Minor
>
> Consider this piece of code:
> {code:java}
> class Example {
> 	@CompileStatic
> 	static void test1() {
> 		Closure<String> x = {
> 			if (true) {
> 				"asd"
> 			} else {
> 				f()
> 				null
> 			}
> 		}
> 	}
> 	@CompileStatic
> 	static void test2() {
> 		Closure<String> x = { // [Static type checking] - Incompatible generic argument types. Cannot assign groovy.lang.Closure <java.lang.Object> to: groovy.lang.Closure <String>
> 			if (true) {
> 				"asd"
> 			} else {
> 				f()
> 			}
> 		}
> 	}
> 	@CompileStatic
> 	static String test3() {
> 		if (true) {
> 			"asd"
> 		} else {
> 			f()
> 		}
> 	}
> 	@CompileStatic
> 	static void f() {
> 	}
> }
> {code}
> The code in _*test1*_ compiles correctly. The type of the closure in _*test2*_ is inferred as _*Closure<Object>*_ and that results in a static type checking error. There is an inconsistency here - in _*test3*_ the type inference yields _*String*_.
> Basically - _*null*_ s are not considered when the type is inferred. Calls to void methods should not be either.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)