From fc166d44f02c1d7baa20e2ae2ef20b599cd99ecf Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Fri, 25 Sep 2015 02:40:57 +0300 Subject: [PATCH] show each object-safety violation once different supertraits can suffer from the same object-safety violation, leading to duplication in the error message. Avoid it. Fixes #20692 --- src/librustc/middle/traits/error_reporting.rs | 9 ++++++-- src/librustc/middle/traits/object_safety.rs | 2 +- src/librustc/middle/ty/mod.rs | 14 +++++++++++ src/test/compile-fail/issue-20692.rs | 23 +++++++++++++++++++ 4 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 src/test/compile-fail/issue-20692.rs diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index ce71ba2ff2e7..4580e642d17d 100644 --- a/src/librustc/middle/traits/error_reporting.rs +++ b/src/librustc/middle/traits/error_reporting.rs @@ -28,7 +28,8 @@ use middle::def_id::DefId; use middle::infer::InferCtxt; use middle::ty::{self, ToPredicate, HasTypeFlags, ToPolyTraitRef, TraitRef, Ty}; use middle::ty::fold::TypeFoldable; -use std::collections::HashMap; +use util::nodemap::{FnvHashMap, FnvHashSet}; + use std::fmt; use syntax::codemap::Span; use rustc_front::attr::{AttributeMethods, AttrMetaMethods}; @@ -124,7 +125,7 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, (gen.name.as_str().to_string(), trait_ref.substs.types.get(param, i) .to_string()) - }).collect::>(); + }).collect::>(); generic_map.insert("Self".to_string(), trait_ref.self_ty().to_string()); let parser = Parser::new(&istring); @@ -329,7 +330,11 @@ pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>, "the trait `{}` cannot be made into an object", tcx.item_path_str(trait_def_id)); + let mut reported_violations = FnvHashSet(); for violation in object_safety_violations(tcx, trait_def_id) { + if !reported_violations.insert(violation.clone()) { + continue; + } match violation { ObjectSafetyViolation::SizedSelf => { tcx.sess.fileline_note( diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs index 3a2602cd5b44..333d23e6eca8 100644 --- a/src/librustc/middle/traits/object_safety.rs +++ b/src/librustc/middle/traits/object_safety.rs @@ -27,7 +27,7 @@ use middle::ty::{self, ToPolyTraitRef, Ty}; use std::rc::Rc; use syntax::ast; -#[derive(Debug)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum ObjectSafetyViolation<'tcx> { /// Self : Sized declared on the trait SizedSelf, diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs index a8adb3886442..4a96260ec1e7 100644 --- a/src/librustc/middle/ty/mod.rs +++ b/src/librustc/middle/ty/mod.rs @@ -272,6 +272,20 @@ impl<'tcx> Method<'tcx> { } } +impl<'tcx> PartialEq for Method<'tcx> { + #[inline] + fn eq(&self, other: &Self) -> bool { self.def_id == other.def_id } +} + +impl<'tcx> Eq for Method<'tcx> {} + +impl<'tcx> Hash for Method<'tcx> { + #[inline] + fn hash(&self, s: &mut H) { + self.def_id.hash(s) + } +} + #[derive(Clone, Copy, Debug)] pub struct AssociatedConst<'tcx> { pub name: Name, diff --git a/src/test/compile-fail/issue-20692.rs b/src/test/compile-fail/issue-20692.rs new file mode 100644 index 000000000000..62d775adac3c --- /dev/null +++ b/src/test/compile-fail/issue-20692.rs @@ -0,0 +1,23 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Array: Sized {} + +fn f(x: &T) { + let _ = x + //~^ ERROR `Array` cannot be made into an object + //~| NOTE the trait cannot require that `Self : Sized` + as + &Array; + //~^ ERROR `Array` cannot be made into an object + //~| NOTE the trait cannot require that `Self : Sized` +} + +fn main() {}