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

Better document the implementors of Clone and Copy #48171

Merged
merged 5 commits into from
Apr 4, 2018

Conversation

FraGag
Copy link
Contributor

@FraGag FraGag commented Feb 12, 2018

There are two parts to this change. The first part is a change to the compiler and to the standard library (specifically, libcore) to allow implementations of Clone and Copy to be written for a subset of builtin types. By adding these implementations to libcore, they now show up in the documentation. This is a [breaking-change] for users of #![no_core], because they will now have to supply their own copy of the implementations of Clone and Copy that were added in libcore.

The second part is purely a documentation change to document the other implementors of Clone and Copy that cannot be described in Rust code (yet) and are thus provided by the compiler.

Fixes #25893

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @joshtriplett (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@pietroalbini pietroalbini added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 12, 2018
@Centril Centril added T-lang Relevant to the language team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools labels Feb 13, 2018
@joshtriplett
Copy link
Member

Sorry for the delayed response.

This looks plausible to me, and I like the idea of moving this out of compiler magic and into the library itself.

I'd like to get at least one other reviewer to check this.

r? @nikomatsakis

@shepmaster
Copy link
Member

This is a [breaking-change] for users of #![no_core]

Should we solicit opinions of people who might be affected by this?

@hanna-kruppe
Copy link
Contributor

hanna-kruppe commented Feb 16, 2018

I believe there are practically no legitimate use cases of no_core other than compiler developers trying to minimize a problem occurring in libcore. Using it is inherently very deeply entangled with compiler internals. Many routine changes can already break no_core usage, such as changing anything about any lang item (including adding or removing them), or even just changing something about the compiler such that compiling your code requires a lang item that previously wasn't required. Basically, using no_core out of tree is not supported.

Edit: Indeed the only use of no_core (other than by compiler developers) I've ever seen was in this twitter thread and that thread exists precisely because using no_core is so insane.

@shepmaster
Copy link
Member

shepmaster commented Feb 16, 2018

I believe there are practically no legitimate use cases of no_core other than compiler developers trying to minimize a problem occurring in libcore.

I know that I've needed to use it when attempting to get AVR-Rust off the ground, I kind of assumed that other embedded folk have needed to do the same.

@joshtriplett
Copy link
Member

Probably couldn't hurt to raise attention on this via TWiR and/or an internals thread.

@hanna-kruppe
Copy link
Contributor

@shepmaster Good point, I forgot about AVR-Rust, sorry! I have reason to suspect AVR-Rust is pretty unique in this regard, though. Most embedded stuff is happening with more mature LLVM backends which have no problem (or not nearly as big a problem, e.g., they may just be missing support for some obscure intrinsics) getting libcore to compile. For example, MPS430 seems to have working libcore .

@hanna-kruppe
Copy link
Contributor

And to be clear, "getting a new target off the ground" is a totally legitimate use of no_core (I've even used it for that myself), but I count that under "usage by compiler developers" and it should usually be very temporary (AVR apparently being an exception). Since there are few compiler developers and even fewer targets being added, I don't think it's particularly likely that this PR will land after someone copied something from libcore, yet before they scrapped that copy and started compiling libcore as-is.

@shepmaster
Copy link
Member

To be clear, I don't have a problem with this change affecting AVR-Rust, it's simply the only reason I know about no_core.

I have reason to suspect AVR-Rust is pretty unique in this regard, though

And to be clear, "getting a new target off the ground" is a totally legitimate use of no_core

I think this is where AVR-Rust is at as well; it's just taking longer because the LLVM support is being worked on in parallel.

I forgot about AVR-Rust, sorry

Not to worry; it's not anywhere near feature complete ;-)

@nikomatsakis
Copy link
Contributor

@FraGag

The first part is a change to the compiler and to the standard library (specifically, libcore) to allow implementations of Clone and Copy to be written for a subset of builtin types.

Can you say a bit more about the motivation here? Is it rustdoc or something else?

@shepmaster
Copy link
Member

@nikomatsakis several comments on the original issue stem from Stack Overflow question-askers not knowing that e.g. i32 is Copy. I'd say that documenting these would be a net win, but I'm not sure if there's more.

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few nits but I think overall this is ok. I wonder if it will affect performance.

@@ -1973,16 +1973,16 @@ differs from the behavior for `&T`, which is always `Copy`).

E0206: r##"
You can only implement `Copy` for a struct or enum. Both of the following
examples will fail, because neither `i32` (primitive type) nor `&'static Bar`
(reference to `Bar`) is a struct or enum:
examples will fail, because neither `fn() -> i32` nor `&'static mut Bar`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should include fn() -> i32 as a sample type. &'static mut Bar is ok I guess.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about [u8; 256]?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, can you add a new test for what happens when we do implement for u32 (outside of libcore)? I guess we get a standard overlap failure, huh? Seems ok.

@FraGag
Copy link
Contributor Author

FraGag commented Feb 24, 2018

@nikomatsakis Addressed nits. I'll squashed and rebase when it's approved.

@bors
Copy link
Contributor

bors commented Feb 27, 2018

☔ The latest upstream changes (presumably #48449) made this pull request unmergeable. Please resolve the merge conflicts.

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 27, 2018
@nikomatsakis
Copy link
Contributor

@FraGag looks good =)

@FraGag
Copy link
Contributor Author

FraGag commented Mar 1, 2018

@nikomatsakis Squashed and rebased. The merge conflicts were just line numbers in .stderr files being anonymized by #48449.

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change the 1.0.0 -- but to what...

bool char
}

