-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Allow omission of unsatisfiable members in trait impls #2829
Comments
Instead of adding special syntax for |
My spider sense should it should have a special syntax, but other than that I have no strong opinion one way or the other. |
This is duplicate of rust-lang/rust#57900, i think. |
I suspect specialization needs the syntax because otherwise specialization drops methods freely. If so, then maybe
Ignoring that we probably would not want this, would this work?
|
I don't see any reason it would. The signatures don't match. |
@burdges This can't work because |
Right, makes sense. I suppose some more explicit use of specialization gets closer, probably still not quite. I'm not actually suggesting
|
That would work, (although your signature is messes up it should be |
As an aside, it might not work in practice because, although a |
This is also a dupe of rust-lang/rust#20021 There's also this semi-related RFC: #1699 |
Currently,
where
bounds on trait methods are largely only useful for one purpose, which is to make traits object-safe. In particular, if we writetrait Foo { fn foo(self) where Self: Sized; }
rather thantrait Foo: Sized { fn foo(self); }
, thendyn Foo
is a valid type, albeit one where we cannot callfoo
due to theSized
constraint. If theSized
constraint is directly onFoo
, however, then sincedyn Foo: !Sized
, we get a constraint thatdyn Foo: Sized
, which is impossible.Interestingly, this lets us make a value of type (
dyn Foo
) implementing a trait (Foo
) but on which a method (foo
) cannot be called due to its unsatisfied constraint (dyn Foo: Sized
).As far as I can tell, this is the only such example. If I try to implement it for another unsized type, I either get an error about
foo
not being implemented or get an error about the constraint being unsatisfied. But it's clearly not an inherent requirement thatfoo
be implemented, becausedyn Foo
has nofoo
implementation, just a surface-level one.Note that you can define a default implementation, and then you get a similar result, with the resulting method not being callable on unsized types like
str
. But then you have to provide a default implementation for all types, which is in many practical examples just going to be an "impossible"panic
, but then you cannot force every implementor to override it, meaning that this impossible panic could leak into real code.Thus, an idea of allowing an impossible constraint to be ignored. Here's an example borrowing a C++ syntax:
In this example, the
= delete
tells the compiler that we deliberately want to not implement the function, and the compiler in this cause ought to see thatstr: !Sized
and permit the impl. This should only be permitted where the compiler can confidently negatively reason, in the same way as when calculating impl overlap. Orphan rules make this viable in many cases.I'm not sure that this feature is incredibly useful---the primary use case I can think of it is to allow specialization of things with additional trait constraints, but in that case you probably have a default implementation anyway. The other thing that comes to mind is trying to ease version migrations, to let you add non-default methods that are conditioned on the version of implementing types, but you'd still need to propagate the constraint which would largely undermine its utility.
The text was updated successfully, but these errors were encountered: