Rollup merge of #110259 - ndrewxie:issue-109964-fix-gitstuff, r=cjgillot
Added diagnostic for pin! macro in addition to Box::pin if Unpin isn't implemented I made a PR earlier, but accidentally renamed a branch and that deleted the PR... sorry for the duplicate Currently, if an operation on `Pin<T>` is performed that requires `T` to implement `Unpin`, the diagnostic suggestion is to use `Box::pin` ("note: consider using `Box::pin`"). This PR suggests pin! as well, as that's another valid way of pinning a value, and avoids a heap allocation. Appropriate diagnostic suggestions were included to highlight the difference in semantics (local pinning for pin! vs non-local for Box::pin). Fixes #109964
This commit is contained in:
commit
e413c2e770
@ -823,7 +823,7 @@ unsafe impl<T: ?Sized> Freeze for &mut T {}
|
|||||||
/// [`pin` module]: crate::pin
|
/// [`pin` module]: crate::pin
|
||||||
#[stable(feature = "pin", since = "1.33.0")]
|
#[stable(feature = "pin", since = "1.33.0")]
|
||||||
#[rustc_on_unimplemented(
|
#[rustc_on_unimplemented(
|
||||||
note = "consider using `Box::pin`",
|
note = "consider using the `pin!` macro\nconsider using `Box::pin` if you need to access the pinned value outside of the current scope",
|
||||||
message = "`{Self}` cannot be unpinned"
|
message = "`{Self}` cannot be unpinned"
|
||||||
)]
|
)]
|
||||||
#[lang = "unpin"]
|
#[lang = "unpin"]
|
||||||
|
@ -6,7 +6,8 @@ LL | Pin::new(&mut self.sleep).poll(cx)
|
|||||||
| |
|
| |
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
= note: consider using `Box::pin`
|
= note: consider using the `pin!` macro
|
||||||
|
consider using `Box::pin` if you need to access the pinned value outside of the current scope
|
||||||
note: required because it appears within the type `Sleep`
|
note: required because it appears within the type `Sleep`
|
||||||
--> $DIR/pin-needed-to-poll-2.rs:8:8
|
--> $DIR/pin-needed-to-poll-2.rs:8:8
|
||||||
|
|
|
|
||||||
|
@ -6,7 +6,8 @@ LL | assert_unpin(generator);
|
|||||||
| |
|
| |
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
= note: consider using `Box::pin`
|
= note: consider using the `pin!` macro
|
||||||
|
consider using `Box::pin` if you need to access the pinned value outside of the current scope
|
||||||
note: required by a bound in `assert_unpin`
|
note: required by a bound in `assert_unpin`
|
||||||
--> $DIR/static-not-unpin.rs:7:20
|
--> $DIR/static-not-unpin.rs:7:20
|
||||||
|
|
|
|
||||||
|
@ -50,7 +50,8 @@ LL | Pin::new(x)
|
|||||||
| |
|
| |
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
= note: consider using `Box::pin`
|
= note: consider using the `pin!` macro
|
||||||
|
consider using `Box::pin` if you need to access the pinned value outside of the current scope
|
||||||
note: required by a bound in `Pin::<P>::new`
|
note: required by a bound in `Pin::<P>::new`
|
||||||
--> $SRC_DIR/core/src/pin.rs:LL:COL
|
--> $SRC_DIR/core/src/pin.rs:LL:COL
|
||||||
|
|
||||||
@ -62,7 +63,8 @@ LL | Pin::new(Box::new(x))
|
|||||||
| |
|
| |
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
= note: consider using `Box::pin`
|
= note: consider using the `pin!` macro
|
||||||
|
consider using `Box::pin` if you need to access the pinned value outside of the current scope
|
||||||
note: required by a bound in `Pin::<P>::new`
|
note: required by a bound in `Pin::<P>::new`
|
||||||
--> $SRC_DIR/core/src/pin.rs:LL:COL
|
--> $SRC_DIR/core/src/pin.rs:LL:COL
|
||||||
|
|
||||||
|
@ -39,7 +39,8 @@ LL | f_unpin(static || { yield; });
|
|||||||
| |
|
| |
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
= note: consider using `Box::pin`
|
= note: consider using the `pin!` macro
|
||||||
|
consider using `Box::pin` if you need to access the pinned value outside of the current scope
|
||||||
note: required by a bound in `f_unpin`
|
note: required by a bound in `f_unpin`
|
||||||
--> $DIR/issue-84973-blacklist.rs:8:15
|
--> $DIR/issue-84973-blacklist.rs:8:15
|
||||||
|
|
|
|
||||||
|
23
tests/ui/suggestions/suggest-pin-macro.rs
Normal file
23
tests/ui/suggestions/suggest-pin-macro.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
use std::pin::Pin;
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Test {
|
||||||
|
_marker: PhantomPinned,
|
||||||
|
}
|
||||||
|
impl Test {
|
||||||
|
fn new() -> Self {
|
||||||
|
Test {
|
||||||
|
_marker: PhantomPinned, // This makes our type `!Unpin`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dummy(_: &mut Test) {}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let mut test1 = Test::new();
|
||||||
|
let mut test1 = unsafe { Pin::new_unchecked(&mut test1) };
|
||||||
|
|
||||||
|
dummy(test1.get_mut()); //~ ERROR E0277
|
||||||
|
}
|
19
tests/ui/suggestions/suggest-pin-macro.stderr
Normal file
19
tests/ui/suggestions/suggest-pin-macro.stderr
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||||
|
--> $DIR/suggest-pin-macro.rs:22:17
|
||||||
|
|
|
||||||
|
LL | dummy(test1.get_mut());
|
||||||
|
| ^^^^^^^ within `Test`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||||
|
|
|
||||||
|
= note: consider using the `pin!` macro
|
||||||
|
consider using `Box::pin` if you need to access the pinned value outside of the current scope
|
||||||
|
note: required because it appears within the type `Test`
|
||||||
|
--> $DIR/suggest-pin-macro.rs:5:8
|
||||||
|
|
|
||||||
|
LL | struct Test {
|
||||||
|
| ^^^^
|
||||||
|
note: required by a bound in `Pin::<&'a mut T>::get_mut`
|
||||||
|
--> $SRC_DIR/core/src/pin.rs:LL:COL
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
@ -6,7 +6,8 @@ LL | copy(r, w);
|
|||||||
| |
|
| |
|
||||||
| required by a bound introduced by this call
|
| required by a bound introduced by this call
|
||||||
|
|
|
|
||||||
= note: consider using `Box::pin`
|
= note: consider using the `pin!` macro
|
||||||
|
consider using `Box::pin` if you need to access the pinned value outside of the current scope
|
||||||
note: required by a bound in `copy`
|
note: required by a bound in `copy`
|
||||||
--> $DIR/issue-90164.rs:1:12
|
--> $DIR/issue-90164.rs:1:12
|
||||||
|
|
|
|
||||||
|
Loading…
Reference in New Issue
Block a user