From 802b5431b197189110a291d14ad1e323fec39877 Mon Sep 17 00:00:00 2001 From: trixnz Date: Fri, 5 Aug 2016 20:05:57 +0200 Subject: [PATCH] Update error format for E0326 --- src/librustc_typeck/check/compare_method.rs | 24 ++++++++++++++++++- .../associated-const-impl-wrong-type.rs | 4 ++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 9844377d0bd32..cc8af0ffa2b13 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -14,6 +14,8 @@ use rustc::ty; use rustc::traits::{self, ProjectionMode}; use rustc::ty::error::ExpectedFound; use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace}; +use rustc::hir::map::Node; +use rustc::hir::{ImplItemKind, TraitItem_}; use syntax::ast; use syntax_pos::Span; @@ -447,7 +449,7 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // Compute skolemized form of impl and trait const tys. let impl_ty = impl_c.ty.subst(tcx, impl_to_skol_substs); let trait_ty = trait_c.ty.subst(tcx, &trait_to_skol_substs); - let origin = TypeOrigin::Misc(impl_c_span); + let mut origin = TypeOrigin::Misc(impl_c_span); let err = infcx.commit_if_ok(|_| { // There is no "body" here, so just pass dummy id. @@ -482,11 +484,31 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, debug!("checking associated const for compatibility: impl ty {:?}, trait ty {:?}", impl_ty, trait_ty); + + // Locate the Span containing just the type of the offending impl + if let Some(impl_trait_node) = tcx.map.get_if_local(impl_c.def_id) { + if let Node::NodeImplItem(impl_trait_item) = impl_trait_node { + if let ImplItemKind::Const(ref ty, _) = impl_trait_item.node { + origin = TypeOrigin::Misc(ty.span); + } + } + } + let mut diag = struct_span_err!( tcx.sess, origin.span(), E0326, "implemented const `{}` has an incompatible type for trait", trait_c.name ); + + // Add a label to the Span containing just the type of the item + if let Some(orig_trait_node) = tcx.map.get_if_local(trait_c.def_id) { + if let Node::NodeTraitItem(orig_trait_item) = orig_trait_node { + if let TraitItem_::ConstTraitItem(ref ty, _) = orig_trait_item.node { + diag.span_label(ty.span, &format!("original trait requirement")); + } + } + } + infcx.note_type_err( &mut diag, origin, Some(infer::ValuePairs::Types(ExpectedFound { diff --git a/src/test/compile-fail/associated-const-impl-wrong-type.rs b/src/test/compile-fail/associated-const-impl-wrong-type.rs index 95508a31044b8..b3776091682da 100644 --- a/src/test/compile-fail/associated-const-impl-wrong-type.rs +++ b/src/test/compile-fail/associated-const-impl-wrong-type.rs @@ -11,7 +11,7 @@ #![feature(associated_consts)] trait Foo { - const BAR: u32; + const BAR: u32; //~ NOTE original trait requirement } struct SignedBar; @@ -19,7 +19,7 @@ struct SignedBar; impl Foo for SignedBar { const BAR: i32 = -1; //~^ ERROR implemented const `BAR` has an incompatible type for trait [E0326] - //~| expected u32, found i32 + //~| NOTE expected u32, found i32 } fn main() {}