This site is maintained for archival purposes only. Eclipse projects have transitioned to GitHub and Eclipse GitLab. Use the Projects search tool to locate your project and access its latest code and issue tracker.
Bug 437444 - [1.8][compiler] Evaluate alternate integration between overload resolution and type inference
Summary: [1.8][compiler] Evaluate alternate integration between overload resolution an...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.4   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 4.5 M3   Edit
Assignee: Srikanth Sankaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 443467 455928 458806 459145 459504 461539 461571 461639 462006 462769 465192 467627 468831 469217 470270 470817 470847 472361 (view as bug list)
Depends on: 446434
Blocks: 432605
  Show dependency tree
 
Reported: 2014-06-14 09:24 EDT by Stephan Herrmann CLA
Modified: 2017-04-14 08:43 EDT (History)
25 users (show)

See Also:
stephan.herrmann: review+


Attachments
Evolving solution - with warts, hacks and all. (206.42 KB, patch)
2014-09-29 15:01 EDT, Srikanth Sankaran CLA
no flags Details | Diff
More closer to home - Revised patch (210.97 KB, patch)
2014-09-30 15:36 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Revised patch - Just two failures in RunAllJava8Tests (235.43 KB, patch)
2014-10-03 16:36 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Patch containing only test changes. (13.02 KB, patch)
2014-10-05 05:53 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Changed files that need only cursory glance through. (16.51 KB, patch)
2014-10-05 06:09 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Changes requiring close inspection. (154.71 KB, patch)
2014-10-05 07:57 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Cumulative patch (184.24 KB, patch)
2014-10-05 08:15 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Cumulative patch - Passes all JDT/Core tests (184.18 KB, patch)
2014-10-05 09:22 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Proposed patch - Ready for review, passes all tests (186.64 KB, patch)
2014-10-07 12:17 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Incremental fix to bug 428811 (4.66 KB, patch)
2014-10-07 23:02 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Incremental fix to bug 444891 (specification amendment) (30.11 KB, application/octet-stream)
2014-10-09 14:04 EDT, Srikanth Sankaran CLA
no flags Details
Incremental fix to bug 444891 (specification amendment) (30.12 KB, patch)
2014-10-09 23:53 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Incremental fix to bug 432626 (6.09 KB, patch)
2014-10-11 05:56 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Cumulative proposed patch (221.82 KB, patch)
2014-10-12 06:11 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Cumulative proposed patch (220.14 KB, patch)
2014-10-13 23:34 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Patch to remove deviations. (8.85 KB, patch)
2014-10-15 04:52 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Fixes for two problems found by other IBM projects. (5.21 KB, patch)
2014-10-17 00:52 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Fix for JRE8 build problems (6.01 KB, patch)
2014-10-17 08:12 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Patch with much clearer version of Scope.parameterCompatibilityLevel (12.45 KB, patch)
2014-10-18 01:12 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Patch to eliminate post inference compatibility checks. (12.85 KB, patch)
2014-10-18 10:42 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Merged patch brought up to date with master. (220.19 KB, patch)
2014-10-21 02:15 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Correct merged patch (223.00 KB, patch)
2014-10-21 02:20 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Addendum for capture bound change under compile time constant (6.07 KB, patch)
2014-10-24 23:08 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Addendum to incorporate review comments (14.05 KB, patch)
2014-10-25 02:51 EDT, Srikanth Sankaran CLA
no flags Details | Diff
Addendum to incorporate review comments (19.78 KB, patch)
2014-10-25 16:41 EDT, Srikanth Sankaran CLA
no flags Details | Diff
CombinedPatch(Comment 177) (60.16 KB, patch)
2014-10-27 01:16 EDT, shankha banerjee CLA
no flags Details | Diff
Revised patch incorporating review comments (19.85 KB, patch)
2014-10-27 09:01 EDT, Srikanth Sankaran CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Stephan Herrmann CLA 2014-06-14 09:24:32 EDT
When investigating differences between javac and ecj, we can identify situation(s) where ecj finds an acceptable solution, which javac does not find, while in fact JLS does not provide an explicit path towards that solution.

This bug shall collect deviations that match the above description. Users will typically *not* complain about these, but still being more in line with JLS is desirable.
Comment 1 Stephan Herrmann CLA 2014-06-14 10:04:03 EDT
The example from https://stackoverflow.com/questions/21905169/java8-ambiguity-with-lambdas-and-overloaded-methods demonstrates a situation where users where surprised that javac8 reports ambiguity. Ecj does *not* report this ambiguity, which is nice from a users' p.o.v. but may be wrong from a JLS p.o.v.

Reporting ambiguity is avoided by our initial stanza inside Scope.mostSpecificMethodBinding, where we recheck parameterCompatibilityLevel in knowledge of substitutions performed during applicability inference.

This stanza is not mandated by JLS, but OTOH, it is required in order to establish javac compatibility for many other situations. Prominent example: bug 429490 required this stanza both for the original example as well as for bug 429490 comment 33. Other changes that lead to the current situation:
- bug 427628
- bug 428366 comment 2

