Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 400051 - [1.8][spec] Can a lambda throw exceptions when the throws clause of descriptor mentions a type variable ?
Summary: [1.8][spec] Can a lambda throw exceptions when the throws clause of descripto...
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.3   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: BETA J8   Edit
Assignee: Srikanth Sankaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 401003
  Show dependency tree
 
Reported: 2013-02-06 00:58 EST by Srikanth Sankaran CLA
Modified: 2013-02-16 23:11 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Srikanth Sankaran CLA 2013-02-06 00:58:52 EST
BETA_JAVA8:

This bug is to record & track a clarification request to the 335 EG:

// ---- 8< -------

The following lambda expression does not compile with 8b74, while the 
implementation of the method in a class does compile: 

// ------------ 
interface G1 { 
  <E extends Exception> Object m(E p) throws E; 
} 
interface G2 { 
  <F extends Exception> String m(F q) throws Exception; 
} 
interface G extends G1, G2 {} 

// G has descriptor <F extends Exception> ()->String throws F 

public class X { 
        
        G g = (x) -> { // Elided type is inferred from descriptor to be F 
            throw x;    // ~== throw new F() 
        }; 
} 

class Y implements G { 
        public <T extends Exception> String m(T t) throws T { 
                throw t; 
        } 
} 
// ----------------------- 

Is this a bug in the implementation or the specification ? 
Since the lambda cannot refer to the type variables of the 
descriptor by name nor declare its own, if 8b74 behavior is 
correct, that would mean that, no checked exceptions could 
be thrown from a lambda if the descriptor of the target 
interface method mentions a type variable in throws clause. 

My analysis is that the lambda should be accepted as it does 
not manufacture any fresh exceptions and simply throws an 
exception that is known to have satisfied the constraints at 
the invocation site, i.e no additional/unexpected surprises 
are there due the lambda throwing the object it was handed.
Comment 1 Srikanth Sankaran CLA 2013-02-06 01:00:46 EST
org.eclipse.jdt.core.tests.compiler.regression.NegativeLambdaExpressionsTest.test041() encodes current Eclipse compiler behavior which differs from javac 8b74
Comment 2 Srikanth Sankaran CLA 2013-02-06 07:59:53 EST
Two observations from the EG:

1. A lambda cannot implement a generic method. While the syntactic limitations
around not being able to provide type parameter are well know, even on an
inferred basis, this is not allowed. If the descriptor is
generic, then the compiler should refuse to compile. (For Reference
expressions, it is ok, assuming other constraints hold)

2. Javac has a bug that results in accepting a lambda expression that
implements a generic method. (in comment#0, the complaint is not about
the attempt to use a lambda expression to implement a generic function
descriptor, but about a throw)

I have adjusted our code base to reflect the clarification. We now issue
a message: 

"Illegal lambda expression: Method {0} of type {1} is generic"
Comment 3 Srikanth Sankaran CLA 2013-02-12 19:45:19 EST
(In reply to comment #2)
> Two observations from the EG:
> 
> 1. A lambda cannot implement a generic method. 

Whether to allow a lambda to implement a generic method is on the
basis that it would infer unmentionable type variables is opened
as a topic of discussion and I don't see much interest so far.

The spec is being clarified to explicitly ban a lambda from
implementing a generic method. javac's observed behavior has
been acknowledged as a bug.

Since ECJ's behavior has already been adjusted to ban this scenario,
closing this bug. Will reopen if there is any change in spec.