-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
#[derive]
sometimes uses incorrect bounds (aka lack of "perfect derive")
#26925
Comments
This is a dupe of #7671 which I suspect may've been accidentally closed. (i.e. the patch that closed it was modified to no longer tackle it.) |
#19839 is relevant. |
The bounds that Unfortunately, the obvious fix (just bounding the field types) causes breakage: #[derive(Clone)]
struct Item<A> { inner: A }
#[derive(Clone)]
pub struct IntoIter<A> { inner: Item<A> }
// The obvious bound is `Item<A> : Clone`, but we can't use that bound
// because `Item` is private. And actually, in the general case there is no bound we can expose because it could involve a requirement that a parameter type implements a private trait. We could in theory special-case certain types syntactically, but that only improves a few special cases like Clone of a reference. It's possible that we could punt computing the bounds off to type-checking (add syntax like |
In terms of syntax, it might perhaps be possible to generalize |
GHC handles the case described in @eefriedman's comment:
It works:
The output is:
Maybe GHC "inlines" the private bounds until it obtains all-public bounds. |
(Some contrivance ahead.) If the bounds would be dropped when possible for existing code, the following would lose its good and intended meaning. The effect would be that #[derive(Copy, Clone)]
pub struct Ptr<Mark>(*mut u8, PhantomData<Mark>);
pub type Ref<'a, T: 'a> = Ptr<&'a T>;
pub type RefMut<'a, T: 'a> = Ptr<&'a mut T>; |
With that I think that even if the bounds are plain wrong, they are part of the stock recipe that one can conjure with derive, it's “part of what you order” and we can't change that backwards incompatibly. Derive can however grow bells and whistles, like the bound customization that rust-derivative and serde offer. |
If there's a good way to make derive do the right thing, the backwards incompatibility issue sounds like the kind of thing epochs could handle. |
We can't use Rust's default deriving mechanism, until rust-lang/rust#26925 and rust-lang/rust#7671 are fixed. But fortunately, there's a crate for that.
We can't use Rust's default deriving mechanism, until rust-lang/rust#26925 and rust-lang/rust#7671 are fixed. But fortunately, there's a crate for that.
We can't use Rust's default deriving mechanism, until rust-lang/rust#26925 and rust-lang/rust#7671 are fixed. But fortunately, there's a crate for that.
This attribute suppresses the default-generated `derive(Clone)`. This may be necessary where `derive(Clone)` copies constraints in an unsatisfiable way. See: https://smallcultfollowing.com/babysteps//blog/2022/04/12/implied-bounds-and-perfect-derive/ See: rust-lang/rust#26925 Fixes: colin-kiegel#325
This attribute suppresses the default-generated `derive(Clone)`. This may be necessary where `derive(Clone)` copies constraints in an unsatisfiable way. See: https://smallcultfollowing.com/babysteps//blog/2022/04/12/implied-bounds-and-perfect-derive/ See: rust-lang/rust#26925 Fixes: colin-kiegel#325
This attribute suppresses the default-generated `derive(Clone)`. This may be necessary where `derive(Clone)` copies constraints in an unsatisfiable way. See: https://smallcultfollowing.com/babysteps//blog/2022/04/12/implied-bounds-and-perfect-derive/ See: rust-lang/rust#26925 Fixes: colin-kiegel#325
This attribute suppresses the default-generated `derive(Clone)`. This may be necessary where `derive(Clone)` copies constraints in an unsatisfiable way. See: https://smallcultfollowing.com/babysteps//blog/2022/04/12/implied-bounds-and-perfect-derive/ See: rust-lang/rust#26925 Fixes: colin-kiegel#325
This attribute suppresses the default-generated `derive(Clone)`. This may be necessary where `derive(Clone)` copies constraints in an unsatisfiable way. See: https://smallcultfollowing.com/babysteps//blog/2022/04/12/implied-bounds-and-perfect-derive/ See: rust-lang/rust#26925 Fixes: colin-kiegel#325
This attribute suppresses the default-generated `derive(Clone)`. This may be necessary where `derive(Clone)` copies constraints in an unsatisfiable way. See: https://smallcultfollowing.com/babysteps//blog/2022/04/12/implied-bounds-and-perfect-derive/ See: rust-lang/rust#26925 Fixes: colin-kiegel#325
Just for reiterate it for the new comers rust-derivative can work around for this issue. |
|
Sorry rust-derivative is not still maintained. But it's a useful starting point of how to find replacement and how to work around it. |
I use the |
Replace derived `Clone` impls for tensor iterators with manual implementations to remove the unnecessary `T: Clone` bound that the derived impl adds. See also rust-lang/rust#26925.
#[derive]
sometimes uses incorrect bounds (aka lack of "perfect derive")
In the following code:
both derives expand to impls that require the corresponding trait to be implemented on the type parameter, e.g.:
However, this isn't actually necessary, as
Y<T>
will still be eligible forCopy
regardless of whetherT
is.This may be hard to fix, given the compilation phase at which
#[derive]
works...The text was updated successfully, but these errors were encountered: