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

[Bug] Can't define extension method for super class of class with same extension method #491

Open
CC007 opened this issue Sep 9, 2023 · 3 comments

Comments

@CC007
Copy link
Contributor

CC007 commented Sep 9, 2023

Describe the bug
When creating the filter and map extension method for Iterable, I get the follwing error:

Compilation failure: Compilation failure: 
[ERROR] /java/util/List.java:[5,17] name clash: filter(java.util.function.Predicate<? super E>) in java.util.Collection and filter(java.util.function.Predicate<E>) in java.lang.Iterable have the same erasure, yet neither overrides the other
[ERROR] /java/util/Collection.java:[37,48] name clash: map(java.util.function.Function<? super E,R>) in java.util.Collection and map(java.util.function.Function<E,R>) in java.lang.Iterable have the same erasure, yet neither overrides the other
[ERROR] /java/util/Collection.java:[41,45] name clash: filter(java.util.function.Predicate<? super E>) in java.util.Collection and filter(java.util.function.Predicate<E>) in java.lang.Iterable have the same erasure, yet neither overrides the other

To Reproduce
Steps to reproduce the behavior:

  1. Create a project with manifold-ext and manifold-collections
  2. Add the following code:
package extensions.java.lang.Iterable;

import manifold.ext.rt.api.Extension;
import manifold.ext.rt.api.This;

import java.util.Collection;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

@Extension
public class IterableExt {

    public static <T> Stream<T> stream(@This Iterable<T> thiz) {
        return thiz instanceof Collection<T> collection
            ? collection.stream()
            : StreamSupport.stream(thiz.spliterator(), false);
    }

    public static <T> Stream<T> filter(@This Iterable<T> thiz, Predicate<T> predicate) {
        return thiz.stream().filter(predicate);
    }

    public static <T, R> Stream<R> map(@This Iterable<T> thiz, Function<T, R> mapper) {
        return thiz.stream().map(mapper);
    }
}
  1. Compile it

Expected behavior
I expect to be able to create an extension method for a superclass of a class that already has that same extension method.

Desktop (please complete the following information):

  • OS Type & Version: Windows 10
  • Java/JDK version: openjdk-20.0.2
  • IDE version (IntelliJ IDEA or Android Studio): IntelliJ 2023.1.5
  • Manifold version: 2023.1.20
  • Manifold IntelliJ plugin version: 23.1.15

Additional context
This page makes it look like you should be able to do what I want, but I don't know if the target being interfaces rather than classes has anything to do with the error.

@CC007 CC007 changed the title [Bug] Can't define extension method for metho [Bug] Can't define extension method for super class with same method Sep 9, 2023
@CC007 CC007 changed the title [Bug] Can't define extension method for super class with same method [Bug] Can't define extension method for super class of class with same method Sep 9, 2023
@CC007 CC007 changed the title [Bug] Can't define extension method for super class of class with same method [Bug] Can't define extension method for super class of class with same extension method Sep 9, 2023
@CC007
Copy link
Contributor Author

CC007 commented Sep 9, 2023

It would also be nice if the IntelliJ plugin showed these method signature conflict issues before compilation.

@rsmckinney
Copy link
Member

Overriding method signatures must exactly match, this includes type variable variance. This means the extension methods used in your project, if they are overrides, must have exactly the same parameter definitions.

For instance, the following error is saying after erasing generics from the methods they are an override pair, however the generic signatures don't match.

filter(java.util.function.Predicate<? super E>) in java.util.Collection and
filter(java.util.function.Predicate<E>) in java.lang.Iterable have the same erasure, yet neither overrides the other

You can change your Predicate<E> to Predicate<? super E> to fix that. And as an aside, that's probably what you want anyway.

Repeat for the other two methods.

I'll add a compile error in IJ to reflect this as well.

@CC007
Copy link
Contributor Author

CC007 commented Mar 29, 2024

Ah derp! You're right, I completely forgot the bounded wildcards!

Thanks for taking your time to look at this.

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

2 participants