Skip to content

Implementing Types with Private API #60302

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

Closed
RohitSaily opened this issue Mar 11, 2025 · 4 comments
Closed

Implementing Types with Private API #60302

RohitSaily opened this issue Mar 11, 2025 · 4 comments

Comments

@RohitSaily
Copy link
Contributor

Dart SDK version: 3.8.0-149.0.dev (dev) (Thu Feb 27 04:01:43 2025 -0800) on "macos_x64"

In the same folder:

lib1.dart

class Super
{	final _secret='🤫';
	@override void shareSecrets(final Super other)
	{	print('This secret is $_secret.');
		print('Other\'s secret is ${other._secret}.');
	}
}

lib2.dart

import 'lib1.dart';
void main()=>
	Super().shareSecrets(Implementer());
final class Implementer implements Super
{	@override void shareSecrets(final Super other)=>
		other.shareSecrets(this);
}

Do dart run lib2.dart and observe the output (stack trace omitted)

This secret is 🤫.
Unhandled exception:
NoSuchMethodError: Class 'Implementer' has no instance getter '_secret'.
Receiver: Instance of 'Implementer'
Tried calling: _secret

This exception makes sense, the issue is not about that. The concern is that there is no indication that it is incorrect for the implementer to be used as a Super in certain cases.

It is natural to believe if one implements a type and it fulfills its contractual obligations through its API, then it must work wherever that type is expected, because it (1) is that type, and (2) is successfully implemented to function as that type.

Solution

Currently, even adding a _secret field to the implementer does not work. That makes sense because the implementer may happen to have a private field that is semantically different than the super type's field.

It would be better if there were some form of warning or restrictions in place.

@eernstg
Copy link
Member

eernstg commented Mar 11, 2025

Note that there is a substantial overlap between the request in this issue and #58506.

@mraleph
Copy link
Member

mraleph commented Mar 11, 2025

Feels also like a duplicate of #58179

@srawlins
Copy link
Member

I'm happy to close, and encourage to follow #58506 and #58179.

@lrhn lrhn closed this as completed Mar 11, 2025
@lrhn
Copy link
Member

lrhn commented Mar 11, 2025

This issue is not new. It's possible to write code that will fail at runtime. It has until Dart 3.0 not been easy to prevent someone else from implementing your class, with its private member, as an interface.

The best place to warn is where code accesses a private member of a type that can be implemented on an object which isn't clearly created inside the same library. Today that might just be "which can be implemented", since we can now prevent that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants