Skip to content

Commit 34bc3c9

Browse files
committed
Display secondary span for E0053 for Mutability TypeErrors
1 parent 3c4ecc9 commit 34bc3c9

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

src/librustc_typeck/check/compare_method.rs

+28
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,34 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
338338
};
339339

340340
let (impl_err_span, trait_err_span) = match terr {
341+
TypeError::Mutability => {
342+
if let Some(trait_m_node_id) = tcx.map.as_local_node_id(trait_m.def_id) {
343+
let trait_m_iter = match tcx.map.expect_trait_item(trait_m_node_id).node {
344+
TraitItem_::MethodTraitItem(ref trait_m_sig, _) =>
345+
trait_m_sig.decl.inputs.iter(),
346+
_ => bug!("{:?} is not a MethodTraitItem", trait_m)
347+
};
348+
349+
impl_m_iter.zip(trait_m_iter).find(|&(ref impl_arg, ref trait_arg)| {
350+
match (&impl_arg.ty.node, &trait_arg.ty.node) {
351+
(&Ty_::TyRptr(_, ref impl_mt), &Ty_::TyRptr(_, ref trait_mt)) |
352+
(&Ty_::TyPtr(ref impl_mt), &Ty_::TyPtr(ref trait_mt)) =>
353+
impl_mt.mutbl != trait_mt.mutbl,
354+
_ => false
355+
}
356+
}).map(|(ref impl_arg, ref trait_arg)| {
357+
match (impl_arg.to_self(), trait_arg.to_self()) {
358+
(Some(impl_self), Some(trait_self)) =>
359+
(impl_self.span, Some(trait_self.span)),
360+
(None, None) => (impl_arg.ty.span, Some(trait_arg.ty.span)),
361+
_ => bug!("impl and trait fns have different first args, \
362+
impl: {:?}, trait: {:?}", impl_arg, trait_arg)
363+
}
364+
}).unwrap_or((origin.span(), tcx.map.span_if_local(trait_m.def_id)))
365+
} else {
366+
(origin.span(), tcx.map.span_if_local(trait_m.def_id))
367+
}
368+
}
341369
TypeError::Sorts(ExpectedFound { expected, found }) => {
342370
if let Some(trait_m_node_id) = tcx.map.as_local_node_id(trait_m.def_id) {
343371
let trait_m_iter = match tcx.map.expect_trait_item(trait_m_node_id).node {

src/test/compile-fail/E0053.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,21 @@
99
// except according to those terms.
1010

1111
trait Foo {
12-
fn foo(x: u16);
13-
fn bar(&self);
12+
fn foo(x: u16); //~ NOTE original trait requirement
13+
fn bar(&self); //~ NOTE original trait requirement
1414
}
1515

1616
struct Bar;
1717

1818
impl Foo for Bar {
19-
fn foo(x: i16) { } //~ ERROR E0053
20-
fn bar(&mut self) { } //~ ERROR E0053
19+
fn foo(x: i16) { }
20+
//~^ ERROR method `foo` has an incompatible type for trait
21+
//~| NOTE expected u16
22+
fn bar(&mut self) { }
23+
//~^ ERROR method `bar` has an incompatible type for trait
24+
//~| NOTE values differ in mutability
25+
//~| NOTE expected type `fn(&Bar)`
26+
//~| NOTE found type `fn(&mut Bar)`
2127
}
2228

2329
fn main() {

0 commit comments

Comments
 (0)