Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rule to detect map.get(wrongType) #1025

Closed
TheBeruriahIncident opened this issue Nov 5, 2019 · 6 comments
Closed

Rule to detect map.get(wrongType) #1025

TheBeruriahIncident opened this issue Nov 5, 2019 · 6 comments
Assignees

Comments

@TheBeruriahIncident
Copy link
Contributor

What happened?

It's currently easy to write code like:

Map<Foo, Object> map;
Bar key;
Object value = map.get(key)

and not realize you have a bug. This is particularly insidious with things like wrapped strings, where you get with the right "thing", you just have to wrap or unwrap it.

For example, see commit 331070 in the major internal repo I work on.

What did you want to happen?

Errorprone to flag that this can't work. IntelliJ does, so I expect this is doable.

CC @carterkozak

@carterkozak carterkozak self-assigned this Nov 5, 2019
@carterkozak
Copy link
Contributor

👍 I'll take a look

@iamdanfox
Copy link
Contributor

I think this is already implemented: https://errorprone.info/bugpattern/CollectionIncompatibleType

I wrote the following code and error-prone refused to compile it:

        ImmutableMap<String, String> of = ImmutableMap.of("foo", "bar");
        System.out.println(of.get(1));
> Task :conjure-backcompat:compileTestJava
/Volumes/git/conjure-backcompat/conjure-backcompat/src/test/java/com/palantir/conjure/backcompat/ConjureBackCompatTest.java:49: error: [CollectionIncompatibleType] Argument '1' should not be passed to this method; its type int is not compatible with its collection's type argument String
        System.out.println(of.get(1));
                                 ^
    (see https://errorprone.info/bugpattern/CollectionIncompatibleType)

@carterkozak
Copy link
Contributor

I don't think CollectionIncompatibleType is quite as strict as we would like, it appears to catch impossible cases, but not those that are unlikely to be correct, for example:

interface FirstIface {}
interface SecondIface {}

String read(Map<FirstIface, String> map, SecondIface key) {
  // it's possible the SecondIface happens to implement FirstIface and this works correctly,
  // but not likely. Idea warns in this case. It would be better to leverage the type system.
  return map.get(key);
}

@carterkozak
Copy link
Contributor

To clarify, we enforce CollectionIncompatibleType in the project where @akroy discovered the bug which prompted this issue!

@markelliot
Copy link
Contributor

markelliot commented Nov 6, 2019 via email

@carterkozak
Copy link
Contributor

carterkozak commented Nov 6, 2019 via email

carterkozak added a commit that referenced this issue Nov 6, 2019
…lection usage

This check is an improvement over `CollectionIncompatibleType` because it
validates that values exist in the same type hierarchy, where it could
theoretically be possible the input implements the collection type,
but the type system doesn't have enough information to be confident.
This check allows both subtypes and supertypes, but does not check
for shared supertypes, which are not common.
@bulldozer-bot bulldozer-bot bot closed this as completed in 57d3cff Nov 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants