eclipse-jdt / eclipse-jdt/eclipse.jdt.core

Challenge exception inference

Open
#2,198 5 comments 0 reactions 1 assignee Claimed by @stephan-herrmann View on GitHub
Dominant language
Java
Stars
237
Forks
195
Avg merge
1d 12h
Merged PRs (30d)
47

Description

Follow-up from #1181, where I tried to create test cases that specifically challenge the interaction of lambda shape analysis and exception inference.

Firstly, I could hardly find any existing test cases in this area.

Secondly, a naive experiment surfaced a few differences to javac that need scrutiny.

Consider the following programm:
```
import java.io.FileNotFoundException;
import java.io.IOException;

class Foo {
boolean test() throws FileNotFoundException { return false; }
}
class Bar { }

public class Ex {

void test(Foo foo) throws IOException {
ThrowingFunction fun = throwingFunction(f -> {
if (f.test())
throw new IllegalAccessException();
return foo;
},
getEx());
}
public ThrowingFunction throwingFunction(
final ThrowingFunction function, X e) {
return function;
}
public ThrowingFunction throwingFunction(
final ThrowingFunction function, X e) {
return function;
}
X getEx() { return null; }
}
interface ThrowingFunction {
abstract T apply(T t) throws X;
}
```

(1) Compiled as given above we get:
* ecj: The method throwingFunction(ThrowingFunction, IOException) is ambiguous for the type Ex
* javac: reference to throwingFunction is ambiguous

(2) When we change the type bound of method `getEx()` to `extends IOException` then:
* ecj: Unhandled exception type IllegalAccessException
* javac: inference variable X#1 has incompatible bounds

(3) When we change the same type bound to `extends IllegalAccessError` then:
* ecj:
* The method test() is undefined for the type Bar
* Type mismatch: cannot convert from Foo to Bar
* javac:
* incompatible types: cannot infer type-variable(s) X (argument mismatch; bad return type in lambda expression Foo cannot be converted to Bar)

For (1) compilers are well aligned. But (2) and (3) show that ecj's inference accepts the program and leaves it to downstream phases to detect resulting errors, whereas javac succeeds to connect the respective problem to inference.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.