#[stable(feature = "rust1", since = "1.0.0")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it doesn't matter, but ! has not been present since 1.0.0. In fact, the type itself isn't even stable yet!

@nikomatsakis
Copy link
Contributor

OK, I updated to 1.25.0

FraGag added a commit to FraGag/libc that referenced this pull request Mar 18, 2018
The libc crate is used as a dependency of the Rust compiler. Its build
system passes `--cfg dox` to all crates when generating their
documentation. libc's documentation is generated when the build system
is asked to generate the compiler documentation because `cargo doc`
automatically documents all dependencies.

When the dox configuration option is enabled, libc disables its
dependency on the core crate and provides the necessary definitions
itself. The dox configuration option is meant for generating
documentation for a multitude of targets even if the core crate for that
target is not installed. However, when documenting the compiler, it's
not necessary to do that; we can just use core or std as usual.

This change is motivated by the changes made to the compiler in
rust-lang/rust#48171. With these changes, it's necessary to provide
implementations of the Clone and Copy traits for some primitive types in
the library that defines these traits (previously, these implementations
were provided by the compiler). Normally, these traits (and thus the
implementations) are provided by core, so any crate that uses
`#![no_core]` must now provide its own copy of the implementations.

Because libc doesn't provide its own copy of the implementations yet,
and because the compiler's build system passes `--cfg dox` to libc,
generating the documentation for the compiler fails when generating
documentation for libc. By renaming the configuration option, libc will
use core or std and will thus have the necessary definitions for the
documentation to be generated successfully.
FraGag added a commit to FraGag/libc that referenced this pull request Mar 18, 2018
The libc crate is used as a dependency of the Rust compiler. Its build
system passes `--cfg dox` to all crates when generating their
documentation. libc's documentation is generated when the build system
is asked to generate the compiler documentation because `cargo doc`
automatically documents all dependencies.

When the dox configuration option is enabled, libc disables its
dependency on the core crate and provides the necessary definitions
itself. The dox configuration option is meant for generating
documentation for a multitude of targets even if the core crate for that
target is not installed. However, when documenting the compiler, it's
not necessary to do that; we can just use core or std as usual.

