Skip to content

Commit 346088b

Browse files
Ariel Ben-Yehudaarielb1
Ariel Ben-Yehuda
authored andcommitted
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
1 parent fe6ad09 commit 346088b

File tree

4 files changed

+45
-3
lines changed

4 files changed

+45
-3
lines changed

src/librustc/middle/traits/error_reporting.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ use middle::def_id::DefId;
2828
use middle::infer::InferCtxt;
2929
use middle::ty::{self, ToPredicate, HasTypeFlags, ToPolyTraitRef, TraitRef, Ty};
3030
use middle::ty::fold::TypeFoldable;
31-
use std::collections::HashMap;
31+
use util::nodemap::{FnvHashMap, FnvHashSet};
32+
3233
use std::fmt;
3334
use syntax::codemap::Span;
3435
use syntax::attr::{AttributeMethods, AttrMetaMethods};
@@ -124,7 +125,7 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
124125
(gen.name.as_str().to_string(),
125126
trait_ref.substs.types.get(param, i)
126127
.to_string())
127-
}).collect::<HashMap<String, String>>();
128+
}).collect::<FnvHashMap<String, String>>();
128129
generic_map.insert("Self".to_string(),
129130
trait_ref.self_ty().to_string());
130131
let parser = Parser::new(&istring);
@@ -335,7 +336,11 @@ pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
335336
"the trait `{}` cannot be made into an object",
336337
tcx.item_path_str(trait_def_id));
337338

339+
let mut reported_violations = FnvHashSet();
338340
for violation in violations {
341+
if !reported_violations.insert(violation.clone()) {
342+
continue;
343+
}
339344
match violation {
340345
ObjectSafetyViolation::SizedSelf => {
341346
tcx.sess.fileline_note(

src/librustc/middle/traits/object_safety.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use middle::ty::{self, ToPolyTraitRef, Ty};
2727
use std::rc::Rc;
2828
use syntax::ast;
2929

30-
#[derive(Debug)]
30+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
3131
pub enum ObjectSafetyViolation<'tcx> {
3232
/// Self : Sized declared on the trait
3333
SizedSelf,

src/librustc/middle/ty/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,20 @@ impl<'tcx> Method<'tcx> {
272272
}
273273
}
274274

275+
impl<'tcx> PartialEq for Method<'tcx> {
276+
#[inline]
277+
fn eq(&self, other: &Self) -> bool { self.def_id == other.def_id }
278+
}
279+
280+
impl<'tcx> Eq for Method<'tcx> {}
281+
282+
impl<'tcx> Hash for Method<'tcx> {
283+
#[inline]
284+
fn hash<H: Hasher>(&self, s: &mut H) {
285+
self.def_id.hash(s)
286+
}
287+
}
288+
275289
#[derive(Clone, Copy, Debug)]
276290
pub struct AssociatedConst<'tcx> {
277291
pub name: Name,

src/test/compile-fail/issue-20692.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
trait Array: Sized {}
12+
13+
fn f<T: Array>(x: &T) {
14+
let _ = x
15+
//~^ ERROR `Array` cannot be made into an object
16+
//~| NOTE the trait cannot require that `Self : Sized`
17+
as
18+
&Array;
19+
//~^ ERROR `Array` cannot be made into an object
20+
//~| NOTE the trait cannot require that `Self : Sized`
21+
}
22+
23+
fn main() {}

0 commit comments

Comments
 (0)