use syntax::ast;
use syntax::codemap;
use syntax::codemap::{Span, DUMMY_SP};
-use util::nodemap::{FnvHashMap, NodeMap};
+use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap};
use self::combine::CombineFields;
use self::region_inference::{RegionVarBindings, RegionSnapshot};
pub fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
+ // the set of predicates on which errors have been reported, to
+ // avoid reporting the same error twice.
+ pub reported_trait_errors: RefCell<FnvHashSet<traits::TraitErrorKey<'tcx>>>,
+
// This is a temporary field used for toggling on normalization in the inference context,
// as we move towards the approach described here:
// https://internals.rust-lang.org/t/flattening-the-contexts-for-fun-and-profit/2293
region_vars: RegionVarBindings::new(tcx),
parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()),
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(errors_will_be_reported)),
+ reported_trait_errors: RefCell::new(FnvHashSet()),
normalize: false,
err_count_on_creation: tcx.sess.err_count()
}
use syntax::codemap::Span;
use syntax::attr::{AttributeMethods, AttrMetaMethods};
+#[derive(Debug, PartialEq, Eq, Hash)]
+pub struct TraitErrorKey<'tcx> {
+ is_warning: bool,
+ span: Span,
+ predicate: ty::Predicate<'tcx>
+}
+
+impl<'tcx> TraitErrorKey<'tcx> {
+ fn from_error<'a>(infcx: &InferCtxt<'a, 'tcx>,
+ e: &FulfillmentError<'tcx>) -> Self {
+ let predicate =
+ infcx.resolve_type_vars_if_possible(&e.obligation.predicate);
+ TraitErrorKey {
+ is_warning: is_warning(&e.obligation),
+ span: e.obligation.cause.span,
+ predicate: infcx.tcx.erase_regions(&predicate)
+ }
+ }
+}
+
pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
errors: &Vec<FulfillmentError<'tcx>>) {
for error in errors {
fn report_fulfillment_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
error: &FulfillmentError<'tcx>) {
+ let error_key = TraitErrorKey::from_error(infcx, error);
+ debug!("report_fulfillment_errors({:?}) - key={:?}",
+ error, error_key);
+ if !infcx.reported_trait_errors.borrow_mut().insert(error_key) {
+ debug!("report_fulfillment_errors: skipping duplicate");
+ return;
+ }
match error.code {
FulfillmentErrorCode::CodeSelectionError(ref e) => {
report_selection_error(infcx, &error.obligation, e);
// than the `SelectionCache`: it avoids duplicate errors and
// permits recursive obligations, which are often generated from
// traits like `Send` et al.
+ //
+ // Note that because of type inference, a predicate can still
+ // occur twice in the predicates list, for example when 2
+ // initially-distinct type variables are unified after being
+ // inserted. Deduplicating the predicate set on selection had a
+ // significant performance cost the last time I checked.
duplicate_set: FulfilledPredicates<'tcx>,
// A list of all obligations that have been registered with this
use middle::ty::{self, HasTypeFlags, Ty};
use middle::ty::fold::TypeFoldable;
use middle::infer::{self, fixup_err_to_string, InferCtxt};
+
use std::rc::Rc;
use syntax::ast;
use syntax::codemap::{Span, DUMMY_SP};
+pub use self::error_reporting::TraitErrorKey;
pub use self::error_reporting::report_fulfillment_errors;
pub use self::error_reporting::report_overflow_error;
pub use self::error_reporting::report_selection_error;
let r = loop {};
r = r + a;
//~^ ERROR not implemented
- //~| ERROR not implemented
}
pub fn f1_uint_uint() {
f1(2u32, 4u32);
//~^ ERROR the trait `Foo` is not implemented
- //~| ERROR the trait `Foo` is not implemented
}
pub fn f1_uint_int() {
fn main() {
let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
//~^ ERROR E0277
- //~| ERROR E0277
}
: [u32; (i8::MAX as i8 + 1u8) as usize]
//~^ ERROR mismatched types
//~| the trait `core::ops::Add<u8>` is not implemented for the type `i8`
- //~| the trait `core::ops::Add<u8>` is not implemented for the type `i8`
= [0; (i8::MAX as usize) + 1];
fn main() {
fn foo<T:fmt::Debug>(x: T) {
println!("{:?}", x);
}
-
apply(&3, takes_imm);
apply(&3, takes_mut);
//~^ ERROR (values differ in mutability)
- //~| ERROR (values differ in mutability)
apply(&mut 3, takes_mut);
apply(&mut 3, takes_imm);
//~^ ERROR (values differ in mutability)
- //~| ERROR (values differ in mutability)
}
y: 2,
};
for x in bogus { //~ ERROR `core::iter::Iterator` is not implemented for the type `MyStruct`
- //~^ ERROR
- //~^^ ERROR
- // FIXME(#21528) not fulfilled obligation error should be reported once, not thrice
drop(x);
}
}
fn main() {
fn bar<T>(_: T) {}
[0][0u8]; //~ ERROR: the trait `core::ops::Index<u8>` is not implemented
- //~^ ERROR: the trait `core::ops::Index<u8>` is not implemented
[0][0]; // should infer to be a usize
v[3_usize];
v[3];
v[3u8]; //~ERROR the trait `core::ops::Index<u8>` is not implemented
- //~^ ERROR the trait `core::ops::Index<u8>` is not implemented
v[3i8]; //~ERROR the trait `core::ops::Index<i8>` is not implemented
- //~^ ERROR the trait `core::ops::Index<i8>` is not implemented
v[3u32]; //~ERROR the trait `core::ops::Index<u32>` is not implemented
- //~^ ERROR the trait `core::ops::Index<u32>` is not implemented
v[3i32]; //~ERROR the trait `core::ops::Index<i32>` is not implemented
- //~^ ERROR the trait `core::ops::Index<i32>` is not implemented
s.as_bytes()[3_usize];
s.as_bytes()[3];
s.as_bytes()[3u8]; //~ERROR the trait `core::ops::Index<u8>` is not implemented
- //~^ ERROR the trait `core::ops::Index<u8>` is not implemented
s.as_bytes()[3i8]; //~ERROR the trait `core::ops::Index<i8>` is not implemented
- //~^ ERROR the trait `core::ops::Index<i8>` is not implemented
s.as_bytes()[3u32]; //~ERROR the trait `core::ops::Index<u32>` is not implemented
- //~^ ERROR the trait `core::ops::Index<u32>` is not implemented
s.as_bytes()[3i32]; //~ERROR the trait `core::ops::Index<i32>` is not implemented
- //~^ ERROR the trait `core::ops::Index<i32>` is not implemented
}
let x = ();
1 +
x //~^ ERROR E0277
- //~| ERROR E0277
;
let x: () = ();
1 +
x //~^ ERROR E0277
- //~| ERROR E0277
;
}
});
2_usize + (loop {});
//~^ ERROR E0277
- //~| ERROR E0277
}
fn main() {
in () { 0 };
//~^ ERROR: the trait `core::ops::Placer<_>` is not implemented
- //~| ERROR: the trait `core::ops::Placer<_>` is not implemented
}
fn changer<'a>(mut things: Box<Iterator<Item=&'a mut u8>>) {
for item in *things { *item = 0 }
//~^ ERROR the trait `core::marker::Sized` is not implemented for the type `core::iter::Iterator
-//~^^ ERROR
-//~^^^ ERROR
-// FIXME(#21528) error should be reported once, not thrice
}
fn main() {}
let mut r = panic!();
for elt in self { r = r + f(*elt); }
//~^ ERROR E0277
- //~| ERROR E0277
}
}
fn main() {
fn main() {
let b = Bob + 3.5;
b + 3 //~ ERROR: is not implemented
- //~^ ERROR: is not implemented
- //~^^ ERROR: is not implemented
- //~^^^ ERROR: mismatched types
+ //~^ ERROR: mismatched types
}
fn main() {
1.0f64 - 1.0;
1.0f64 - 1 //~ ERROR: is not implemented
- //~^ ERROR: is not implemented
}
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ let _ = Iterator::next(&mut ());
+ //~^ ERROR the trait `core::iter::Iterator` is not implemented
+
+ for _ in false {}
+ //~^ ERROR the trait `core::iter::Iterator` is not implemented
+
+ let _ = Iterator::next(&mut ());
+ //~^ ERROR the trait `core::iter::Iterator` is not implemented
+
+ other()
+}
+
+pub fn other() {
+ // check errors are still reported globally
+
+ let _ = Iterator::next(&mut ());
+ //~^ ERROR the trait `core::iter::Iterator` is not implemented
+
+ let _ = Iterator::next(&mut ());
+ //~^ ERROR the trait `core::iter::Iterator` is not implemented
+
+ for _ in false {}
+ //~^ ERROR the trait `core::iter::Iterator` is not implemented
+}
fn foo(p: &Panolpy) {
22 >> p.char;
//~^ ERROR E0277
- //~| ERROR E0277
22 >> p.str;
//~^ ERROR E0277
- //~| ERROR E0277
22 >> p;
//~^ ERROR E0277
- //~| ERROR E0277
let x;
22 >> x; // ambiguity error winds up being suppressed
pub fn main() {
let s: &str = "hello";
let c: u8 = s[4]; //~ ERROR the trait `core::ops::Index<_>` is not implemented
- //~^ ERROR the trait `core::ops::Index<_>` is not implemented
}
s[1usize] = bot();
//~^ ERROR `core::ops::Index<usize>` is not implemented for the type `str`
//~| ERROR `core::ops::IndexMut<usize>` is not implemented for the type `str`
- //~| ERROR `core::ops::Index<usize>` is not implemented for the type `str`
}
pub fn main() {}
fn c() {
let z = call_it_once(square, 22);
//~^ ERROR not implemented
- //~| ERROR not implemented
}
fn main() { }
fn c() {
let z = call_it_once(square, 22);
//~^ ERROR not implemented
- //~| ERROR not implemented
}
fn main() { }
fn c() {
let z = call_it_once(square, 22);
//~^ ERROR not implemented
- //~| ERROR not implemented
}
fn main() { }