Keep track of the whole error chain
This commit is contained in:
parent
8818693496
commit
607f60712c
|
@ -1928,6 +1928,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unused_comparisons)]
|
||||
fn derived_cause(&self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
variant: fn(Rc<ty::Binder<ty::TraitRef<'tcx>>>,
|
||||
|
@ -1945,7 +1946,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
* reporting.
|
||||
*/
|
||||
|
||||
if obligation.recursion_depth == 0 {
|
||||
// NOTE(flaper87): As of now, it keeps track of the whole error
|
||||
// chain. Ideally, we should have a way to configure this either
|
||||
// by using -Z verbose or just a CLI argument.
|
||||
if obligation.recursion_depth >= 0 {
|
||||
ObligationCause::new(obligation.cause.span,
|
||||
obligation.trait_ref.def_id().node,
|
||||
variant(obligation.trait_ref.clone(),
|
||||
|
|
|
@ -26,8 +26,11 @@ pub fn expand_deriving_bound<F>(cx: &mut ExtCtxt,
|
|||
MetaWord(ref tname) => {
|
||||
match tname.get() {
|
||||
"Copy" => "Copy",
|
||||
"Send" => "Send",
|
||||
"Sync" => "Sync",
|
||||
"Send" | "Sync" => {
|
||||
return cx.span_err(span,
|
||||
format!("{} is an unsafe trait and it \
|
||||
should be implemented explicitly", *tname)[])
|
||||
}
|
||||
ref tname => {
|
||||
cx.span_bug(span,
|
||||
format!("expected built-in trait name but \
|
||||
|
|
|
@ -8,8 +8,12 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[deriving(Sync(Bad),Send,Copy)]
|
||||
#[deriving(Copy(Bad))]
|
||||
//~^ ERROR unexpected value in deriving, expected a trait
|
||||
struct Test;
|
||||
|
||||
#[deriving(Sync)]
|
||||
//~^ ERROR Sync is an unsafe trait and it should be implemented explicitly
|
||||
struct Test1;
|
||||
|
||||
pub fn main() {}
|
||||
|
|
|
@ -14,6 +14,6 @@ struct Foo { marker: marker::NoSync }
|
|||
|
||||
static FOO: uint = 3;
|
||||
static BAR: Foo = Foo { marker: marker::NoSync };
|
||||
//~^ ERROR: shared static items must have a type which implements Sync
|
||||
//~^ ERROR: the trait `core::kinds::Sync` is not implemented
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -33,4 +33,5 @@ struct A {
|
|||
fn main() {
|
||||
let a = A {v: box B{v: None} as Box<Foo+Send>};
|
||||
//~^ ERROR the trait `core::kinds::Send` is not implemented
|
||||
//~^^ ERROR the trait `core::kinds::Send` is not implemented
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ use std::cell::RefCell;
|
|||
// Regresion test for issue 7364
|
||||
static boxed: Box<RefCell<int>> = box RefCell::new(0);
|
||||
//~^ ERROR statics are not allowed to have custom pointers
|
||||
//~^^ ERROR: shared static items must have a type which implements Sync
|
||||
//~^^ ERROR: the trait `core::kinds::Sync` is not implemented for the type
|
||||
//~^^^ ERROR: the trait `core::kinds::Sync` is not implemented for the type
|
||||
//~^^^^ ERROR: the trait `core::kinds::Sync` is not implemented for the type
|
||||
|
||||
fn main() { }
|
||||
|
|
|
@ -9,19 +9,6 @@
|
|||
// except according to those terms.
|
||||
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
struct Foo {
|
||||
f: Rc<int>,
|
||||
}
|
||||
|
||||
impl Drop for Foo {
|
||||
//~^ ERROR the trait `core::kinds::Send` is not implemented
|
||||
//~^^ NOTE cannot implement a destructor on a structure or enumeration that does not satisfy Send
|
||||
fn drop(&mut self) {
|
||||
}
|
||||
}
|
||||
|
||||
struct Bar<'a> {
|
||||
f: &'a int,
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ fn bar<F:FnOnce() + Send>(_: F) { }
|
|||
|
||||
fn main() {
|
||||
let x = Rc::new(3u);
|
||||
bar(move|| foo(x)); //~ ERROR `core::kinds::Send` is not implemented
|
||||
bar(move|| foo(x));
|
||||
//~^ ERROR `core::kinds::Send` is not implemented
|
||||
//~^^ ERROR `core::kinds::Send` is not implemented
|
||||
}
|
||||
|
||||
|
|
|
@ -8,14 +8,13 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate core;
|
||||
|
||||
fn assert_send<T:Send>() { }
|
||||
|
||||
// unsafe ptrs are ok unless they point at unsendable things
|
||||
fn test70() {
|
||||
assert_send::<*mut int>();
|
||||
}
|
||||
fn test71<'a>() {
|
||||
assert_send::<*mut &'a int>(); //~ ERROR declared lifetime bound not satisfied
|
||||
assert_send::<*mut &'a int>();
|
||||
//~^ ERROR the trait `core::kinds::Send` is not implemented for the type
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -14,5 +14,8 @@ fn f<T: Sync>(_: T) {}
|
|||
|
||||
fn main() {
|
||||
let x = RefCell::new(0i);
|
||||
f(x); //~ ERROR `core::kinds::Sync` is not implemented
|
||||
f(x);
|
||||
//~^ ERROR `core::kinds::Sync` is not implemented
|
||||
//~^^ ERROR `core::kinds::Sync` is not implemented
|
||||
//~^^^ ERROR `core::kinds::Sync` is not implemented
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ fn main() {
|
|||
|
||||
task::spawn(move|| {
|
||||
//~^ ERROR `core::kinds::Send` is not implemented
|
||||
//~^^ ERROR `core::kinds::Send` is not implemented
|
||||
let y = x;
|
||||
println!("{}", y);
|
||||
});
|
||||
|
|
|
@ -16,4 +16,5 @@ fn main() {
|
|||
let x = Rc::new(5i);
|
||||
bar(x);
|
||||
//~^ ERROR `core::kinds::Send` is not implemented
|
||||
//~^^ ERROR `core::kinds::Send` is not implemented
|
||||
}
|
||||
|
|
|
@ -17,4 +17,5 @@ fn main() {
|
|||
let x = Rc::new(RefCell::new(5i));
|
||||
bar(x);
|
||||
//~^ ERROR the trait `core::kinds::Sync` is not implemented
|
||||
//~^^ ERROR the trait `core::kinds::Sync` is not implemented
|
||||
}
|
||||
|
|
|
@ -12,8 +12,11 @@
|
|||
// in this file all test region bound and lifetime violations that are
|
||||
// detected during type check.
|
||||
|
||||
extern crate core;
|
||||
use core::ptr::Unique;
|
||||
|
||||
fn assert_send<T:Send>() { }
|
||||
trait Dummy { }
|
||||
trait Dummy:Send { }
|
||||
|
||||
// lifetime pointers with 'static lifetime are ok
|
||||
|
||||
|
@ -58,7 +61,7 @@ fn box_with_region_not_ok<'a>() {
|
|||
|
||||
fn object_with_random_bound_not_ok<'a>() {
|
||||
assert_send::<&'a (Dummy+'a)>();
|
||||
//~^ ERROR not implemented
|
||||
//~^ ERROR reference has a longer lifetime
|
||||
}
|
||||
|
||||
fn object_with_send_bound_not_ok<'a>() {
|
||||
|
@ -73,17 +76,12 @@ fn closure_with_lifetime_not_ok<'a>() {
|
|||
|
||||
// unsafe pointers are ok unless they point at unsendable things
|
||||
|
||||
struct UniqueUnsafePtr(Unique<*const int>);
|
||||
|
||||
unsafe impl Send for UniqueUnsafePtr {}
|
||||
|
||||
fn unsafe_ok1<'a>(_: &'a int) {
|
||||
assert_send::<*const int>();
|
||||
assert_send::<*mut int>();
|
||||
}
|
||||
|
||||
fn unsafe_ok2<'a>(_: &'a int) {
|
||||
assert_send::<*const &'a int>(); //~ ERROR declared lifetime bound not satisfied
|
||||
}
|
||||
|
||||
fn unsafe_ok3<'a>(_: &'a int) {
|
||||
assert_send::<*mut &'a int>(); //~ ERROR declared lifetime bound not satisfied
|
||||
assert_send::<UniqueUnsafePtr>();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -17,4 +17,5 @@ fn test_send<S: Send>() {}
|
|||
pub fn main() {
|
||||
test_send::<rand::TaskRng>();
|
||||
//~^ ERROR `core::kinds::Send` is not implemented
|
||||
//~^^ ERROR `core::kinds::Send` is not implemented
|
||||
}
|
||||
|
|
|
@ -30,12 +30,15 @@ fn test<T: Sync>(s: T){
|
|||
fn main() {
|
||||
let us = UnsafeCell::new(MySync{u: UnsafeCell::new(0i)});
|
||||
test(us);
|
||||
//~^ ERROR `core::kinds::Sync` is not implemented
|
||||
|
||||
let uns = UnsafeCell::new(NoSync{m: marker::NoSync});
|
||||
test(uns);
|
||||
//~^ ERROR `core::kinds::Sync` is not implemented
|
||||
|
||||
let ms = MySync{u: uns};
|
||||
test(ms);
|
||||
//~^ ERROR `core::kinds::Sync` is not implemented
|
||||
|
||||
let ns = NoSync{m: marker::NoSync};
|
||||
test(ns);
|
||||
|
|
|
@ -16,5 +16,7 @@ fn f<T:Send>(_i: T) {
|
|||
|
||||
fn main() {
|
||||
let i = box Rc::new(100i);
|
||||
f(i); //~ ERROR `core::kinds::Send` is not implemented
|
||||
f(i);
|
||||
//~^ ERROR `core::kinds::Send` is not implemented
|
||||
//~^^ ERROR `core::kinds::Send` is not implemented
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ fn foo(i:int, j: Rc<String>) -> foo {
|
|||
|
||||
fn main() {
|
||||
let cat = "kitty".to_string();
|
||||
let (tx, _) = channel(); //~ ERROR `core::kinds::Send` is not implemented
|
||||
let (tx, _) = channel();
|
||||
//~^ ERROR `core::kinds::Send` is not implemented
|
||||
//~^^ ERROR `core::kinds::Send` is not implemented
|
||||
tx.send(foo(42, Rc::new(cat)));
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[deriving(Sync,Send,Copy)]
|
||||
#[deriving(Copy)]
|
||||
struct Test;
|
||||
|
||||
pub fn main() {}
|
||||
|
|
|
@ -11,30 +11,34 @@
|
|||
use std::kinds::marker;
|
||||
use std::cell::UnsafeCell;
|
||||
|
||||
struct MyUnsafePack<T>(UnsafeCell<T>);
|
||||
|
||||
unsafe impl<T: Send> Sync for MyUnsafePack<T> {}
|
||||
|
||||
struct MyUnsafe<T> {
|
||||
value: UnsafeCell<T>
|
||||
value: MyUnsafePack<T>
|
||||
}
|
||||
|
||||
impl<T> MyUnsafe<T> {
|
||||
fn forbidden(&self) {}
|
||||
}
|
||||
|
||||
impl<T: Send> Sync for MyUnsafe<T> {}
|
||||
unsafe impl<T: Send> Sync for MyUnsafe<T> {}
|
||||
|
||||
enum UnsafeEnum<T> {
|
||||
VariantSafe,
|
||||
VariantUnsafe(UnsafeCell<T>)
|
||||
}
|
||||
|
||||
impl<T: Send> Sync for UnsafeEnum<T> {}
|
||||
unsafe impl<T: Send> Sync for UnsafeEnum<T> {}
|
||||
|
||||
static STATIC1: UnsafeEnum<int> = UnsafeEnum::VariantSafe;
|
||||
|
||||
static STATIC2: UnsafeCell<int> = UnsafeCell { value: 1 };
|
||||
const CONST: UnsafeCell<int> = UnsafeCell { value: 1 };
|
||||
static STATIC2: MyUnsafePack<int> = MyUnsafePack(UnsafeCell { value: 1 });
|
||||
const CONST: MyUnsafePack<int> = MyUnsafePack(UnsafeCell { value: 1 });
|
||||
static STATIC3: MyUnsafe<int> = MyUnsafe{value: CONST};
|
||||
|
||||
static STATIC4: &'static UnsafeCell<int> = &STATIC2;
|
||||
static STATIC4: &'static MyUnsafePack<int> = &STATIC2;
|
||||
|
||||
struct Wrap<T> {
|
||||
value: T
|
||||
|
@ -42,8 +46,8 @@ struct Wrap<T> {
|
|||
|
||||
unsafe impl<T: Send> Sync for Wrap<T> {}
|
||||
|
||||
static UNSAFE: UnsafeCell<int> = UnsafeCell{value: 1};
|
||||
static WRAPPED_UNSAFE: Wrap<&'static UnsafeCell<int>> = Wrap { value: &UNSAFE };
|
||||
static UNSAFE: MyUnsafePack<int> = MyUnsafePack(UnsafeCell{value: 2});
|
||||
static WRAPPED_UNSAFE: Wrap<&'static MyUnsafePack<int>> = Wrap { value: &UNSAFE };
|
||||
|
||||
fn main() {
|
||||
let a = &STATIC1;
|
||||
|
|
Loading…
Reference in New Issue