Skip to content

Error with property in interface implemented by a record #699

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

Open
EotT123 opened this issue Apr 26, 2025 · 2 comments
Open

Error with property in interface implemented by a record #699

EotT123 opened this issue Apr 26, 2025 · 2 comments

Comments

@EotT123
Copy link
Contributor

EotT123 commented Apr 26, 2025

When defining a property in an interface using the @val syntax, implementing that interface with a record fails due to changed getter names for records.

public interface MyInterface {
    // Using property syntax causes issues:
    @val String foo;
}

// ERROR: Class 'test' must implement abstract method 'getFoo()' in 'MyInterface'
public record TestRecord(String foo) implements MyInterface { }

Changing MyInterface to use a standard getter method resolves the issue, but it means I can no longer access the property directly and must instead use the getter:

public interface MyInterface {
    String foo();
}
EotT123 pushed a commit to EotT123/manifold-test that referenced this issue Apr 26, 2025
@rsmckinney
Copy link
Member

This one's a bit tough.

First off, properties already support records where you reference record components using property syntax:

public record TestRecord(String foo) {}

TestRecord test = new TestRecord("hi");
String foo = test.foo; // access as properties

That might make it seem like record access methods should implement properties too, but as you've discovered, they don't.

The trouble is, record methods can't directly override getter methods. To make this work, Manifold would have to step in and generate getter methods that forward to record methods. Early on I avoided that because at the time it felt too invasive. Now that I'm revisiting the idea, I feel less opposed to it.

Still, you can always write the getters manually when you need to:

public interface MyInterface {
    @val String foo;
}

public record TestRecord(String foo) implements MyInterface { 
  public String getFoo() {
    return foo();
  }
}

Hope that helps! I'll give some more thought to auto-generating the forwarding getters too.

@EotT123
Copy link
Contributor Author

EotT123 commented Apr 27, 2025

Thank you for the explanation and suggestion.

I find it a bit counterintuitive that implementing an interface with both a record and a regular class requires different code. I hadn't considered your proposed workaround and had reverted to using a standard getter, but your solution is definitely more effective.

While it may not be intuitive, your workaround allows me to utilize properties, which I appreciate.

Generating the getters automatically seems to be a good way to handle the problem.

EotT123 pushed a commit to EotT123/manifold-test that referenced this issue May 23, 2025
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