Summary: | [1.5][compiler] Possibly incorrect Bounds Mismatch errors for complicated bounds | ||
---|---|---|---|
Product: | [Eclipse Project] JDT | Reporter: | Kory Markevich <vulcannis> |
Component: | Core | Assignee: | Philipe Mulet <philippe_mulet> |
Status: | VERIFIED FIXED | QA Contact: | |
Severity: | normal | ||
Priority: | P3 | CC: | frederic_fusier |
Version: | 3.1 | ||
Target Milestone: | 3.1 RC1 | ||
Hardware: | PC | ||
OS: | Windows 2000 | ||
Whiteboard: |
Description
Kory Markevich
2005-05-17 15:47:14 EDT
Simpler testcase: class Key<E extends Key<E>> {} class Store<A, B extends Key<B>> {} public class X<T> { Store<T, ? extends Key<T>> store; } Even simpler: class Key<E extends Key<E>> {} class Store<F extends Key<F>> {} public class X<T> { Store<? extends Key<T>> store; } Now appears the origin of the compiler diagnostic. Key requires its argument E to be a subtype of Key<E>. However, when used in store field definition, Key<T> is wrong since T has no bound, and doesn't meet expectation (subtype of Key<E>). In order to compile it clear, you should do: class Key<E extends Key<E>> {} class Store<F extends Key<F>> {} public class X<T extends Key<T>> { Store<? extends Key<T>> store; } I believe this is rather a bug in javac. Unfortunately by eliminating Environment your examples changed the meaning. This: class Key< E, K extends Key< E, K > > { } class Store< E, K extends Key< E, K > > { } class X< E > { Store< E, ? > store1; Store< E, ? extends Key< E, ? > > store2; } is more in line with what I was trying to accomplish. Unfortunately store1's type is not restrictive enough; it doesn't indicate that all the Key's have type Key< E, ? >. store2 adds this information, but generates the same bug as I reported above. Now store2 isn't perfect either, as the fact that the two ?'s should be equal isn't evident. However this could be realized by looking at Store's restrictions, could it not? I'm not sure what the JLS says about cases like this. Further your examples introduced T which fixes the type of the Key being used, while I'm trying to range over many subtypes. Perhaps this simply isn't expressible with java's type system, but it seems that my store2 example does at least get close. I simplified the example as long as I could preserve the discrepancy between javac and us. Also, renaming type variables (and uses) has no effect on semantics, I was trying to better separate the various cases. When adding a bound onto T, I fixed the simplified issue for us; in a way which suggests javac failed a bound check (when bound was missing). I will look into your simpler example Problem is that both wildcards may represent a different type, which could burn the bound check. javac seems to miss this case. If you make both be the same type, by introducing an extra type parameter, then we will compile it clean. I was guessing you could hide it from the outside, by using a member type ? class Key<E, K extends Key<E, K>> {} class Store<E, K extends Key<E, K>> {} class X<E> { class Y <F extends Key<E, F>> { Store<E, F> store; } } } Last thinking is that your scenario would be valid, and our diagnostic wrong. Added GenericTypeTest#test673-675,679-681. Changed bound check to better reflect capture mechanism, performing an intersection check. Also removed unnecessary bounds from wildcard, since these are only held on by the actual capture. Fixed Unfortunately, it seems that test case of comment 0 produce an NPE... Select Type in"..., T extends Type<Environment,..." and hit F3 => Error Excuting Command... Reason NPE Stack trace: java.lang.NullPointerException at org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding.boundCheck(TypeVariableBinding.java:112) at org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding.boundCheck(ParameterizedTypeBinding.java:59) at org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference.checkBounds(ParameterizedSingleTypeReference.java:40) at org.eclipse.jdt.internal.compiler.ast.TypeParameter.checkBounds(TypeParameter.java:36) at org.eclipse.jdt.internal.compiler.lookup.ClassScope.checkParameterizedTypeBounds(ClassScope.java:699) at org.eclipse.jdt.internal.compiler.lookup.ClassScope.connectTypeHierarchy(ClassScope.java:886) at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.connectTypeHierarchy(CompilationUnitScope.java:254) at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.completeTypeBindings(LookupEnvironment.java:249) at org.eclipse.jdt.internal.codeassist.impl.Engine.accept(Engine.java:92) at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.askForType(LookupEnvironment.java:131) at org.eclipse.jdt.internal.compiler.lookup.PackageBinding.getTypeOrPackage(PackageBinding.java:178) at org.eclipse.jdt.internal.compiler.lookup.Scope.getTypeOrPackage(Scope.java:2491) at org.eclipse.jdt.internal.compiler.lookup.Scope.getType(Scope.java:2237) at org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference.internalResolveType(ParameterizedSingleTypeReference.java:99) at org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference.resolveType(ParameterizedSingleTypeReference.java:209) at org.eclipse.jdt.internal.codeassist.select.SelectionOnParameterizedSingleTypeReference.resolveType(SelectionOnParameterizedSingleTypeReference.java:30) at org.eclipse.jdt.internal.compiler.lookup.Scope.connectTypeVariables(Scope.java:402) at org.eclipse.jdt.internal.compiler.lookup.ClassScope.connectTypeHierarchy(ClassScope.java:880) at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.connectTypeHierarchy(CompilationUnitScope.java:254) at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.completeTypeBindings(LookupEnvironment.java:249) at org.eclipse.jdt.internal.codeassist.SelectionEngine.select(SelectionEngine.java:657) at org.eclipse.jdt.internal.core.Openable.codeSelect(Openable.java:165) at org.eclipse.jdt.internal.core.CompilationUnit.codeSelect(CompilationUnit.java:314) at org.eclipse.jdt.internal.core.CompilationUnit.codeSelect(CompilationUnit.java:308) at org.eclipse.jdt.internal.ui.actions.SelectionConverter.codeResolve(SelectionConverter.java:219) at org.eclipse.jdt.internal.ui.actions.SelectionConverter.codeResolve(SelectionConverter.java:153) at org.eclipse.jdt.internal.ui.actions.SelectionConverter.codeResolve(SelectionConverter.java:162) at org.eclipse.jdt.ui.actions.OpenAction.run(OpenAction.java:128) at org.eclipse.jdt.ui.actions.SelectionDispatchAction.dispatchRun(SelectionDispatchAction.java:226) at org.eclipse.jdt.ui.actions.SelectionDispatchAction.run(SelectionDispatchAction.java:198) at org.eclipse.jface.action.Action.runWithEvent(Action.java:996) at org.eclipse.ui.commands.ActionHandler.execute(ActionHandler.java:182) at org.eclipse.ui.internal.handlers.LegacyHandlerWrapper.execute(LegacyHandlerWrapper.java:108) at org.eclipse.core.commands.Command.execute(Command.java:311) at org.eclipse.core.commands.ParameterizedCommand.execute(ParameterizedCommand.java:396) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.executeCommand(WorkbenchKeyboard.java:459) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.press(WorkbenchKeyboard.java:781) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.processKeyEvent(WorkbenchKeyboard.java:828) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.filterKeySequenceBindings(WorkbenchKeyboard.java:550) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.access$3(WorkbenchKeyboard.java:493) at org.eclipse.ui.internal.keys.WorkbenchKeyboard$KeyDownFilter.handleEvent(WorkbenchKeyboard.java:117) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66) at org.eclipse.swt.widgets.Display.filterEvent(Display.java:788) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:843) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:868) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:853) at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:881) at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:877) at org.eclipse.swt.widgets.Widget.wmKeyDown(Widget.java:1469) at org.eclipse.swt.widgets.Control.WM_KEYDOWN(Control.java:3348) at org.eclipse.swt.widgets.Control.windowProc(Control.java:3067) at org.eclipse.swt.widgets.Display.windowProc(Display.java:3553) at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method) at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:1650) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2560) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:1694) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1658) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:366) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:143) at org.eclipse.ui.internal.ide.IDEApplication.run(IDEApplication.java:103) at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:226) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:375) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:162) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:324) at org.eclipse.core.launcher.Main.invokeFramework(Main.java:334) at org.eclipse.core.launcher.Main.basicRun(Main.java:278) at org.eclipse.core.launcher.Main.run(Main.java:973) at org.eclipse.core.launcher.Main.main(Main.java:948) To be fair, that looks the same as bug 95481. Unfortunately 95481 was marked as RC2, which sucks since two small, simple files reduce the JDT to functionality barely above Notepad. :( Closing, other issue is separate and got addressed indpendantly in bug 95481. Frederic - pls verify the original defect. Verified with build I20050527-1300 that there's no compile error. |