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

unexpected rustdoc result about auto-trait #111126

Closed
bvanjoi opened this issue May 3, 2023 · 3 comments
Closed

unexpected rustdoc result about auto-trait #111126

bvanjoi opened this issue May 3, 2023 · 3 comments
Labels
C-bug Category: This is a bug.

Comments

@bvanjoi
Copy link
Contributor

bvanjoi commented May 3, 2023

code:

pub struct Inner<T>(T);

trait MyTrait {
    type MyItem;
}

trait OtherTrait {}

impl<T> Unpin for Inner<T>
where
    T: MyTrait<MyItem = bool>,
{
}

pub struct Foo<K> {
    inner_field: Inner<K>,
}

because Unpin is not implement for Foo explicitly, I expected to see this happen after execute rustdoc :

image

Instead, this happened:

image

I am not sure the rendered if right or not, so I created the issue to seek some answer.

related #110740

@bvanjoi bvanjoi added the C-bug Category: This is a bug. label May 3, 2023
@fmease
Copy link
Member

fmease commented May 3, 2023

This is the intended output (as far as I am aware).

because Unpin is not implement for Foo

I'm not sure what you mean by that. Unpin is implemented for Foo<K> for all types K where
the type of field inner_field Inner<K> implements Unpin (since no explicit impl exists).
Whether a struct impls an auto-trait doesn't depend on the generic parameters (as your 1st picture shows)
but on the field types. You can read more about that here.

So technically speaking, the synthetic impl of Unpin for Foo looks like

impl<K> Unpin for Foo<K>
where
    Inner<K>: Unpin

but since one can argue that the constraint Inner<K>: Unpin is not that helpful (“actionable”) to the reader, we simplify the constraint. In this case Inner<K>: Unpin is implied by the explicit impl impl<T> Unpin for Inner<T> as long as the constraint T: MyTrait<MyItem = bool> holds. Thus we propagate that constraint and end up with the synthetic impl as seen in your 2nd screenshot.

@fmease
Copy link
Member

fmease commented May 3, 2023

impl<K> Unpin for Foo<K> where K: MyTrait<MyItem = bool> is not “more correct” than
impl<K> Unpin for Foo<K> where Inner<K>: Unpin (what the compiler actually sees), it's
simply a different way to display the constraint.

impl<K> Unpin for Foo<K> where K: Unpin on the other hand is not correct in this case
because of the existence of the explicit impl impl<T> Unpin for Inner<T> where …. If you were
to remove it, then that synthetic impl would be correct since

  1. for all types K, Foo<K>: Unpin is implied by
  2. for all types K, Inner<K>: Unpin is implied by
  3. for all types T, T: Unpin (where T corresponds to the type of field 0 of the tuple struct Inner)

@jyn514
Copy link
Member

jyn514 commented May 26, 2023

It looks like this isn't a bug, so I'm going to close the issue.

@jyn514 jyn514 closed this as completed May 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants