|
1 | 1 | use crate::check::{FnCtxt, Expectation, Diverges, Needs};
|
2 | 2 | use crate::check::coercion::CoerceMany;
|
3 | 3 | use crate::util::nodemap::FxHashMap;
|
4 |
| -use errors::Applicability; |
5 |
| -use rustc::hir::{self, PatKind}; |
| 4 | +use errors::{Applicability, DiagnosticBuilder}; |
| 5 | +use rustc::hir::{self, PatKind, Pat}; |
6 | 6 | use rustc::hir::def::{Def, CtorKind};
|
7 | 7 | use rustc::hir::pat_util::EnumerateAndAdjustIterator;
|
8 | 8 | use rustc::infer;
|
@@ -377,64 +377,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
377 | 377 | // Look for a case like `fn foo(&foo: u32)` and suggest
|
378 | 378 | // `fn foo(foo: &u32)`
|
379 | 379 | if let Some(mut err) = err {
|
380 |
| - if let PatKind::Binding(..) = inner.node { |
381 |
| - let parent_id = tcx.hir().get_parent_node_by_hir_id(pat.hir_id); |
382 |
| - let parent = tcx.hir().get_by_hir_id(parent_id); |
383 |
| - debug!("inner {:?} pat {:?} parent {:?}", inner, pat, parent); |
384 |
| - match parent { |
385 |
| - hir::Node::Item(hir::Item { |
386 |
| - node: hir::ItemKind::Fn(..), .. |
387 |
| - }) | |
388 |
| - hir::Node::ForeignItem(hir::ForeignItem { |
389 |
| - node: hir::ForeignItemKind::Fn(..), .. |
390 |
| - }) | |
391 |
| - hir::Node::TraitItem(hir::TraitItem { |
392 |
| - node: hir::TraitItemKind::Method(..), .. |
393 |
| - }) | |
394 |
| - hir::Node::ImplItem(hir::ImplItem { |
395 |
| - node: hir::ImplItemKind::Method(..), .. |
396 |
| - }) => { // this pat is likely an argument |
397 |
| - if let Ok(snippet) = tcx.sess.source_map() |
398 |
| - .span_to_snippet(inner.span) |
399 |
| - { // FIXME: turn into structured suggestion, will need |
400 |
| - // a span that also includes the the arg's type. |
401 |
| - err.help(&format!( |
402 |
| - "did you mean `{}: &{}`?", |
403 |
| - snippet, |
404 |
| - expected, |
405 |
| - )); |
406 |
| - } |
407 |
| - } |
408 |
| - hir::Node::Expr(hir::Expr { |
409 |
| - node: hir::ExprKind::Match(..), .. |
410 |
| - }) => { // rely on match ergonomics |
411 |
| - if let Ok(snippet) = tcx.sess.source_map() |
412 |
| - .span_to_snippet(inner.span) |
413 |
| - { |
414 |
| - err.span_suggestion( |
415 |
| - pat.span, |
416 |
| - "you can rely on match ergonomics and remove \ |
417 |
| - the explicit borrow", |
418 |
| - snippet, |
419 |
| - Applicability::MaybeIncorrect, |
420 |
| - ); |
421 |
| - } |
422 |
| - } |
423 |
| - hir::Node::Pat(_) => { // nested `&&pat` |
424 |
| - if let Ok(snippet) = tcx.sess.source_map() |
425 |
| - .span_to_snippet(inner.span) |
426 |
| - { |
427 |
| - err.span_suggestion( |
428 |
| - pat.span, |
429 |
| - "you can probaly remove the explicit borrow", |
430 |
| - snippet, |
431 |
| - Applicability::MaybeIncorrect, |
432 |
| - ); |
433 |
| - } |
434 |
| - } |
435 |
| - _ => {} // don't provide suggestions in other cases #55175 |
436 |
| - } |
437 |
| - } |
| 380 | + self.borrow_pat_suggestion(&mut err, &pat, &inner, &expected); |
438 | 381 | err.emit();
|
439 | 382 | }
|
440 | 383 | (rptr_ty, inner_ty)
|
@@ -566,6 +509,59 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
566 | 509 | // subtyping.
|
567 | 510 | }
|
568 | 511 |
|
| 512 | + fn borrow_pat_suggestion( |
| 513 | + &self, |
| 514 | + err: &mut DiagnosticBuilder<'_>, |
| 515 | + pat: &Pat, |
| 516 | + inner: &Pat, |
| 517 | + expected: &Ty<'tcx>, |
| 518 | + ) { |
| 519 | + let tcx = self.tcx; |
| 520 | + if let PatKind::Binding(..) = inner.node { |
| 521 | + let parent_id = tcx.hir().get_parent_node_by_hir_id(pat.hir_id); |
| 522 | + let parent = tcx.hir().get_by_hir_id(parent_id); |
| 523 | + debug!("inner {:?} pat {:?} parent {:?}", inner, pat, parent); |
| 524 | + match parent { |
| 525 | + hir::Node::Item(hir::Item { node: hir::ItemKind::Fn(..), .. }) | |
| 526 | + hir::Node::ForeignItem(hir::ForeignItem { |
| 527 | + node: hir::ForeignItemKind::Fn(..), .. |
| 528 | + }) | |
| 529 | + hir::Node::TraitItem(hir::TraitItem { node: hir::TraitItemKind::Method(..), .. }) | |
| 530 | + hir::Node::ImplItem(hir::ImplItem { node: hir::ImplItemKind::Method(..), .. }) => { |
| 531 | + // this pat is likely an argument |
| 532 | + if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) { |
| 533 | + // FIXME: turn into structured suggestion, will need a span that also |
| 534 | + // includes the the arg's type. |
| 535 | + err.help(&format!("did you mean `{}: &{}`?", snippet, expected)); |
| 536 | + } |
| 537 | + } |
| 538 | + hir::Node::Expr(hir::Expr { node: hir::ExprKind::Match(..), .. }) => { |
| 539 | + // rely on match ergonomics |
| 540 | + if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) { |
| 541 | + err.span_suggestion( |
| 542 | + pat.span, |
| 543 | + "you can rely on match ergonomics and remove the explicit borrow", |
| 544 | + snippet, |
| 545 | + Applicability::MaybeIncorrect, |
| 546 | + ); |
| 547 | + } |
| 548 | + } |
| 549 | + hir::Node::Pat(_) => { |
| 550 | + // nested `&&pat` |
| 551 | + if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) { |
| 552 | + err.span_suggestion( |
| 553 | + pat.span, |
| 554 | + "you can probably remove the explicit borrow", |
| 555 | + snippet, |
| 556 | + Applicability::MaybeIncorrect, |
| 557 | + ); |
| 558 | + } |
| 559 | + } |
| 560 | + _ => {} // don't provide suggestions in other cases #55175 |
| 561 | + } |
| 562 | + } |
| 563 | + } |
| 564 | + |
569 | 565 | pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::Pat) -> bool {
|
570 | 566 | if let PatKind::Binding(..) = inner.node {
|
571 | 567 | if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) {
|
|
0 commit comments