This change is motivated by the changes made to the compiler in
rust-lang/rust#48171. With these changes, it's necessary to provide
implementations of the Clone and Copy traits for some primitive types in
the library that defines these traits (previously, these implementations
were provided by the compiler). Normally, these traits (and thus the
implementations) are provided by core, so any crate that uses
`#![no_core]` must now provide its own copy of the implementations.

Because libc doesn't provide its own copy of the implementations yet,
and because the compiler's build system passes `--cfg dox` to libc,
generating the documentation for the compiler fails when generating
documentation for libc. By renaming the configuration option, libc will
use core or std and will thus have the necessary definitions for the
documentation to be generated successfully.
bors added a commit to rust-lang/libc that referenced this pull request Mar 19, 2018
Rename the dox configuration option to cross_platform_docs

The libc crate is used as a dependency of the Rust compiler. Its build system passes `--cfg dox` to all crates when generating their documentation. libc's documentation is generated when the build system is asked to generate the compiler documentation because `cargo doc` automatically documents all dependencies.

When the dox configuration option is enabled, libc disables its dependency on the core crate and provides the necessary definitions itself. The dox configuration option is meant for generating documentation for a multitude of targets even if the core crate for that target is not installed. However, when documenting the compiler, it's not necessary to do that; we can just use `core` or `std` as usual.

This change is motivated by the changes made to the compiler in rust-lang/rust#48171. With these changes, it's necessary to provide implementations of the `Clone` and `Copy` traits for some primitive types in the library that defines these traits (previously, these implementations were provided by the compiler). Normally, these traits (and thus the implementations) are provided by core, so any crate that uses `#![no_core]` must now provide its own copy of the implementations.

Because libc doesn't provide its own copy of the implementations yet, and because the compiler's build system passes `--cfg dox` to libc, generating the documentation for the compiler fails when generating documentation for libc. By renaming the configuration option, libc will use `core` or `std` and will thus have the necessary definitions for the documentation to be generated successfully.

**Note:** rust-lang/rust#48171 is blocked on this PR and on a release of libc including this change on crates.io. (Some crates in the compiler use libc as a submodule, while others use a version from crates.io.)
bors added a commit to rust-lang/libc that referenced this pull request Mar 24, 2018
Rename the dox configuration option to cross_platform_docs

The libc crate is used as a dependency of the Rust compiler. Its build system passes `--cfg dox` to all crates when generating their documentation. libc's documentation is generated when the build system is asked to generate the compiler documentation because `cargo doc` automatically documents all dependencies.

When the dox configuration option is enabled, libc disables its dependency on the core crate and provides the necessary definitions itself. The dox configuration option is meant for generating documentation for a multitude of targets even if the core crate for that target is not installed. However, when documenting the compiler, it's not necessary to do that; we can just use `core` or `std` as usual.

This change is motivated by the changes made to the compiler in rust-lang/rust#48171. With these changes, it's necessary to provide implementations of the `Clone` and `Copy` traits for some primitive types in the library that defines these traits (previously, these implementations were provided by the compiler). Normally, these traits (and thus the implementations) are provided by core, so any crate that uses `#![no_core]` must now provide its own copy of the implementations.

Because libc doesn't provide its own copy of the implementations yet, and because the compiler's build system passes `--cfg dox` to libc, generating the documentation for the compiler fails when generating documentation for libc. By renaming the configuration option, libc will use `core` or `std` and will thus have the necessary definitions for the documentation to be generated successfully.

**Note:** rust-lang/rust#48171 is blocked on this PR and on a release of libc including this change on crates.io. (Some crates in the compiler use libc as a submodule, while others use a version from crates.io.)
@pietroalbini
Copy link
Member

@FraGag weekly ping from the triage team! What's the status on this?

Add implementations of `Clone` and `Copy` for some primitive types to
libcore so that they show up in the documentation. The concerned types
are the following:

* All primitive signed and unsigned integer types (`usize`, `u8`, `u16`,
  `u32`, `u64`, `u128`, `isize`, `i8`, `i16`, `i32`, `i64`, `i128`);
