Bug 561898 - [compiler] Wrong unsafe cast warning reported when downcasting generic type variable
Summary: [compiler] Wrong unsafe cast warning reported when downcasting generic type v...
Status: ASSIGNED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.15   Edit
Hardware: PC Windows 10
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks:
 
Reported: 2020-04-08 04:04 EDT by Lukas Eder CLA
Modified: 2024-05-23 11:05 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lukas Eder CLA 2020-04-08 04:04:36 EDT
Consider this program:

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

public class X<T> {
    <U extends List<?>> ArrayList<T> unsafe(U list) {
        return (ArrayList<T>) list;
    }

    <U extends List<T>> ArrayList<T> safe1(U list) {
        return (ArrayList<T>) list;
    }

    ArrayList<T> safe2(List<T> list) {
        return (ArrayList<T>) list;
    }
}
// ---------------------------------------------

To me, both of these look like a classic downcast, nothing unsafe about it because ArrayList<T> <: List<T> and since U <: List<T>, we should be able to downcast.

javac seems to agree with me. In javac 11.0.6, only the cast in unsafe() is reported as unsafe. The cast in safe1() should be safe.
Comment 1 Stephan Herrmann CLA 2020-04-09 09:33:48 EDT
Thanks, we would be looking at this list from JLS ยง5.1.6.2:


"The unchecked narrowing reference conversions are as follows: 

..."

Does this list have a useful answer?

bullet 3 handles intersection types and is clearly inapplicable here.

bullet 2 handles cast *to* a type variable, which is the inverse of what we have here.

bullet 1 has two sub-bullets, of which the second looks most promising among the bunch:

"T <: S, and S has no subtype X other than T where the type arguments of X are not contained in the type arguments of T."

S = U
T = ArrayList<T>

Generally, it seems strange to assume that all X have type arguments that are comparable to those of T. Subtypes X could have more or fewer type arguments then S or T. Generally, type arguments can only be compared if the generic type is the same, which is not our case. At first glance, JLS seems to over-simplify the situation. OTOH, the one type argument that we know of, T, is the identical for all relevant types.

I'll take a look if perhaps ecj fails to look into type bounds of U, which factually restrict the possible subtypes of U. If I don't find anything obvious, I may have to put the bug back into the big bucket.
Comment 2 Eclipse Genie CLA 2022-05-27 17:41:58 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

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

--
The automated Eclipse Genie.
Comment 3 Eclipse Genie CLA 2024-05-23 11:05:52 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

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

--
The automated Eclipse Genie.