diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 715b82183a7..53d1ac7b024 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -380,23 +380,59 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let PatKind::Binding(..) = inner.node { let parent_id = tcx.hir().get_parent_node_by_hir_id(pat.hir_id); let parent = tcx.hir().get_by_hir_id(parent_id); + debug!("inner {:?} pat {:?} parent {:?}", inner, pat, parent); match parent { - hir::Node::Item(_) | - hir::Node::ForeignItem(_) | - hir::Node::TraitItem(_) | - hir::Node::ImplItem(_) => { // this pat is an argument + hir::Node::Item(hir::Item { + node: hir::ItemKind::Fn(..), .. + }) | + hir::Node::ForeignItem(hir::ForeignItem { + node: hir::ForeignItemKind::Fn(..), .. + }) | + hir::Node::TraitItem(hir::TraitItem { + node: hir::TraitItemKind::Method(..), .. + }) | + hir::Node::ImplItem(hir::ImplItem { + node: hir::ImplItemKind::Method(..), .. + }) => { // this pat is likely an argument if let Ok(snippet) = tcx.sess.source_map() - .span_to_snippet(pat.span) + .span_to_snippet(inner.span) { // FIXME: turn into structured suggestion, will need - // a span that also includes the the type. + // a span that also includes the the arg's type. err.help(&format!( "did you mean `{}: &{}`?", - &snippet[1..], + snippet, expected, )); } } - _ => {} // don't provide the suggestion from above #55175 + hir::Node::Expr(hir::Expr { + node: hir::ExprKind::Match(..), .. + }) => { // rely on match ergonomics + if let Ok(snippet) = tcx.sess.source_map() + .span_to_snippet(inner.span) + { + err.span_suggestion( + pat.span, + "you can rely on match ergonomics and remove \ + the explicit borrow", + snippet, + Applicability::MaybeIncorrect, + ); + } + } + hir::Node::Pat(_) => { // nested `&&pat` + if let Ok(snippet) = tcx.sess.source_map() + .span_to_snippet(inner.span) + { + err.span_suggestion( + pat.span, + "you can probaly remove the explicit borrow", + snippet, + Applicability::MaybeIncorrect, + ); + } + } + _ => {} // don't provide suggestions in other cases #55175 } } err.emit(); diff --git a/src/test/ui/destructure-trait-ref.stderr b/src/test/ui/destructure-trait-ref.stderr index 7f389299afb..47ecadfd01a 100644 --- a/src/test/ui/destructure-trait-ref.stderr +++ b/src/test/ui/destructure-trait-ref.stderr @@ -20,7 +20,10 @@ error[E0308]: mismatched types --> $DIR/destructure-trait-ref.rs:31:10 | LL | let &&x = &1isize as &T; - | ^^ expected trait T, found reference + | ^^ + | | + | expected trait T, found reference + | help: you can probaly remove the explicit borrow: `x` | = note: expected type `dyn T` found type `&_` @@ -29,7 +32,10 @@ error[E0308]: mismatched types --> $DIR/destructure-trait-ref.rs:36:11 | LL | let &&&x = &(&1isize as &T); - | ^^ expected trait T, found reference + | ^^ + | | + | expected trait T, found reference + | help: you can probaly remove the explicit borrow: `x` | = note: expected type `dyn T` found type `&_` diff --git a/src/test/ui/mismatched_types/issue-38371.stderr b/src/test/ui/mismatched_types/issue-38371.stderr index 30da48ba4a8..833b8998c33 100644 --- a/src/test/ui/mismatched_types/issue-38371.stderr +++ b/src/test/ui/mismatched_types/issue-38371.stderr @@ -12,7 +12,10 @@ error[E0308]: mismatched types --> $DIR/issue-38371.rs:18:9 | LL | fn agh(&&bar: &u32) { - | ^^^^ expected u32, found reference + | ^^^^ + | | + | expected u32, found reference + | help: you can probaly remove the explicit borrow: `bar` | = note: expected type `u32` found type `&_`