From 34bc3c94f2639c16d3c009026e4b0e1d1a83d9a2 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Wed, 17 Aug 2016 04:04:14 -0700 Subject: [PATCH] Display secondary span for E0053 for Mutability TypeErrors --- src/librustc_typeck/check/compare_method.rs | 28 +++++++++++++++++++++ src/test/compile-fail/E0053.rs | 14 ++++++++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 93badd98130..043883df035 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -338,6 +338,34 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }; let (impl_err_span, trait_err_span) = match terr { + TypeError::Mutability => { + if let Some(trait_m_node_id) = tcx.map.as_local_node_id(trait_m.def_id) { + let trait_m_iter = match tcx.map.expect_trait_item(trait_m_node_id).node { + TraitItem_::MethodTraitItem(ref trait_m_sig, _) => + trait_m_sig.decl.inputs.iter(), + _ => bug!("{:?} is not a MethodTraitItem", trait_m) + }; + + impl_m_iter.zip(trait_m_iter).find(|&(ref impl_arg, ref trait_arg)| { + match (&impl_arg.ty.node, &trait_arg.ty.node) { + (&Ty_::TyRptr(_, ref impl_mt), &Ty_::TyRptr(_, ref trait_mt)) | + (&Ty_::TyPtr(ref impl_mt), &Ty_::TyPtr(ref trait_mt)) => + impl_mt.mutbl != trait_mt.mutbl, + _ => false + } + }).map(|(ref impl_arg, ref trait_arg)| { + match (impl_arg.to_self(), trait_arg.to_self()) { + (Some(impl_self), Some(trait_self)) => + (impl_self.span, Some(trait_self.span)), + (None, None) => (impl_arg.ty.span, Some(trait_arg.ty.span)), + _ => bug!("impl and trait fns have different first args, \ + impl: {:?}, trait: {:?}", impl_arg, trait_arg) + } + }).unwrap_or((origin.span(), tcx.map.span_if_local(trait_m.def_id))) + } else { + (origin.span(), tcx.map.span_if_local(trait_m.def_id)) + } + } TypeError::Sorts(ExpectedFound { expected, found }) => { if let Some(trait_m_node_id) = tcx.map.as_local_node_id(trait_m.def_id) { let trait_m_iter = match tcx.map.expect_trait_item(trait_m_node_id).node { diff --git a/src/test/compile-fail/E0053.rs b/src/test/compile-fail/E0053.rs index 4effda3c49e..7022010714a 100644 --- a/src/test/compile-fail/E0053.rs +++ b/src/test/compile-fail/E0053.rs @@ -9,15 +9,21 @@ // except according to those terms. trait Foo { - fn foo(x: u16); - fn bar(&self); + fn foo(x: u16); //~ NOTE original trait requirement + fn bar(&self); //~ NOTE original trait requirement } struct Bar; impl Foo for Bar { - fn foo(x: i16) { } //~ ERROR E0053 - fn bar(&mut self) { } //~ ERROR E0053 + fn foo(x: i16) { } + //~^ ERROR method `foo` has an incompatible type for trait + //~| NOTE expected u16 + fn bar(&mut self) { } + //~^ ERROR method `bar` has an incompatible type for trait + //~| NOTE values differ in mutability + //~| NOTE expected type `fn(&Bar)` + //~| NOTE found type `fn(&mut Bar)` } fn main() {