You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Eric Milles (Jira)" <ji...@apache.org> on 2021/04/25 09:32:00 UTC

[jira] [Comment Edited] (GROOVY-10053) STC: Wrong type inferred for lambda parameter in a generic method

    [ https://issues.apache.org/jira/browse/GROOVY-10053?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17331466#comment-17331466 ] 

Eric Milles edited comment on GROOVY-10053 at 4/25/21, 9:31 AM:
----------------------------------------------------------------

You can add a type argument to "map" as a workaround, in case you are stuck on this:
{code:groovy}
getNumbers().stream().filter(numberType::isInstance)
  .<T>map(numberType::cast).forEach(n -> set.add(num))
// ^^^
{code}

I see the same error when replacing "numberType::cast" with "n -> (T) n" or "\{ n -> (T) n \}".  With that, I have isolated the issue to {{StaticTypeCheckingVisitor#inferReturnTypeGenerics}}.  When the reference, lambda or closure return type {{T}} is compared to the "map" parameter type (see below), it cannot work out your "T" for "R" due to "? extends R".
{code:java}
interface Stream<T> extends BaseStream<T, Stream<T>> {
    <R> Stream<R> map(Function<? super T, ? extends R> mapper);
}
{code}


was (Author: emilles):
You can add a type argument to "map" as a workaround, in case you are stuck on this:
{code:groovy}
getNumbers().stream().filter(numberType::isInstance)
  .<T>map(numberType::cast).forEach(n -> set.add(num))
{code}

I see the same error when replacing "numberType::cast" with "n -> (T) n" or "{ n -> (T) n }".  With that, I have isolated the issue to {{StaticTypeCheckingVisitor#inferReturnTypeGenerics}}.  When the reference, lambda or closure return type {{T}} is compared to the "map" parameter type (see below), it cannot work out your "T" for "R" due to "? extends R".
{code:java}
interface Stream<T> extends BaseStream<T, Stream<T>> {
    <R> Stream<R> map(Function<? super T, ? extends R> mapper);
}
{code}

> STC: Wrong type inferred for lambda parameter in a generic method
> -----------------------------------------------------------------
>
>                 Key: GROOVY-10053
>                 URL: https://issues.apache.org/jira/browse/GROOVY-10053
>             Project: Groovy
>          Issue Type: Bug
>          Components: Static Type Checker
>         Environment: OpenJDK8
>            Reporter: Lyuben Atanasov
>            Assignee: Eric Milles
>            Priority: Major
>
> Following the fix of GROOVY-10049, a new issue has appeared. Consider the following code example:
> {code}
> class Test {
> 	Set<Number> getNumbers() {
> 		// mock return value, needed to demonstrate the issue
> 		return Collections.emptySet();
> 	}
> 	
> 	<T extends Number> Set<T> filterNumbers(Class<T> numberType) {
> 		Set<T> filteredNumbers = new HashSet<>();
> 		getNumbers().stream()
> 			.filter(numberType::isInstance)
> 			.map(numberType::cast)
> 			.forEach(num -> {
> 				filteredNumbers.add(num);
> 			});
> 		return filteredNumbers;
> 	}
> }
> def test = new Test()'
> test.filterNumbers(Integer);
> {code}
> Compiling with static type checking enabled produces an error:
> {noformat}
> Script_de4295e2a5171ce6c5ecd73605504d73.groovy: 14: [Static type checking] - Cannot call java.util.Set#add(T) with arguments [R] 
>  @ line 14, column 5.
>    				filteredNumbers.add(num);
> {noformat}
> This used to work fine before applying the fix for GROOVY-10049. Tested against https://github.com/apache/groovy/commit/e07f0112c5eff8d9c6828bd0ddb69e4b7f7cc1d6



--
This message was sent by Atlassian Jira
(v8.3.4#803005)