Rollup merge of #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.
This commit is contained in:
Guillaume Gomez
2026-05-05 02:50:10 +02:00
committed by GitHub
4 changed files with 73 additions and 2 deletions
+9 -2
View File
@@ -1352,7 +1352,6 @@ fn suggest_adding_missing_ref_or_removing_ref(
}
/// Precondition: pat is a `Ref(_)` pattern
// FIXME(pin_ergonomics): add suggestions for `&pin mut` or `&pin const` patterns
fn borrow_pat_suggestion(&self, err: &mut Diag<'_>, pat: &Pat<'_>) {
let tcx = self.tcx;
if let PatKind::Ref(inner, pinned, mutbl) = pat.kind
@@ -1407,6 +1406,14 @@ fn borrow_pat_suggestion(&self, err: &mut Diag<'_>, pat: &Pat<'_>) {
};
match binding_parent {
hir::Node::Param(hir::Param { ty_span, pat, .. })
if pat.span != *ty_span
&& pinned.is_pinned()
&& !tcx.features().pin_ergonomics() =>
{
// FIXME(pin_ergonomics): Once `pin_ergonomics` is stabilized, remove this
// gate and allow the pinned reference type-position suggestion unconditionally.
}
// Check that there is explicit type (ie this is not a closure param with inferred type)
// so we don't suggest moving something to the type that does not exist
hir::Node::Param(hir::Param { ty_span, pat, .. }) if pat.span != *ty_span => {
@@ -1414,7 +1421,7 @@ fn borrow_pat_suggestion(&self, err: &mut Diag<'_>, pat: &Pat<'_>) {
format!("to take parameter `{binding}` by reference, move `&{pin_and_mut}` to the type"),
vec![
(pat.span.until(inner.span), "".to_owned()),
(ty_span.shrink_to_lo(), mutbl.ref_prefix_str().to_owned()),
(ty_span.shrink_to_lo(), format!("&{}", pinned.prefix_str(mutbl))),
],
Applicability::MachineApplicable
);
@@ -0,0 +1,12 @@
//@ run-rustfix
#![feature(pin_ergonomics)]
#![allow(unused)]
fn pin_mut_param(x: &pin mut i32) {}
//~^ ERROR mismatched types
fn pin_const_param(x: &pin const i32) {}
//~^ ERROR mismatched types
fn main() {}
@@ -0,0 +1,12 @@
//@ run-rustfix
#![feature(pin_ergonomics)]
#![allow(unused)]
fn pin_mut_param(&pin mut x: i32) {}
//~^ ERROR mismatched types
fn pin_const_param(&pin const x: i32) {}
//~^ ERROR mismatched types
fn main() {}
@@ -0,0 +1,40 @@
error[E0308]: mismatched types
--> $DIR/ref-pat-suggestions.rs:6:18
|
LL | fn pin_mut_param(&pin mut x: i32) {}
| ^^^^^^^^^^ --- expected due to this
| |
| expected `i32`, found `Pin<&mut _>`
|
= note: expected type `i32`
found struct `Pin<&mut _>`
note: to declare a mutable parameter use: `mut x`
--> $DIR/ref-pat-suggestions.rs:6:18
|
LL | fn pin_mut_param(&pin mut x: i32) {}
| ^^^^^^^^^^
help: to take parameter `x` by reference, move `&pin mut` to the type
|
LL - fn pin_mut_param(&pin mut x: i32) {}
LL + fn pin_mut_param(x: &pin mut i32) {}
|
error[E0308]: mismatched types
--> $DIR/ref-pat-suggestions.rs:9:20
|
LL | fn pin_const_param(&pin const x: i32) {}
| ^^^^^^^^^^^^ --- expected due to this
| |
| expected `i32`, found `Pin<&_>`
|
= note: expected type `i32`
found struct `Pin<&_>`
help: to take parameter `x` by reference, move `&pin const` to the type
|
LL - fn pin_const_param(&pin const x: i32) {}
LL + fn pin_const_param(x: &pin const i32) {}
|
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.