Skip to content

Commit a4565b1

Browse files
committed
Fix pin_ergonomics tests
1 parent bb1d842 commit a4565b1

11 files changed

+726
-252
lines changed

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
556556
let binding_mode = adjust_binding_mode(Pinnedness::Pinned, inner_mutability);
557557
// If the pinnedness is `Not`, it means the pattern is unpinned
558558
// and thus requires an `Unpin` bound.
559-
if binding_mode == ByRef::Yes(Pinnedness::Not, Mutability::Mut) {
559+
if matches!(binding_mode, ByRef::Yes(Pinnedness::Not, _)) {
560560
self.register_bound(
561561
inner_ty,
562562
self.tcx.require_lang_item(hir::LangItem::Unpin, pat.span),
@@ -2681,9 +2681,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26812681
expected = self.try_structurally_resolve_type(pat.span, expected);
26822682
// Determine whether we're consuming an inherited reference and resetting the default
26832683
// binding mode, based on edition and enabled experimental features.
2684-
// FIXME(pin_ergonomics): since `&pin` pattern is supported, the condition here
2685-
// should be adjusted to `pat_pin == inh_pin`
2686-
if let ByRef::Yes(Pinnedness::Not, inh_mut) = pat_info.binding_mode {
2684+
if let ByRef::Yes(inh_pin, inh_mut) = pat_info.binding_mode
2685+
// FIXME(pin_ergonomics): since `&pin` pattern is supported, the condition here
2686+
// should be adjusted to `pat_pin == inh_pin`
2687+
&& (!self.tcx.features().pin_ergonomics() || inh_pin == Pinnedness::Not)
2688+
{
26872689
match self.ref_pat_matches_inherited_ref(pat.span.edition()) {
26882690
InheritedRefMatchRule::EatOuter => {
26892691
// ref pattern attempts to consume inherited reference
@@ -2702,22 +2704,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
27022704
return expected;
27032705
}
27042706
InheritedRefMatchRule::EatInner => {
2705-
let expected_ref_or_pinned_ref = || {
2706-
if self.tcx.features().pin_ergonomics()
2707-
&& let Some(ty::Ref(_, _, r_mutbl)) =
2708-
expected.pinned_ty().map(|ty| *ty.kind())
2709-
&& pat_mutbl <= r_mutbl
2710-
{
2711-
return Some((Pinnedness::Pinned, r_mutbl));
2712-
}
2713-
if let ty::Ref(_, _, r_mutbl) = *expected.kind()
2714-
&& pat_mutbl <= r_mutbl
2715-
{
2716-
return Some((Pinnedness::Not, r_mutbl));
2717-
}
2718-
None
2719-
};
2720-
if let Some((_, r_mutbl)) = expected_ref_or_pinned_ref() {
2707+
if let ty::Ref(_, _, r_mutbl) = *expected.kind()
2708+
&& pat_mutbl <= r_mutbl
2709+
{
27212710
// Match against the reference type; don't consume the inherited ref.
27222711
// NB: The check for compatible pattern and ref type mutability assumes that
27232712
// `&` patterns can match against mutable references (RFC 3627, Rule 5). If
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
error[E0507]: cannot move out of a shared reference
2+
--> $DIR/pattern-matching-deref-pattern.rs:45:28
3+
|
4+
LL | let Foo { x, y } = foo.as_mut();
5+
| - - ^^^^^^^^^^^^
6+
| | |
7+
| | ...and here
8+
| data moved here
9+
|
10+
= note: move occurs because these variables have types that don't implement the `Copy` trait
11+
help: consider borrowing the pattern binding
12+
|
13+
LL | let Foo { ref x, y } = foo.as_mut();
14+
| +++
15+
help: consider borrowing the pattern binding
16+
|
17+
LL | let Foo { x, ref y } = foo.as_mut();
18+
| +++
19+
20+
error[E0507]: cannot move out of a shared reference
21+
--> $DIR/pattern-matching-deref-pattern.rs:35:24
22+
|
23+
LL | let Foo { x, y } = foo.as_mut();
24+
| - - ^^^^^^^^^^^^
25+
| | |
26+
| | ...and here
27+
| data moved here
28+
|
29+
= note: move occurs because these variables have types that don't implement the `Copy` trait
30+
help: consider borrowing the pattern binding
31+
|
32+
LL | let Foo { ref x, y } = foo.as_mut();
33+
| +++
34+
help: consider borrowing the pattern binding
35+
|
36+
LL | let Foo { x, ref y } = foo.as_mut();
37+
| +++
38+
39+
error[E0507]: cannot move out of a shared reference
40+
--> $DIR/pattern-matching-deref-pattern.rs:67:28
41+
|
42+
LL | let Foo { x, y } = foo.as_ref();
43+
| - - ^^^^^^^^^^^^
44+
| | |
45+
| | ...and here
46+
| data moved here
47+
|
48+
= note: move occurs because these variables have types that don't implement the `Copy` trait
49+
help: consider borrowing the pattern binding
50+
|
51+
LL | let Foo { ref x, y } = foo.as_ref();
52+
| +++
53+
help: consider borrowing the pattern binding
54+
|
55+
LL | let Foo { x, ref y } = foo.as_ref();
56+
| +++
57+
58+
error[E0507]: cannot move out of a shared reference
59+
--> $DIR/pattern-matching-deref-pattern.rs:57:24
60+
|
61+
LL | let Foo { x, y } = foo.as_ref();
62+
| - - ^^^^^^^^^^^^
63+
| | |
64+
| | ...and here
65+
| data moved here
66+
|
67+
= note: move occurs because these variables have types that don't implement the `Copy` trait
68+
help: consider borrowing the pattern binding
69+
|
70+
LL | let Foo { ref x, y } = foo.as_ref();
71+
| +++
72+
help: consider borrowing the pattern binding
73+
|
74+
LL | let Foo { x, ref y } = foo.as_ref();
75+
| +++
76+
77+
error[E0507]: cannot move out of a shared reference
78+
--> $DIR/pattern-matching-deref-pattern.rs:89:25
79+
|
80+
LL | let Bar(x, y) = bar.as_mut();
81+
| - - ^^^^^^^^^^^^
82+
| | |
83+
| | ...and here
84+
| data moved here
85+
|
86+
= note: move occurs because these variables have types that don't implement the `Copy` trait
87+
help: consider borrowing the pattern binding
88+
|
89+
LL | let Bar(ref x, y) = bar.as_mut();
90+
| +++
91+
help: consider borrowing the pattern binding
92+
|
93+
LL | let Bar(x, ref y) = bar.as_mut();
94+
| +++
95+
96+
error[E0507]: cannot move out of a shared reference
97+
--> $DIR/pattern-matching-deref-pattern.rs:79:21
98+
|
99+
LL | let Bar(x, y) = bar.as_mut();
100+
| - - ^^^^^^^^^^^^
101+
| | |
102+
| | ...and here
103+
| data moved here
104+
|
105+
= note: move occurs because these variables have types that don't implement the `Copy` trait
106+
help: consider borrowing the pattern binding
107+
|
108+
LL | let Bar(ref x, y) = bar.as_mut();
109+
| +++
110+
help: consider borrowing the pattern binding
111+
|
112+
LL | let Bar(x, ref y) = bar.as_mut();
113+
| +++
114+
115+
error[E0507]: cannot move out of a shared reference
116+
--> $DIR/pattern-matching-deref-pattern.rs:111:25
117+
|
118+
LL | let Bar(x, y) = bar.as_ref();
119+
| - - ^^^^^^^^^^^^
120+
| | |
121+
| | ...and here
122+
| data moved here
123+
|
124+
= note: move occurs because these variables have types that don't implement the `Copy` trait
125+
help: consider borrowing the pattern binding
126+
|
127+
LL | let Bar(ref x, y) = bar.as_ref();
128+
| +++
129+
help: consider borrowing the pattern binding
130+
|
131+
LL | let Bar(x, ref y) = bar.as_ref();
132+
| +++
133+
134+
error[E0507]: cannot move out of a shared reference
135+
--> $DIR/pattern-matching-deref-pattern.rs:101:21
136+
|
137+
LL | let Bar(x, y) = bar.as_ref();
138+
| - - ^^^^^^^^^^^^
139+
| | |
140+
| | ...and here
141+
| data moved here
142+
|
143+
= note: move occurs because these variables have types that don't implement the `Copy` trait
144+
help: consider borrowing the pattern binding
145+
|
146+
LL | let Bar(ref x, y) = bar.as_ref();
147+
| +++
148+
help: consider borrowing the pattern binding
149+
|
150+
LL | let Bar(x, ref y) = bar.as_ref();
151+
| +++
152+
153+
error: aborting due to 8 previous errors
154+
155+
For more information about this error, try `rustc --explain E0507`.

tests/ui/pin-ergonomics/pattern-matching-deref-pattern.rs

Lines changed: 70 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
//@ revisions: pin_ergonomics normal
22
//@ edition:2024
3-
//@ check-pass
4-
// //@[normal] check-pass
5-
// //@[pin_ergonomics] rustc-env:RUSTC_LOG=rustc_hir_typeck::expr_use_visitor=DEBUG
3+
//@[pin_ergonomics] check-pass
64
#![cfg_attr(pin_ergonomics, feature(pin_ergonomics))]
75
#![feature(deref_patterns)]
86
#![allow(incomplete_features)]
@@ -24,67 +22,99 @@ enum Baz<T, U> {
2422
Bar { x: T, y: U },
2523
}
2624

27-
fn foo_mut<T: Unpin, U: Unpin>(foo: Pin<&mut Foo<T, U>>) {
28-
let Foo { .. } = foo;
29-
let Pin { .. } = foo;
30-
let _ = || {
31-
let Foo { .. } = foo;
32-
let Pin { .. } = foo;
33-
};
25+
trait IsPinMut {}
26+
trait IsPinConst {}
27+
impl<T: ?Sized> IsPinMut for Pin<&mut T> {}
28+
impl<T: ?Sized> IsPinConst for Pin<&T> {}
3429

30+
fn assert_pin_mut<T: IsPinMut>(_: T) {}
31+
fn assert_pin_const<T: IsPinConst>(_: T) {}
32+
33+
fn foo_mut<T: Unpin, U: Unpin>(mut foo: Pin<&mut Foo<T, U>>) {
34+
let Foo { .. } = foo.as_mut();
35+
let Foo { x, y } = foo.as_mut();
36+
//[normal]~^ ERROR cannot move out of a shared reference
3537
#[cfg(pin_ergonomics)]
36-
let Foo { x, y } = foo;
38+
assert_pin_mut(x);
3739
#[cfg(pin_ergonomics)]
40+
assert_pin_mut(y);
41+
let Pin { .. } = foo.as_mut();
42+
3843
let _ = || {
39-
let Foo { x, y } = foo;
44+
let Foo { .. } = foo.as_mut();
45+
let Foo { x, y } = foo.as_mut();
46+
//[normal]~^ ERROR cannot move out of a shared reference
47+
#[cfg(pin_ergonomics)]
48+
assert_pin_mut(x);
49+
#[cfg(pin_ergonomics)]
50+
assert_pin_mut(y);
51+
let Pin { .. } = foo.as_mut();
4052
};
4153
}
4254

4355
fn foo_const<T: Unpin, U: Unpin>(foo: Pin<&Foo<T, U>>) {
44-
let Foo { .. } = foo;
45-
let Pin { .. } = foo;
46-
let _ = || {
47-
let Foo { .. } = foo;
48-
let Pin { .. } = foo;
49-
};
50-
56+
let Foo { .. } = foo.as_ref();
57+
let Foo { x, y } = foo.as_ref();
58+
//[normal]~^ ERROR cannot move out of a shared reference
5159
#[cfg(pin_ergonomics)]
52-
let Foo { x, y } = foo;
60+
assert_pin_const(x);
5361
#[cfg(pin_ergonomics)]
54-
let _ = || {
55-
let Foo { x, y } = foo;
56-
};
57-
}
62+
assert_pin_const(y);
63+
let Pin { .. } = foo.as_ref();
5864

59-
fn bar_mut<T: Unpin, U: Unpin>(bar: Pin<&mut Bar<T, U>>) {
60-
let Bar(..) = bar;
61-
let Pin { .. } = bar;
6265
let _ = || {
63-
let Bar(..) = bar;
64-
let Pin { .. } = bar;
66+
let Foo { .. } = foo.as_ref();
67+
let Foo { x, y } = foo.as_ref();
68+
//[normal]~^ ERROR cannot move out of a shared reference
69+
#[cfg(pin_ergonomics)]
70+
assert_pin_const(x);
71+
#[cfg(pin_ergonomics)]
72+
assert_pin_const(y);
73+
let Pin { .. } = foo.as_ref();
6574
};
75+
}
6676

77+
fn bar_mut<T: Unpin, U: Unpin>(mut bar: Pin<&mut Bar<T, U>>) {
78+
let Bar(..) = bar.as_mut();
79+
let Bar(x, y) = bar.as_mut();
80+
//[normal]~^ ERROR cannot move out of a shared reference
6781
#[cfg(pin_ergonomics)]
68-
let Bar(x, y) = bar;
82+
assert_pin_mut(x);
6983
#[cfg(pin_ergonomics)]
84+
assert_pin_mut(y);
85+
let Pin { .. } = bar.as_mut();
86+
7087
let _ = || {
71-
let Bar(x, y) = bar;
88+
let Bar(..) = bar.as_mut();
89+
let Bar(x, y) = bar.as_mut();
90+
//[normal]~^ ERROR cannot move out of a shared reference
91+
#[cfg(pin_ergonomics)]
92+
assert_pin_mut(x);
93+
#[cfg(pin_ergonomics)]
94+
assert_pin_mut(y);
95+
let Pin { .. } = bar.as_mut();
7296
};
7397
}
7498

7599
fn bar_const<T: Unpin, U: Unpin>(bar: Pin<&Bar<T, U>>) {
76-
let Bar(..) = bar;
77-
let Pin { .. } = bar;
78-
let _ = || {
79-
let Bar(..) = bar;
80-
let Pin { .. } = bar;
81-
};
82-
100+
let Bar(..) = bar.as_ref();
101+
let Bar(x, y) = bar.as_ref();
102+
//[normal]~^ ERROR cannot move out of a shared reference
83103
#[cfg(pin_ergonomics)]
84-
let Bar(x, y) = bar;
104+
assert_pin_const(x);
85105
#[cfg(pin_ergonomics)]
106+
assert_pin_const(y);
107+
let Pin { .. } = bar.as_ref();
108+
86109
let _ = || {
87-
let Bar(x, y) = bar;
110+
let Bar(..) = bar.as_ref();
111+
let Bar(x, y) = bar.as_ref();
112+
//[normal]~^ ERROR cannot move out of a shared reference
113+
#[cfg(pin_ergonomics)]
114+
assert_pin_const(x);
115+
#[cfg(pin_ergonomics)]
116+
assert_pin_const(y);
117+
let Pin { .. } = bar.as_ref();
88118
};
89119
}
90120

0 commit comments

Comments
 (0)