Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1352,7 +1352,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

/// 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
Expand Down Expand Up @@ -1407,14 +1406,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};

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 => {
err.multipart_suggestion(
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
);
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/pin-ergonomics/ref-pat-suggestions.fixed
Original file line number Diff line number Diff line change
@@ -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() {}
12 changes: 12 additions & 0 deletions tests/ui/pin-ergonomics/ref-pat-suggestions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//@ run-rustfix

#![feature(pin_ergonomics)]
#![allow(unused)]
Comment thread
P8L1 marked this conversation as resolved.

fn pin_mut_param(&pin mut x: i32) {}
//~^ ERROR mismatched types

fn pin_const_param(&pin const x: i32) {}
//~^ ERROR mismatched types

fn main() {}
40 changes: 40 additions & 0 deletions tests/ui/pin-ergonomics/ref-pat-suggestions.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Loading