Skip to content

Commit 5e4d49a

Browse files
committed
Use helper trait for better errors
1 parent 9bb2a3a commit 5e4d49a

File tree

4 files changed

+22
-32
lines changed

4 files changed

+22
-32
lines changed

‎library/core/src/pin.rs‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,15 +1691,15 @@ mod hidden {
16911691
}
16921692

16931693
#[unstable(feature = "pin_derefmut_internals", issue = "none")]
1694-
impl<Ptr: Deref> Deref for PinHelper<Ptr> {
1695-
type Target = Ptr::Target;
1696-
fn deref(&self) -> &Ptr::Target {
1697-
&self.pointer
1698-
}
1694+
pub trait DerefMutHelper {
1695+
type Target: ?Sized;
1696+
fn deref_mut(&mut self) -> &mut Self::Target;
16991697
}
17001698

17011699
#[unstable(feature = "pin_derefmut_internals", issue = "none")]
1702-
impl<Ptr: DerefMut<Target: Unpin>> DerefMut for PinHelper<Ptr> {
1700+
impl<Ptr: DerefMut<Target: Unpin>> DerefMutHelper for PinHelper<Ptr> {
1701+
type Target = Ptr::Target;
1702+
17031703
#[inline(always)]
17041704
fn deref_mut(&mut self) -> &mut Ptr::Target {
17051705
&mut self.pointer
@@ -1712,12 +1712,12 @@ mod hidden {
17121712
impl<Ptr> DerefMut for Pin<Ptr>
17131713
where
17141714
Ptr: Deref,
1715-
hidden::PinHelper<Ptr>: DerefMut<Target = Self::Target>,
1715+
hidden::PinHelper<Ptr>: hidden::DerefMutHelper<Target = Self::Target>,
17161716
{
17171717
fn deref_mut(&mut self) -> &mut Ptr::Target {
17181718
// SAFETY: Pin and PinHelper have the same layout, so this is equivalent to
17191719
// `&mut self.pointer` which is safe because `Target: Unpin`.
1720-
unsafe { &mut **(self as *mut Pin<Ptr> as *mut hidden::PinHelper<Ptr>) }
1720+
hidden::DerefMutHelper::deref_mut(unsafe { &mut *(self as *mut Pin<Ptr> as *mut hidden::PinHelper<Ptr>) })
17211721
}
17221722
}
17231723

‎tests/ui/deref/pin-impl-deref.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ impl MyPinType {
2222
fn impl_deref_mut(_: impl DerefMut) {}
2323
fn unpin_impl_ref(r_unpin: Pin<&MyUnpinType>) {
2424
impl_deref_mut(r_unpin)
25-
//~^ ERROR: the trait bound `pin::hidden::PinHelper<&MyUnpinType>: DerefMut` is not satisfied
25+
//~^ ERROR: the trait bound `&MyUnpinType: DerefMut` is not satisfied
2626
}
2727
fn unpin_impl_mut(r_unpin: Pin<&mut MyUnpinType>) {
2828
impl_deref_mut(r_unpin)
2929
}
3030
fn pin_impl_ref(r_pin: Pin<&MyPinType>) {
3131
impl_deref_mut(r_pin)
3232
//~^ ERROR: `PhantomPinned` cannot be unpinned
33-
//~| ERROR: the trait bound `pin::hidden::PinHelper<&MyPinType>: DerefMut` is not satisfied
33+
//~| ERROR: the trait bound `&MyPinType: DerefMut` is not satisfied
3434
}
3535
fn pin_impl_mut(r_pin: Pin<&mut MyPinType>) {
3636
impl_deref_mut(r_pin)

‎tests/ui/deref/pin-impl-deref.stderr‎

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,36 @@
1-
error[E0277]: the trait bound `pin::hidden::PinHelper<&MyUnpinType>: DerefMut` is not satisfied
1+
error[E0277]: the trait bound `&MyUnpinType: DerefMut` is not satisfied
22
--> $DIR/pin-impl-deref.rs:24:20
33
|
44
LL | impl_deref_mut(r_unpin)
5-
| -------------- ^^^^^^^ the trait `DerefMut` is not implemented for `pin::hidden::PinHelper<&MyUnpinType>`
5+
| -------------- ^^^^^^^ the trait `DerefMut` is not implemented for `&MyUnpinType`
66
| |
77
| required by a bound introduced by this call
88
|
9-
= note: required for `pin::hidden::PinHelper<&MyUnpinType>` to implement `DerefMut`
10-
= note: 1 redundant requirement hidden
9+
= note: `DerefMut` is implemented for `&mut MyUnpinType`, but not for `&MyUnpinType`
10+
= note: required for `pin::hidden::PinHelper<&MyUnpinType>` to implement `pin::hidden::DerefMutHelper`
1111
= note: required for `Pin<&MyUnpinType>` to implement `DerefMut`
1212
note: required by a bound in `impl_deref_mut`
1313
--> $DIR/pin-impl-deref.rs:22:27
1414
|
1515
LL | fn impl_deref_mut(_: impl DerefMut) {}
1616
| ^^^^^^^^ required by this bound in `impl_deref_mut`
17-
help: consider mutably borrowing here
18-
|
19-
LL | impl_deref_mut(&mut r_unpin)
20-
| ++++
2117

22-
error[E0277]: the trait bound `pin::hidden::PinHelper<&MyPinType>: DerefMut` is not satisfied
18+
error[E0277]: the trait bound `&MyPinType: DerefMut` is not satisfied
2319
--> $DIR/pin-impl-deref.rs:31:20
2420
|
2521
LL | impl_deref_mut(r_pin)
26-
| -------------- ^^^^^ the trait `DerefMut` is not implemented for `pin::hidden::PinHelper<&MyPinType>`
22+
| -------------- ^^^^^ the trait `DerefMut` is not implemented for `&MyPinType`
2723
| |
2824
| required by a bound introduced by this call
2925
|
30-
= note: required for `pin::hidden::PinHelper<&MyPinType>` to implement `DerefMut`
31-
= note: 1 redundant requirement hidden
26+
= note: `DerefMut` is implemented for `&mut MyPinType`, but not for `&MyPinType`
27+
= note: required for `pin::hidden::PinHelper<&MyPinType>` to implement `pin::hidden::DerefMutHelper`
3228
= note: required for `Pin<&MyPinType>` to implement `DerefMut`
3329
note: required by a bound in `impl_deref_mut`
3430
--> $DIR/pin-impl-deref.rs:22:27
3531
|
3632
LL | fn impl_deref_mut(_: impl DerefMut) {}
3733
| ^^^^^^^^ required by this bound in `impl_deref_mut`
38-
help: consider mutably borrowing here
39-
|
40-
LL | impl_deref_mut(&mut r_pin)
41-
| ++++
4234

4335
error[E0277]: `PhantomPinned` cannot be unpinned
4436
--> $DIR/pin-impl-deref.rs:31:20
@@ -55,8 +47,7 @@ note: required because it appears within the type `MyPinType`
5547
|
5648
LL | struct MyPinType(core::marker::PhantomPinned);
5749
| ^^^^^^^^^
58-
= note: required for `pin::hidden::PinHelper<&MyPinType>` to implement `DerefMut`
59-
= note: 1 redundant requirement hidden
50+
= note: required for `pin::hidden::PinHelper<&MyPinType>` to implement `pin::hidden::DerefMutHelper`
6051
= note: required for `Pin<&MyPinType>` to implement `DerefMut`
6152
note: required by a bound in `impl_deref_mut`
6253
--> $DIR/pin-impl-deref.rs:22:27
@@ -79,8 +70,7 @@ note: required because it appears within the type `MyPinType`
7970
|
8071
LL | struct MyPinType(core::marker::PhantomPinned);
8172
| ^^^^^^^^^
82-
= note: required for `pin::hidden::PinHelper<&mut MyPinType>` to implement `DerefMut`
83-
= note: 1 redundant requirement hidden
73+
= note: required for `pin::hidden::PinHelper<&mut MyPinType>` to implement `pin::hidden::DerefMutHelper`
8474
= note: required for `Pin<&mut MyPinType>` to implement `DerefMut`
8575
note: required by a bound in `impl_deref_mut`
8676
--> $DIR/pin-impl-deref.rs:22:27

‎tests/ui/typeck/pin-unsound-issue-85099-derefmut.stderr‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ LL | impl<'b, 'a, Fut> DerefMut for Pin<&'b dyn SomeTrait<'a, Fut>> {
66
|
77
= note: conflicting implementation in crate `core`:
88
- impl<Ptr> DerefMut for Pin<Ptr>
9-
where <pin::hidden::PinHelper<Ptr> as Deref>::Target == <Pin<Ptr> as Deref>::Target, Ptr: Deref, pin::hidden::PinHelper<Ptr>: DerefMut, pin::hidden::PinHelper<Ptr>: ?Sized;
10-
= note: upstream crates may add a new impl of trait `std::ops::DerefMut` for type `std::pin::hidden::PinHelper<&dyn SomeTrait<'_, _>>` in future versions
9+
where <pin::hidden::PinHelper<Ptr> as pin::hidden::DerefMutHelper>::Target == <Pin<Ptr> as Deref>::Target, Ptr: Deref, pin::hidden::PinHelper<Ptr>: pin::hidden::DerefMutHelper, pin::hidden::PinHelper<Ptr>: ?Sized;
10+
= note: upstream crates may add a new impl of trait `std::pin::hidden::DerefMutHelper` for type `std::pin::hidden::PinHelper<&dyn SomeTrait<'_, _>>` in future versions
1111

1212
error: aborting due to 1 previous error
1313

0 commit comments

Comments
 (0)