Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 91826b6

Browse files
authoredMar 6, 2025
Rollup merge of #135733 - frank-king:feature/pin-self-receiver, r=oli-obk,traviscross
Implement `&pin const self` and `&pin mut self` sugars This PR implements part of #130494. It introduces the sugars `&pin const self` and `&pin mut self` for `self: Pin<&Self>` and `self: Pin<&mut Self>`.
2 parents 30f168e + 50d0f99 commit 91826b6

File tree

10 files changed

+308
-76
lines changed

10 files changed

+308
-76
lines changed
 

‎compiler/rustc_ast/src/ast.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2641,6 +2641,8 @@ pub enum SelfKind {
26412641
Value(Mutability),
26422642
/// `&'lt self`, `&'lt mut self`
26432643
Region(Option<Lifetime>, Mutability),
2644+
/// `&'lt pin const self`, `&'lt pin mut self`
2645+
Pinned(Option<Lifetime>, Mutability),
26442646
/// `self: TYPE`, `mut self: TYPE`
26452647
Explicit(P<Ty>, Mutability),
26462648
}
@@ -2650,6 +2652,8 @@ impl SelfKind {
26502652
match self {
26512653
SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
26522654
SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2655+
SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2656+
SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
26532657
SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
26542658
unreachable!("if we had an explicit self, we wouldn't be here")
26552659
}
@@ -2666,11 +2670,13 @@ impl Param {
26662670
if ident.name == kw::SelfLower {
26672671
return match self.ty.kind {
26682672
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2669-
TyKind::Ref(lt, MutTy { ref ty, mutbl })
2670-
| TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2673+
TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2674+
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2675+
}
2676+
TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
26712677
if ty.kind.is_implicit_self() =>
26722678
{
2673-
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2679+
Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
26742680
}
26752681
_ => Some(respan(
26762682
self.pat.span.to(self.ty.span),
@@ -2712,6 +2718,15 @@ impl Param {
27122718
tokens: None,
27132719
}),
27142720
),
2721+
SelfKind::Pinned(lt, mutbl) => (
2722+
mutbl,
2723+
P(Ty {
2724+
id: DUMMY_NODE_ID,
2725+
kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
2726+
span,
2727+
tokens: None,
2728+
}),
2729+
),
27152730
};
27162731
Param {
27172732
attrs,

‎compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,13 @@ impl<'a> State<'a> {
17831783
self.print_mutability(*m, false);
17841784
self.word("self")
17851785
}
1786+
SelfKind::Pinned(lt, m) => {
1787+
self.word("&");
1788+
self.print_opt_lifetime(lt);
1789+
self.word("pin ");
1790+
self.print_mutability(*m, true);
1791+
self.word("self")
1792+
}
17861793
SelfKind::Explicit(typ, m) => {
17871794
self.print_mutability(*m, false);
17881795
self.word("self");

‎compiler/rustc_parse/src/parser/item.rs

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2954,14 +2954,27 @@ impl<'a> Parser<'a> {
29542954
}
29552955
_ => unreachable!(),
29562956
};
2957+
// is lifetime `n` tokens ahead?
2958+
let is_lifetime = |this: &Self, n| this.look_ahead(n, |t| t.is_lifetime());
29572959
// Is `self` `n` tokens ahead?
29582960
let is_isolated_self = |this: &Self, n| {
29592961
this.is_keyword_ahead(n, &[kw::SelfLower])
29602962
&& this.look_ahead(n + 1, |t| t != &token::PathSep)
29612963
};
2964+
// Is `pin const self` `n` tokens ahead?
2965+
let is_isolated_pin_const_self = |this: &Self, n| {
2966+
this.look_ahead(n, |token| token.is_ident_named(sym::pin))
2967+
&& this.is_keyword_ahead(n + 1, &[kw::Const])
2968+
&& is_isolated_self(this, n + 2)
2969+
};
29622970
// Is `mut self` `n` tokens ahead?
29632971
let is_isolated_mut_self =
29642972
|this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1);
2973+
// Is `pin mut self` `n` tokens ahead?
2974+
let is_isolated_pin_mut_self = |this: &Self, n| {
2975+
this.look_ahead(n, |token| token.is_ident_named(sym::pin))
2976+
&& is_isolated_mut_self(this, n + 1)
2977+
};
29652978
// Parse `self` or `self: TYPE`. We already know the current token is `self`.
29662979
let parse_self_possibly_typed = |this: &mut Self, m| {
29672980
let eself_ident = expect_self_ident(this);
@@ -3012,26 +3025,35 @@ impl<'a> Parser<'a> {
30123025
let eself_lo = self.token.span;
30133026
let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind {
30143027
token::And => {
3015-
let eself = if is_isolated_self(self, 1) {
3016-
// `&self`
3017-
self.bump();
3018-
SelfKind::Region(None, Mutability::Not)
3019-
} else if is_isolated_mut_self(self, 1) {
3020-
// `&mut self`
3021-
self.bump();
3022-
self.bump();
3023-
SelfKind::Region(None, Mutability::Mut)
3024-
} else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) {
3025-
// `&'lt self`
3026-
self.bump();
3027-
let lt = self.expect_lifetime();
3028-
SelfKind::Region(Some(lt), Mutability::Not)
3029-
} else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) {
3030-
// `&'lt mut self`
3031-
self.bump();
3032-
let lt = self.expect_lifetime();
3033-
self.bump();
3034-
SelfKind::Region(Some(lt), Mutability::Mut)
3028+
let has_lifetime = is_lifetime(self, 1);
3029+
let skip_lifetime_count = has_lifetime as usize;
3030+
let eself = if is_isolated_self(self, skip_lifetime_count + 1) {
3031+
// `&{'lt} self`
3032+
self.bump(); // &
3033+
let lifetime = has_lifetime.then(|| self.expect_lifetime());
3034+
SelfKind::Region(lifetime, Mutability::Not)
3035+
} else if is_isolated_mut_self(self, skip_lifetime_count + 1) {
3036+
// `&{'lt} mut self`
3037+
self.bump(); // &
3038+
let lifetime = has_lifetime.then(|| self.expect_lifetime());
3039+
self.bump(); // mut
3040+
SelfKind::Region(lifetime, Mutability::Mut)
3041+
} else if is_isolated_pin_const_self(self, skip_lifetime_count + 1) {
3042+
// `&{'lt} pin const self`
3043+
self.bump(); // &
3044+
let lifetime = has_lifetime.then(|| self.expect_lifetime());
3045+
self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3046+
self.bump(); // pin
3047+
self.bump(); // const
3048+
SelfKind::Pinned(lifetime, Mutability::Not)
3049+
} else if is_isolated_pin_mut_self(self, skip_lifetime_count + 1) {
3050+
// `&{'lt} pin mut self`
3051+
self.bump(); // &
3052+
let lifetime = has_lifetime.then(|| self.expect_lifetime());
3053+
self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
3054+
self.bump(); // pin
3055+
self.bump(); // mut
3056+
SelfKind::Pinned(lifetime, Mutability::Mut)
30353057
} else {
30363058
// `&not_self`
30373059
return Ok(None);

‎src/tools/rustfmt/src/items.rs

Lines changed: 34 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2359,6 +2359,21 @@ impl Rewrite for ast::Param {
23592359
}
23602360
}
23612361

2362+
fn rewrite_opt_lifetime(
2363+
context: &RewriteContext<'_>,
2364+
lifetime: Option<ast::Lifetime>,
2365+
) -> RewriteResult {
2366+
let Some(l) = lifetime else {
2367+
return Ok(String::new());
2368+
};
2369+
let mut result = l.rewrite_result(
2370+
context,
2371+
Shape::legacy(context.config.max_width(), Indent::empty()),
2372+
)?;
2373+
result.push(' ');
2374+
Ok(result)
2375+
}
2376+
23622377
fn rewrite_explicit_self(
23632378
context: &RewriteContext<'_>,
23642379
explicit_self: &ast::ExplicitSelf,
@@ -2367,58 +2382,34 @@ fn rewrite_explicit_self(
23672382
shape: Shape,
23682383
has_multiple_attr_lines: bool,
23692384
) -> RewriteResult {
2370-
match explicit_self.node {
2385+
let self_str = match explicit_self.node {
23712386
ast::SelfKind::Region(lt, m) => {
23722387
let mut_str = format_mutability(m);
2373-
match lt {
2374-
Some(ref l) => {
2375-
let lifetime_str = l.rewrite_result(
2376-
context,
2377-
Shape::legacy(context.config.max_width(), Indent::empty()),
2378-
)?;
2379-
Ok(combine_strs_with_missing_comments(
2380-
context,
2381-
param_attrs,
2382-
&format!("&{lifetime_str} {mut_str}self"),
2383-
span,
2384-
shape,
2385-
!has_multiple_attr_lines,
2386-
)?)
2387-
}
2388-
None => Ok(combine_strs_with_missing_comments(
2389-
context,
2390-
param_attrs,
2391-
&format!("&{mut_str}self"),
2392-
span,
2393-
shape,
2394-
!has_multiple_attr_lines,
2395-
)?),
2396-
}
2388+
let lifetime_str = rewrite_opt_lifetime(context, lt)?;
2389+
format!("&{lifetime_str}{mut_str}self")
2390+
}
2391+
ast::SelfKind::Pinned(lt, m) => {
2392+
let mut_str = m.ptr_str();
2393+
let lifetime_str = rewrite_opt_lifetime(context, lt)?;
2394+
format!("&{lifetime_str}pin {mut_str} self")
23972395
}
23982396
ast::SelfKind::Explicit(ref ty, mutability) => {
23992397
let type_str = ty.rewrite_result(
24002398
context,
24012399
Shape::legacy(context.config.max_width(), Indent::empty()),
24022400
)?;
2403-
2404-
Ok(combine_strs_with_missing_comments(
2405-
context,
2406-
param_attrs,
2407-
&format!("{}self: {}", format_mutability(mutability), type_str),
2408-
span,
2409-
shape,
2410-
!has_multiple_attr_lines,
2411-
)?)
2401+
format!("{}self: {}", format_mutability(mutability), type_str)
24122402
}
2413-
ast::SelfKind::Value(mutability) => Ok(combine_strs_with_missing_comments(
2414-
context,
2415-
param_attrs,
2416-
&format!("{}self", format_mutability(mutability)),
2417-
span,
2418-
shape,
2419-
!has_multiple_attr_lines,
2420-
)?),
2421-
}
2403+
ast::SelfKind::Value(mutability) => format!("{}self", format_mutability(mutability)),
2404+
};
2405+
Ok(combine_strs_with_missing_comments(
2406+
context,
2407+
param_attrs,
2408+
&self_str,
2409+
span,
2410+
shape,
2411+
!has_multiple_attr_lines,
2412+
)?)
24222413
}
24232414

24242415
pub(crate) fn span_lo_for_param(param: &ast::Param) -> BytePos {

‎src/tools/rustfmt/tests/source/pin_sugar.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,13 @@ fn g<'a>(x: & 'a pin const i32) {}
88
fn h<'a>(x: & 'a pin
99
mut i32) {}
1010
fn i(x: &pin mut i32) {}
11+
12+
struct Foo;
13+
14+
impl Foo {
15+
fn f(&pin const self) {}
16+
fn g<'a>(& 'a pin const self) {}
17+
fn h<'a>(& 'a pin
18+
mut self) {}
19+
fn i(&pin mut self) {}
20+
}

‎src/tools/rustfmt/tests/target/pin_sugar.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,12 @@ fn f(x: &pin const i32) {}
77
fn g<'a>(x: &'a pin const i32) {}
88
fn h<'a>(x: &'a pin mut i32) {}
99
fn i(x: &pin mut i32) {}
10+
11+
struct Foo;
12+
13+
impl Foo {
14+
fn f(&pin const self) {}
15+
fn g<'a>(&'a pin const self) {}
16+
fn h<'a>(&'a pin mut self) {}
17+
fn i(&pin mut self) {}
18+
}