* All primitive floating point types (`f32`, `f64`)
* `bool`
* `char`
* `!`
* Raw pointers (`*const T` and `*mut T`)
* Shared references (`&'a T`)

These types already implemented `Clone` and `Copy`, but the
implementation was provided by the compiler. The compiler no longer
provides these implementations and instead tries to look them up as
normal trait implementations. The goal of this change is to make the
implementations appear in the generated documentation.

For `Copy` specifically, the compiler would reject an attempt to write
an `impl` for the primitive types listed above with error `E0206`; this
error no longer occurs for these types, but it will still occur for the
other types that used to raise that error.

The trait implementations are guarded with `#[cfg(not(stage0))]` because
they are invalid according to the stage0 compiler. When the stage0
compiler is updated to a revision that includes this change, the
attribute will have to be removed, otherwise the stage0 build will fail
because the types mentioned above no longer implement `Clone` or `Copy`.

For type variants that are variadic, such as tuples and function
pointers, and for array types, the `Clone` and `Copy` implementations
are still provided by the compiler, because the language is not
expressive enough yet to be able to write the appropriate
implementations in Rust.

The initial plan was to add `impl` blocks guarded by `#[cfg(dox)]` to
make them apply only when generating documentation, without having to
touch the compiler. However, rustdoc's usage of the compiler still
rejected those `impl` blocks.

This is a [breaking-change] for users of `#![no_core]`, because they
will now have to supply their own implementations of `Clone` and `Copy`
for the primitive types listed above. The easiest way to do that is to
simply copy the implementations from `src/libcore/clone.rs` and
`src/libcore/marker.rs`.

Fixes rust-lang#25893
There are types that implement `Clone` and `Copy` but are not mentioned
in the documentation, because the implementations are provided by the
compiler. They are types of variants that cannot be fully covered by
trait implementations in Rust code, because the language is not
expressive enough.
Simply checking for the presence of `llvm.memset` is too brittle because
this instrinsic can be used for seemingly trivial operations, such as
zero-initializing a `RawVec`.
@FraGag
Copy link
Contributor Author

FraGag commented Mar 27, 2018

Now that rust-lang/libc#951 has been merged and libc 0.2.40 published, I can progress.

I just rebased and tweaked my branch to account for the changes made in #49299, which made some changes to the documentation for Clone and Copy, to avoid redundancy with the changes I had made previously and to remove now broken links to the unstable book (thanks to the linkchecker tool for catching these!).

@nikomatsakis r?

@pietroalbini pietroalbini added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Mar 27, 2018
@shepmaster
Copy link
Member

Ping from triage, @nikomatsakis !

@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Apr 4, 2018

📌 Commit 87c08f9 has been approved by nikomatsakis

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 4, 2018
@bors
Copy link
Contributor

bors commented Apr 4, 2018

⌛ Testing commit 87c08f9 with merge fb44b4c...

bors added a commit that referenced this pull request Apr 4, 2018
Better document the implementors of Clone and Copy

There are two parts to this change. The first part is a change to the compiler and to the standard library (specifically, libcore) to allow implementations of `Clone` and `Copy` to be written for a subset of builtin types. By adding these implementations to libcore, they now show up in the documentation. This is a [breaking-change] for users of `#![no_core]`, because they will now have to supply their own copy of the implementations of `Clone` and `Copy` that were added in libcore.

The second part is purely a documentation change to document the other implementors of `Clone` and `Copy` that cannot be described in Rust code (yet) and are thus provided by the compiler.

Fixes #25893
@bors
Copy link
Contributor

bors commented Apr 4, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: nikomatsakis
Pushing fb44b4c to master...

@bors bors merged commit 87c08f9 into rust-lang:master Apr 4, 2018
@FraGag FraGag deleted the doc-copy-clone-impls branch April 4, 2018 23:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-lang Relevant to the language team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.