diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2017-01-10 14:45:30 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2017-01-10 14:47:58 -0500 |
| commit | 59d7d4c80ef94ec5b001ffe1a8bac40694c50c3f (patch) | |
| tree | 7063a25edd98023f4f9a6f3d2f6bd8c2e13a22a4 /src | |
| parent | 563ecc1b1fe8f8daea20910a23b7090411cf2de8 (diff) | |
only emit suggestion to move `&` if the inner pattern is a binding
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_typeck/check/_match.rs | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index f05c9a00be2..f7fd78097b8 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -30,10 +30,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.check_pat_arg(pat, expected, false); } + /// The `is_arg` argument indicates whether this pattern is the + /// *outermost* pattern in an argument (e.g., in `fn foo(&x: + /// &u32)`, it is true for the `&x` pattern but not `x`). This is + /// used to tailor error reporting. pub fn check_pat_arg(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>, is_arg: bool) { let tcx = self.tcx; - debug!("check_pat(pat={:?},expected={:?})", pat, expected); + debug!("check_pat(pat={:?},expected={:?},is_arg={})", pat, expected, is_arg); let ty = match pat.node { PatKind::Wild => { @@ -206,6 +210,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // can, to avoid creating needless variables. This // also helps with the bad interactions of the given // hack detailed in (*) below. + debug!("check_pat_arg: expected={:?}", expected); let (rptr_ty, inner_ty) = match expected.sty { ty::TyRef(_, mt) if mt.mutbl == mutbl => { (expected, mt.ty) @@ -216,15 +221,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl }; let region = self.next_region_var(infer::PatternRegion(pat.span)); let rptr_ty = tcx.mk_ref(region, mt); + debug!("check_pat_arg: demanding {:?} = {:?}", expected, rptr_ty); let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty); + + // Look for a case like `fn foo(&foo: u32)` and suggest + // `fn foo(foo: &u32)` if let Some(mut err) = err { if is_arg { - if let Ok(snippet) = self.sess().codemap() - .span_to_snippet(pat.span) - { - err.help(&format!("did you mean `{}: &{}`?", - &snippet[1..], - expected)); + if let PatKind::Binding(..) = inner.node { + if let Ok(snippet) = self.sess().codemap() + .span_to_snippet(pat.span) + { + err.help(&format!("did you mean `{}: &{}`?", + &snippet[1..], + expected)); + } } } err.emit(); |