‎tests/pretty/pin-ergonomics.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//@ pp-exact
2+
3+
#![feature(pin_ergonomics)]
4+
#![allow(dead_code, incomplete_features)]
5+
6+
struct Foo;
7+
8+
impl Foo {
9+
fn baz(&pin mut self) {}
10+
11+
fn baz_const(&pin const self) {}
12+
13+
fn baz_lt<'a>(&'a pin mut self) {}
14+
15+
fn baz_const_lt(&'_ pin const self) {}
16+
}
17+
18+
fn foo(_: &pin mut Foo) {}
19+
fn foo_lt<'a>(_: &'a pin mut Foo) {}
20+
21+
fn foo_const(_: &pin const Foo) {}
22+
fn foo_const_lt(_: &'_ pin const Foo) {}
23+
24+
fn main() {}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//@ check-pass
2+
3+
#![feature(pin_ergonomics)]
4+
#![allow(dead_code, incomplete_features)]
5+
6+
// Makes sure we can handle `&pin mut self` and `&pin const self` as sugar for
7+
// `self: Pin<&mut Self>` and `self: Pin<&Self>`.
8+
9+
use std::pin::Pin;
10+
11+
struct Foo;
12+
13+
impl Foo {
14+
fn baz(&pin mut self) {}
15+
16+
fn baz_const(&pin const self) {}
17+
18+
fn baz_lt<'a>(&'a pin mut self) {}
19+
20+
fn baz_const_lt(&'_ pin const self) {}
21+
}
22+
23+
fn foo(_: &pin mut Foo) {}
24+
25+
fn foo_const(_: &pin const Foo) {}
26+
27+
fn bar(x: &pin mut Foo) {
28+
// For the calls below to work we need to automatically reborrow,
29+
// as if the user had written `foo(x.as_mut())`.
30+
foo(x);
31+
foo(x);
32+
33+
Foo::baz(x);
34+
Foo::baz(x);
35+
36+
// make sure we can reborrow &mut as &.
37+
foo_const(x);
38+
Foo::baz_const(x);
39+
40+
let x: &pin const _ = Pin::new(&Foo);
41+
42+
foo_const(x); // make sure reborrowing from & to & works.
43+
foo_const(x);
44+
}
45+
46+
fn main() {}

‎tests/ui/feature-gates/feature-gate-pin_ergonomics.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ struct Foo;
77
impl Foo {
88
fn foo(self: Pin<&mut Self>) {
99
}
10+
fn foo_sugar(&pin mut self) {} //~ ERROR pinned reference syntax is experimental
11+
fn foo_sugar_const(&pin const self) {} //~ ERROR pinned reference syntax is experimental
1012
}
1113

12-
fn foo(x: Pin<&mut Foo>) {
14+
fn foo(mut x: Pin<&mut Foo>) {
15+
Foo::foo_sugar(x.as_mut());
16+
Foo::foo_sugar_const(x.as_ref());
1317
let _y: &pin mut Foo = x; //~ ERROR pinned reference syntax is experimental
1418
}
1519

@@ -27,4 +31,38 @@ fn baz(mut x: Pin<&mut Foo>) {
2731

2832
fn baz_sugar(_: &pin const Foo) {} //~ ERROR pinned reference syntax is experimental
2933

34+
#[cfg(any())]
35+
mod not_compiled {
36+
use std::pin::Pin;
37+
38+
struct Foo;
39+
40+
impl Foo {
41+
fn foo(self: Pin<&mut Self>) {
42+
}
43+
fn foo_sugar(&pin mut self) {} //~ ERROR pinned reference syntax is experimental
44+
fn foo_sugar_const(&pin const self) {} //~ ERROR pinned reference syntax is experimental
45+
}
46+
47+
fn foo(mut x: Pin<&mut Foo>) {
48+
Foo::foo_sugar(x.as_mut());
49+
Foo::foo_sugar_const(x.as_ref());
50+
let _y: &pin mut Foo = x; //~ ERROR pinned reference syntax is experimental
51+
}
52+
53+
fn foo_sugar(_: &pin mut Foo) {} //~ ERROR pinned reference syntax is experimental
54+
55+
fn bar(x: Pin<&mut Foo>) {
56+
foo(x);
57+
foo(x);
58+
}
59+
60+
fn baz(mut x: Pin<&mut Foo>) {
61+
x.foo();
62+
x.foo();
63+
}
64+
65+
fn baz_sugar(_: &pin const Foo) {} //~ ERROR pinned reference syntax is experimental
66+
}
67+
3068
fn main() {}

‎tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
error[E0658]: pinned reference syntax is experimental
2-
--> $DIR/feature-gate-pin_ergonomics.rs:13:14
2+
--> $DIR/feature-gate-pin_ergonomics.rs:10:19
3+
|
4+
LL | fn foo_sugar(&pin mut self) {}
5+
| ^^^
6+
|
7+
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
8+
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
11+
error[E0658]: pinned reference syntax is experimental
12+
--> $DIR/feature-gate-pin_ergonomics.rs:11:25
13+
|
14+
LL | fn foo_sugar_const(&pin const self) {}
15+
| ^^^
16+
|
17+
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
18+
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
19+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
20+
21+
error[E0658]: pinned reference syntax is experimental
22+
--> $DIR/feature-gate-pin_ergonomics.rs:17:14
323
|
424
LL | let _y: &pin mut Foo = x;
525
| ^^^
@@ -9,7 +29,7 @@ LL | let _y: &pin mut Foo = x;
929
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1030

1131
error[E0658]: pinned reference syntax is experimental
12-
--> $DIR/feature-gate-pin_ergonomics.rs:16:18
32+
--> $DIR/feature-gate-pin_ergonomics.rs:20:18
1333
|
1434
LL | fn foo_sugar(_: &pin mut Foo) {}
1535
| ^^^
@@ -19,7 +39,7 @@ LL | fn foo_sugar(_: &pin mut Foo) {}
1939
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
2040

2141
error[E0658]: pinned reference syntax is experimental
22-
--> $DIR/feature-gate-pin_ergonomics.rs:28:18
42+
--> $DIR/feature-gate-pin_ergonomics.rs:32:18
2343
|
2444
LL | fn baz_sugar(_: &pin const Foo) {}
2545
| ^^^
@@ -28,8 +48,58 @@ LL | fn baz_sugar(_: &pin const Foo) {}
2848
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
2949
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
3050

51+
error[E0658]: pinned reference syntax is experimental
52+
--> $DIR/feature-gate-pin_ergonomics.rs:43:23
53+
|
54+
LL | fn foo_sugar(&pin mut self) {}
55+
| ^^^
56+
|
57+
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
58+
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
59+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
60+
61+
error[E0658]: pinned reference syntax is experimental
62+
--> $DIR/feature-gate-pin_ergonomics.rs:44:29
63+
|
64+
LL | fn foo_sugar_const(&pin const self) {}
65+
| ^^^
66+
|
67+
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
68+
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
69+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
70+
71+
error[E0658]: pinned reference syntax is experimental
72+
--> $DIR/feature-gate-pin_ergonomics.rs:50:18
73+
|
74+
LL | let _y: &pin mut Foo = x;
75+
| ^^^
76+
|
77+
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
78+
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
79+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
80+
81+
error[E0658]: pinned reference syntax is experimental
82+
--> $DIR/feature-gate-pin_ergonomics.rs:53:22
83+
|
84+
LL | fn foo_sugar(_: &pin mut Foo) {}
85+
| ^^^
86+
|
87+
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
88+
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
89+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
90+
91+
error[E0658]: pinned reference syntax is experimental
92+
--> $DIR/feature-gate-pin_ergonomics.rs:65:22
93+
|
94+
LL | fn baz_sugar(_: &pin const Foo) {}
95+
| ^^^
96+
|
97+
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
98+
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
99+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
100+
31101
error[E0382]: use of moved value: `x`
32-
--> $DIR/feature-gate-pin_ergonomics.rs:20:9
102+
--> $DIR/feature-gate-pin_ergonomics.rs:24:9
33103
|
34104
LL | fn bar(x: Pin<&mut Foo>) {
35105
| - move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
@@ -39,15 +109,15 @@ LL | foo(x);
39109
| ^ value used here after move
40110
|
41111
note: consider changing this parameter type in function `foo` to borrow instead if owning the value isn't necessary
42-
--> $DIR/feature-gate-pin_ergonomics.rs:12:11
112+
--> $DIR/feature-gate-pin_ergonomics.rs:14:15
43113
|
44-
LL | fn foo(x: Pin<&mut Foo>) {
45-
| --- ^^^^^^^^^^^^^ this parameter takes ownership of the value
114+
LL | fn foo(mut x: Pin<&mut Foo>) {
115+
| --- ^^^^^^^^^^^^^ this parameter takes ownership of the value
46116
| |
47117
| in this function
48118

49119
error[E0382]: use of moved value: `x`
50-
--> $DIR/feature-gate-pin_ergonomics.rs:25:5
120+
--> $DIR/feature-gate-pin_ergonomics.rs:29:5
51121
|
52122
LL | fn baz(mut x: Pin<&mut Foo>) {
53123
| ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
@@ -66,7 +136,7 @@ help: consider reborrowing the `Pin` instead of moving it
66136
LL | x.as_mut().foo();
67137
| +++++++++
68138

69-
error: aborting due to 5 previous errors
139+
error: aborting due to 12 previous errors
70140

71141
Some errors have detailed explanations: E0382, E0658.
72142
For more information about an error, try `rustc --explain E0382`.

0 commit comments

Comments
 (0)
Please sign in to comment.