Bug 484960 - [1.8] Compile error using orElse after streaming Map to Consumer with super in generic type
Summary: [1.8] Compile error using orElse after streaming Map to Consumer with super i...
Status: NEW
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.5.1   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks:
 
Reported: 2015-12-29 03:59 EST by Boris van Katwijk CLA
Modified: 2022-06-03 12:25 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Boris van Katwijk CLA 2015-12-29 03:59:40 EST
I ran into an unexpected compile error on line 13 (orElse line) of the following example class:

import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

public class Example<E> {
    public void mapMethod(Consumer<? super E> defaultConsumer) {
        Map<Object, Consumer<? super E>> map = new HashMap<>();
        Consumer<? super E> consumer = map.entrySet()
            .stream()
            .filter(x -> true)
            .map(Map.Entry::getValue)
            .findAny()
            .orElse(defaultConsumer); // <- Error here on orElse
    }
}

The message is:

The method orElse(Consumer<capture#3-of ? super E>) in the type Optional<Consumer<capture#3-of ? super E>> is not applicable for the arguments (Consumer<capture#6-of ? super E>)

However, it compiles fine with javac 1.8.0_45. Also worth mentioning is that on using a similar stream composition with a List<Consumer<? super E> instead of a map, it does compile.
Comment 1 Stephan Herrmann CLA 2015-12-29 12:32:52 EST
(In reply to Boris van Katwijk from comment #0)
> The message is:
> 
> The method orElse(Consumer<capture#3-of ? super E>) in the type
> Optional<Consumer<capture#3-of ? super E>> is not applicable for the
> arguments (Consumer<capture#6-of ? super E>)

At a quick glance this looks like a correct message to me. Types parameterized with different captures are not compatible.
 
> However, it compiles fine with javac 1.8.0_45.

Thanks for trying. Unfortunately, javac is quite "sloppy" in handling wildcard captures (see https://bugs.openjdk.java.net/browse/JDK-8016207), so this observation alone doesn't necessarily say that it's correct to accept that program.

> Also worth mentioning is that
> on using a similar stream composition with a List<Consumer<? super E>
> instead of a map, it does compile.

That sounds interesting, can you give a full example of that variant?
Comment 2 Boris van Katwijk CLA 2016-01-04 03:48:19 EST
> That sounds interesting, can you give a full example of that variant?

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class Example<E> {
	// List of Consumer of super of c: works!
	public void listMethod(Consumer<? super E> defaultConsumer) {
		List<Consumer<? super E>> list = new ArrayList<>();
		Consumer<? super E> consumer = list.stream()
			.filter(x -> true)
			.findAny()
			.orElse(defaultConsumer);
	}
}


Additionally I've copied the map variant to IntelliJ where it does compile, and also with javac as mentioned before. I also wrote unit tests which suggest that it uses the generic typing in a correct way, although those tests are not covering the full range of possibilities.
Comment 3 Eclipse Genie CLA 2022-06-03 12:25:17 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.