Ergo: we should weed out the various reasons why we need that stanza of checks, like:
- filter out overridden methods which should never have entered the inference in the first place
- avoid ambiguity with some ad-hoc reasoning because javac doesn't report any
Comment 2 Srikanth Sankaran CLA 2014-09-17 14:35:09 EDT
(In reply to Stephan Herrmann from comment #1)
> The example from
> https://stackoverflow.com/questions/21905169/java8-ambiguity-with-lambdas-
> and-overloaded-methods demonstrates a situation where users where surprised
> that javac8 reports ambiguity. Ecj does *not* report this ambiguity, which
> is nice from a users' p.o.v. but may be wrong from a JLS p.o.v.
> 
> Reporting ambiguity is avoided by our initial stanza inside
> Scope.mostSpecificMethodBinding, where we recheck
> parameterCompatibilityLevel in knowledge of substitutions performed during
> applicability inference.

This is creating problems for us - https://bugs.eclipse.org/bugs/show_bug.cgi?id=443596 is an example. The materialized PGMB as well as call site arguments
have captures and what is a perfectly applicable method gets rejected :(

In that bug I also see odd captures like (IIRC) ? extends ? extends ? Type1 & Type2 - does that make sense.

Problem is compounded by ICTB not implementing uncapture (yet).

ICTB is also not hooked up everywhere in isCompatibleWith and isEquivalent to etc.

What would it take to move to reusing the existing Binding.INTERSECTION_TYPE wrapped in a WildcardBinding instead of ICTB Stephan ?
Comment 3 Srikanth Sankaran CLA 2014-09-17 14:36:30 EDT
(In reply to Srikanth Sankaran from comment #2)

> Problem is compounded by ICTB not implementing uncapture (yet).

Does not implement swapResolved either. Just things to watch for.
Comment 4 Stephan Herrmann CLA 2014-09-17 17:54:48 EDT
(In reply to Srikanth Sankaran from comment #2)
> What would it take to move to reusing the existing Binding.INTERSECTION_TYPE
> wrapped in a WildcardBinding instead of ICTB Stephan ?

I see your point. Hm, originally I didn't have my stakes in ICTB, but meanwhile inference is using ICTB in some places as the canonical representation of "intersection types". So, removing ICTB is slightly delicate, but I see no hard reason against.

OTOH, when wrapping such thing in a WB, what assumptions are clients making when they see a WB? We won't have meaningful values for rank and typeVariable, but could be harmless? If we set boundKind to EXTENDS, even WB.signature() could work for an intersection type.

Maybe, it's even more educating to look at what clients expect when they see Binding.INTERSECTION_TYPE? Anything wildcardish in that area? If so, that could be a killer?

If feasible, I'd welcome, if we manage to reduce the number of Binding classes.
Comment 5 Stephan Herrmann CLA 2014-09-17 17:58:47 EDT
(In reply to Srikanth Sankaran from comment #2)
> (In reply to Stephan Herrmann from comment #1)
> > The example from
> > https://stackoverflow.com/questions/21905169/java8-ambiguity-with-lambdas-
> > and-overloaded-methods demonstrates a situation where users where surprised
> > that javac8 reports ambiguity. Ecj does *not* report this ambiguity, which
> > is nice from a users' p.o.v. but may be wrong from a JLS p.o.v.
> > 
> > Reporting ambiguity is avoided by our initial stanza inside
> > Scope.mostSpecificMethodBinding, where we recheck
> > parameterCompatibilityLevel in knowledge of substitutions performed during
> > applicability inference.
> 
> This is creating problems for us -
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=443596 is an example. The
> materialized PGMB as well as call site arguments
> have captures and what is a perfectly applicable method gets rejected :(

but where did the PGMB get its captures from? Shouldn't those be identical to the call site arguments in this case? Could be a bug in the area of capture bounds during inference...
Comment 6 Srikanth Sankaran CLA 2014-09-17 20:06:20 EDT
(In reply to Stephan Herrmann from comment #4)

> OTOH, when wrapping such thing in a WB, what assumptions are clients making
> when they see a WB? We won't have meaningful values for rank and
> typeVariable, but could be harmless? If we set boundKind to EXTENDS, even
> WB.signature() could work for an intersection type.
> 
> Maybe, it's even more educating to look at what clients expect when they see
> Binding.INTERSECTION_TYPE? Anything wildcardish in that area? If so, that
> could be a killer?

Given a WildcardBinding with binding kind set to INTERSECTION_TYPE is what Java 7
engine uses shouldn't we expect all these concerns to be addressed already ?
Are there any special requirements for Java 8 case that you can recall off the
top of your head that ICTB has been extended to support ?
Comment 7 Srikanth Sankaran CLA 2014-09-17 20:07:11 EDT
(In reply to Stephan Herrmann from comment #5)

> but where did the PGMB get its captures from? Shouldn't those be identical
> to the call site arguments in this case? Could be a bug in the area of
> capture bounds during inference...

I'll sit down with Shankha next week and understand this in more detail and
share my findings.
Comment 8 Srikanth Sankaran CLA 2014-09-19 05:43:57 EDT
I am curious about why inferInvocation type is split from PGMB.computeCompatibleMethod - i.e why doesn't PGMB.computeCompatibleMethod
return a fully inferred method considering target type et all, as the Java 7 
engine does ?
Comment 9 Stephan Herrmann CLA 2014-09-19 09:47:27 EDT
(In reply to Srikanth Sankaran from comment #8)
> I am curious about why inferInvocation type is split from
> PGMB.computeCompatibleMethod - i.e why doesn't PGMB.computeCompatibleMethod
> return a fully inferred method considering target type et all, as the Java 7 
> engine does ?

Are you questioning the split into 18.5.1 and 18.5.2?

Have you seen the argument "inferenceLevel" in PGMB.computeCompatibleMethod?
Comment 10 Srikanth Sankaran CLA 2014-09-25 20:37:39 EDT
(In reply to Stephan Herrmann from comment #9)

> Have you seen the argument "inferenceLevel" in PGMB.computeCompatibleMethod?

Yes. 

I see that MessageSend never returns a poly type binding. I suspect, this will integrate a lot cleanly if we don't have these levels and PGMB.computeCompatibleMethod

    - where expression context defines a target type and a target type is
available or where expression context does not define a target type
        - returns a fully instantiated method on success (invocation type inferred)
        - returns null on failure.

    - where expression context defines a target type and a target type is
not available (invocation context)
       - performs applicability inference and if it fails return null.
       - if applicability inference succeeds returns a method it returns today
BUT with its return type set to PolyTypeBinding.

This would fit well with the general overload resolution scheme which is driven
off of two calls: isCompatibleWith and sIsMoreSpecific - which MessageSend would
have to implement - there was a patch I posted earlier that had infrastructure
support for these.

If this is in place, then F in Scope.java does not have to deal with inference
at all. All the various rebind methods would go away too and all the inner poly
expression resolution can happen in one place in AST.resolvePoly*

I'll see if I can get Sasi to prototype this solution and we can see what
it looks like and see if it is worth integrating. My gut feel is it will 
significantly simplify the interaction between F & G and get rid of a few
bugs there.

Sasi, this would be a very nice project to work on after lambda shape analysis.
Let us discuss next week.
Comment 11 Stephan Herrmann CLA 2014-09-27 12:22:44 EDT
Just to document how we got here: I was integrating inference with the general mechanisms of method lookup under the premise to essentially keep the 1.7- code for method lookup as is.

If you develop a second universe of the Scope.findMethod family of methods which is structurally closer to the 1.8 spec, this will certainly give a cleaner solution for 1.8 inference, too (for the price of code duplication).

I'm not sure if this will completely remove the need for rebinding etc. but we'll find out when we get there, I suppose.
Comment 12 Srikanth Sankaran CLA 2014-09-28 08:23:39 EDT
(In reply to Stephan Herrmann from comment #11)
> Just to document how we got here: I was integrating inference with the
> general mechanisms of method lookup under the premise to essentially keep
> the 1.7- code for method lookup as is.
> 
> If you develop a second universe of the Scope.findMethod family of methods
> which is structurally closer to the 1.8 spec, this will certainly give a
> cleaner solution for 1.8 inference, too (for the price of code duplication).
> 
> I'm not sure if this will completely remove the need for rebinding etc. but
> we'll find out when we get there, I suppose.

I have made lots of progress on this - so far it looks very promising.
I have about 40+ failures to clean up in RunOnlyJava8Tests before declaring
victory on the first milestone.

I am noticing some "interesting" results produced by inference:

Given:

 List<Person> roster = new ArrayList<>();
        
        Map<String, Person> map = 
            roster
                .stream()
                .collect(
                    Collectors.toMap(
                        Person::getLast,
                        Function.identity() 
                    ));

The PGMB for collect has this signature:
    Collector<? super Person, Object ,Map<java.lang.String,Person>>
as can be seen in the hover.

This is wrong. It should be 
    Collector<? super Person, ? ,Map<java.lang.String,Person>>

If you extract the toMap call and assign it to a variable of the same
type we incorrectly infer:

Collector<? super Person, Object ,Map<java.lang.String,Person>> some =
           Collectors.toMap(
                Person::getLast,
                Function.identity() 
            );

This does not compile (correct)

While this compiles (correct again)
Collector<? super Person, ?,Map<java.lang.String,Person>> some =
           Collectors.toMap(
                Person::getLast,
                Function.identity() 
            );

Due to our bypassing re-evaluation of inner expressions and directly
updating the bindings, we are able to get away with this - 

This shows up as a problem in the new implementation. I'll see what needs
to be done.
Comment 13 Srikanth Sankaran CLA 2014-09-28 08:26:51 EDT
(In reply to Srikanth Sankaran from comment #10)

> Sasi, this would be a very nice project to work on after lambda shape
> analysis.
> Let us discuss next week.

I started looking into what it would take and the scope of it turns out to be
very large (my evolving patch modifies ~30 files and the patch is ~4 KLOC)
not the best choice for beginner project, so let me handle this and I'll continue
to look for interesting work for you and Shankha in other areas.
Comment 14 Srikanth Sankaran CLA 2014-09-29 15:01:18 EDT
Created attachment 247456 [details]
Evolving solution - with warts, hacks and all.

This patch completely rewires the integration between part G & part F. This
looks very very promising IMO. I'll write detailed design notes once I confirm
it will fly.

Still fails 18 tests in RunOnlyJava8Tests - this is under investigation.

Stephan, CEF:290 reads:

TypeBinding rPrime = rAppl.capture(inferenceContext.scope, 14); // FIXME capture position??

Consider your wrist slapped :) Actually it made me LOL, after a long 
investigation led me to there :)
Comment 15 Srikanth Sankaran CLA 2014-09-29 15:10:02 EDT
One thing that was not clear to me was whether in the current scheme of
things, inner poly expressions are fully re-resolved or not. It appears
that in some paths we simply update the bindings and not reevaluate the
expression against the eventual target type ? If so that would be problematic
since there is prologue - find method - epilogue protocol. After the call
to findMethodBinding() there is a big body of code in MessageSend for example.

I say this because, some of the bindings computed in for example https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444 are wrong and reevaluation
would have reported the error - we silently compile the program.

This is proving to be a very challenging yet fun work - hopefully it will
fly and we will have a very strong and clean integration that should serve
us in good stead.
Comment 16 Stephan Herrmann CLA 2014-09-29 16:19:43 EDT
(In reply to Srikanth Sankaran from comment #15)
> One thing that was not clear to me was whether in the current scheme of
> things, inner poly expressions are fully re-resolved or not. It appears
> that in some paths we simply update the bindings and not reevaluate the
> expression against the eventual target type ? If so that would be problematic
> since there is prologue - find method - epilogue protocol. After the call
> to findMethodBinding() there is a big body of code in MessageSend for
> example.

You're right, this isn't fully kosher. As for checking argument expressions against final target types I'm silently assuming that inference won't produce a solution that would fail such a check. For other checks I have no "excuse".

 
> I say this because, some of the bindings computed in for example
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444 are wrong and
> reevaluation
> would have reported the error - we silently compile the program.

Which particular check would fail in that example?

Historically, when first working on MessageSend I was still hoping that processing order could essentially be maintained as in 1.7- times. When specific problems re diamond allocations occurred, I bit the bullet and split that resolve method into three parts.
After doing so for AllocationExpression, it sounds like a good idea to revisit MessageSend and try if the approach from AllocationExpression could be transferred also to MessageSend: separate those parts concerning tentative resolve from those that are done after overload resolution & inference have picked the final method & types.
Comment 17 Srikanth Sankaran CLA 2014-09-29 20:24:21 EDT
(In reply to Stephan Herrmann from comment #16)

> > I say this because, some of the bindings computed in for example
> > https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444 are wrong and
> > reevaluation
> > would have reported the error - we silently compile the program.
> 
> Which particular check would fail in that example?

I was working with so many snippets I don't know where I found the problem,
I didn't recheck whether the code in https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444 exhibits the problem, perhaps it does, but ...

Any nested inference where the nested call returns a wildcard parameterized
type would/should fail re-evaluation of the nested poly method call since
re-evaluation of the MessageSend would "recapture" the returned expression 
and we have no mechanisms in place to recognize they are identical captures 
of the same wildcard.

In the evolving patch, I first attempted to solve the problem by associating the
capturing ASTNode with the capture, but this falls flat because we copy 
lambdas and the original capture during type inference is from an alien
parallel universe :)

Finally, I have had to change TypeSystem to hand out unique captures on a 
CUD basis: i.e new CaptureBinding(...) is not safe anymore, LE.createCapturedWildcard should be used instead - this will "intern" captures
in such a way that recaptures from the safe site would return the prior capture.

Luckily, we didn't need to create parallel Scope's and LEs, so this should
work for us.

    

> 
> Historically, when first working on MessageSend I was still hoping that
> processing order could essentially be maintained as in 1.7- times. When
> specific problems re diamond allocations occurred, I bit the bullet and
> split that resolve method into three parts.
> After doing so for AllocationExpression, it sounds like a good idea to
> revisit MessageSend and try if the approach from AllocationExpression could
> be transferred also to MessageSend: separate those parts concerning
> tentative resolve from those that are done after overload resolution &
> inference have picked the final method & types.
Comment 18 Srikanth Sankaran CLA 2014-09-29 20:27:02 EDT
(In reply to Srikanth Sankaran from comment #17)

> Any nested inference where the nested call returns a wildcard parameterized
> type would/should fail re-evaluation of the nested poly method call since

Correction: 

The above *and* inference solution on the aggregate basis found some instantiation
that involved a captured wildcard that loops through outer and inner.
Comment 19 Stephan Herrmann CLA 2014-09-30 08:15:33 EDT
(In reply to Srikanth Sankaran from comment #18)
> (In reply to Srikanth Sankaran from comment #17)
> 
> > Any nested inference where the nested call returns a wildcard parameterized
> > type would/should fail re-evaluation of the nested poly method call since
> 
> Correction: 
> 
> The above *and* inference solution on the aggregate basis found some
> instantiation
> that involved a captured wildcard that loops through outer and inner.

If it's indeed a type compatibility check post findMethod-with-inference, then performing those checks might be wrong, actually. If inference finds a solution it is correct by definition. We should just trust in its result, no? I thought you might have observed issues regarding visility, staticness, missing enclosing instance or such. Some of those might not be covered by inference, indeed.
Comment 20 Srikanth Sankaran CLA 2014-09-30 08:21:34 EDT
(In reply to Stephan Herrmann from comment #19)

> If it's indeed a type compatibility check post findMethod-with-inference,
> then performing those checks might be wrong, actually. If inference finds a
> solution it is correct by definition. We should just trust in its result,
> no? 

I am saying it is just an implementation detail today that will result in inner's
reevaluation to fail.  If the inner is reevaluated and it applies wildcard
capture on its result value - the capture should not act as a fresh capture,
that does not make sense but our implementation of PTB.capture() is not set
up to handle the case.
Comment 21 Srikanth Sankaran CLA 2014-09-30 15:36:39 EDT
Created attachment 247501 [details]
More closer to home - Revised patch

This patch fails 15 tests in RunAllJava8Tests. At least half of them require
simply remastering the expected result - since we now always reevaluate the
inner expressions we get additional errors. So very close to being green.

I have made sure various experimental changes I had in the earlier version
are removed.

I plan to release a first batch of infrastructure changes that have no real bearing
on the rest of the work - just so we have sharper focus and less distraction.

This change set will be carefully selected so the final question of moving
forward with solution or not does not become fait_accompli of sorts. Every
change pertinent to the applicability :) of the core solution will go through
the review process.

I'll write up detailed design document and a structured review plan once all tests are green - i.e in some cases it does make sense to view the delta in the 
comparator, but just read the new code etc.
Comment 22 Srikanth Sankaran CLA 2014-09-30 15:40:13 EDT
The scope has broadened. Adjusted the title accordingly.
Comment 23 Srikanth Sankaran CLA 2014-10-03 16:36:36 EDT
Created attachment 247615 [details]
Revised patch - Just two failures in RunAllJava8Tests

Once those are addressed, I'll start the clean up/polish + document the code
changes.
Comment 24 Srikanth Sankaran CLA 2014-10-04 10:53:22 EDT
Today is the day I am high on questions and low on answers.

Down to one failure, but the last one has me in a bind: GRT.testBug431408:

Looking at this passage:

Otherwise, if R θ is a parameterized type, G<A1, ..., An>, and one of A1, ..., An is a wildcard, then, for fresh inference variables β1, ..., βn, the 
constraint 
formula ‹G<β1, ..., βn> → T› is reduced and incorporated, along with the bound 
G<β1, ...,βn> = capture(G<A1, ..., An>), with B2.

I am having trouble mapping this to our implementation: As already discussed
and acknowledged 

1. there is no capture in our code. 

2. I also don't see the bound G<β1, ...,βn> = capture(G<A1, ..., An>) being 
reduced and incorporated, but could that have been by design ? We instead keep 
track of this capture bound details in the bound set and handle it during 
incorporation.

Is this indirect strategy because 18.1.3 says:

A bound of the form G<α1, ..., αn> = capture(G<A1, ..., An>) indicates that 
α1, ..., αn are placeholders for the results of capture conversion. This is 
necessary because capture conversion can only be performed on a proper type, 
and the inference variables in A1, ..., An may not yet be resolved.

3. R θ is a .... passage calls for fresh variables explicitly, we are
reusing existing variables - Is this right ? 

4. Should we creating new inference variables for arguments that are plain
types ? if R is SomeType<T, String> does it make sense to create an inference
variable for String ? 

5. Should we be creating fresh variables against the generic type's type
variables as opposed to the parameterized type's type arguments ?

6. Does the while loop in incorporate that handles capture bounds effectively
amount to the capture bound being incorporated ? 

7. There are some passages that talk about all inference variables being
instantiated before capture bounds being processed. Are we handling this
correctly ?
Comment 25 Stephan Herrmann CLA 2014-10-04 15:34:30 EDT
(In reply to Srikanth Sankaran from comment #24)
> Today is the day I am high on questions and low on answers.
> 
> Down to one failure, but the last one has me in a bind: GRT.testBug431408:
> 
> Looking at this passage:
> 
> Otherwise, if R θ is a parameterized type, G<A1, ..., An>, and one of A1,
> ..., An is a wildcard, then, for fresh inference variables β1, ..., βn, the 
> constraint 
> formula ‹G<β1, ..., βn> → T› is reduced and incorporated, along with the
> bound 
> G<β1, ...,βn> = capture(G<A1, ..., An>), with B2.
> 
> I am having trouble mapping this to our implementation: As already discussed
> and acknowledged 
> 
> 1. there is no capture in our code.

In bug 445274 comment 2 I acknowledged this as a bug. Today, however, I believe this was premature: the word "capture" in these constraints is just a symbol that must not be evaluated, because when processing the capture bound we only operate on the original G, A1, ... An (see, e.g., 18.3.2). No part of the spec seems to use the (evaluated) *type* "capture(G<A1,...An>)".

I see it similar to the relation "→throws", all forms listed in 18.1.2 and 18.1.3 are forms of contraints/bounds to be processed by pattern matching according to the rules of chap.18, *not* by regular evaluation.

 
> 2. I also don't see the bound G<β1, ...,βn> = capture(G<A1, ..., An>) being 
> reduced and incorporated, but could that have been by design ? We instead
> keep 
> track of this capture bound details in the bound set and handle it during 
> incorporation.
> 
> Is this indirect strategy because 18.1.3 says:
> 
> A bound of the form G<α1, ..., αn> = capture(G<A1, ..., An>) indicates that 
> α1, ..., αn are placeholders for the results of capture conversion. This is 
> necessary because capture conversion can only be performed on a proper type, 
> and the inference variables in A1, ..., An may not yet be resolved.

Right, "capture" bounds are handled specifically, these only appear in
- 18.1.3 (definition)
- 18.3.2 (incorporation)
- 18.4 (considered for inference variable dependencies and during actual resolution)
- 18.5.2 (produces these bounds)

In particular, reduction is applied to *constraints* - capture bounds, however, are already considered as bounds, hence no reduction is necessary in fact.

See that also "throws" bounds are handled in a separate structure.


> 3. R θ is a .... passage calls for fresh variables explicitly, we are
> reusing existing variables - Is this right ? 

We're looking at this line of code, right?
  InferenceVariable[] betas = inferenceContext.addTypeVariableSubstitutions(arguments);

Inside that method, we essentially create fresh type variables, but indeed we exempt existing inference variables. I'd have to dig deeper to retrieve the case where this exception was needed. Might be worth trying if this exception is still needed.

> 4. Should we creating new inference variables for arguments that are plain
> types ? if R is SomeType<T, String> does it make sense to create an inference
> variable for String ? 

Here I see some room for interpretation, indeed. spec speaks of the full set of "fresh inference variables β1, ..., βn", without explicit exceptions. I'm already excluding inference variables. When substituting String by βi, aren't we immediately deriving a bound βi = String ? In that case avoiding this βi in the first place might be an optimization, but I wouldn't expect this to change observable behavior. Have you observed differently?

Maybe the same reasoning actually holds for existing inference variables, implying it doesn't really matter whether or not we create an inference variable for an inference variable.
 
> 5. Should we be creating fresh variables against the generic type's type
> variables as opposed to the parameterized type's type arguments ?

I don't think so. Spec explicitly says "R θ is a parameterized type, G<A1, ..., An>". What we need are new bounds that "capture" information about these A1, ... An, which are type arguments.

> 6. Does the while loop in incorporate that handles capture bounds effectively
> amount to the capture bound being incorporated ? 

Yes, that loop implements 18.3.2.


> 7. There are some passages that talk about all inference variables being
> instantiated before capture bounds being processed. Are we handling this
> correctly ?

Where do you see this? 
In fact treating capture() purely as a symbol implies that we evaluate all constraints and bounds before actually performing any capture.

HTH
Comment 26 Srikanth Sankaran CLA 2014-10-04 20:01:05 EDT
(In reply to Stephan Herrmann from comment #25)

> In bug 445274 comment 2 I acknowledged this as a bug. Today, however, I
> believe this was premature: the word "capture" in these constraints is just
> a symbol that must not be evaluated, because when processing the capture
> bound we only operate on the original G, A1, ... An (see, e.g., 18.3.2). No
> part of the spec seems to use the (evaluated) *type* "capture(G<A1,...An>)".

You are right that 18.3.2 operates on original G, However, I don't think
capture is just a symbol there - 18.5.2 "Otherwise, if R θ is a parameterized
type, G<A1, ..., An>," portion needs a capture for correctness. So I think
the right thing to do is to apply the capture, but for 18.3.2 operate on
the uncaptured type.

> but I wouldn't expect
> this to change observable behavior. Have you observed differently?

I didn't try - but I expect no change to observable behavior either.

> Maybe the same reasoning actually holds for existing inference variables,
> implying it doesn't really matter whether or not we create an inference
> variable for an inference variable.

Would think so.

> > 6. Does the while loop in incorporate that handles capture bounds effectively
> > amount to the capture bound being incorporated ? 
> 
> Yes, that loop implements 18.3.2.

OK, more questions.

(8) The only place where I see us adding an entry to BoundSet.captures is
in inferPolyInvocation* - Are there supposed to be other places that the
implementation is missing (I have missed noticing ?). The choice of Set and
the iteration makes me expect other. 18.3 preamble talks about "New capture 
variables are not generated when reducing subtyping constraints". Is this
saying no new capture bounds are created ? It says variables though.

(9) What necessitates this stashing of the capture bound in BoundSet.captures
and processing it during next round of incorporation rather than doing it 
right away in inferPoly* ? 

(10) After the round of incorporation, we immediately call captures.clear()
Is that correct ? There are quite a few clauses that read like if there exist
a capture bound ... for example 18.4 requires it. Should we not be clearing
this. but instead be setting a bit to say we have processed the capture bound ?
Comment 27 Srikanth Sankaran CLA 2014-10-05 01:12:10 EDT
(In reply to Stephan Herrmann from comment #25)

> > 4. Should we creating new inference variables for arguments that are plain
> > types ? if R is SomeType<T, String> does it make sense to create an inference
> > variable for String ? 
> 
> Here I see some room for interpretation, indeed. spec speaks of the full set
> of "fresh inference variables β1, ..., βn", without explicit exceptions. I'm
> already excluding inference variables. When substituting String by βi,
> aren't we immediately deriving a bound βi = String ?

Eureka !

> aren't we immediately deriving a bound βi = String ?

That holds the key to the puzzle. 

The capture bound handling code looks like this:

while (captIter.hasNext()) {

 // ...

for (int i = 0, length = parameters.length; i < length; i++) {
// A set of bounds on α1, ..., αn, constructed from the declared bounds of P1, 
//..., Pn as described in 18.1.3, is immediately implied.
    TypeVariableBinding pi = parameters[i];
    InferenceVariable alpha = (InferenceVariable) gAlpha.arguments[i];
				addBounds(pi.getTypeBounds(alpha, theta),   
                                context.environment);

    TypeBinding ai = gA.arguments[i];
    TypeBinding cai = cgA.arguments[i];
    if (ai instanceof WildcardBinding) {


    } else {
         addBound(new TypeBound(alpha, ai, ReductionResult.SAME),
                                                      context.environment);
   }
}

// --

while this code above would provide for "immediately deriving a bound 
βi = String" it would not help us derive the bound "βi = capture#1-of ?"
in this scenario:

On HEAD/master, suppose in CEF.inferPoly*

   - method's *declared* returnType is Collector<? super T, A, R>
   - rTheta is Collector<T#0,?,List<T#0>>
   - gbeta would then be Collector<T#0,?#1,List<T#0>#2>
 
Then in incorporate:

    - gAlpha is same as gbeta of inferPoly* so == Collector<T#0,?#1,List<T#0>#2>
    - ga same as parameterizedType of inferPoly* which same as rTheta
    - So ga == Collector<T#0,?,List<T#0>>

Given this and the code above what would allow us to discover

"?#1 = capture# of ?" and thereby discover A#1 = capture# of ?

Nothing.

Ergo.

BoundSet.capture should be passed in the parameterized type after wildcard
capture and it should arrange to discover "?#1 = capture# of ?" and propagate
that.

I think we get by on master because, we are not reevaluating inner message 
sends.

So most of the mystery is solved.

(In reply to Srikanth Sankaran from comment #26)

> (8) The only place where I see us adding an entry to BoundSet.captures is
> in inferPolyInvocation* - Are there supposed to be other places that the
> implementation is missing (I have missed noticing ?). The choice of Set and
> the iteration makes me expect other.

OK, I got the answer to this open. Capture bounds get bubbled up from
inner poly invocations. So we need the set and the iterations. Makes sense.

> (9) What necessitates this stashing of the capture bound in BoundSet.captures
> and processing it during next round of incorporation rather than doing it 
> right away in inferPoly* ? 

I think I have the answer to this one too.

So the one question that still puzzles me is : Are we prematurely clearing
BoundSet.captures ? 

Resolve() checks to see if there are capture bounds - When we enter resolve
captures is cleared by prior incorporation. Is it that resolution itself
can cause some capture bounds to be created ?
Comment 28 Srikanth Sankaran CLA 2014-10-05 05:33:52 EDT
In http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=2156fedddc9b679afe1f45ef1e9d318ac4df4d9a, I release a set of 23 files
with changes that enable, but are only peripheral to the core solution.
Since of these changes produce a large delta (refactoring of locals into
fields for example with the this. qualifier all over the place) they will
be a distraction given that reviewer's time is at a premium.

Here are the description of the changes:

    - Enable the test suite harness to support capture free comparison of
expected and actual errors. One test in particular (GRT1_8.testBug433158)
produces non-deterministic capture ids.

    - New suite RunOnly335CompilerTests.java to run only a subset of generics
and polyexpression tests.

    - Fix to broken existing test (ASTConverter17.java) caused by bad code
in Lambda shape analysis.

    - Preparing AE, QAE and MessageSend for reentrancy by extracting some
locals into fields. (Why doesn't Java support C's function static variables
again ? - their semantics cannot be carried over as is since we need to 
discriminate between instance and class variables, but ...)

    - Support for "interned captures" at the type system and attendant changes
to a couple of files to produce unique capture positions - some expression's
source end overlaps the contained expression's source end. BTW ATM this is
disabled for null analysis - a couple of tests fail. Seeing that there is
some capture binding tweaking code that is null analysis specific, I thought
it is best left for you Stephan to determine what is best.

    - Make CaptureBinding implement substituteInferenceVariable rather than
inherit super's method which is wrong for captures.

    - Fix an NPE potential site (CUScope.java)

    - A few useful APIs - (Poly)TypeBinding, ProblemMethodBinding etc.

Later in the day, I'll post the final patch for review along with a review
plan.
Comment 29 Srikanth Sankaran CLA 2014-10-05 05:53:15 EDT
Created attachment 247626 [details]
Patch containing only test changes.

I have tried hard to make sure that diagnostics produced match what we do
on master. A few tests need remastering and are in this patch:

Description of changes:

    - A few tests produce 1 less or 1 more message due to inner poly expression's
reevaluation as opposed to binding update. These message look reasonable.

    - GRT1_8.testBug435767 becomes a conform test from being a negative test.
JDK 8u20 compiles this code too.

    - One test NullTAT used to emit duplicate message - went way.

I have verified the messages for all changed tests against javac as well as
ECJ head. Looks reasonable.
Comment 30 Srikanth Sankaran CLA 2014-10-05 06:09:22 EDT
Created attachment 247627 [details]
Changed files that need only cursory glance through.

These are peripheral changes, but could not be checked in without changes
that require deep review going in. A cursory look through is fine for these
files.
Comment 31 Srikanth Sankaran CLA 2014-10-05 07:57:39 EDT
Created attachment 247628 [details]
Changes requiring close inspection.

Description:

[While I have tried to minimize white space changes, some files still
have quite a few noise changes, so set your comparator to ignore white 
spaces, Thanks]

ASTNode.java:

    - One version of ResolvePolyExpressions went away and the other one got
simplified. I suggest that the comparator be used only for structure compare
and the (only) method be directly studied - it is only 30 LOC.

Invocation.java:

    - Loses the APIs:
          - usesInference
          - updateBindings
          - innersNeedUpdate
          - InnerUpdateDone
          - innerInferenceHelper
      Again, a structure compare and a glance through would be best.

ExplicitConstructorCall.java:

     - Adjust to changes in Invocation.
     - ECC not being an expression, some of the Invocation APIs don't
make sense. Changed to either just return or throw exception.

Scope.java:

    - We don't use inference levels anymore. In particular F does not
drive G. G drives itself. So there are no calls to inferInvocationType
from Scope. Nor do we pass around inference levels.

    - We now skip compatibility checks after PGMB.cCM ONLY if invocation
type was inferred. When only applicability is inferred, we fall through
and check compatibility. This is so we can weed out incompatible methods
that would have passed applicability in G due to arguments being not
pertinent to applicability. (I need to think a bit more to see if this
calls for additional changes for direct type variables in parameters 
targetting functional expressions)

    - Parameter compatibility checks got simplified quite a bit.
compatibilityLevel18FromInner and compatibilityLevel18 are not needed
anymore. All poly expressions respond to isCompatibleWith and 
isBoxingCompatibleWith

   - getExactMethod and getExactConstructor now return a PGMB.
Finally ! :) 

   - Ignore inference variables boolean is not used anymore. I
don't remember why/how it is not required anymore, but believe me
it is not :)

    - The preamble stanza in mSMB went away. The raison d'etre
of this bug - Removing 38 LOC required ~4.5 KLOC and two weeks
of time :)

MessageSend:

    - Is designed to be called once or reentered if a poly expression.
    - Announces itself as a poly type if G finds an applicable
method with no target type in invocation context.
    - Some code for improved error reporting by stealing the closes match.
    - Implements isCompatibleWith and isBoxingCompatibleWith
which is what helps us eliminate all the inner compatibility checks
from Scope. (this can trigger needless re-inference, but there is
an open bug to address that)
    
QAE:

    - Loses inner inference helper.

AE:

    - ResolutionState abstraction goes away. The three parts
are merged into one part.
    - Implements isCompatibleWith and isBoxingCompatibleWith
    - Respond to changes in Invocation.

PGMB:

    - All 1.8 code got moved into cCM18
    - This method now returns a PolyParameterizedGenericMethod
if applicability succeeded and we have no target type.
    - This is a "marker" class. It serves to let MessageSend
know that it is a poly expression. This is also wrapped as the
closest match in case post applicability inference compatibility
checks fail so that we have better error reports.
    - I also expect that this will address ambiguities at mSMB,
i.e if we see a PPGMB, simply return that as the MSM and let
MessageSend deal with it - not yet done.

IC18:

    - All nested inference handling and inner poly expression rebinding
code is eliminated - Now this is the responsibility of ASTNode.resolvePoly*

BoundSet:

    - BoundSet.captures now get passed captured GA. It establishes
the trivial relationships between the fresh inference variables and
capture(GA) and arranges to propagate these to dependancies.
Perhaps this code could be a bit cleaner ?

CTF:

    - Now in formulas we can encounter a PolyTB, if we do, we need to
resolve them and discover the real type against the target type.

CEF:

    - In reduce against a proper type, we had several clauses to handle
different kinds of expressions. Now we take advantage of polymorphism
and ask the expression if it is compatible against the proper type. This
addresses some loose ends also that are acknowledged in the code.

    - Fix to an AIOOB I observed in reference expression reduction.

    - Capture position 14 fixed :)

    - Missing capture for inexact method reference fixed.

    - Pass captured parametrized type for capture bound incorporation

    - Other capture position problems fixed.

Shortly, I'll also post a cumulative patch.
Comment 32 Srikanth Sankaran CLA 2014-10-05 08:15:40 EDT
Created attachment 247629 [details]
Cumulative patch

Recommended structured review plan:

1. (Optional) Glance through the infrastructure changes already released:
http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=2156fedddc9b679afe1f45ef1e9d318ac4df4d9a

2. (Optional) Glance through the ~12 tests that underwent diagnostic change.
https://bugs.eclipse.org/bugs/attachment.cgi?id=247626

3. Cursory review of https://bugs.eclipse.org/bugs/attachment.cgi?id=247627

4. Close scrutiny of the patch https://bugs.eclipse.org/bugs/attachment.cgi?id=247628 documented at https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444#c31.

    A good order would be ASTNode, Invocation, MessageSend, Scope, PGMB, QAE,
AE, ECC, IC18, CEF, CTF, BoundSet,

Thanks a million in advance, I know this is a big ask of your time and energy -
I appreciate your comments/feedback. IMHO this reintegration is what your
effort at G deserves given how well/clean it is written !

I'll get some additional testing done through the UI team as well as other
IBM teams.
Comment 33 Srikanth Sankaran CLA 2014-10-05 08:17:01 EDT
Noopur, could you please get all UI tests run with the cumulative patch and
report back results ? TIA.
Comment 34 Srikanth Sankaran CLA 2014-10-05 08:54:02 EDT
OK, so what of the design itself ? 

Preamble: 

The basic "problem" is that on master MessageSend does not play the role of
a poly expression to perfection i.e it never announces itself as a poly 
expression and does not implement certain parts of the poly expression protocol
(which we never unfortunately documented in an IPolyExpression interface) 

As a result it does not take advantage of the solution devised for https://bugs.eclipse.org/bugs/show_bug.cgi?id=382701#c54 which is to
introduce a level of indirection by implementing isCompatibleWith and 
isBoxingCompatibleWith 

For https://bugs.eclipse.org/bugs/show_bug.cgi?id=400874 in 
https://bugs.eclipse.org/bugs/attachment.cgi?id=237885, I did post some
early prototype code for this, but never found the time to follow through :(

So the present patch follows through on that. 

Key ideas:

    - MessageSend announces itself as a poly expression if G finds an applicable
method and has no target type to proceed to invocation type inference.

    - This is accomplished by PGMB.cCM18 returning an object of a "marker" 
class PolyParametrizedGenericMethodBinding

    - MessageSend.binding when called by G against a specific target type
computes the binding freshly (this method should be renamed 
resolveMethodExpecting and LE.getResolved* and RE.findCompile* should also
be renamed so they all speak in the same tongue)

    - By also implementing isCompatibleWith and isBoxingCompatible with
this removes any G specific code in F to deal with inner compatibility.
(Having that is intrusive there, the reason for this bug.)

    - All poly expression resolution code is centralized into ASTNode.resolvePoly* - there is no need for IC18 to keep track of inner polies
and schedule rebinding etc. In a way the inners are already tracked by the
outer in its this.arguments and this.argumentTypes. So this redundancy is
removed.

    - Re-resolving the nested poly expressions after the outer call is fully
resolved also addresses problems about various checks being skipped and only
bindings being updated.

    - Diamond inference also is simplified a good bit. Now AE refuses to
resolve itself until a target type is known if the context provides a target
type.

Follow up ideas: (against different tickets) 

    - When target type is absent throwing AbsentTargetTypeException may lead
to an even cleaner design. Some open bugs that deal with ambiguity post
applicability inference where there should be no ambiguity should go away
with that

    - Write up IPolyExpression. Unify all disparate methods we have under
one scheme (resolveTypeExpecting, resolveMethodExpecting, isCompatibleWith,
isBoxingCompatibleWith ...) 

    - See if ReferenceExpression should really implement Invocation. We "invoke"
a method in RE, not to execute it, but to pass it around. So that should
qualify. Too many places there is casts and instanceof checks due to 
InvocationSite and Invocation split.

    - All poly expressions should implement a cache against targets to avoid
recomputation.

    - Check that all poly expressions' resolve method looks like:

    if (this.constant != Constant.NotAConstant) {
    } else {
    }
Comment 35 Srikanth Sankaran CLA 2014-10-05 09:22:16 EDT
Created attachment 247630 [details]
Cumulative patch - Passes all JDT/Core tests

(In reply to Srikanth Sankaran from comment #31)

> ExplicitConstructorCall.java:

>      - ECC not being an expression, some of the Invocation APIs don't
> make sense. Changed to either just return or throw exception.

This was not in the tested version. I added code to throw an ISE when
I was scanning through the changes to document them here, bad idea :)
Fixed and reposted the cumulative patch that passes all JDT Core tests.

(In reply to Srikanth Sankaran from comment #32)
> I appreciate your comments/feedback. IMHO this reintegration is what your
> effort at G deserves given how well/clean it is written !

That sentence looks subject to interpretation.

Just so it does not seem unseemly, by "how well/clean it is written !" I was
referring to your work in type inference Stephan, not to my work here :)
Comment 36 Srikanth Sankaran CLA 2014-10-05 09:42:02 EDT
For some broken cases, I get an NPE during build. I'll look into this - it does
not have to hold the review.

// --
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class X {
	public static void main(String[] args) {
		List<Person> roster = new ArrayList<>();
        
        Map<String, Person> map = 
            roster
                .stream()
                .collect(
                    Collectors.toMap(
                        Person::getLast,
                        Function.identity() 
                    ));

	}
}

class Person {
	
}
Comment 37 Srikanth Sankaran CLA 2014-10-05 11:50:50 EDT
(In reply to Srikanth Sankaran from comment #36)
> For some broken cases, I get an NPE during build. I'll look into this - it
> does
> not have to hold the review.

Trivial problem, I have a fix in my workspace. Basically, when arguments have
errors, we do some trickery to find the closest match which happens to be a PGMB.
We return to the caller and then outer inference results in binding() and isCompatible et al being called with argumenTypes array containing nulls. Fix is
simply to promote the fact we had argument errors to a field and consult in
binding and isCom* and do the right thing.
Comment 38 Srikanth Sankaran CLA 2014-10-06 00:49:34 EDT
There is a "mild" problem: 

15.12.2 says

Although the method invocation may be a poly expression, only its argument
expressions - not the invocation's target type - influence the selection of applicable methods.

// --

This would require a bit of redoing/rethinking. So let us hold on the review.
I'll let you know when it is ready.
Comment 39 Srikanth Sankaran CLA 2014-10-06 04:07:29 EDT
(In reply to Srikanth Sankaran from comment #38)
> There is a "mild" problem: 
> 
> 15.12.2 says
> 
> Although the method invocation may be a poly expression, only its argument
> expressions - not the invocation's target type - influence the selection of
> applicable methods.
> 
> // --
> 
> This would require a bit of redoing/rethinking. So let us hold on the review.
> I'll let you know when it is ready.

Damage assessment: Nothing major. Right now I am proceeding to invocation
type inference if target type is available, I need to split this as is done
on master.

This would also simplify the implementation further by a good bit. 
Invocation.binding() can simply revert to what is doing on master - 
rather than looking up the method against the target type. I can also 
eliminate the repeat eventual resolution by memoizing the results from
nested inference. 

It is going to take a couple of days of work - I'll get on it after a day's
break.

(In reply to Srikanth Sankaran from comment #34)

>     - MessageSend.binding when called by G against a specific target type
> computes the binding freshly 

This would be a waste of time. The behavior of binding should revert to
what it is on head.

>     - Re-resolving the nested poly expressions after the outer call is fully
> resolved also addresses problems about various checks being skipped and only
> bindings being updated.

This can simply re-use the memoized result.

> Follow up ideas: (against different tickets) 
> 
>     - When target type is absent throwing AbsentTargetTypeException may lead
> to an even cleaner design. Some open bugs that deal with ambiguity post
> applicability inference where there should be no ambiguity should go away
> with that

Not sure if this idea will lead to a a conforming implementation.
Comment 40 Noopur Gupta CLA 2014-10-06 05:10:57 EDT
(In reply to Srikanth Sankaran from comment #33)
> Noopur, could you please get all UI tests run with the cumulative patch and
> report back results ? TIA.

All tests pass with the cumulative  patch.
Comment 41 shankha banerjee CLA 2014-10-07 07:45:02 EDT
The test cases mentioned in Bug 437973 do not get resolved through this patch.
Comment 42 Srikanth Sankaran CLA 2014-10-07 09:51:41 EDT
(In reply to Srikanth Sankaran from comment #38)
> There is a "mild" problem: 
> 
> 15.12.2 says
> 
> Although the method invocation may be a poly expression, only its argument
> expressions - not the invocation's target type - influence the selection of
> applicable methods.
> 
> // --
> 
> This would require a bit of redoing/rethinking. So let us hold on the review.
> I'll let you know when it is ready.

OK, I have analyzed this closely. No change is required.

There are two ways invocation's target type can illegally influence/affect
the selection of MSMB.

    - If we somehow take that into consideration to pick the method - 
we never did and we don't now with this patch

    - If invocation type inference "improves" the method and the improved
method beats others to quality as the MSMB and it would not otherwise have
but for the improvement.

The latter point was what worried me - but it proved to be unnecessary. During MSMB computation, we operate on the generic method and not on the
instantiations. So any improvements seen during invocation type inference
cannot affect overload resolution.
 
While investigating this point though I noticed that my redone Invocation.binding was horrible/dumb incurring expensive computation which
would be thrown right away. I have fixed this.

Patch will follow shortly.
Comment 43 Srikanth Sankaran CLA 2014-10-07 12:17:21 EDT
Created attachment 247687 [details]
Proposed patch - Ready for review, passes all tests
Comment 44 Srikanth Sankaran CLA 2014-10-07 12:28:59 EDT
(In reply to Srikanth Sankaran from comment #43)
> Created attachment 247687 [details]
> Proposed patch - Ready for review, passes all tests

In http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=817f5b60f1b5283073ee91db13e8dcaec6a51e5d, I released some more 
infrastructure changes that are peripheral in nature to minimize clutter
in the change set input to review.

The proposed patch is essentially the same as the "Cumulative patch" posted
earlier, with:

    - Reverting the behavior of Invocation.binding to simply return the
binding and not do wasteful computation.

    - Improved handling of compatibility checks for methods that pass
applicability - to weed out incompatible method early.

    - Some clean up of C set construction based on 
https://bugs.openjdk.java.net/browse/JDK-8052325 

    - Some performance improvements to isCompatibleWith - there is no
need to tunnel through overload resolution all over again.

Known issues I plan to address in a separate ticket along with issues
raised during code review:

    1. AllocationExpression can use common code blocks replicated in 2-3
places, These could be factored into a method.

    2. Further improvements to isCompatibeWith by caching results.

    3. When inner is reevaluated, it computes its binding all over.
We need to arrange for results forwarded/cached etc.

It has been gruelling work to get to this stage, these issues that are
not blockers can be addressed separately in a few days time.

Ball is back in your court Stephan, at your convenient pace.  TIA.
I am happy help any way I can, answer questions etc. Let me know.
Comment 45 Srikanth Sankaran CLA 2014-10-07 23:02:17 EDT
Created attachment 247700 [details]
Incremental fix to bug 428811

This incremental patch fixes bug 428811.

Two changes were required:

    - Earlier "Proposed patch" over eagerly pruned some code necessary to
weed out incompatible method from MSMB race.

    - We attempt to diamond infer when we should not.
      e.g: ArrayList<T>::new should not trigger diamond inference while
      ArrayList::new should.
Comment 46 Srikanth Sankaran CLA 2014-10-09 00:16:08 EDT
Question:

This chunk of code from master in C set construction:

if (expri instanceof Invocation && expri.isPolyExpression()) {
			Invocation invocation = (Invocation) expri;
			MethodBinding innerMethod = invocation.binding(null, false, null);
			if (innerMethod instanceof ParameterizedGenericMethodBinding) {
				InferenceContext18 innerCtx = invocation.getInferenceContext((ParameterizedMethodBinding) innerMethod);
				if (innerCtx != null) { // otherwise innerMethod does not participate in inference
					return addConstraintsToC(invocation.arguments(), c, innerMethod.genericMethod(), innerCtx.inferenceKind);
				}
			}

Is it doing the right thing for diamond inference resolving to a non-generic
method ? 

// --
If ei is a poly class instance creation expression (§15.9) or a poly method
invocation expression (§15.12), C contains all the constraint formulas that
would appear in the set C generated by §18.5.2 when inferring the poly
expression's invocation type.

// --
A class instance creation expression is a poly expression (§15.2) if it 
uses the diamond form for type arguments to the class, and it appears in 
an assignment context or an invocation context (§5.2, §5.3). Otherwise, 
it is a standalone expression.

So it looks like we should not check for PGMB instance ?
Comment 47 Stephan Herrmann CLA 2014-10-09 05:22:37 EDT
(In reply to Srikanth Sankaran from comment #46)
> So it looks like we should not check for PGMB instance ?

I think you're right.

Originally, Invocation.getInferenceContext() required a PGMB argument, that's why we have this instanceof - using then the innerCtx as an indication that the inner actually uses inference.

In Bug 427483 I generalized getInferenceContext() to accept a PMB, and in that bug's commit you see one instanceof check adjusted. It probably makes sense that other similar locations should have been adjusted accordingly, which conceptually acknowledges the spec passages you cite: not PGMB vs. PMB tells us about poly or not poly, but getInferenceContext(PMB) will.

OTOH, just changing this one instanceof check may not be effective, unless we also re-visit the use of PGMB in other methods of AllocationExpression: registerInferenceContext(), updateBindings(), usesInference().


Would this change how you handle things in this bug?
Comment 48 Stephan Herrmann CLA 2014-10-09 06:24:12 EDT
(In reply to Srikanth Sankaran from comment #32)
> Recommended structured review plan:
> 
> 1. (Optional) Glance through the infrastructure changes already released:
> http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/
> ?id=2156fedddc9b679afe1f45ef1e9d318ac4df4d9a

Looking at this commit...

AllocationExpression:
I was curious about moving argumentTypes from ResolutionState to AE itself. When accounting for multiple invocations of AE.resolveType() I figured we should push all intermediate resolution results into the ResolutionState, to allow for different results during different attempts. At a closer look I don't see how different attempts could produce different argumentTypes, though 
=> Looks OK.

CaptureBinding:
Own version of substituteInferenceVariable() no longer handles superclass & superInterfaces (nor lowerBound, which we didn't handle before, either).
Question: can we assert that the fresh CaptureBinding created here gets initializeBounds called when needed? Could we end up working with an insufficiently initialized CaptureBinding downstream?
=> @Srikanth, please comment.

ProblemReasons:
InferredAppliableMethodInapplicable
=> typo :)

ParameterizedTypeBinding:
capture() has this comment:
// A couple of NTAT tests fail with interned captures. The new messages look better and correct. Stephan to validate. 
=> I filed bug 446434 to follow up. No need to let it block this bug.

Everything else looks fine with no further questions asked.
Comment 49 Srikanth Sankaran CLA 2014-10-09 08:13:21 EDT
Let us start numbering issues so it is easy for follow up and cross
referencing:

Follow up tasks so far:

    1. AllocationExpression uses common code blocks replicated in 2-3
places, These could be factored into a method.

    2. Further improvements to isCompatibeWith by caching results.

    3. When inner is reevaluated, it computes its binding all over.
We need to arrange for results forwarded/cached etc.

    4. CaptureBinding.substituteInferenceVariable should check for
need to initialize superclass and super interfaces in the substitute.

    5. Typo in ProblemReasons:InferredAppliableMethodInapplicable

(Clean up of instanceof PGMB check in C set construction included in a
patch for the spec bug fix already)
Comment 50 Srikanth Sankaran CLA 2014-10-09 12:08:42 EDT
Another question: 

Should the calls to getResolvedCopyForInferenceTargeting in CExceptionF.reduce
and CExpressionF.inputVariables() be preceded by computation of ground target
type ? 

I am not sure there is a correctness issue here - If nothing else they would 
defeat the caching being put in at least for implicit lambdas with wild card 
parametrized funcional interface targets ?
Comment 51 Srikanth Sankaran CLA 2014-10-09 14:04:27 EDT
Created attachment 247764 [details]
Incremental fix to bug 444891 (specification amendment)

I am cross posting the patch here because it needs to be applied on top
of the others already posted here.

I have verified that this patch run all tests clean + fixes 
bug 433158 bug 435187 bug 433852 bug 442916 bug 442769 bug 432682 bug 442446 bug 435767 which were tagged as duplicates.

The one outlier is https://bugs.eclipse.org/bugs/show_bug.cgi?id=439594.
This was tagged as a duplicate but problem persists - There should be something
more there that should be investigated. I'll reopen that bug shortly.
Comment 52 Stephan Herrmann CLA 2014-10-09 14:19:44 EDT
(In reply to Srikanth Sankaran from comment #51)
> Created attachment 247764 [details]
> Incremental fix to bug 444891 (specification amendment)
> 
> I am cross posting the patch here because it needs to be applied on top
> of the others already posted here.
> 
> I have verified that this patch run all tests clean + fixes 
> bug 433158 bug 435187 bug 433852 bug 442916 bug 442769 bug 432682 bug 442446
> bug 435767 which were tagged as duplicates.

That's very good news, as it shows that both improvements harmonize.
Hooray!
Comment 53 Stephan Herrmann CLA 2014-10-09 14:22:18 EDT
(In reply to Srikanth Sankaran from comment #49)
> (Clean up of instanceof PGMB check in C set construction included in a
> patch for the spec bug fix already)

In that universe: do methods AE.{registerInferenceContext,updateBindings,usesInference} still exist? If so, would they still need the same cleanup?
Comment 54 Stephan Herrmann CLA 2014-10-09 14:42:35 EDT
(In reply to Srikanth Sankaran from comment #50)
> Another question: 
> 
> Should the calls to getResolvedCopyForInferenceTargeting in
> CExceptionF.reduce
> and CExpressionF.inputVariables() be preceded by computation of ground target
> type ? 
> 
> I am not sure there is a correctness issue here - If nothing else they would 
> defeat the caching being put in at least for implicit lambdas with wild card 
> parametrized funcional interface targets ?

Why precede? Inside resolveType we call findGroundTargetType(). Isn't that sufficient?

Do you want to use the ground target type as a key for caching? Is the plain target type inappropriate for that task? How?
Comment 55 Srikanth Sankaran CLA 2014-10-09 14:46:33 EDT
With the set of patches here, These go away:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=445725,
https://bugs.eclipse.org/bugs/show_bug.cgi?id=429430
https://bugs.eclipse.org/bugs/show_bug.cgi?id=434394
https://bugs.eclipse.org/bugs/show_bug.cgi?id=445274
https://bugs.eclipse.org/bugs/show_bug.cgi?id=429555

I'll include tests for these in a later patch.

Of these, https://bugs.eclipse.org/bugs/show_bug.cgi?id=429430 is interesting.
We have a call at the tail end of MessageSend that reads:

recordExceptionsForEnclosingLambda(scope, this.binding.thrownExceptions);

Inner's full reevaluation enables the propagation of the thrown exceptions now.
Comment 56 Srikanth Sankaran CLA 2014-10-09 14:51:07 EDT
(In reply to Stephan Herrmann from comment #54)

> Why precede? Inside resolveType we call findGroundTargetType(). Isn't that
> sufficient?

No, the caching code is going to look like,

    - check the HashMap<TargetType,LE> and if an entry is found recycle it.
    - otherwise copy + resolve + add to map and return.
 
> Do you want to use the ground target type as a key for caching? Is the plain
> target type inappropriate for that task? How?

Thing is from some parts of the engine we call getResolved* with the
ground target type and from others (the ones I cited earlier) with wildcards.
So these will produce two copies.

Inside LE.resolve, we compute the ground target type, but that is after a
"cache miss"


(In reply to Stephan Herrmann from comment #53)
> (In reply to Srikanth Sankaran from comment #49)
> > (Clean up of instanceof PGMB check in C set construction included in a
> > patch for the spec bug fix already)
> 
> In that universe: do methods
> AE.{registerInferenceContext,updateBindings,usesInference} still exist? If
> so, would they still need the same cleanup?

The last two go away, I think we do the right thing for the first one.
Comment 57 Stephan Herrmann CLA 2014-10-09 15:08:33 EDT
(In reply to Srikanth Sankaran from comment #32)
> 2. (Optional) Glance through the ~12 tests that underwent diagnostic change.
> https://bugs.eclipse.org/bugs/attachment.cgi?id=247626

At a cursory glance no obvious problems.
I'll give it slightly deeper scrutiny after reviewing the actual code changes, at what point I can make more sense of debugging a few selected samples.

Some of the additional errors look like candidates for better efforts in detecting the root cause in the presence of inference failure (part 1 of the three-years-AI-research-project :) ). Needn't hold up the current bug.
Comment 58 Stephan Herrmann CLA 2014-10-09 15:22:20 EDT
(In reply to Srikanth Sankaran from comment #56)
> Thing is from some parts of the engine we call getResolved* with the
> ground target type and from others (the ones I cited earlier) with wildcards.
> So these will produce two copies.
> 
> Inside LE.resolve, we compute the ground target type, but that is after a
> "cache miss"

From all callers of getResolved* this one seems to be the outlier:

In CExprF.reduce() inside "if (this.left instanceof LambdaExpression) {"
That's the only one using the ground target type, and perhaps unnecessarily so.
Do you want to try replacing the 't' argument by 'this.right'?

From a spec p.o.v. using 't' may not be necessary, inside resolveType we use the ground target type anyway and if it helps agreeing on one hash key, couldn't this be our friend?
Comment 59 Stephan Herrmann CLA 2014-10-09 15:49:45 EDT
(In reply to Srikanth Sankaran from comment #32)
> 3. Cursory review of https://bugs.eclipse.org/bugs/attachment.cgi?id=247627

part of the change in RE has crept into commit 817f5b60f1b5283073ee91db13e8dcaec6a51e5d, needs to be manually merged, when applying the attached patch.

One more issue for the list:

  6. FE has bogus white space changes (wow I'm finding "problems" :) )

I didn't immediately understand the changes in ProblemReporter.invalidMethod, will return to this later.
Comment 60 Srikanth Sankaran CLA 2014-10-09 20:42:40 EDT
(In reply to Stephan Herrmann from comment #58)

> In CExprF.reduce() inside "if (this.left instanceof LambdaExpression) {"
> That's the only one using the ground target type, and perhaps unnecessarily
> so.
> Do you want to try replacing the 't' argument by 'this.right'?
> 
> From a spec p.o.v. using 't' may not be necessary, inside resolveType we use
> the ground target type anyway

It could be too late for inference. I think CEF.fGTT adds additional type
variables for explicitly typed lambdas for functional interface parameterization inference - no ?
Comment 61 Srikanth Sankaran CLA 2014-10-09 20:55:02 EDT
7. Tighten capture semantics. Right now we use ASTNode, sourceEnd pair.
This may not be enough as shown by the changes made for Assignment and CastExpression - for these expressions, the contained expression's source
end overlaps the containing expression's source end. A better solution
would be to use ASTNode, sourceEnd, sourceStart.

8. Present capture interning code likely to introduce performance problems.
For a given wildcard all captures go in the same same linear list across all
modules compiled under the same LookupEnv*. Déjà vu all over again.

9. On master we bypass post inference compatibility checks in Scope.cCM.
On the proposed solution, we by pass post inference compatibility checks in 
Scope.cCM if IC18.stepCompleted >= TYPE_INFERRED. This needs to be adjusted
so that these checks are not redone for arguments pertinent to applicability
as this can wastefully trigger re-inference through isCompatibleWith calls.

10. On master as well on this patch we are skipping 15.12.3 Compile-Time Step 3
for Java 8 ??
Comment 62 Srikanth Sankaran CLA 2014-10-09 23:53:18 EDT
Created attachment 247783 [details]
Incremental fix to bug 444891 (specification amendment)

(In reply to Srikanth Sankaran from comment #51)
> Created attachment 247764 [details]
> Incremental fix to bug 444891 (specification amendment)

> The one outlier is https://bugs.eclipse.org/bugs/show_bug.cgi?id=439594.
> This was tagged as a duplicate but problem persists - There should be
> something
> more there that should be investigated. I'll reopen that bug shortly.

Actually, it is very much a duplicate, but was failing due to a small error
in the previous patch. (Instead of passing along the boolean `interleaved'
I was passing false incorrectly from addConstraintsToC into addConstraintsToC_OneExpr. A one token correction fixes the problem.

I should also mention apart from the fix for the spec amendment, this patch
also sneaks in:

     - Lambda copy caching.
     - A bug fix to lambda shape analysis,
     - A performance fix to isBoxingCompatibile, It does not make sense
for LE, RE and AE and for MS only on occasion (when the target type is
a primitive or boxed primitive) We should not trigger expensive reinference
in these cases.
     - Gets rid of a a couple of bogus uncapture() calls.
     - Cleanups to a couple of places that materialize lambda return
expressions in a convoluted way.
Comment 63 Srikanth Sankaran CLA 2014-10-10 06:59:23 EDT
(In reply to Stephan Herrmann from comment #59)

>   6. FE has bogus white space changes (wow I'm finding "problems" :) )

IIRC, this indentation problem is fixed in one of the later incremental
patches.

That said, some files have undergone significant change: most notably
AE, Scope and IC18 and some amount of noise diff sneaked in - sorry about
that,
Comment 64 Srikanth Sankaran CLA 2014-10-11 05:56:36 EDT
Created attachment 247816 [details]
Incremental fix to bug 432626

During 18.5.2 bullet 3.3.1, we hit a snag.

We see two types HashMap<K#8,V#9> and HashMap<K#8,ArrayList<T>> and
conclude they are two different parameterizations of the same generic class 
or interface.

But current bound set contains the instantiation V#9 = ArrayList<T>
and they are the one and the same.

Fix to to compare after application of instatiations.

This patch also contains a couple of clean ups in CTF and RTB.
Comment 65 Stephan Herrmann CLA 2014-10-11 09:20:15 EDT
(In reply to Srikanth Sankaran from comment #64)

I made a note in bug 428061 comment 8.
Comment 66 Srikanth Sankaran CLA 2014-10-11 12:15:33 EDT
Stephan, when only applicability is inferred, would be wrong to leave
unresoved type variables instatiated by themselves as opposed to jlO ? 

This would simplify post inference compatibility checking.

What i would like to implement is:

    - if invocation type inferred, trust inference completely and skip any
compatibility checks

    - If only applicability was inferred, skip compatibility checks for
arguments pertinent to applicability, but still check those parameters
whose arguments were not pertinent to applicability.

    The latter step is weed out obviously incompatible cases such as
a lambda with a bad target type. By admitting patently incompatible methods
we make MSMB deal with them and sometime run into ambiguity or other problems.

    This scheme would work well, if the PGMB computed after just applicability
does not have jlO substitutions, but instead has the unresolved type variables
intact. 

    Since we anyway toss out any resolutions and start with the shallow
method for further inference, there should be no issues ?
Comment 67 Stephan Herrmann CLA 2014-10-11 16:23:54 EDT
(In reply to Srikanth Sankaran from comment #60)
> (In reply to Stephan Herrmann from comment #58)
> 
> > In CExprF.reduce() inside "if (this.left instanceof LambdaExpression) {"
> > That's the only one using the ground target type, and perhaps unnecessarily
> > so.
> > Do you want to try replacing the 't' argument by 'this.right'?
> > 
> > From a spec p.o.v. using 't' may not be necessary, inside resolveType we use
> > the ground target type anyway
> 
> It could be too late for inference. I think CEF.fGTT adds additional type
> variables for explicitly typed lambdas for functional interface
> parameterization inference - no ?

To avoid potential misunderstanding: I didn't mean to delete the call to fGTT, only to not use its result 't' in the call to getResolvedCopy*.

But I'm not on firm grounds yet ...
Comment 68 Stephan Herrmann CLA 2014-10-11 16:34:16 EDT
(In reply to Srikanth Sankaran from comment #66)
> This scheme would work well, if the PGMB computed after just applicability
> does not have jlO substitutions, but instead has the unresolved type
> variables intact. 

I'm confused: I understood that after only applicability inference we don't produce any PGMB but a PolyParameterizedGenericMethod?

What am I missing?

BTW, I plan to get started on the core review on Tuesday.

I found your recommendation in comment 32 very helpful. Is this still applicable 30+ comments later?
Comment 69 Srikanth Sankaran CLA 2014-10-11 20:15:44 EDT
(In reply to Stephan Herrmann from comment #68)

> I'm confused: I understood that after only applicability inference we don't
> produce any PGMB but a PolyParameterizedGenericMethod?

Yes, but a PPGMB is a PGMB. PPGMB is just a marker class that wraps the
PGMB produced by applicability inference. It has no other state or behavior.
We may as well set a bit in the PGMB to say only applicability was inferred
or alternately consult IC18.stepCompleted to concluded that the MessageSend
should announce itself as a poly expression, but using the new "marker" class
makes the design intent clear.

> BTW, I plan to get started on the core review on Tuesday.

Sounds great.

> I found your recommendation in comment 32 very helpful. Is this still
> applicable 30+ comments later?

For the most part should be. I'll take a look and refresh later today if needed.
Comment 70 Srikanth Sankaran CLA 2014-10-12 05:21:00 EDT
(In reply to Srikanth Sankaran from comment #66)
> Stephan, when only applicability is inferred, would be wrong to leave
> unresoved type variables instatiated by themselves as opposed to jlO ? 
> 
> This would simplify post inference compatibility checking.

I am about to give up on this problem, I am not sure it is solvable without
a whole lot of AI.

I'll shortly post a patch that treads the middle path by:

    - Not doing any post inference compatibility checks if full inference
was completed.

    - If only applicability was inferred, skip compatibility checks for
all arguments pertinent to applicability.

i.e trust inference engine fully for the above scenarios.

   - When only applicability was inferred, if argument is an functional
type, assert that parameter is also and otherwise weed out the method.

    - If the PPGMB's parameter does not mention jlO, then do full checks
for functional expression compatibility.

I don't think more can be done easily. The PPGMB is a chimera that doesn't
lend itself well to compatibility checks due to partial resolution and
object substitutions for the rest.
Comment 71 Srikanth Sankaran CLA 2014-10-12 05:58:42 EDT
I'll repost a cumulative patch shortly. To facilitate the review here
is a (re) summary of key changes:

    1. All poly expression resolution against eventual target type is
centralized in one place. ASTNode.resolvePolyExpressionArguments.

    2. Poly expressions are reevaluated, we don't just update the bindings.
On the +ve side, this enables all the checks that take place post method
resolution to take place. On the -ve side, ATM, this means some wasteful 
reinference, but we have a task in follow up task list to have the results 
forwarded to avoid reinference. I'll address this as a top priority task 
post review and release of the work here.

    3. Poly allocation expression resolution got overhauled completely.
The three part resolution is back as one part in AE.resolveType.

    4. Perhaps the biggest change of all is that MessageSend announces
itself as poly expression by returning a PolyTypeBinding when required.

    5. All poly expressions implement isCompatibleWith and 
isBoxingCompatibleWith thereby eliminating the need for all the
inner invocation compatibility checking code in Scope. The existing
Java 7 overload resolution code "just works" given these APIs.

    6. In master we skip post inference compatibility checks whether
or not full inference is run. We make an improved effort to weed out
incompatible methods now with the proposed solution.
Comment 72 Srikanth Sankaran CLA 2014-10-12 06:11:12 EDT
Created attachment 247819 [details]
Cumulative proposed patch

This patch merged all the incremental fixes and also includes a candidate
fix for bug 432605 based on the interpretation that a captured wildcard
has to be treated as a wildcard for type argument containment assertion
purposes. If we hear otherwise from the spec lead, we can back out this
change.
Comment 73 Srikanth Sankaran CLA 2014-10-12 07:23:35 EDT
Here is the revised structured review plan: (I am halting all work on this
so the goal post don't keep shifting)

1. Since your last glance through, the changed test suites:

GenericTypeTest.java
GenericsRegressionTest_1_8.java
LambdaExpressionsTest.java
NegativeLambdaExpressionsTest.java
NullTypeAnnotationTest.java

have had several tests added or enabled.

Only a couple of tests got _modified_. These are safe changes and so no need
to review these again. For all new and modified tests, behavior has been
compared with 8u20.

2. These files have minimal peripheral changes. Some of it you have skimmed
through already, some new. It wouldn't hurt to take glance through afresh to
regain context. I estimate that 15 minutes should be plenty.

Expression.java
CodeSnippetScope.java
RawTypeBinding.java
SyntheticFactoryMethodBinding.java
TypeBinding.java
ProblemReporter.java
FunctionalExpression.java
ReferenceExpression.java
PolyParameterizedGenericMethodBinding.java
PolyTypeBinding.java
ProblemReasons.java
ConditionalExpression.java
LambdaExpression.java
QualifiedAllocationExpression.java

3. That leaves us with 11 files requiring close inspection. These can be
broken down into an easy set and a more involved set.

3.A Easy set:  summary of changes:
---------------------------------

(a) ASTNode.java

    - One version of ResolvePolyExpressions went away and the other one got
simplified. I suggest that the comparator be used only for structure compare
and the (only) method be directly studied - it is only 30 LOC.

(b) Invocation.java:

    - Loses the APIs:
          - usesInference
          - updateBindings
          - innersNeedUpdate
          - InnerUpdateDone
          - innerInferenceHelper

     and a couple of other APIs lose a parameter or two.
    
      Again, a structure compare and a glance through would be best.

(c) ExplicitConstructorCall.java:

     - Adjusts to changes in Invocation.
     - ECC not being an expression, some of the Invocation APIs don't
make sense. Changed to either just return.

(d) MessageSend.java (ignore whitespace in comparator)

    - Announces itself as a poly expression when required.
    - Implements isCompatibleWith and isBoxingCompatibleWith
    - Adjusts to Invocation interface changes.
    - Loses inner inference helper.

3.B More involved set with description of changes:
--------------------------------------------------

(a) BoundSet.java:

    - Capture bound handling changes.
    - Correction to 18.5.2 bullet 3.3.1 handling to consult instantiations.


(b) ConstraintTypeFormula.java:

    - Experimental fix for bug 432605 that treats as a captured wildcard
as a wildcard for type argument containment assertions.

    - Handling POLY_TYPEs inside the engine in type equations.

    - isInsignificantParameterized eliminated and replaced with a call
to TypeBinding.isParameterizedWithOwnVariables.

(c) ConstraintExpressionFormula.java:

    - Reduction against a proper type is handled polymorphically via
isCompatibleWith and isBoxingCompatibleWith.

    - Pass proper scope to Invocation.binding()

    - For inner invocations interleaved by a lambda, reduce is a nop
as the C set construction code has effectively lifted everything that
needs to be lifted that would amount to B3. We must lift them at C
set construction time because type variables would need substitution with
inference variables before they get on the C set.

    - Lambda return expressions directly materialized with resultExpressions

    - Fixes to reference expression reduction to avoid AIOOB, implement
missing/inappropriate captures, to not treat ArrayList<T>::new as diamond
inference, proper handling of capture bounds in inferPolyInvocationType
etc.

(d) ParameterizedGenericMethodBinding.java:

    - All 1.8+ code moved into cCM18
    - We don't use inference level anymore. If target type is available
or if context does not provide a target type, we proceed to infer invocation
type.

(e) Scope.java

    - Inference level not passed around anymore.
    - Various places that would call inferInvocation type don't do
that anymore since PGMB.cCM18 already proceeds to do that.
    - Make best effort basis compatibility checks post applicability
inference.
    - parameterCompatibilityLevel18, compatibilityLevel18FromInner and
some helpers used by them are eliminated.
    - getExactMethod and getExactConstructor return a PGMB when required.
    - mSMB leading stanza got simplified/eliminated.
    - parameterCompatibilityLevel(MethodBinding, TypeBinding[], boolean)
makes an effort to weed out methods that are blatant mismatches.
    - Other assorted obvious changes.

(f) AllocationExpression.java (This file is easier directly reviewed)

    - We don't use ResolutionState abstraction anymore.
    - Loses inner inference helper.
    - Three part resolution merged into one.
    - Implements isCompatibleWith and isBoxingCompatibleWith
    - Adjusts to changes in Invocation.

(g) InferenceContext18.java:

    - Loses a bunch of abstraction, state and behavior dealing with
inner poly expression rebinding.
    - Corrections to javadoc and comments to bring it up to date
    - Support for nested inference with an interleaving lambda.
This calls for us to lift the type variables and initial bounds from
inner to current context. This needs to happen here and now during C set
construction because the formulas that get on the C set should see the
inference variable and not the type variables. So input variables and
output variables could be computed correctly and formulas could be
sequenced/scheduled properly for reduction to make progress.

That should be it. Thanks Stephan.

As promised, I'll freeze on the changes until the review is over and not
go on sneaking in more and more. We have rounded up all the nasties anyways.
Comment 74 Srikanth Sankaran CLA 2014-10-12 07:27:37 EDT
Upto date list of follow up tasks:

Follow up tasks so far:

1. AllocationExpression uses common code blocks replicated in 2-3
places, These could be factored into a method.

2. Further improvements to isCompatibeWith by caching results.

3. When inner is reevaluated, it computes its binding all over.
We need to arrange for results forwarded/cached etc.

4. CaptureBinding.substituteInferenceVariable should check for
need to initialize superclass and super interfaces in the substitute.

5. Tighten capture semantics. Right now we use ASTNode, sourceEnd pair.
This may not be enough as shown by the changes made for Assignment and CastExpression - for these expressions, the contained expression's source
end overlaps the containing expression's source end. A better solution
would be to use ASTNode, sourceEnd, sourceStart.

6. Present capture interning code likely to introduce performance problems.
For a given wildcard all captures go in the same same linear list across all
modules compiled under the same LookupEnv*. Déjà vu all over again.

7. See if we can improve further on post applicability compatibility checks.

8. On master as well on this patch we are skipping 15.12.3 Compile-Time 
Step 3 for Java 8 ??
Comment 75 Srikanth Sankaran CLA 2014-10-12 07:28:30 EDT
I propose that we address only absolute ship stoppers before release and
move all others to post release in a follow up ticket. Thanks.
Comment 76 Srikanth Sankaran CLA 2014-10-13 23:34:19 EDT
Created attachment 247850 [details]
Cumulative proposed patch

(In reply to Srikanth Sankaran from comment #72)
> Created attachment 247819 [details]
> Cumulative proposed patch
> 
> This patch merged all the incremental fixes and also includes a candidate
> fix for bug 432605 based on the interpretation that a captured wildcard
> has to be treated as a wildcard for type argument containment assertion
> purposes. If we hear otherwise from the spec lead, we can back out this
> change.

I heard back from the spec lead that a captured wildcard is to be treated 
as a type and not as a wildcard. Happily we don't need to deviate in our
treatment to fix https://bugs.eclipse.org/bugs/show_bug.cgi?id=432605. The
whole confusion came about because of my disabling of interned captures 
while null analysis is turned on (bug 446434).

The patch has been updated to backout this hacky/unwarranted change.
Comment 77 Noopur Gupta CLA 2014-10-14 03:55:43 EDT
(In reply to Srikanth Sankaran from comment #76)
> Created attachment 247850 [details]
> Cumulative proposed patch

All JDT UI tests are green with this patch.
Comment 78 Srikanth Sankaran CLA 2014-10-14 04:08:12 EDT
(In reply to Noopur Gupta from comment #77)

> All JDT UI tests are green with this patch.

Thanks Noopur. 

Jay has offered to verify that we build JRE8 alrigtht with this patch and
Shankha will work with other IBM departments to get some stress testing
done. Thanks Jay and Shankha.
Comment 79 Stephan Herrmann CLA 2014-10-14 07:00:27 EDT
Defining the goal post to be attachment 247850 [details] from comment 76 (and assuming bug 446434 has been taken care of - test result pending) I'm starting the main review now.
Comment 80 Stephan Herrmann CLA 2014-10-14 07:19:47 EDT
RawTypeBinding does participate in capture() (inherited from PTB), but in uncapture() we explicitly opt out of the inherited behavior. Do you have a quick explanation, why?

I wouldn't be worried, were it not for RawTypeBinding.initializeArguments() ...
Comment 81 Stephan Herrmann CLA 2014-10-14 08:01:33 EDT
(In reply to Srikanth Sankaran from comment #71)
>     2. Poly expressions are reevaluated, we don't just update the bindings.
> On the +ve side, this enables all the checks that take place post method
> resolution to take place. On the -ve side, ATM, this means some wasteful 
> reinference, but we have a task in follow up task list to have the results 
> forwarded to avoid reinference. I'll address this as a top priority task 
> post review and release of the work here.

Looking at the removal of SyntheticFactoryMethodBinding.applyTypeArgumentsOnConstructor():
This method was introduced to obtain a useful map key for AE.inferenceContexts

After the removal we are in danger not to find some registered inference contexts (original key: factory method, lookup key: constructor).

Could this difference be masked by the fact that now from ASTNode.resolvePolyExpressionArguments() we directly go into:

ParameterizedGenericMethodBinding.computeCompatibleMethod18(MethodBinding, TypeBinding[], Scope, InvocationSite) line: 166	
ParameterizedGenericMethodBinding.computeCompatibleMethod(MethodBinding, TypeBinding[], Scope, InvocationSite) line: 81	
MethodScope(Scope).computeCompatibleMethod(MethodBinding, TypeBinding[], InvocationSite, boolean) line: 733	
MethodScope(Scope).computeCompatibleMethod(MethodBinding, TypeBinding[], InvocationSite) line: 690	
MethodScope(Scope).getStaticFactory(ParameterizedTypeBinding, ReferenceBinding, TypeBinding[], InvocationSite) line: 4947	
AllocationExpression.inferElidedTypes(ParameterizedTypeBinding, ReferenceBinding, TypeBinding[], Scope) line: 562	
AllocationExpression.resolveType(BlockScope) line: 470	
ASTNode.resolvePolyExpressionArguments(Invocation, MethodBinding, TypeBinding[], BlockScope) line: 674	

... without any attempt to re-use the existing inference contexts?

Did the removed method create any trouble? Otherwise we might choose to keep it (incl. its use) to avoid bad surprises when later we try to restore some of the caching-related code?
Comment 82 Stephan Herrmann CLA 2014-10-14 08:07:53 EDT
On error reporting:

I see in the patch:
- some additional secondary errors in test cases
- removal of an attempt in ProblemReporter to delegate reporting to an outer inference context to avoid secondary errors.

Is this tendency to report more errors intended in terms of user experience or a result from technical considerations?
Comment 83 Stephan Herrmann CLA 2014-10-14 08:58:45 EDT
Nitpick re ConditionalExpression:

isPertinentToApplicability() has comment:  "// not perfect."
From my p.o.v. this implementation *is* perfect, if you see reason against please specify :)

isFunctionalType() uses || where I'd expect &&.
Comment 84 Stephan Herrmann CLA 2014-10-14 09:15:58 EDT
Nitpick re ASTNode:

Change removes the attempt to fetch variableArity from an existing inference context. 

If such inference context exists, infCtx.isVarArgs() is authoritative.

The remaining check is best effort to recover this information.

I have no counter example, so the common sense checks *may* be sufficient?
Comment 85 Stephan Herrmann CLA 2014-10-14 09:26:21 EDT
More re ASTNode:

Removed javadoc snippet seems to be still relevant:
 * If this resolving produces better types for any arguments, update the 'argumentTypes' array in-place as an
 * intended side effect that will feed better type information in checkInvocationArguments() and others.


Regarding this check:
  if (!lambda.isCompatibleWith(parameterType, scope) || lambda.hasErrors())
I found no test requiring the first part. Is it needed? I was curious how we could get into that situation.
Comment 86 Stephan Herrmann CLA 2014-10-14 09:53:58 EDT
ExplicitConstructorCall:

Why doesn't this remember any inference contexts any more?

I'd assume that test coverage for this part is low, so not seeing a test that needs it would be a weak reason for removing functionality, IMHO.
Comment 87 Stephan Herrmann CLA 2014-10-14 10:16:00 EDT
I was thinking about the type of PolyTypeBinding.expression: I thought the design might be clearer if we invent an interface (PolyExpression or such) and move/copy all methods required by PolyTypeBinding into that interface.

Unfortunately, methods like Expr.isCompatibleWith are used in a few contexts where arbitrary expressions are possible, not just potential PolyExpressions. While the group of nodes that have meaningful implementations is small, requiring additional (expr instanceof PolyExpression) checks might be overkill.

Just thinking aloud.
Comment 88 Srikanth Sankaran CLA 2014-10-14 10:26:21 EDT
(In reply to Stephan Herrmann from comment #80)
> RawTypeBinding does participate in capture() (inherited from PTB), but in
> uncapture() we explicitly opt out of the inherited behavior. Do you have a
> quick explanation, why?
> 
> I wouldn't be worried, were it not for RawTypeBinding.initializeArguments()
> ...

I don't think it matters in terms of observable behavior, but for clarity's
sakes, RTB should override capture to return itself unmodified.

I don't understand what RTB.initializeArguments purports to do, but in any
event it cannot introduce a wildcard into the picture so leaving capture
to be inherited from PTB should have no effect, but I'll override it in RTB.

(In reply to Stephan Herrmann from comment #81)

> Did the removed method create any trouble? Otherwise we might choose to keep
> it (incl. its use) to avoid bad surprises when later we try to restore some
> of the caching-related code?

Sounds good, I'll add it to the follow up tasks.

(In reply to Stephan Herrmann from comment #82)

> Is this tendency to report more errors intended in terms of user experience
> or a result from technical considerations?

The honest answer is it is neither. I made a good bit of effort to minimize
diagnostic differences and we are where we are with this patch after
such effort. I think we should take a fresh look at this whole issue
separately perhaps under 

https://bugs.eclipse.org/bugs/show_bug.cgi?id=406614 
https://bugs.eclipse.org/bugs/show_bug.cgi?id=404675
https://bugs.eclipse.org/bugs/show_bug.cgi?id=428489
https://bugs.eclipse.org/bugs/show_bug.cgi?id=400831

merged into one project.

(In reply to Stephan Herrmann from comment #83)
> Nitpick re ConditionalExpression:
> 
> isPertinentToApplicability() has comment:  "// not perfect."
> From my p.o.v. this implementation *is* perfect, if you see reason against
> please specify :)

I think this one is fine and the comment can be deleted.

> isFunctionalType() uses || where I'd expect &&.

Here it is intentional even if it seems a bit odd for what could be
seen to be an API.

isFunctionalType() is used eliminate incompatible methods in scope.cCM.
If one arm of the ternary is a functional type, that is enough to assert
that the parameter should be a functional interface. Post applicability
inference, I am checking only functional arguments for compatibility.
Checking more/all arguments is not incorrect, but a waste of time.

I see two possibilities: Rename the method to be mayBeFunctionalType or
kindaSortaFunctionalType :) or document that CE behaves this way, so 
if in future we make use of this API for additional purposes, there
is documentation.

(In reply to Stephan Herrmann from comment #84)
> Nitpick re ASTNode:
> 
> Change removes the attempt to fetch variableArity from an existing inference
> context. 

I think it should be restored along with doing what the TODO suggests.
(Long ago there was a mechanism to let the expressions know they are
arguments at the ellipsis position.) Alternately we should be able to
trivially determine if variable arity was a concern in overloading/type
inference by simply checking the argument to see if it is an array or
element.

(In reply to Stephan Herrmann from comment #85)
> More re ASTNode:
> 
> Removed javadoc snippet seems to be still relevant:
>  * If this resolving produces better types for any arguments, update the
> 'argumentTypes' array in-place as an
>  * intended side effect that will feed better type information in
> checkInvocationArguments() and others.

Correct, this should be reinstated.

> Regarding this check:
>   if (!lambda.isCompatibleWith(parameterType, scope) || lambda.hasErrors())
> I found no test requiring the first part. Is it needed? I was curious how we
> could get into that situation.

Actually, I put it in there because some test produced more/less messages
than required, don't recall which - it may not have been from the suite,
but from some code I played with in the IDE.

The thing is LE.resolveType can finish successfully when it should not - 
for example, value/void compatibility is not checked during resolve and 
so hasErrors() will return false if that is the only sort of error.

Once Sasi's work on lambda shape analysis is integrated, this should be
a non-issue. The new analyzeShape() phase can be initiated right within
LE.resolveType

(In reply to Stephan Herrmann from comment #86)
> ExplicitConstructorCall:
> 
> Why doesn't this remember any inference contexts any more?
> 
> I'd assume that test coverage for this part is low, so not seeing a test
> that needs it would be a weak reason for removing functionality, IMHO.

ECC is not an expression but a statement ? It can never be an inner/nested 
poly expression. So I felt there is no use in preserving the context.

However I already see one use for the inference context. Per earlier /**/ in 
ASTNode.resolvePoly* if we want to check if the method should be seen
to be varargs, it could be useful. However, I think we can simply check
the argument and parameter to see if argument is an array or element type.
expression. Based on how we resolve the ASTNode.resolvePoly* issue, we can
decided on restoring this.

(In reply to Stephan Herrmann from comment #87)
> I was thinking about the type of PolyTypeBinding.expression: I thought the
> design might be clearer if we invent an interface (PolyExpression or such)
> and move/copy all methods required by PolyTypeBinding into that interface.
> 
> Unfortunately, methods like Expr.isCompatibleWith are used in a few contexts
> where arbitrary expressions are possible, not just potential
> PolyExpressions. While the group of nodes that have meaningful
> implementations is small, requiring additional (expr instanceof
> PolyExpression) checks might be overkill.
> 
> Just thinking aloud.

I think it is useful to provide a IPolyExpression interface that is
implemented by the 5 ASTNodes - with "default methods" in Expression
that are overridden in specific types. If nothing else, it makes the
design clear and will also help unify the rest of the work. E.g:
Invocation.binding(), LE.getResolvedCopy* and RE.findCompile* should
all ideally have the same name.
Comment 89 Srikanth Sankaran CLA 2014-10-14 10:34:12 EDT
(In reply to Srikanth Sankaran from comment #88)

> Invocation.binding(), LE.getResolvedCopy* and RE.findCompile* should
> all ideally have the same name.

BTW, we have punted so far on the issue of what should be the return type
of LE.resolveType and RE.resolveType - It should ideally be a new abstraction
FunctionTypeBinding which is a subtype of SourceTypeBinding. There is a
skeleton in LambdaExpression.getTypeBinding().LambdaTypeBinding.
Comment 90 Srikanth Sankaran CLA 2014-10-14 10:36:52 EDT
See also https://bugs.eclipse.org/bugs/show_bug.cgi?id=429430#c35.

But this is a separate project - not an urgent one.
Comment 91 Stephan Herrmann CLA 2014-10-14 11:03:59 EDT
A change in BoundSet reminded me of this "ancient" question:

(In reply to Srikanth Sankaran from comment #26)
> (10) After the round of incorporation, we immediately call captures.clear()
> Is that correct ? There are quite a few clauses that read like if there exist
> a capture bound ... for example 18.4 requires it. Should we not be clearing
> this. but instead be setting a bit to say we have processed the capture
> bound ?

I guess this is still valid, right?

Indeed incorporation makes no mentioning of deleting capture bounds, only resolution does.
Comment 92 Srikanth Sankaran CLA 2014-10-14 11:15:01 EDT
(In reply to Stephan Herrmann from comment #91)
> A change in BoundSet reminded me of this "ancient" question:
> 
> (In reply to Srikanth Sankaran from comment #26)
> > (10) After the round of incorporation, we immediately call captures.clear()
> > Is that correct ? There are quite a few clauses that read like if there exist
> > a capture bound ... for example 18.4 requires it. Should we not be clearing
> > this. but instead be setting a bit to say we have processed the capture
> > bound ?
> 
> I guess this is still valid, right?
> 
> Indeed incorporation makes no mentioning of deleting capture bounds, only
> resolution does.

Yes, at the moment, the patch retains the behavior on master. We don't have
a test case that establishes that clearing them after incorporation is a 
problem.
Comment 93 Stephan Herrmann CLA 2014-10-14 13:30:48 EDT
Diving into the changes in BoundSet, apparently we need to resume the discussion in comment 24 - comment 27.

(In reply to Srikanth Sankaran from comment #26)
> (In reply to Stephan Herrmann from comment #25)
> 
> > In bug 445274 comment 2 I acknowledged this as a bug. Today, however, I
> > believe this was premature: the word "capture" in these constraints is just
> > a symbol that must not be evaluated, because when processing the capture
> > bound we only operate on the original G, A1, ... An (see, e.g., 18.3.2). No
> > part of the spec seems to use the (evaluated) *type* "capture(G<A1,...An>)".
> 
> You are right that 18.3.2 operates on original G, However, I don't think
> capture is just a symbol there - 18.5.2 "Otherwise, if R θ is a parameterized
> type, G<A1, ..., An>," portion needs a capture for correctness. So I think
> the right thing to do is to apply the capture, but for 18.3.2 operate on
> the uncaptured type.

I'm not convinced by your reasoning. If I say "x is bounded by the capture of y" there's nothing requiring me to actually compute the "capture of y". Performing capture and uncapture is a noop, unless someone really refers to "capture of y" as a type. I can't find this in the spec.

Interestingly, reverting this change causes regressions, because of the way you continue using cgA (inside BoundSet.incorporate), so let's include that in the discussion:

(In reply to Srikanth Sankaran from comment #27)
> ...
> Given this and the code above what would allow us to discover
> 
> "?#1 = capture# of ?" and thereby discover A#1 = capture# of ?
> 
> Nothing.
> 
> Ergo.
> 
> BoundSet.capture should be passed in the parameterized type after wildcard
> capture and it should arrange to discover "?#1 = capture# of ?" and propagate
> that.

Your inventing! :)

Do you have any backing by the spec, or can you get it from Oracle?
Comment 94 Srikanth Sankaran CLA 2014-10-14 13:48:44 EDT
(In reply to Stephan Herrmann from comment #93)

> I'm not convinced by your reasoning. If I say "x is bounded by the capture
> of y" there's nothing requiring me to actually compute the "capture of y".
> Performing capture and uncapture is a noop, unless someone really refers to
> "capture of y" as a type. I can't find this in the spec.

The specification calls for 

"Otherwise, if R θ is a parameterized type, G<A1, ..., An>, and one of A1, 
..., An is a wildcard, then, for fresh inference variables β1, ..., βn, the
constraint formula ‹G<β1, ..., βn> → T› is reduced and incorporated, along 
with the bound G<β1, ..., βn> = capture(G<A1, ..., An>), with B2.

I think this is as explicit as it needs to get ?

That we add the capture bound to a set and incorporate later is an
implementation detail. What would reducing and incorporating the bound
G<β1, ..., βn> = capture(G<A1, ..., An>) right then and there do/look
like ?

> Interestingly, reverting this change causes regressions, because of the way
> you continue using cgA 

No, I don't think it is because of the way ... 

It is because that is what is required to be done :)

See there needs to NECESSARILY be a capture of the return type as it
is an expression and so and must go through capture conversion. Capture 
there  is not a symbol - what else would/could it symbolize ? This is the 
only mention of capture there.

> Do you have any backing by the spec, or can you get it from Oracle?

This looks too cut and dry IMHO to escalate ? 

Just as a parallel see that in many other places the spec calls for 
captures - in reduce reference expression compatibility for one example.
Comment 95 Stephan Herrmann CLA 2014-10-14 14:06:14 EDT
(In reply to Srikanth Sankaran from comment #94)
> (In reply to Stephan Herrmann from comment #93)
> 
> > I'm not convinced by your reasoning. If I say "x is bounded by the capture
> > of y" there's nothing requiring me to actually compute the "capture of y".
> > Performing capture and uncapture is a noop, unless someone really refers to
> > "capture of y" as a type. I can't find this in the spec.
> 
> The specification calls for 
> 
> "Otherwise, if R θ is a parameterized type, G<A1, ..., An>, and one of A1, 
> ..., An is a wildcard, then, for fresh inference variables β1, ..., βn, the
> constraint formula ‹G<β1, ..., βn> → T› is reduced and incorporated, along 
> with the bound G<β1, ..., βn> = capture(G<A1, ..., An>), with B2.
> 
> I think this is as explicit as it needs to get ?

This still doesn't convince me, but debugging this disagreement may indeed be beside the point.

The main point I'm objecting is the additional formula you seem to be inventing inside incorporate() (and which uses the capture):

  if (!reduceOneConstraint(context, ConstraintTypeFormula.create(bound.right, cai, ReductionResult.SAME)))
	return false;

Do you have a reference for this?
Comment 96 Stephan Herrmann CLA 2014-10-14 14:10:37 EDT
Oops, this typo might be significant:

(In reply to Stephan Herrmann from comment #93)
> Your inventing! :)

Meant to say: "You're inventing", implying that inventing new rules is s.t. we are not allowed to do.
Comment 97 Stephan Herrmann CLA 2014-10-14 14:18:00 EDT
Inside ConstraintTypeFormula.reduceSubType() there's a new
   case Binding.POLY_TYPE:

I wanted to watch this code block live and in color, but RunAllJava8Tests doesn't seem to trigger this. Do you recall if this was required by any tests or added just to keep us honest about all possible cases?
Comment 98 Srikanth Sankaran CLA 2014-10-14 14:23:44 EDT
(In reply to Stephan Herrmann from comment #95)

> This still doesn't convince me, but debugging this disagreement may indeed
> be beside the point.
> 
> The main point I'm objecting is the additional formula you seem to be
> inventing inside incorporate() (and which uses the capture):
> 
>   if (!reduceOneConstraint(context,
> ConstraintTypeFormula.create(bound.right, cai, ReductionResult.SAME)))
> 	return false;
> 
> Do you have a reference for this?

Let us go back to the your comment#25:

(In reply to Stephan Herrmann from comment #25)

>Here I see some room for interpretation, indeed. spec speaks of the full 
> set of "fresh inference variables β1, ..., βn", without explicit >exceptions. I'm >already excluding inference variables. When substituting >String by βi, aren't >we immediately deriving a bound βi = String ? 

Let us ignore What ever is the means by which we would derive the bound
βi = String. It is a requirement for inference to succeed that βi must be
found to be String.

In a similar fashion, in these programs that fail without the change under
discussion, we must discover that

"?#1 = capture# of ?" and therefore discover A#1 = capture# of ?

Now we can certainly argue/debate whether the code change in place is
the best way to get it done. I am open to suggestions on improvements or
a cleaner fix - Just that not applying capture and dropping a vital clue to
solving the inference puzzle will necessarily mean we will fail.
Comment 99 Srikanth Sankaran CLA 2014-10-14 14:25:55 EDT
(In reply to Stephan Herrmann from comment #97)
> Inside ConstraintTypeFormula.reduceSubType() there's a new
>    case Binding.POLY_TYPE:
> 
> I wanted to watch this code block live and in color, but RunAllJava8Tests
> doesn't seem to trigger this. Do you recall if this was required by any
> tests or added just to keep us honest about all possible cases?

Strange, I did add it after some test failed !

I didn't find it surprising that this block would be required there, because
now MessageSend returns a PolyTB.
Comment 100 Srikanth Sankaran CLA 2014-10-14 14:30:25 EDT
(In reply to Stephan Herrmann from comment #93)

> > BoundSet.capture should be passed in the parameterized type after wildcard
> > capture and it should arrange to discover "?#1 = capture# of ?" and propagate
> > that.
> 
> Your inventing! :)

Actually adding a bound just for "?#1 = capture# of ?" should suffice
as incorporation should take care of the rest - that surely should not
be objectionable ?
Comment 101 Stephan Herrmann CLA 2014-10-14 15:59:39 EDT
Here's how the contention could potentially be resolved:

---------------------------
Change 18.3.2

Add before the bullets:
  Let G<T1,...,Tn> be a capture of G<A1,...,An>.

Change bullet 1
from
 * If Ai is not a wildcard, then the bound αi = Ai is implied. 

to
 * If Ai is not a wildcard, then the bound αi = Ai is implied.
   Otherwise, the bound αi = Ti is implied.

Change bullet 2.1
from
 * αi = R implies the bound false
to
 * αi = R, if R is not a wildcard, implies the bound false
---------------------------


This would match to your implementation (taking comment 100 into consideration) and passes most [1] tests.

We should suggest this to Dan.

I expect that he will agree that s.t. is missing, but he might come up with a different fix for the problem.



[1] GenericsRegressionTest.testBug431408() indicates that the additional bound αi = Ti must only be added inside this branch:

if (ai instanceof WildcardBinding) {
	...
	if (three != null) {
		...
		if (three.sameBounds != null) {
			// HERE

I don't have an explanation for this, but I have to stop for today.
Comment 103 Srikanth Sankaran CLA 2014-10-15 01:07:50 EDT
(In reply to Stephan Herrmann from comment #101)
> We should suggest this to Dan.
> 
> I expect that he will agree that s.t. is missing, but he might come up with
> a different fix for the problem.

I am prototyping a solution that would follow the spec closely and eliminate
deviations however minor. i.e

    - Create fresh inference variables, not recycle.
    - Not apply capture at inferPolyInvocationType - I think JLS is clear
that capture should not be attempted on non-proper types.
    - Eliminate the changes I made to incorporate dealing with captures
and the propagation by reducing new constraints.
    - Not clear captures after incorporation.
    - In Resolve, CaptureBinding18 should be created with new but with
a factory method that would ensure internment.

Let us see if toeing the line in toto helps.
Comment 104 Srikanth Sankaran CLA 2014-10-15 01:23:40 EDT
(In reply to Srikanth Sankaran from comment #103)

>     - In Resolve, CaptureBinding18 should be created with new but with

Should not be created with new ...
Comment 105 Srikanth Sankaran CLA 2014-10-15 01:40:20 EDT
(In reply to Srikanth Sankaran from comment #103)

> Let us see if toeing the line in toto helps.

Looks promising on first glance, IC18.freshCapture has some problems.
CaptureBinding.sourceType is set to this.scope.enclosingSourceType().

Can't be good :)
Comment 106 Srikanth Sankaran CLA 2014-10-15 03:42:02 EDT
(In reply to Srikanth Sankaran from comment #105)
> (In reply to Srikanth Sankaran from comment #103)
> 
> > Let us see if toeing the line in toto helps.
> 
> Looks promising on first glance, IC18.freshCapture has some problems.
> CaptureBinding.sourceType is set to this.scope.enclosingSourceType().
> 
> Can't be good :)

Hmm, that in itself is OK, but I am checking this part of the code anyways.
Comment 107 Srikanth Sankaran CLA 2014-10-15 04:52:12 EDT
Created attachment 247885 [details]
Patch to remove deviations.

This patch removes a few minor deviations in existing code on master
as well backs out my ad-hoc experimentation.

    - Fresh variables are created for capture bound
    - We used to not call incorporate from reduceAndIncorporate. Fixed.
    - Don't apply captures on non-proper types.
    - Not clear captures after incorporation.
   
Why would this code fail LET.testCapture ? Perhaps we will get answer if we
study that.

We fail reducing this constrain where the RHS is a Capturebinding18. I don't
yet know what to make of this:

Type Constraint:
	⟨java.util.Map<K#3,U#4> = <Z#7-Map<K#3,U#4>#7>⟩
Comment 108 Srikanth Sankaran CLA 2014-10-15 09:16:47 EDT
(In reply to Srikanth Sankaran from comment #107)

> We fail reducing this constrain where the RHS is a Capturebinding18. I don't
> yet know what to make of this:
> 
> Type Constraint:
> 	⟨java.util.Map<K#3,U#4> = <Z#7-Map<K#3,U#4>#7>⟩

Analysis: 

// --
18.4:

If the bound set contains a bound of the form G<..., αi, ...> = 
capture(G<...>) for some i (1 ≤ i ≤ n), 

or;

If the bound set produced in the step above contains the bound false;

then let Y1, ..., Yn be fresh type variables whose bounds are as follows:
// --

On master due to our premature clearing of captures from the boundset,
we never reach the "let Y1 .. Yn" portion with capture bounds intact.
We reach this portion of code only for the "Or; if the bound set ...
contains the bound false" portion.

There are only 4 tests in RunAllJava8Tests all from GRT1_8 viz

testBug426671_ok
testBug426671_medium
testBug426671_full
testBug426540

that ever reach here first having created fresh inference variables
in CEF.inferPolyInvocationType. But in all these cases, we reach 18.4
from IC18.inferInvocationType with a request to resolve a subset of
inference variables none of which are the fresh inference variables
created in CEF.inferPolyInvocation*

As a result, we have never encountered certain situations with additional
fresh inference variables and dependencies between them in this portion
of IC18.resolve() 

Now that I have disabled premature clearing of captures, incorporation
is spewing out formulas with CaptureBinding18 in them that CTF is not
prepared to handle.

From my reading of 18.4, ATM, it looks like there is no gap in spec and
we should be able to solve the problem without escalation - Let us see
if this bears out to be true.
Comment 109 Srikanth Sankaran CLA 2014-10-15 13:22:09 EDT
(In reply to Srikanth Sankaran from comment #108)

> Now that I have disabled premature clearing of captures, incorporation
> is spewing out formulas with CaptureBinding18 in them that CTF is not
> prepared to handle.
> 
> From my reading of 18.4, ATM, it looks like there is no gap in spec and
> we should be able to solve the problem without escalation - Let us see
> if this bears out to be true.

I tied this - unfortunately, this requires a fair amount of 
invention/interpretation along the way.

For example, how are we supposed to reduce this:

⟨java.util.Map<K#3,U#4> = <Z#8-Map<K#3,U#4>#7 extends java.lang.Object>⟩ ? 

RHS is CB18, LHS is PTB.

We don't enter:

if ((this.left.isClass() || this.left.isInterface()) 
						&& (this.right.isClass() || this.right.isInterface())
						&& TypeBinding.equalsEquals(this.left.erasure(), this.right.erasure())) 

what is supposed to the erasure of the "fresh type variable"
<Z#8-Map<K#3,U#4>#7 extends java.lang.Object> ? 

If I invent formulas like:

				if (this.right.isSyntheticTypeVariable()) {
					CaptureBinding18 cb18 = (CaptureBinding18) this.right;
					return ConstraintTypeFormula.create(cb18.getInferenceVariable(), this.left, SAME, this.isSoft);
				}
				if (this.left.isSyntheticTypeVariable()) {
					CaptureBinding18 cb18 = (CaptureBinding18) this.left;
					return ConstraintTypeFormula.create(cb18.getInferenceVariable(), this.right, SAME, this.isSoft);
				}

and also a bunch of changes to CB18 to prefer consulting lower bound
before upper bound(s) I am able to get it to infer the collect call in

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class Person {
	String getLast() { return null; };
}
public class X {
	void test1(List<Person> roster) {
        Map<String, Person> map = 
                roster
                    .stream()
                    .collect(
                        Collectors.toMap(
                            p -> p.getLast(), //[1]
                            p -> p            //[2]
                        ));
	}
}

to be 

Map<java.lang.String,Person> collect(Collector<? super Person,java.lang.Object,Map<java.lang.String,Person>>) 

but that is missing the wildcard capture.

I don't think the spec leads to a solution that would contain the
capture. As long as we don't associate 

"?#1 = capture# of ?" 

we are not going to solve it and I don't see that in JLS.
Comment 110 Srikanth Sankaran CLA 2014-10-15 21:04:06 EDT
(In reply to Srikanth Sankaran from comment #109)

> I don't think the spec leads to a solution that would contain the
> capture. As long as we don't associate 
> 
> "?#1 = capture# of ?" 
> 
> we are not going to solve it and I don't see that in JLS.


Stephan, while we wait for clarifications from Oracle, based on your time 
availability, we can still proceed with the review of the rest of the patch.

(Unfortunately, though this should be a side issue for the core solution
it is not - the new approach depends on being able to reevaluate and obtain
the same capture that inference saw and we are having trouble locating in the
JLS where inference should apply the capture - nevertheless, it is one
isolated issue and rest of the changes can continue to be reviewed.)
Comment 111 Srikanth Sankaran CLA 2014-10-17 00:52:08 EDT
Created attachment 247955 [details]
Fixes for two problems found by other IBM projects.

(In reply to Srikanth Sankaran from comment #78)

> Shankha will work with other IBM departments to get some stress testing
> done. Thanks Jay and Shankha.

Testing went fine, two issues got reported. This patch has corrections for
those two problems.

    - AllocationExpression.isBoxingCompatible was missing a call to compute
boxing type.
    - After ground target type is determined, we may still be left with 
wildcards in the ground target type that could make the target type and
the lambda incompatible - on master this case was handled in 
Expression.resolveTypeExpecting. Now we don't reach there, so a check is
needed in LE itself.
Comment 112 Srikanth Sankaran CLA 2014-10-17 00:56:12 EDT
(In reply to Srikanth Sankaran from comment #78)

> Jay has offered to verify that we build JRE8 alrigtht with this patch

Jay, to test JRE and Eclipse SDK builds, you will have to apply the patch
"Cumulative ..." and "Fixes for two ..." and NOT the "patch to remove ..."
That was an experimental patch I wanted to share with Stephan.
Comment 113 Jay Arthanareeswaran CLA 2014-10-17 06:25:11 EDT
(In reply to Srikanth Sankaran from comment #112)
> Jay, to test JRE and Eclipse SDK builds, you will have to apply the patch
> "Cumulative ..." and "Fixes for two ..." and NOT the "patch to remove ..."
> That was an experimental patch I wanted to share with Stephan.

I tried to build JRE from source after long time today and found 6 compilation errors, of which 5 are present on HEAD. Here's the testcase for the additional error:

public class OpenMBeanInfoSupport extends MBeanInfo {
    public OpenMBeanInfoSupport(MBeanNotificationInfo[] notifications) {
        super((notifications == null) ? null : notifications.clone());
    }
}

class MBeanInfo  {
    public MBeanInfo(MBeanNotificationInfo[] notifications)
            throws IllegalArgumentException {
    }
}
interface MBeanNotificationInfo {}

Here's the testcase for the errors that are produced in HEAD (this has nothing to do with the patch, though, so I will raise a new bug for this):

public class RMIConnector {
	private Integer addListenerWithSubject(MarshalledObject<String> filter) {
		final MarshalledObject<String>[] filters = 
						Util.cast(new MarshalledObject<?>[] { filter });
		return null;
	}
}

class Util {
	@SuppressWarnings("unchecked")
	public static <T> T cast(Object x) {
		return (T) x;
	}
}

class MarshalledObject<T> {}
Comment 114 Srikanth Sankaran CLA 2014-10-17 07:47:14 EDT
(In reply to Jayaprakash Arthanareeswaran from comment #113)
> (In reply to Srikanth Sankaran from comment #112)
> > Jay, to test JRE and Eclipse SDK builds, you will have to apply the patch
> > "Cumulative ..." and "Fixes for two ..." and NOT the "patch to remove ..."
> > That was an experimental patch I wanted to share with Stephan.
> 
> I tried to build JRE from source after long time today and found 6
> compilation errors, of which 5 are present on HEAD. Here's the testcase for
> the additional error:

Thanks Jay, I see three problems:

    - NPE only with the patch while compiling one of the snippets - traced it 
to an pre-existing/dormant bug in Expression.isBoxingCompatibleWith. It is
missing a null check compared to its counterpart Expression.isCompatibleWith.
We simply didn't exercise this path earlier.

    - Failure in type inference on master and with the patch. I traced it to
a bug in BoundSet.ThreeSets.upperBounds(boolean, InferenceVariable). If the
only upper bound is an ArrayBinding, we incorrectly return NO_TYPES.

These two are fixed.

    - Failure to compile the super call with poly conditional expression.
I traced it to existing behavior of LE.computeArrayClone - it returns
the same binding for all array clones with return type set to Object !
We need one for each array type. I am working on this.
Comment 115 Srikanth Sankaran CLA 2014-10-17 08:12:09 EDT
Created attachment 247972 [details]
Fix for JRE8 build problems

I think this should fix the problems seen on master as well as with
the patch set under consideration here.

Jay, appreciate your giving it a quick spin, tests are still running, but
I don't expect any issues.
Comment 116 Srikanth Sankaran CLA 2014-10-17 08:28:25 EDT
(In reply to Srikanth Sankaran from comment #115)

> Jay, appreciate your giving it a quick spin, tests are still running, but
> I don't expect any issues.

RunAllJava8Tests finished alright. Jay also confirmed that JRE8 full
build is fine.
Comment 117 Jay Arthanareeswaran CLA 2014-10-17 10:46:39 EDT
Completed some more testing - building the eclipse SDK with the patches. Everything looks good. I was able to compile the eclipse projects successfully as is and with the artificially boosted compliance of 1.8 with the patch provided here:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=428203#c6
Comment 118 Srikanth Sankaran CLA 2014-10-17 10:51:05 EDT
Summarizing:

   - JDT/Core, JDT/UI, JDT/APT tests look good,
   - JRE8 builds fine.
   - Boostrap tests with artificial boost to project settings to 1.8 went OK.
   - Other IBM teams engaged in testing and the reported issues resolved.
Comment 119 Stephan Herrmann CLA 2014-10-17 16:04:50 EDT
I'm back to asking trivial questions :)

PGMB.cCM18()
- Comment has been added: "// CHECK"
  Who's supposed to check what?

- Given that methodSubstitute is a local variable, what's this snippet saying
  (2 occurrences):
	methodSubstitute = null;
	return problemMethod;
  ?
Comment 120 Stephan Herrmann CLA 2014-10-17 16:11:59 EDT
(In reply to Srikanth Sankaran from comment #114)
>     - Failure in type inference on master and with the patch. I traced it to
> a bug in BoundSet.ThreeSets.upperBounds(boolean, InferenceVariable). If the
> only upper bound is an ArrayBinding, we incorrectly return NO_TYPES.

Thanks for catching this.

Follow-up task for me:
  Seeing an ArrayBinding in local variable 'simpleUpper' raises an alert:
  Check if "instanceof ReferenceBinding" was meant to be
    !right.isPrimitiveType()
  I'm pretty sure I was thinking that ArrayBinding is a ReferenceBinding.
  (Then: change type of 'rights' to TypeBinding[])
Comment 121 Stephan Herrmann CLA 2014-10-17 16:59:48 EDT
I'm having a bit trouble digesting the changes in Scope.parameterCompatibilityLevel().

- what exactly is checkOnlyFunctionalTypes controling?
  - it seems to cause both more and less checking
    (see the "return NOT_COMPATIBLE" and "continue" arms inside)
  - from three added blocks governed by "if (checkOnlyFunctionalTypes)"
    (1) has different logic than (2) & (3), which all could be converted
    to (almost?) the same shape. Is there a significant difference?
  - how is mentioning of jlO connected to the issue of functional types?
- why is some of this controlled from outside via
  Scope.shouldConsultShadowOriginal()?
  Note the typo, should be "shallow".
Comment 122 Stephan Herrmann CLA 2014-10-17 17:30:28 EDT
Status reached in reviewing:

- The majority of classes with changes have been reviewed.

- Changes in BoundSet await clarification from Dan

- Reviewing still to be completed for:
  - ConstraintExpressionFormula
  - InferenceContext18
  - Scope
  - Tests


Refreshing our memories of issues raised in previous comments:

Comment 88 has several (yet unnumbered) follow-up tasks.

From comment 83, part two (re isFunctionalType()):
The answer in comment 88 doesn't fully convince me, aren't you saying
  b ? new Runnable() : new Object()
makes the expression a functional thing? Probably I didn't fully grok the
semantics of "kindaSortaFunctionalType" :)

Comment 97 calls for constructing a new test case. It could be quite
hard, though, to direct the control flow into this dark corner ...
Comment 123 Srikanth Sankaran CLA 2014-10-17 20:57:58 EDT
(In reply to Stephan Herrmann from comment #119)
> I'm back to asking trivial questions :)
> 
> PGMB.cCM18()
> - Comment has been added: "// CHECK"
>   Who's supposed to check what?
> 
> - Given that methodSubstitute is a local variable, what's this snippet saying
>   (2 occurrences):
> 	methodSubstitute = null;
> 	return problemMethod;
>   ?

Sorry, these should be cleaned up. 

(In reply to Stephan Herrmann from comment #122)

> Refreshing our memories of issues raised in previous comments:

> Comment 88 has several (yet unnumbered) follow-up tasks.

Don't worry about this, I'll make one full pass over all the scattered
comments and enumerate them at the right time.

> From comment 83, part two (re isFunctionalType()):
> The answer in comment 88 doesn't fully convince me, aren't you saying
>   b ? new Runnable() : new Object()
> makes the expression a functional thing? Probably I didn't fully grok the
> semantics of "kindaSortaFunctionalType" :)

No, I am saying

    b ? () -> { /* */ } : new Object()

is an argument expression that is a functional type despite only one
arm of it being a functional type.

Basically an argument expression being tagged as a functional type allows
to us assert the corresponding parameter MUST be a functional interface
type. In this case, even though "new Object()" does not require its
matching parameter to be a functional interface, the lambda does and so
it is correct to assert that the whole conditional expression can be
a compatible argument only if the parameter is a functional interface.

(In reply to Stephan Herrmann from comment #121)
> I'm having a bit trouble digesting the changes in
> Scope.parameterCompatibilityLevel().

After my morning table tennis game :)
Comment 124 Srikanth Sankaran CLA 2014-10-17 22:39:55 EDT
(In reply to Srikanth Sankaran from comment #123)

> No, I am saying
> 
>     b ? () -> { /* */ } : new Object()
> 
> is an argument expression that is a functional type despite only one
> arm of it being a functional type.

i.e on the argument expression side, we are checking if it is a functional
type (i.e whether a lambda or a method reference) not whether it is a 
functional interface, while on the parameter side we are checking if it is
a functional interface type not whether it is a functional type (which does
not make sense as a lambda or a method reference cannot be a parameter, only
an argument)
Comment 125 Srikanth Sankaran CLA 2014-10-18 01:12:26 EDT
Created attachment 247988 [details]
Patch with much clearer version of Scope.parameterCompatibilityLevel

(In reply to Srikanth Sankaran from comment #123)

> (In reply to Stephan Herrmann from comment #121)
> > I'm having a bit trouble digesting the changes in
> > Scope.parameterCompatibilityLevel().
> 
> After my morning table tennis game :)

OK, 4 games (longer version of the game) to 3, great start to the day :)

This attachment eliminates the (misspelled) hack around
Scope.consultShadowOriginal() and also has Scope.parameterCompatibilityLevel
rewritten to make for much easier understanding. (It also corrects some
self defeating even if not incorrect code that was not achieving the
intended purpose)

The small test case GRT1_8.testBug424205b highlights many of the problems
in compatibility checking post just applicability inference.

Here is a further reduced version of it:

interface I {
	void bar(String t);
}
public class X<T> {
	X(String x) {}
	X(T x) {}
	public void one(X<I> c){}
	public void two() {
		one(new X<>((String s) -> { }));
	}
}

During the initial resolve of the poly allocation expression, 
new X<>((String s) -> { }), 

in the static factory based type inference we readily disqualify X(String x) 
as not being applicable and X(T x) as being applicable with the PPGMB 
computed being  X<java.lang.Object> <factory>(java.lang.Object)

(We don't have a target type - so don't/can't proceed to invocation type
inference.)

Now if this PPGMB were to be subjected to argument/parameter compatibility
checks (if invocation type is inferred, we just accept results from part G)
here are some pertinent observations that can be made about how/what those
compatibility checks should do or look like.

1. If the argument expression is NOT a functional type
(FunctionalExpression), it is anyway pertinent to applicability, inference 
would have ensured that it is compatible and so it is wasteful to recheck
compatibility post inference.

It would not be incorrect to recheck, but just wasteful.

So the checkOnlyFunctionalTypes is an optimization. (The optimization
was not properly implemented in the earlier version perhaps leading to the
confusion in understanding)

2. If the argument expression is a functional type then we cannot 
necessarily immediately assert that the corresponding parameter of the 
PPGMB must be a functional interface type. Some caution is required to 
first make sure that the argument expression is pertinent to applicability 
given the shallow original's parameter.

For example: (in the snippet above)

During diamond inference, the (non-generic) candidate constructor 
X<T>.X(T x) from the example above gets a parameterized static factory
 
<T'> X<T'> <factory>(T')

and the inferred PPGMB in the absence of a target type is 

X<java.lang.Object> <factory>(java.lang.Object). 

Now if we ask the argument expression (String s) -> { } if it is compatible 
with the parameter 'Object' of the PPGMB, it would answer false since Object
is not a functional interface. But we should not be asking that question at 
all, since in the generic factory method against which inference would check
for compatibility in the presence of a target type the corresponding 
parameter is T' and T' as the target type for the lambda expression makes 
it not pertinent to applicability given it is a type variable of the 
generic method in consideration (even though the lambda is an explicit 
lambda expression)

This explains the need for and all the uses of code of the form:

if (!shallowParameters[i].isPertinentToApplicability(arg, shallowOriginal))
    continue;

and its minor variants. 

This recently introduced API reaches FunctionalExpression.isPertinent*
through a circuitous route when it should and when it need not, answers
appropriately directly.

3. We may have to exercise caution when applicability inference would/could
have instantiated a PPGMB with partial substitution of inferred solutions 
and j.l.Object for others for the same parameter's type - I don't have a 
test case for this, but this is just defensive coding. If we see the 
parameter mentioning j.l.O at all, we say it is not safe to check 
compatibility. In future we may relax this - this needs much more thinking
to convince ourselves that we will not, looking at partially substituted 
parameter dismiss the method as being incompatible. 

See that the whole "post applicability inference compatibility check" effort
is a best case effort to weed out some methods that on master we would allow
into Scope.mSMB and may be to result in ambiguity: 

See https://bugs.eclipse.org/bugs/show_bug.cgi?id=428811#c3 for example of
a case that would be readily be weeded out due to such checks. (Since
Characteristics[] is not a functional interface while the argument 
expression ImmutableList::copyOf is a functional expression) (even though 
in that bug these checks are not needed with the proposed patch since we 
now proceed to invocation type inference if target type is available and 
target type *is* available in that case) 

A slightly modified case from there where the Collector.of call is not 
in return expression, but is an argument to an invocation would benefit 
from these checks post applicability inference.

See that I also have a follow up task in 
https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444#c74
7. See if we can improve further on post applicability compatibility checks.

So the goal for the present bug is to improve on master behavior without
introducing any bugs --> defensive/conservative checks. If unsure we can
safely check compatibility, back off. Hence the check for jlO being 
mentioned. (this would cover the type variable case also, but ...)

Finally, the Scope.shouldConsultShadowOriginal() piece is withdrawn. It was
originally introduced to tackle a certain difficulty in tunneling through
overload resolution all over again after inferring elided to types to find
the constructor binding. This is unncessary. By reinstating
SyntheticFactoryMethodBinding.applyTypeArgumentsOnConstructor(TypeBinding[])
we get directly get the constructor without looking up the method again.
Comment 126 Srikanth Sankaran CLA 2014-10-18 01:17:39 EDT
(In reply to Srikanth Sankaran from comment #125)

> the constructor binding. This is unncessary. By reinstating
> SyntheticFactoryMethodBinding.applyTypeArgumentsOnConstructor(TypeBinding[])
> we get directly get the constructor without looking up the method again.

See the new method AE.inferConstructorOfElidedParameterizedType.

It should be noted that on both master and with the proposed patch,
after the <> is inferred, we needlessly tunnel through overload resolution
again via the call to findConstructorBinding. We should just retrieve the
constructor from the static factory by using applyTypeArgumentsOnConstructor.
That is a follow up task.
Comment 127 Srikanth Sankaran CLA 2014-10-18 01:50:28 EDT
(In reply to Srikanth Sankaran from comment #125)

> So the checkOnlyFunctionalTypes is an optimization. (The optimization
> was not properly implemented in the earlier version perhaps leading to the
> confusion in understanding)

[...]

> See that the whole "post applicability inference compatibility check" effort
> is a best case effort to weed out some methods that on master we would allow
> into Scope.mSMB and may be to result in ambiguity: 

I just realized that the concerned Scope.parameterCompatibilityLevel could
be reached from Scope.mSMB, in which case this optimization would be 
incorrect. When called from Scope.mSMB, we not only want to know the method
is compatible given the arguments, but also the compatibility "level", 
while post applicability inference, we don't care about the level only 
that it is compatible.

Three ways of resolving:

    - Restore master behavior and say for 1.8 PGMBs and PPGMBs don't
check compatibility post inference. Get rid of the changes to pCL.
Deal with any problems with ambiguity as they arise. 

    - make checkOnlyFunctionalTypes a parameter to pCL.

    - Post applicability inference at 1.8 don't attempt the optimization
and check all arguments against parameters.

I am open to suggestions. In particular, I am fine punting on this whole
issue and deferring to a later date despite the effort invested.
Comment 128 Srikanth Sankaran CLA 2014-10-18 10:27:42 EDT
(In reply to Srikanth Sankaran from comment #127)

> I am open to suggestions. In particular, I am fine punting on this whole
> issue and deferring to a later date despite the effort invested.

After thinking long and hard, I have decided to defer this issue - the
present project is complicated enough that we should not attempt to pile
on more and more.

So, I'll restore the behavior from master with respect to post-applicability-
only-inference compatibility checks into the proposed solution.

I have raised https://bugs.eclipse.org/bugs/show_bug.cgi?id=447767 which
fails on master and will also fail once I withdraw the code changes in
Scope.pCL made on behalf of this bug. This bug nicely illustrates some
of the complexities I was trying to handle in pCL.

We will deal with https://bugs.eclipse.org/bugs/show_bug.cgi?id=447767
separately post resolution of the current bug. This should also take
care of the follow up task (7) listed earlier.

Patch withdrawing the elaborate checks in pCL is under test, will post
shortly.
Comment 129 Srikanth Sankaran CLA 2014-10-18 10:42:50 EDT
Created attachment 247989 [details]
Patch to eliminate post inference compatibility checks.

This patch

    - Eliminates the hack around the mis-spelt 
Scope.shouldConsultShadowOriginal(). That hack was to cope with some
complications in tunneling through overload resolution post elided type
inference to compute the constructor binding. Now we avoid that unnecessary
tunneling by using the reinstated method SFMB.applyTypeArgumentsOnConstructor
See AE.inferConstructorOfElidedParameterizedType.

    - Restores the behavior from master that we will not do compatibility
checks on inferred PGMBs/PPGMBs. This means we will fail on https://bugs.eclipse.org/bugs/show_bug.cgi?id=447767 with this patch as with
master and that failure will have to be handled separately.

I also verified that the need for tolerateInferenceVariable usage goes
away legitimately with the proposed solution. 

Ball is back at your court Stephan.
Comment 130 Srikanth Sankaran CLA 2014-10-18 22:33:27 EDT
(In reply to Srikanth Sankaran from comment #102)
> See https://bugs.openjdk.java.net/browse/JDK-8055963 and 
> https://bugs.openjdk.java.net/browse/JDK-8056092.

Follow up task for this: Remove BoundSet.applyInstantiation and just
check for supers[0-1] being a proper type.
Comment 131 Stephan Herrmann CLA 2014-10-19 09:46:54 EDT
(In reply to Srikanth Sankaran from comment #124)
> (In reply to Srikanth Sankaran from comment #123)
> 
> > No, I am saying
> > 
> >     b ? () -> { /* */ } : new Object()
> > 
> > is an argument expression that is a functional type despite only one
> > arm of it being a functional type.
> 
> i.e on the argument expression side, we are checking if it is a functional
> type (i.e whether a lambda or a method reference) not whether it is a 
> functional interface, while on the parameter side we are checking if it is
> a functional interface type not whether it is a functional type (which does
> not make sense as a lambda or a method reference cannot be a parameter, only
> an argument)

OK, I see: if we have at least one LE or RE, the target type *must* be a functional type. Thanks.

Would "needsFunctionalTargetType" capture the intended semantics, then?
Comment 132 Stephan Herrmann CLA 2014-10-19 09:57:57 EDT
(In reply to Srikanth Sankaran from comment #128)
> After thinking long and hard, I have decided to defer this issue - the
> present project is complicated enough that we should not attempt to pile
> on more and more.

Thanks

(In reply to Srikanth Sankaran from comment #129)
> Created attachment 247989 [details]
> Patch to eliminate post inference compatibility checks.

I've pulled this into my workspace and continue reviewing from here.
Comment 133 Srikanth Sankaran CLA 2014-10-19 10:47:31 EDT
(In reply to Stephan Herrmann from comment #131)

> Would "needsFunctionalTargetType" capture the intended semantics, then?

Sounds better than kindaSortaFunctionalType actually :) Thanks, will do.
Comment 134 Stephan Herrmann CLA 2014-10-19 11:27:14 EDT
Revisiting AE after comment 129 I'm curious about the role of this line:

	ParameterizedTypeBinding parameterizedType = scope.environment().createParameterizedType(genericType, genericType.typeVariables(), genericType.enclosingType());

(several occurrences)

Parameterizing a generic type with its own type variables doesn't really add interesting information. While I don't see a bug here, I wonder if this could be simplified.

The PTB is needed only for passing into inferElidedTypes() and finally getFactoryMethod(). Inside getFactoryMethod() most work is done using its genericType(), only one call to mMSB() uses the actual PTB. Even there, the generic type *might* suffice.
Comment 135 Srikanth Sankaran CLA 2014-10-19 11:41:10 EDT
(In reply to Stephan Herrmann from comment #134)
> Parameterizing a generic type with its own type variables doesn't really add
> interesting information. While I don't see a bug here, I wonder if this
> could be simplified.

Probably, that code is from Java 7 days. I think there was an outline of
what needed to be done shared in the EG list IIRC and it was supposed to
be a close implementation of that.
Comment 136 Stephan Herrmann CLA 2014-10-19 13:15:15 EDT
I was wondering why everything about this thingy in Scope.mSMB was removed:

  innerInferenceHelper.getArgumentTypesForCandidate(..)

this lead me to see that indeed the root cause leading to that tricky solution is fixed: instead of using argumentTypes from the provisionalResult of applicability inference, we now simply get a PolyTypeBinding in argumentTypes. This PolyTypeBinding serves well for all compatibility checks (In master MessageSend doesn't answer PolyTypeBinding).

Cool!

(reference this obsoletes all that was said and done in bug 426290).
Comment 137 Stephan Herrmann CLA 2014-10-19 13:23:46 EDT
(In reply to Srikanth Sankaran from comment #88)
> (In reply to Stephan Herrmann from comment #82)
> 
> > Is this tendency to report more errors intended in terms of user experience
> > or a result from technical considerations?
> 
> The honest answer is it is neither. I made a good bit of effort to minimize
> diagnostic differences and we are where we are with this patch after
> such effort. I think we should take a fresh look at this whole issue
> separately perhaps under 
> 
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=406614 
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=404675
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=428489
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=400831
> 
> merged into one project.

Note for that future project: in master, IC18 has unfinished work on leveraging a connection from inner to outer inference for better error reporting. It may be interesting to restore IC18.outerContext once we more fully address this.
Comment 138 Srikanth Sankaran CLA 2014-10-19 21:37:07 EDT
(In reply to Stephan Herrmann from comment #136)
> I was wondering why everything about this thingy in Scope.mSMB was removed:
> 
>   innerInferenceHelper.getArgumentTypesForCandidate(..)
> 
> this lead me to see that indeed the root cause leading to that tricky
> solution is fixed: instead of using argumentTypes from the provisionalResult
> of applicability inference, we now simply get a PolyTypeBinding in
> argumentTypes. This PolyTypeBinding serves well for all compatibility checks
> (In master MessageSend doesn't answer PolyTypeBinding).

For the record, this is also the reason why the need for 
`tolerateInferenceVariable' goes away.
Comment 139 Srikanth Sankaran CLA 2014-10-19 21:42:46 EDT
(In reply to Stephan Herrmann from comment #137)

> Note for that future project: in master, IC18 has unfinished work on
> leveraging a connection from inner to outer inference for better error
> reporting. It may be interesting to restore IC18.outerContext once we more
> fully address this.

Right, will do.
Comment 140 Srikanth Sankaran CLA 2014-10-21 02:15:43 EDT
Created attachment 248033 [details]
Merged patch brought up to date with master.

(In reply to Stephan Herrmann from comment #132)

> I've pulled this into my workspace and continue reviewing from here.

Since you have applied the patches already, I took the liberty of merging
the 4 outstanding patches into one, bringing it upto date with master so
it can be applied on top of master in one stroke and reposting here.

There are no new changes in this patch.
Comment 141 Srikanth Sankaran CLA 2014-10-21 02:20:26 EDT
Created attachment 248034 [details]
Correct merged patch

Sorry, uploaded the wrong patch by mistake.
Comment 142 Stephan Herrmann CLA 2014-10-21 16:51:16 EDT
Inching along:

In IC18.addConstraintsToC_OneExpr() the early return according to https://bugs.openjdk.java.net/browse/JDK-8052325 should only happen within

  } else if (expri instanceof Invocation && expri.isPolyExpression()) {

not sure if it makes a difference, tests seem to be fine with this move.
Comment 143 Stephan Herrmann CLA 2014-10-21 17:37:00 EDT
More re IC18.addConstraintsToC_OneExpr()

Inside the "Invocation" branch I begin to believe that more preparation might be necessary before recursion. OK (I'm only unsure, why this preparation would happen only *sometimes*).

However, the block inside "if (expri instanceof LambdaExpression)" looks unmotivated to me from a spec p.o.v. Is this another pending spec amendment?
After
  "If ei is a LambdaExpression, C contains ‹LambdaExpression →throws Fi θ›"
I only see a full stop.
:)

Running GRT_18 with and without that code block I see obvious regressions, but when reverting GRT_18 to master, regressions are less significant.

The difference is due to
- changed test expectations
- added tests

Question: is that added code block intrinsic part of the new F-G-integration, or a change on top, perhaps in trying to better align with javac?
Comment 144 Stephan Herrmann CLA 2014-10-21 18:13:15 EDT
CExprF.reduceReferenceExpressionCompatibility:

you moved the lookup of reference.findCompileTimeMethodTargeting into the branch for inexact RE. This leaves the branch for exact RE without check for applicable method. Apparently, you compensated this by

	} else if (n != k) {
		return FALSE;

- are there other criteria for potentially applicable that we are now missing here?

- if it stays, could you please add a comment, saying that this new branch corresponds to the check for applicable method? On its own it seems to be in conflict with the spec saying: "In all other cases, n = k".


HEADS-UP: I feel I'm running out of original new critique. Phew.

Great piece of work!!

Once we receive answer from Dan - at least concerning the capture bounds issue - we should be ready to come to some conclusion ... and that conclusion will be positive :)
Comment 145 Stephan Herrmann CLA 2014-10-21 18:15:07 EDT
(In reply to Stephan Herrmann from comment #144)
> CExprF.reduceReferenceExpressionCompatibility:
> 
> Apparently, you compensated this by
> 
> 	} else if (n != k) {
> 		return FALSE;

I meant to document which test revealed this connection:
It's LET.test430766
Comment 146 Stephan Herrmann CLA 2014-10-21 18:17:44 EDT
PS: I'm deferring a final walk through test changes until after we decided what goes in, how capture bounds will be handled, ..., i.e. freeze the behaviour of the compiler.
Comment 147 Srikanth Sankaran CLA 2014-10-21 22:12:26 EDT
(In reply to Stephan Herrmann from comment #142)
> Inching along:
> 
> In IC18.addConstraintsToC_OneExpr() the early return according to
> https://bugs.openjdk.java.net/browse/JDK-8052325 should only happen within
> 
>   } else if (expri instanceof Invocation && expri.isPolyExpression()) {
> 
> not sure if it makes a difference, tests seem to be fine with this move.

I think it is correct where it is, but there is value in moving it to where 
you suggest so that someone in future reading code in parallel with 
the specification would find it more aligned. Will do.

(In reply to Stephan Herrmann from comment #143)
> More re IC18.addConstraintsToC_OneExpr()
> 
> Inside the "Invocation" branch I begin to believe that more preparation
> might be necessary before recursion. OK (I'm only unsure, why this
> preparation would happen only *sometimes*).

OK, here is the explanation:

We need to do this preparation only for invocations interleaved by a
lambda. For invocations that are direct arguments to the outer generic
method, because they are necessarily pertinent to the applicability of
the outer method, the equivalent "preparation" would have happened in 
CEF.reduce() during applicability inference.

See that reduce of a poly invocation expression calls for the bound set 
b3 to be transferred to the outer context - we don't literally do this 
on master (or in this patch) but we lift the inference variables, 
initial constraints from parameters and the initial bound set from type
parameter bounds into the outer context => This is b2 from the inner call.
And then by calling CEF.inferPoly*, we add additional constraints for
18.5.2.

All this "effectively amounts to" b3 from the inner call ==> we are good
on master (and since this is not changed in the proposed patch, we are
good with the patch too on this part)

However when a poly invocation is interleaved by a lambda that is not
pertinent to applicability (which means I should check if we are doing
extra/incorrect work when the interleaving lambda *is* pertinent to
applicability of the outer call), this preparation would not have
happened during the applicability inference of the outer call. i.e outer
inference context will not yet have the inference variables, initial
bound set from type variables ... it its context. Hence we need to do
this preparation to lift them to the outer context during C set 
construction.

Corollarywise, because for lambda interleaved inner poly invocations, we
lift the inference variables, initials bounds from type parameters and
initial constraints from parameters during C set construction, their
reduction at CEF.reduce is a NOP.  
 
> However, the block inside "if (expri instanceof LambdaExpression)" looks
> unmotivated to me from a spec p.o.v. Is this another pending spec amendment?
> After
>   "If ei is a LambdaExpression, C contains ‹LambdaExpression →throws Fi θ›"
> I only see a full stop.
> :)

I think you are missing https://bugs.openjdk.java.net/browse/JDK-8038747
referenced by https://bugs.eclipse.org/bugs/show_bug.cgi?id=444891.

> Question: is that added code block intrinsic part of the new
> F-G-integration, or a change on top, perhaps in trying to better align with
> javac?

Per above, it is to cover the spec amendment for 
https://bugs.openjdk.java.net/browse/JDK-8038747. Without this change,
none of the dozen or so duplicates of 
https://bugs.openjdk.java.net/browse/JDK-8038747 would work.
Comment 148 Srikanth Sankaran CLA 2014-10-21 22:23:15 EDT
(In reply to Srikanth Sankaran from comment #147)

> However when a poly invocation is interleaved by a lambda that is not
> pertinent to applicability (which means I should check if we are doing
> extra/incorrect work when the interleaving lambda *is* pertinent to
> applicability of the outer call), this preparation would not have
> happened during the applicability inference of the outer call. i.e outer
> inference context will not yet have the inference variables, initial
> bound set from type variables ... it its context. Hence we need to do
> this preparation to lift them to the outer context during C set 
> construction.

Explicit documentation for a future reader:

...

Hence we need to do this preparation ...

... because if we don't do this preparation during C set construction,
the recursive call to  addConstraintsToC from addConstraintsToC_OneExpr 
for a poly invocation interleaved by an impertinent(!) lambda, will not be 
able substitute inner's type variables with equivalent inference variables
and leave them as naked type variables themselves, which will means the C 
set constraints will not see the inference variables from the inner call,
which will means reduction sequencing using "bottom set - input variables 
- output variables" algorithm will see the naked type variables and not
the inference variables which will mean reduction sequencing will break
down, which will mean things won't work.
Comment 149 Srikanth Sankaran CLA 2014-10-21 22:26:51 EDT
(In reply to Srikanth Sankaran from comment #147)
> 
> > Question: is that added code block intrinsic part of the new
> > F-G-integration, or a change on top, perhaps in trying to better align with
> > javac?
> 
> Per above, it is to cover the spec amendment for 
> https://bugs.openjdk.java.net/browse/JDK-8038747. Without this change,
> none of the dozen or so duplicates of 
> https://bugs.openjdk.java.net/browse/JDK-8038747 would work.

I meant none of the dozen or so duplicates of
https://bugs.eclipse.org/bugs/show_bug.cgi?id=432682 would work.
Comment 150 Srikanth Sankaran CLA 2014-10-22 02:17:46 EDT
(In reply to Stephan Herrmann from comment #144)
> CExprF.reduceReferenceExpressionCompatibility:
> 
> you moved the lookup of reference.findCompileTimeMethodTargeting into the
> branch for inexact RE. This leaves the branch for exact RE without check for
> applicable method. Apparently, you compensated this by
> 
> 	} else if (n != k) {
> 		return FALSE;
> 
> - are there other criteria for potentially applicable that we are now
> missing here?
> 
> - if it stays, could you please add a comment, saying that this new branch
> corresponds to the check for applicable method? On its own it seems to be in
> conflict with the spec saying: "In all other cases, n = k".

Analysis: 

I misspoke in https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444#c138
regarding the reason why the need for tolerateInferenceVariables goes away.

Here is the proper analysis:

During reference expression reduction, we can take one of 4 possible paths:
(a) proper target type, exact method reference
(b) proper target type, inexact method reference.
(c) improper target type, exact method reference,
(d) improper target type, inexact method reference.

For (a) and (b), we will never see inference variables during method
lookup - we also don't get into CEF.reduceREC.

For (d), we assert that function type's parameters must be proper types.
so again we will not need the tolerateInferenceVariable provision.

So only for (c) we will hit that situation, but for (c) we should really
NOT be tunneling through overload resolution since we know we have an
exact method reference lying around.

The other interesting point here is that the spec talks of a potentially
applicable method - we don't have the infrastructure to deliver answers
for that. We compute compatible method which does more work than necessary.

So what I can do as a follow up here is to restore the code relating to
this change from master so the code closely follows/aligns with the spec
and push the change into RE.findCompile* i.e this method would where an
exact method reference exists return that if n == k or n == k + 1 otherwise
null.

Recording another follow up task so it does not fall through the cracks:

ASTNode.resolvePolyExpressionArguments requires a null check at
if (argumentTypes[i].isPolyType()) {

as I noticed an NPE when debugging a broken test case.
Comment 151 Srikanth Sankaran CLA 2014-10-22 02:40:40 EDT
(In reply to Stephan Herrmann from comment #144)

> HEADS-UP: I feel I'm running out of original new critique. Phew.
> 
> Great piece of work!!

Thanks, my goal is to come up with an integration worthy of the inference
engine which is very well written, hopefully this achieves that.

OK, now the mutual admiration society membership subscription is complete. Perfect :) 
 
> Once we receive answer from Dan - at least concerning the capture bounds
> issue - we should be ready to come to some conclusion ... and that
> conclusion will be positive :)

There are several follow up tasks scattered throughout the comments.
AFAICT, the one about the capture bound incorporation is the only
one that needs to be addressed to satisfaction before release, others
can be relegated to a different ticket.

(In reply to Stephan Herrmann from comment #146)
> PS: I'm deferring a final walk through test changes until after we decided
> what goes in, how capture bounds will be handled, ..., i.e. freeze the
> behaviour of the compiler.

Sounds good for now. I have sent a reminder to Dan since it is a week
now with no response. With M3 approaching, I hope we hear soon. I would
really like this to go in for M3 - on the due diligence part, we look
good. 

BTW, there are very small patches on top of the present patch posted for
review at

https://bugs.eclipse.org/bugs/show_bug.cgi?id=430686
https://bugs.eclipse.org/bugs/show_bug.cgi?id=440019 and
https://bugs.eclipse.org/bugs/show_bug.cgi?id=448028

I estimate it should take no more than an hour - it would be good
to release them also for M3. TIA.
Comment 152 Srikanth Sankaran CLA 2014-10-24 05:34:48 EDT
(In reply to Srikanth Sankaran from comment #151)

> BTW, there are very small patches on top of the present patch posted for
> review at
> 
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=430686
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=440019 and
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=448028

and one more:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=444334

For the record, we have word from the spec lead that there are unresolved
issues with capture bound incorporation details:

"I need to spend some more time with this example to be sure (I'll get 
back to you), but you may be running into JDK-8054721.

https://bugs.openjdk.java.net/browse/JDK-8054721

The portion of 18.4 that talks about "fresh type variables" is intended to 
simulate capture, replacing the placeholder inference variables with actual 
type variables.  But it has some problems, not distinguishing between 
declared bounds and inferred bounds."

We need to decide what to do for M3.

I am very comfortable with the change we have - it is small & localized.
If deemed necessary, I am willing to have this controlled by an environment
variable/system property, but that is an overkill IMO.

Duplicates included, we are looking at 30+ issues being resolved.
Comment 153 Srikanth Sankaran CLA 2014-10-24 06:55:15 EDT
(In reply to Srikanth Sankaran from comment #152)

> I am very comfortable with the change we have - it is small & localized.

I meant to add - with a further change to infer bounds of the form
"?#1 = capture# of ?" only when the wildcard in GA is of proper type.

(the proposed patch does more than that)
Comment 154 Stephan Herrmann CLA 2014-10-24 11:45:47 EDT
(In reply to Srikanth Sankaran from comment #152)
> For the record, we have word from the spec lead that there are unresolved
> issues with capture bound incorporation details:
> 
> "I need to spend some more time with this example to be sure (I'll get 
> back to you), but you may be running into JDK-8054721.
> 
> https://bugs.openjdk.java.net/browse/JDK-8054721
> 
> The portion of 18.4 that talks about "fresh type variables" is intended to 
> simulate capture, replacing the placeholder inference variables with actual 
> type variables.  But it has some problems, not distinguishing between 
> declared bounds and inferred bounds."
> 
> We need to decide what to do for M3.
> 
> I am very comfortable with the change we have - it is small & localized.
> If deemed necessary, I am willing to have this controlled by an environment
> variable/system property, but that is an overkill IMO.

Right, I'm not interested in a system property, either. While we don't have the final solution, I'm mainly interested in estimating the effort to change this, once the final solution is given at the spec level.

Let's just document the exact extent of the extra-constitutional part, so that it will be easy, to pull the plug on all of that, without forgetting parts. This can happen by a compile time constant or any documentation device.

The other question is, will the interim solution make it harder to adopt the final solution? This could potentially happen, if the interim solution makes some wrong assumptions and if other changes piled on top of this bend over backwards in order to harmonize with this interim change.

To give a number into the calculation: when draftily reverting the changes re capture bounds, RunAllJava8Tests gives 17 regressions. What's the cause behind those? Maybe I pulled the wrong plug? Was it the previous implementation (master) that bent over backwards to harmonize with the lack of this change?

Since the test changes contained in this bug are part of that equation, I will take a look at those as my next step.
Comment 155 Srikanth Sankaran CLA 2014-10-24 14:07:23 EDT
(In reply to Stephan Herrmann from comment #154)

> Let's just document the exact extent of the extra-constitutional part, so
> that it will be easy, to pull the plug on all of that, without forgetting
> parts. This can happen by a compile time constant or any documentation
> device.

Sounds good.

> The other question is, will the interim solution make it harder to adopt the
> final solution? This could potentially happen, if the interim solution makes
> some wrong assumptions and if other changes piled on top of this bend over
> backwards in order to harmonize with this interim change.

It is hard to make predictions especially about future, but I think
we are on safe grounds here. Basically the change is to infer a bound
equating the fresh type variable that stands for a wild card with a
capture of the wildcard when the wildcard is a proper type. I don't
expect other changes building on top of this. 

> To give a number into the calculation: when draftily reverting the changes
> re capture bounds, RunAllJava8Tests gives 17 regressions. What's the cause
> behind those? 

Basically, you will find that most if not all of the failing tests
will have Collectors.toMap call in them. This has a signature 
Collector<T, ?, M> toMap(...) introducing the wildcard into the
picture.

On master as https://bugs.eclipse.org/bugs/show_bug.cgi?id=445274
points out, we silently instantiate the enclosing collect call to be
Collector<? super Person, Object ,Map<java.lang.String,Person>>.
Now if after outer inference, we push the target type onto inner
and ask it to evaluate it would fail because outer inference is
missing a captured wildcard and jlO is seen there instead.

The situation on master is problematic as some refactoring such as
extract local variable would yield a code fragment that would not
compile.

I think bottom line is that JLS has some open issues as acknowledged
by Dan. Our implementation also has issues - in terms of premature clearing
of capture bounds as well as how CaptureBinding18 behaves. I think
it is supposed to act as a type that potentially has both lower and
upper bounds, but it for the most part it looks only at upper bound.

Another interesting experiment would be what would happen with master
if we don't clear the capture bounds - I recall seeing a handful of
failures with this experiment when I tried earlier. I think the
spec intends that they not be cleared and sooner or later we will
run into a test case that will trigger this scenario.

So this area is going to require revisit anyways, not just on account
of this extra constitutional change.
Comment 156 Srikanth Sankaran CLA 2014-10-24 14:11:43 EDT
Tomorrow, (a) I'll prepare a patch isolating the changes for capture bound
incorporation under a compile time constant as well as minimizing the
changes if possible. I didn't so far get to investigate your observations
at the bottom of https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444#c101.
(b) Raise follow up bugs for all issues pointed out by both of us so we have
a clear picture of what the finishing touch required is going to be.
Comment 157 Srikanth Sankaran CLA 2014-10-24 23:08:24 EDT
Created attachment 248173 [details]
Addendum for capture bound change under compile time constant

This patch isolates the changes for capture bound incorporation under a
compile time constant IC18.SHOULD_WORKAROUND_BUG_JDK_8054721

There are exactly two chunks of change under this guard and I am convinced
they are absolutely harmless.

It is likely that when we adjust fully to proper handling of capture bound
incorporation (i.e don't clear capture bounds prematurely and deal with
them in 18.4 taking https://bugs.openjdk.java.net/browse/JDK-8054721 into
account and https://bugs.eclipse.org/bugs/show_bug.cgi?id=447576 into account)
we may not need real captures anymore. 

Thing is either we need proper simulated captures or real captures, it cannot 
be neither and this patch takes the real capture route.
Comment 158 Srikanth Sankaran CLA 2014-10-25 01:50:15 EDT
OK, I have gone through every single comment with a fine toothed comb 
and raised follow up tickets under the umbrella bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=448791.

We have 13 tasks of none of which is a blocker for M3.

I would rate:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=447767
https://bugs.eclipse.org/bugs/show_bug.cgi?id=448792
https://bugs.eclipse.org/bugs/show_bug.cgi?id=448793
https://bugs.eclipse.org/bugs/show_bug.cgi?id=448794 and
https://bugs.eclipse.org/bugs/show_bug.cgi?id=448802

as candidates for M4.

For various other small corrections/suggestions that don't have to be 
deferred to their own tickets, I have a prepared a patch that is being
tested against all JDT/Core tests. 

Will upload once done.

Looks all set.
Comment 159 Srikanth Sankaran CLA 2014-10-25 02:51:30 EDT
Created attachment 248174 [details]
Addendum to incorporate review comments
Comment 160 Srikanth Sankaran CLA 2014-10-25 02:56:57 EDT
The patch "addendum for capture bound ..." and "Addendum to incorporate ..."
need to be applied on top of the patch for 
https://bugs.eclipse.org/bugs/show_bug.cgi?id=444334 which itself specifies
its application order in https://bugs.eclipse.org/bugs/show_bug.cgi?id=444334#c12. (I should really start working on branches)

All tests are green - Once I hear a final go, I'll promote the changes. 

If there are no objections, I would like to promote all of the follow up
fixes listed in https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444#c152.
There are 4 of them - these are routine bug fixes and can be reviewed one
by one, at your leisure. Or perhaps you could give it a high level once over
before promotion and closer review can come in the next week or two.

Thanks Stephan.
Comment 161 Stephan Herrmann CLA 2014-10-25 07:47:17 EDT
(In reply to Srikanth Sankaran from comment #158)
> OK, I have gone through every single comment with a fine toothed comb 
> and raised follow up tickets under the umbrella bug:
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=448791.
> 
> We have 13 tasks of none of which is a blocker for M3.

Looks clean. I agree, no blocker for M3.
Comment 162 Stephan Herrmann CLA 2014-10-25 08:00:56 EDT
A summary from another p.o.v: pending spec changes adopted by this patch:

see comment 44:
https://bugs.openjdk.java.net/browse/JDK-8052325 

see comment 102:
https://bugs.openjdk.java.net/browse/JDK-8055963 (javac bug)
https://bugs.openjdk.java.net/browse/JDK-8056092 (spec bug)

see comment 147 & bug 444891
https://bugs.openjdk.java.net/browse/JDK-8038747

see comment 152:
https://bugs.openjdk.java.net/browse/JDK-8054721

None of these spec bugs are resolved, our implementation is built on good faith that directions outlined in the bugs will actually appear in a future version of JLS and represent the original intention for Java 8.

Am I describing the situation correctly?
Comment 163 Srikanth Sankaran CLA 2014-10-25 08:07:34 EDT
(In reply to Stephan Herrmann from comment #162)

> Am I describing the situation correctly?

Yes, that is correct. We need to see if there is a way to add ourselves
to the notification list to listen in further amendments and/or resolution.
I am not sure how to do this yet.

I'll forward to the team as well as also document here the link provided by 
Daniel Smith on specification bugs open, in progress and recently resolved:

// ---

> [Do you have a canned query that would show me all the open and recently 
> resolved defects against the JLS ?] 

https://bugs.openjdk.java.net/issues/?jql=project%20%3D%20JDK%20AND%20component%20%3D%20specification%20AND%20status%20in%20(Open%2C%20%22In%20Progress%22)%20ORDER%20BY%20fixVersion%20ASC

Roughly, "Open" and "In Progress" bugs are acknowledged problems, with varying degrees of resolution (some are problem statements, some have suggested replacement text).  "Resolved" and "Closed" bugs have been addressed and the fixes published.  (The line between the two states in each case is fuzzy, as far as I know.)

Fix Version will tell you whether something is intended for a maintenance review of SE 8 or deferred until (at least) SE 9.  These are subject to change.


// ---
Comment 164 Srikanth Sankaran CLA 2014-10-25 08:14:14 EDT
(In reply to Stephan Herrmann from comment #161)

> Looks clean. I agree, no blocker for M3.

I'll wait for an explicit go and not treat this as one. I think per https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444#c146
you wanted to look through the test changes after the code changes are frozen.
Comment 165 Stephan Herrmann CLA 2014-10-25 08:29:17 EDT
Closing one more loose end:

My concern raised in comment 143 is indeed answered by the reference to https://bugs.openjdk.java.net/browse/JDK-8038747. 
Just two tiny question remain:

(1) why this line:
  if (substF.isFunctionalInterface(skope)) { // could be an inference variable.
after a check experiment (only GRT18) this should suffice:
  if (substF instanceof ReferenceBinding) {
Do you have a counter-example?

(2) before calling IC18.getInferenceContext() we inconsistently ask instanceof PMB vs. PGMB (getInferenceContext only requires PMB).
I seem to remember that some of the pending patches has changes already in this field? If not, might be worth a tiny new child of bug 448791

Certainly no blockers, though.  


(In reply to Srikanth Sankaran from comment #164)
> (In reply to Stephan Herrmann from comment #161)
> 
> > Looks clean. I agree, no blocker for M3.
> 
> I'll wait for an explicit go and not treat this as one. I think per
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444#c146
> you wanted to look through the test changes after the code changes are
> frozen.

Right, comment 161 concerned the follow-up tasks. Final look through test changes starting right now ...
Comment 166 Srikanth Sankaran CLA 2014-10-25 08:34:28 EDT
(In reply to Stephan Herrmann from comment #84)

> Change removes the attempt to fetch variableArity from an existing inference
> context. 
> 
> If such inference context exists, infCtx.isVarArgs() is authoritative.
> 
> The remaining check is best effort to recover this information.
> 
> I have no counter example, so the common sense checks *may* be sufficient?

Yes, this is sufficient.
Comment 167 Srikanth Sankaran CLA 2014-10-25 09:00:53 EDT
(In reply to Stephan Herrmann from comment #165)

> Just two tiny question remain:
> 
> (1) why this line:
>   if (substF.isFunctionalInterface(skope)) { // could be an inference
> variable.
> after a check experiment (only GRT18) this should suffice:
>   if (substF instanceof ReferenceBinding) {

OK, the thing is we can generate meaningful C set elements only when
substF is a functional interface. Given that we can quit early checking for
functional interface target or quit a bit later after seeing that we
don't have a sam which is really the same check. (isFI populates the cache
so getSAM() returns instantaneously.)

One thing I could have done and didn't choose to was to return false
if target is not a functional interface. Originally it was there, but
then I realized that we could see an inference variable and could
return false incorrectly and turned it to what it is now.

We could still return false if it is not functional and not an inference
variable, but I didn't see this part's role in triggering an early failure
as an important one.


> Do you have a counter-example?
> 
> (2) before calling IC18.getInferenceContext() we inconsistently ask
> instanceof PMB vs. PGMB (getInferenceContext only requires PMB).
> I seem to remember that some of the pending patches has changes already in
> this field? If not, might be worth a tiny new child of bug 448791
> 
> Certainly no blockers, though.  
> 
> 
> (In reply to Srikanth Sankaran from comment #164)
> > (In reply to Stephan Herrmann from comment #161)
> > 
> > > Looks clean. I agree, no blocker for M3.
> > 
> > I'll wait for an explicit go and not treat this as one. I think per
> > https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444#c146
> > you wanted to look through the test changes after the code changes are
> > frozen.
> 
> Right, comment 161 concerned the follow-up tasks. Final look through test
> changes starting right now ...
Comment 168 Stephan Herrmann CLA 2014-10-25 09:43:13 EDT
The OCD part of the team has found no reason for holding back this patch any longer:

+1 for releasing attachment 248034 [details] and attachment 248173 [details]
Comment 169 Srikanth Sankaran CLA 2014-10-25 10:19:02 EDT
(In reply to Stephan Herrmann from comment #165)

> (2) before calling IC18.getInferenceContext() we inconsistently ask
> instanceof PMB vs. PGMB (getInferenceContext only requires PMB).
> I seem to remember that some of the pending patches has changes already in
> this field? If not, might be worth a tiny new child of bug 448791

This one needs a longer explanation and also a peek into the pending patches.

With all 7 patches applied I see all calls to getIC preceded consistently
by an instanceof check for PGMB and not PMB. 

In the final implementation if the <> constructor is NOT generic it is not 
useful to return the static factory's context. It is actually harmful.

All patches considered, the inner inference context is used for these purposes:

    1. To decide whether reduction to b3 should just be a NOP, effectively
equivalent things having already been done during C set construction.
(this has some issues - there is a FIXME in CEF.reduce that maps to
https://bugs.eclipse.org/bugs/show_bug.cgi?id=448802)

    2. To transfer b2 to the outer context to subsequently augment it to b3.
We should transfer b2 and not "what would effectively reduce to b2" as 
documented elsewhere as the atomicity problem"

    3. To determine what inference kind was used earlier.

    4. To see if unchecked conversion was involved earlier

Non-generic constructor case:
-----------------------------

Now for a non-generic constructor returning the inference context of the
factory is harmful because the factory is really a synthesized method with
extra type variables to stand in for the class's type variables. It does
not map properly to the generic constructor itself. There are 
"out of scope" variables, bounds etc, so things quickly go south.

The else part of
if (previousMethod instanceof ParameterizedGenericMethodBinding) {
    // ...
} else {

}

effectively does what we do on master.

Is this sufficient ?

Clearly (3) is addressed and (2) is addressed as well as on master
but for (1) and (4) it needs some thinking through.

Now considering the case where the constructor does turns out to be
generic: 

This generic constructor is not inferred, but is directly manufactured by
AE.inferConstructorOfElidedParameterizedType by using 
SFMB.applyTypeArgumentsOnConstructor

As a result, we don't have an inference context for that. I am not certain
it would be right/wrong to use the factory's context for the generic 
constructor for reasons cited just now.

That means that for a generic constructor we should be doing:

if (innerCtx == null) { // no inference -> assume it wasn't ...
    TypeBinding exprType = this.left.resolvedType;
    if (exprType == null || !exprType.isValidBinding())
	return FALSE;
    return ConstraintTypeFormula.create(exprType, this.right, COMPATIBLE, this.isSoft);
}

Is this sufficient ? I don't know.

I say "we should be doing" because I don't see a single test triggering
the conditional breakpoint 

previousMethod instanceof ParameterizedGenericMethodBinding && previousMethod.isConstructor()

in RunAllJava8Tests - i.e we don't have a test for a <> allocation that 
would bind to a generic method *and* is itself a nested invocation under 
a generic method.

I'll add a follow up task to investigate this further under 
https://bugs.eclipse.org/bugs/show_bug.cgi?id=448799.
This particular task would need to be done for M3 while the other
activities of https://bugs.eclipse.org/bugs/show_bug.cgi?id=448799 can
come in for M4.
Comment 170 Srikanth Sankaran CLA 2014-10-25 10:35:30 EDT
(In reply to Srikanth Sankaran from comment #169)

> I'll add a follow up task to investigate this further under 
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=448799.
> This particular task would need to be done for M3 while the other
> activities of https://bugs.eclipse.org/bugs/show_bug.cgi?id=448799 can
> come in for M4.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=448799#c1.

It also outlines a possible resolution - I'll get this followed up for M3.

Given the complexity, the size and scope this project has come to assume
some amount of going back and forth, sorry about that.

Looking at https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444#c129,
AE.inferConstructorOfElidedParameterizedType was introduced at the same
time Scope.consultShadowOriginal() hack and post applicability checks
were withdrawn.

    (1) Post applicability compatibility checks cause problems when 
tunneling through overload resolution for a constructor after inferring
its elided types in the absence of a target type.

    (2) Scope.consultShadowOriginal() was a mechanism to circumvent those
problems.

    (3) AE.inferConstructorOfElidedParameterizedType avoids tunneling
through overload resolution.

Given (1) is withdrawn, (2) is unnecessary and is withdrawn.

Given (1) is withdrawn, tunneling through overload resolution is safe
and so (3) which is just an optimization can be foregone.

If we forego (3), we will have an inference context for a generic 
constructor as we would expect.

Ergo, this should be a simple fix.
Comment 171 Srikanth Sankaran CLA 2014-10-25 11:49:29 EDT
(In reply to Stephan Herrmann from comment #168)
> The OCD part of the team has found no reason for holding back this patch any
> longer:
> 
> +1 for releasing attachment 248034 [details] and attachment 248173 [details]

Here:

http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=f357f309273e0bfe8345ff708d18fa83c6a34931

and here: 

http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=192820efad9191d4773fbd88aa6d8a5ea915ea14.

Thanks.

OCD ? which one of http://acronyms.thefreedictionary.com/OCD did you mean ? :)
Comment 172 Srikanth Sankaran CLA 2014-10-25 11:52:11 EDT
Comment on attachment 248174 [details]
Addendum to incorporate review comments

I'll repost this one with two further changes called out:

(1) Ensure generic constructor gets an inference context.
(2) CEF.reduce: merge if (innerCtx == null) and if (innerCtx.stepCompleted >= InferenceContext18.TYPE_INFERRED)

I will do this well in time for your planned review slot tomorrow.
Comment 173 Stephan Herrmann CLA 2014-10-25 11:54:43 EDT
(In reply to Srikanth Sankaran from comment #171)
> OCD ? which one of http://acronyms.thefreedictionary.com/OCD did you mean ?
> :)

The first, of course.
To prove: if I were not OCD I'd leave this question unanswered ...
Comment 174 Srikanth Sankaran CLA 2014-10-25 15:59:19 EDT
SFMB.applyTypeArgumentsOnConstructor always returns a PMB, it only
receives the class type arguments and not the method type arguments.

I think it should receive both and if method type arguments is not
empty instantiate and return a PGMB - No ?
Comment 175 Srikanth Sankaran CLA 2014-10-25 16:41:48 EDT
Created attachment 248182 [details]
Addendum to incorporate review comments

New additions: 

   - Makes suitable changes to SFMB.applyTypeArgumentsOnConstructor to make
it returns a PGMB when it should.

   - Establish an inference context for a parameterized generic constructor.

Passes RunOnlyJava8Tests. Running all tests now.

(this patch should be applied after the 4 bug fixes in queue)
Comment 176 Srikanth Sankaran CLA 2014-10-25 19:53:49 EDT
(In reply to Srikanth Sankaran from comment #175)

> Passes RunOnlyJava8Tests. Running all tests now.

All clear.
Comment 177 Srikanth Sankaran CLA 2014-10-27 00:21:17 EDT
Noopur, Shankha, Jay,

Sorry for the rework, but the changes for M3 have been phenomenal in
scope and volume.

Can we get another round of elaborate testing organized for M3 (i.e right away)
for JDT/UI, JRE8, SDK bootstrap and working with other IBM team to get some
testing done.

If you are unable to spare cycles, please let me know, I'll make alternate
plans: 

I would say 95% of the code is already on master, you will need to apply
these patches on top of master in this order: 

(1) The patch at https://bugs.eclipse.org/bugs/show_bug.cgi?id=444334
(2) The patch here: (Addendum ...)
(3) The patch https://bugs.eclipse.org/bugs/show_bug.cgi?id=443596 

Thanks in advance.
Comment 178 shankha banerjee CLA 2014-10-27 01:16:56 EDT
Created attachment 248194 [details]
CombinedPatch(Comment 177)

(In reply to Srikanth Sankaran from comment #177)
> 
> (1) The patch at https://bugs.eclipse.org/bugs/show_bug.cgi?id=444334
> (2) The patch here: (Addendum ...)
> (3) The patch https://bugs.eclipse.org/bugs/show_bug.cgi?id=443596 
> 

All three patches combined.
Comment 179 Jay Arthanareeswaran CLA 2014-10-27 01:27:48 EDT
I am able to compile JRE 8 and Eclipse SDK with the patches without any issue. Looks good to me.
Comment 180 Srikanth Sankaran CLA 2014-10-27 09:01:21 EDT
Created attachment 248206 [details]
Revised patch incorporating review comments

Same patch but refreshed since antecedents got some methods relating to
unchecked conversion reporting restored.
Comment 181 Srikanth Sankaran CLA 2014-10-27 10:10:46 EDT
In CEF.inferPoly*() I think there should be a call to initializeBounds()
on the capture - Not sure - the test cases that necessitate this whole
work around mostly use unbounded wildcard (Collectors.groupingBy() and
Collectors.toMap()) for those cases it should not matter, but ...
Comment 182 shankha banerjee CLA 2014-10-27 10:17:52 EDT
(In reply to Srikanth Sankaran from comment #177)
UI test results are good.
Comment 183 Srikanth Sankaran CLA 2014-10-27 18:09:22 EDT
Review comments incorporated and released here: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=b0ee678b65f48d1cfab35972dd53d6bd85389446
Comment 184 Srikanth Sankaran CLA 2014-10-28 02:51:18 EDT
(In reply to Srikanth Sankaran from comment #181)
> In CEF.inferPoly*() I think there should be a call to initializeBounds()
> on the capture - Not sure - the test cases that necessitate this whole
> work around mostly use unbounded wildcard (Collectors.groupingBy() and
> Collectors.toMap()) for those cases it should not matter, but ...

Addressed here: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=9c251eade23f2143003635a87c2f3f96ae52d898
Comment 185 Jay Arthanareeswaran CLA 2014-10-30 05:18:49 EDT
Verified for 4.5 M3 using I20141029-2000 build

We also need to decide on whether or not we want this for 4.4.2. This is fairly big change for a maintenance release, but here are reasons why we might want this:

1. Obviously this fixes lot of issues in inference and overload resolution areas.
2. Since this alters an important area of the compiler in a big way, maintaining two different versions will be difficult.

Srikanth/Stephan, would like to add anything?
Comment 186 Srikanth Sankaran CLA 2014-10-30 20:42:27 EDT
(In reply to Jayaprakash Arthanareeswaran from comment #185)

> Srikanth/Stephan, would like to add anything?

I personally see no choice here - This fixes four cluster of bugs around
(a) nested inference in the presence of an interleaving lambda expression 
(b) handling wildcard capture bounds and (c) raw types and (d) assorted
others that go away with the new implementation.

Unfortunately, apart from the one deviation in our implementation 
(https://bugs.eclipse.org/bugs/show_bug.cgi?id=448793) and some small 
bugs here and there, we fail to compile these cases by *being compliant* 
to the spec as it existed on Java 8 GA.

Stephan's comment at https://bugs.eclipse.org/bugs/show_bug.cgi?id=437444#c162
summarizes this situation nicely.

There is too much inter-dependency in the solution to attempt to 
isolate just the fixes and attempt to back port only them.

So I think rather than ask should we back port, a better question would be 
how can we minimize risks - this we can do by beefing up due diligence 
activities: apart from unit tests, work with other IBM teams to stress test
verify JRE8 builds and Eclipse SDK bootstrap builds are fine etc.

And perhaps most importantly, involve the community (after M3 fixes are
a few select M4 candidates are back ported) with an honest feedback that
4.4.2 is heading to be a release that carries much more changes for a
maintenance release than usual and this is because (a) Java 8 is a huge 
change to Java (b) because there were crucial spec changes post GA which
were implemented by javac *ahead of GA* and so we require active engagement 
from them to test it out.

I recommend we look at backport of M3 fixes after a full 1 month of field
testing of M3.

That is my input for consideration to the JDT leads
Comment 187 Jay Arthanareeswaran CLA 2014-10-31 04:35:07 EDT
(In reply to Srikanth Sankaran from comment #186)
> I recommend we look at backport of M3 fixes after a full 1 month of field
> testing of M3.

Ref: Bug 449389 - We will be using M3 compiler soon for building eclipse SDK.
Comment 188 Jay Arthanareeswaran CLA 2014-11-21 00:16:44 EST
After discussions with Srikanth and Stephan, it's been decided that this is too big a change for back porting.
Comment 189 Stephan Herrmann CLA 2014-12-22 09:24:13 EST
*** Bug 455928 has been marked as a duplicate of this bug. ***
Comment 190 Stephan Herrmann CLA 2015-02-01 14:51:28 EST
*** Bug 458806 has been marked as a duplicate of this bug. ***
Comment 191 Jay Arthanareeswaran CLA 2015-02-04 10:41:03 EST
*** Bug 459145 has been marked as a duplicate of this bug. ***
Comment 192 Stephan Herrmann CLA 2015-02-09 17:49:55 EST
*** Bug 459504 has been marked as a duplicate of this bug. ***
Comment 193 Stephan Herrmann CLA 2015-03-05 19:40:18 EST
*** Bug 461539 has been marked as a duplicate of this bug. ***
Comment 194 Stephan Herrmann CLA 2015-03-08 10:28:49 EDT
*** Bug 461639 has been marked as a duplicate of this bug. ***
Comment 195 Stephan Herrmann CLA 2015-03-08 12:47:01 EDT
*** Bug 461639 has been marked as a duplicate of this bug. ***
Comment 196 Stephan Herrmann CLA 2015-03-08 13:01:42 EDT
*** Bug 461571 has been marked as a duplicate of this bug. ***
Comment 197 Stephan Herrmann CLA 2015-03-12 19:18:22 EDT
*** Bug 462006 has been marked as a duplicate of this bug. ***
Comment 198 Stephan Herrmann CLA 2015-03-22 19:20:00 EDT
*** Bug 462769 has been marked as a duplicate of this bug. ***
Comment 199 Stephan Herrmann CLA 2015-04-22 13:23:33 EDT
*** Bug 465192 has been marked as a duplicate of this bug. ***
Comment 200 Stephan Herrmann CLA 2015-04-29 16:57:24 EDT
*** Bug 465859 has been marked as a duplicate of this bug. ***
Comment 201 Stephan Herrmann CLA 2015-05-20 17:20:51 EDT
*** Bug 467627 has been marked as a duplicate of this bug. ***
Comment 202 Stephan Herrmann CLA 2015-05-29 13:48:07 EDT
*** Bug 468831 has been marked as a duplicate of this bug. ***
Comment 203 Stephan Herrmann CLA 2015-06-26 19:24:40 EDT
*** Bug 470270 has been marked as a duplicate of this bug. ***
Comment 204 Sasikanth Bharadwaj CLA 2015-06-30 06:30:57 EDT
*** Bug 470847 has been marked as a duplicate of this bug. ***
Comment 205 Stephan Herrmann CLA 2015-07-12 12:01:28 EDT
*** Bug 472361 has been marked as a duplicate of this bug. ***
Comment 206 Stephan Herrmann CLA 2016-12-16 09:58:47 EST
*** Bug 469217 has been marked as a duplicate of this bug. ***
Comment 207 Stephan Herrmann CLA 2017-04-01 14:01:36 EDT
*** Bug 470817 has been marked as a duplicate of this bug. ***
Comment 208 Stephan Herrmann CLA 2017-04-14 08:43:53 EDT
*** Bug 443467 has been marked as a duplicate of this bug. ***