Skip to content

Commit 90cd3d3

Browse files
Rollup merge of rust-lang#156087 - P8L1:improve-pin-pattern-suggestions, r=Kivooeo
Improve `&pin` reference-pattern suggestions This fills in the `pin_ergonomics` FIXME in `borrow_pat_suggestion` by making the diagnostic prefix account for both `Pinnedness` and `Mutability`. Previously, the type-position suggestion path used ordinary reference spelling, which can spell `&` and `&mut` but cannot correctly spell pinned reference-pattern suggestions such as `&pin const` and `&pin mut`. This is a diagnostic-only change. It adds focused UI coverage for both pinned const and pinned mut reference-pattern suggestions.
2 parents 7a08b69 + 14d414b commit 90cd3d3

4 files changed

Lines changed: 73 additions & 2 deletions

File tree

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13521352
}
13531353

13541354
/// Precondition: pat is a `Ref(_)` pattern
1355-
// FIXME(pin_ergonomics): add suggestions for `&pin mut` or `&pin const` patterns
13561355
fn borrow_pat_suggestion(&self, err: &mut Diag<'_>, pat: &Pat<'_>) {
13571356
let tcx = self.tcx;
13581357
if let PatKind::Ref(inner, pinned, mutbl) = pat.kind
@@ -1407,14 +1406,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14071406
};
14081407

14091408
match binding_parent {
1409+
hir::Node::Param(hir::Param { ty_span, pat, .. })
1410+
if pat.span != *ty_span
1411+
&& pinned.is_pinned()
1412+
&& !tcx.features().pin_ergonomics() =>
1413+
{
1414+
// FIXME(pin_ergonomics): Once `pin_ergonomics` is stabilized, remove this
1415+
// gate and allow the pinned reference type-position suggestion unconditionally.
1416+
}
14101417
// Check that there is explicit type (ie this is not a closure param with inferred type)
14111418
// so we don't suggest moving something to the type that does not exist
14121419
hir::Node::Param(hir::Param { ty_span, pat, .. }) if pat.span != *ty_span => {
14131420
err.multipart_suggestion(
14141421
format!("to take parameter `{binding}` by reference, move `&{pin_and_mut}` to the type"),
14151422
vec![
14161423
(pat.span.until(inner.span), "".to_owned()),
1417-
(ty_span.shrink_to_lo(), mutbl.ref_prefix_str().to_owned()),
1424+
(ty_span.shrink_to_lo(), format!("&{}", pinned.prefix_str(mutbl))),
14181425
],
14191426
Applicability::MachineApplicable
14201427
);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ run-rustfix
2+
3+
#![feature(pin_ergonomics)]
4+
#![allow(unused)]
5+
6+
fn pin_mut_param(x: &pin mut i32) {}
7+
//~^ ERROR mismatched types
8+
9+
fn pin_const_param(x: &pin const i32) {}
10+
//~^ ERROR mismatched types
11+
12+
fn main() {}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ run-rustfix
2+
3+
#![feature(pin_ergonomics)]
4+
#![allow(unused)]
5+
6+
fn pin_mut_param(&pin mut x: i32) {}
7+
//~^ ERROR mismatched types
8+
9+
fn pin_const_param(&pin const x: i32) {}
10+
//~^ ERROR mismatched types
11+
12+
fn main() {}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/ref-pat-suggestions.rs:6:18
3+
|
4+
LL | fn pin_mut_param(&pin mut x: i32) {}
5+
| ^^^^^^^^^^ --- expected due to this
6+
| |
7+
| expected `i32`, found `Pin<&mut _>`
8+
|
9+
= note: expected type `i32`
10+
found struct `Pin<&mut _>`
11+
note: to declare a mutable parameter use: `mut x`
12+
--> $DIR/ref-pat-suggestions.rs:6:18
13+
|
14+
LL | fn pin_mut_param(&pin mut x: i32) {}
15+
| ^^^^^^^^^^
16+
help: to take parameter `x` by reference, move `&pin mut` to the type
17+
|
18+
LL - fn pin_mut_param(&pin mut x: i32) {}
19+
LL + fn pin_mut_param(x: &pin mut i32) {}
20+
|
21+
22+
error[E0308]: mismatched types
23+
--> $DIR/ref-pat-suggestions.rs:9:20
24+
|
25+
LL | fn pin_const_param(&pin const x: i32) {}
26+
| ^^^^^^^^^^^^ --- expected due to this
27+
| |
28+
| expected `i32`, found `Pin<&_>`
29+
|
30+
= note: expected type `i32`
31+
found struct `Pin<&_>`
32+
help: to take parameter `x` by reference, move `&pin const` to the type
33+
|
34+
LL - fn pin_const_param(&pin const x: i32) {}
35+
LL + fn pin_const_param(x: &pin const i32) {}
36+
|
37+
38+
error: aborting due to 2 previous errors
39+
40+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)