mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #155621 - mejrs:document_diagnostic_on_move, r=chenyukang
Document #[diagnostic::on_move] in the unstable book. Also adds the attribute on `std::fs::File` to stay consistent with the prose in the unstable book entry. cc @estebank @rperier Rendered: <img width="791" height="903" alt="image" src="https://github.com/user-attachments/assets/a27a5211-7717-4f7f-a514-8316dccc78d5" /> <img width="779" height="390" alt="image" src="https://github.com/user-attachments/assets/a983108d-575e-4551-ab14-28611344e9b0" />
This commit is contained in:
@@ -131,6 +131,7 @@
|
||||
/// [`read`]: File::read
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "File")]
|
||||
#[diagnostic::on_move(note = "you can use `File::try_clone` to duplicate a `File` instance")]
|
||||
pub struct File {
|
||||
inner: fs_imp::File,
|
||||
}
|
||||
|
||||
@@ -278,6 +278,7 @@
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(deprecated_suggestion)]
|
||||
#![feature(diagnostic_on_move)]
|
||||
#![feature(doc_cfg)]
|
||||
#![feature(doc_masked)]
|
||||
#![feature(doc_notable_trait)]
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
# `diagnostic_on_move`
|
||||
|
||||
The tracking issue for this feature is: [#154181]
|
||||
|
||||
------------------------
|
||||
|
||||
The `diagnostic_on_move` feature allows use of the `#[diagnostic::on_move]` attribute. It should be
|
||||
placed on struct, enum and union declarations, though it is not an error to be located in other
|
||||
positions. This attribute is a hint to the compiler to supplement the error message when the
|
||||
annotated type is involved in a borrowcheck error.
|
||||
|
||||
For example, [`File`] is annotated as such:
|
||||
```rust
|
||||
#![feature(diagnostic_on_move)]
|
||||
|
||||
#[diagnostic::on_move(note = "you can use `File::try_clone` \
|
||||
to duplicate a `File` instance")]
|
||||
pub struct File {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
When you try to use a `File` after it's already been moved, it will helpfully tell you about `try_clone`.
|
||||
|
||||
The message and label can also be customized:
|
||||
|
||||
```rust
|
||||
#![feature(diagnostic_on_move)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[diagnostic::on_move(
|
||||
message = "`{Self}` cannot be used multiple times",
|
||||
label = "this token may only be used once",
|
||||
note = "you can create a new `Token` with `Token::conjure()`"
|
||||
)]
|
||||
pub struct Token<'brand> {
|
||||
spooky: PhantomData<&'brand ()>,
|
||||
}
|
||||
|
||||
impl Token<'_> {
|
||||
pub fn conjure<'u>() -> Token<'u> {
|
||||
Token {
|
||||
spooky: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
The user may try to use it like this:
|
||||
```rust,compile_fail,E0382
|
||||
# #![feature(diagnostic_on_move)]
|
||||
#
|
||||
# use std::marker::PhantomData;
|
||||
#
|
||||
# #[diagnostic::on_move(
|
||||
# message = "`{Self}` cannot be used multiple times",
|
||||
# label = "this token may only be used once",
|
||||
# note = "you can create a new `Token` with `Token::conjure()`"
|
||||
# )]
|
||||
# pub struct Token<'brand> {
|
||||
# spooky: PhantomData<&'brand ()>,
|
||||
# }
|
||||
#
|
||||
# impl Token<'_> {
|
||||
# pub fn conjure<'u>() -> Token<'u> {
|
||||
# Token {
|
||||
# spooky: PhantomData,
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# fn main() {
|
||||
let token = Token::conjure();
|
||||
let _ = (token, token);
|
||||
# }
|
||||
```
|
||||
This will result in the following error:
|
||||
```text
|
||||
error[E0382]: `Token` cannot be used multiple times
|
||||
--> src/main.rs:24:21
|
||||
|
|
||||
1 | let token = Token::conjure();
|
||||
| ----- this token may only be used once
|
||||
2 | let _ = (token, token);
|
||||
| ----- ^^^^^ value used here after move
|
||||
| |
|
||||
| value moved here
|
||||
|
|
||||
= note: you can create a new `Token` with `Token::conjure()`
|
||||
```
|
||||
|
||||
[`File`]: https://doc.rust-lang.org/nightly/std/fs/struct.File.html "File in std::fs"
|
||||
[#154181]: https://github.com/rust-lang/rust/issues/154181 "Tracking Issue for #[diagnostic::on_move]"
|
||||
@@ -0,0 +1,25 @@
|
||||
//@ dont-require-annotations: NOTE
|
||||
|
||||
use std::fs::File;
|
||||
use std::sync::Arc;
|
||||
use std::rc::Rc;
|
||||
|
||||
fn main(){
|
||||
let file = File::open("foo.txt").unwrap();
|
||||
(file, file);
|
||||
//~^ ERROR use of moved value: `file`
|
||||
//~| NOTE you can use `File::try_clone` to duplicate a `File` instance
|
||||
|
||||
let arc = Arc::new(42);
|
||||
//~^ NOTE this move could be avoided by cloning the original `Arc`, which is inexpensive
|
||||
(arc, arc);
|
||||
//~^ ERROR the type `Arc` does not implement `Copy`
|
||||
//~| NOTE consider using `Arc::clone`
|
||||
|
||||
|
||||
let rc = Rc::new(12);
|
||||
//~^ NOTE this move could be avoided by cloning the original `Rc`, which is inexpensive
|
||||
(rc, rc);
|
||||
//~^ ERROR the type `Rc` does not implement `Copy`
|
||||
//~| NOTE consider using `Rc::clone`
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
error[E0382]: use of moved value: `file`
|
||||
--> $DIR/std_impls.rs:9:12
|
||||
|
|
||||
LL | let file = File::open("foo.txt").unwrap();
|
||||
| ---- move occurs because `file` has type `File`, which does not implement the `Copy` trait
|
||||
LL | (file, file);
|
||||
| ---- ^^^^ value used here after move
|
||||
| |
|
||||
| value moved here
|
||||
|
|
||||
= note: you can use `File::try_clone` to duplicate a `File` instance
|
||||
|
||||
error[E0382]: the type `Arc` does not implement `Copy`
|
||||
--> $DIR/std_impls.rs:15:11
|
||||
|
|
||||
LL | let arc = Arc::new(42);
|
||||
| --- this move could be avoided by cloning the original `Arc`, which is inexpensive
|
||||
LL |
|
||||
LL | (arc, arc);
|
||||
| --- ^^^ value used here after move
|
||||
| |
|
||||
| value moved here
|
||||
|
|
||||
= note: consider using `Arc::clone`
|
||||
help: clone the value to increment its reference count
|
||||
|
|
||||
LL | (arc.clone(), arc);
|
||||
| ++++++++
|
||||
|
||||
error[E0382]: the type `Rc` does not implement `Copy`
|
||||
--> $DIR/std_impls.rs:22:10
|
||||
|
|
||||
LL | let rc = Rc::new(12);
|
||||
| -- this move could be avoided by cloning the original `Rc`, which is inexpensive
|
||||
LL |
|
||||
LL | (rc, rc);
|
||||
| -- ^^ value used here after move
|
||||
| |
|
||||
| value moved here
|
||||
|
|
||||
= note: consider using `Rc::clone`
|
||||
help: clone the value to increment its reference count
|
||||
|
|
||||
LL | (rc.clone(), rc);
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0382`.
|
||||
Reference in New Issue
Block a user