From 607f60712c7c9d3b96a162d2605a89ff2554fc7e Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Tue, 23 Dec 2014 10:57:44 +0100 Subject: [PATCH] Keep track of the whole error chain --- src/librustc/middle/traits/select.rs | 6 ++++- src/libsyntax/ext/deriving/bounds.rs | 7 ++++-- src/test/compile-fail/deriving-bounds.rs | 6 ++++- .../compile-fail/issue-17718-static-sync.rs | 2 +- src/test/compile-fail/issue-7013.rs | 1 + src/test/compile-fail/issue-7364.rs | 4 +++- .../compile-fail/kindck-destructor-owned.rs | 13 ----------- src/test/compile-fail/kindck-nonsendable-1.rs | 4 +++- src/test/compile-fail/kindck-send-unsafe.rs | 9 ++++---- src/test/compile-fail/mut-not-freeze.rs | 5 ++++- src/test/compile-fail/no-send-res-ports.rs | 1 + src/test/compile-fail/no_send-rc.rs | 1 + src/test/compile-fail/no_share-rc.rs | 1 + .../compile-fail/regions-bounded-by-send.rs | 22 +++++++++---------- .../compile-fail/task-rng-isnt-sendable.rs | 1 + .../typeck-unsafe-always-share.rs | 3 +++ src/test/compile-fail/unique-unique-kind.rs | 4 +++- src/test/compile-fail/unsendable-class.rs | 4 +++- src/test/run-pass/deriving-bounds.rs | 2 +- .../issue-17718-static-unsafe-interior.rs | 20 ++++++++++------- 20 files changed, 67 insertions(+), 49 deletions(-) diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index fe9ef3346791..d09287dbf927 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -1928,6 +1928,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + #[allow(unused_comparisons)] fn derived_cause(&self, obligation: &TraitObligation<'tcx>, variant: fn(Rc>>, @@ -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(), diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs index c27a27fce6a9..cf29bb048d64 100644 --- a/src/libsyntax/ext/deriving/bounds.rs +++ b/src/libsyntax/ext/deriving/bounds.rs @@ -26,8 +26,11 @@ pub fn expand_deriving_bound(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 \ diff --git a/src/test/compile-fail/deriving-bounds.rs b/src/test/compile-fail/deriving-bounds.rs index 1f9bd881afe2..d61ad98ee1e5 100644 --- a/src/test/compile-fail/deriving-bounds.rs +++ b/src/test/compile-fail/deriving-bounds.rs @@ -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() {} diff --git a/src/test/compile-fail/issue-17718-static-sync.rs b/src/test/compile-fail/issue-17718-static-sync.rs index 2304b18adb63..63a40e2374b1 100644 --- a/src/test/compile-fail/issue-17718-static-sync.rs +++ b/src/test/compile-fail/issue-17718-static-sync.rs @@ -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() {} diff --git a/src/test/compile-fail/issue-7013.rs b/src/test/compile-fail/issue-7013.rs index bef8ca6b86cb..a8a699d62d5e 100644 --- a/src/test/compile-fail/issue-7013.rs +++ b/src/test/compile-fail/issue-7013.rs @@ -33,4 +33,5 @@ struct A { fn main() { let a = A {v: box B{v: None} as Box}; //~^ ERROR the trait `core::kinds::Send` is not implemented + //~^^ ERROR the trait `core::kinds::Send` is not implemented } diff --git a/src/test/compile-fail/issue-7364.rs b/src/test/compile-fail/issue-7364.rs index 7f0d9ef3b11e..2646edd7684e 100644 --- a/src/test/compile-fail/issue-7364.rs +++ b/src/test/compile-fail/issue-7364.rs @@ -14,6 +14,8 @@ use std::cell::RefCell; // Regresion test for issue 7364 static boxed: Box> = 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() { } diff --git a/src/test/compile-fail/kindck-destructor-owned.rs b/src/test/compile-fail/kindck-destructor-owned.rs index 1a82a2b3832c..803da617abdc 100644 --- a/src/test/compile-fail/kindck-destructor-owned.rs +++ b/src/test/compile-fail/kindck-destructor-owned.rs @@ -9,19 +9,6 @@ // except according to those terms. -use std::rc::Rc; - -struct Foo { - f: Rc, -} - -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, } diff --git a/src/test/compile-fail/kindck-nonsendable-1.rs b/src/test/compile-fail/kindck-nonsendable-1.rs index c96054afc2f3..fdd8584a8bb0 100644 --- a/src/test/compile-fail/kindck-nonsendable-1.rs +++ b/src/test/compile-fail/kindck-nonsendable-1.rs @@ -17,6 +17,8 @@ fn bar(_: 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 } diff --git a/src/test/compile-fail/kindck-send-unsafe.rs b/src/test/compile-fail/kindck-send-unsafe.rs index 33314149d1fa..4e1641025d5a 100644 --- a/src/test/compile-fail/kindck-send-unsafe.rs +++ b/src/test/compile-fail/kindck-send-unsafe.rs @@ -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() { } -// 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() { diff --git a/src/test/compile-fail/mut-not-freeze.rs b/src/test/compile-fail/mut-not-freeze.rs index 60921c041356..4b058f6fdb34 100644 --- a/src/test/compile-fail/mut-not-freeze.rs +++ b/src/test/compile-fail/mut-not-freeze.rs @@ -14,5 +14,8 @@ fn f(_: 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 } diff --git a/src/test/compile-fail/no-send-res-ports.rs b/src/test/compile-fail/no-send-res-ports.rs index e1ba36de7c03..48747c7ce1da 100644 --- a/src/test/compile-fail/no-send-res-ports.rs +++ b/src/test/compile-fail/no-send-res-ports.rs @@ -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); }); diff --git a/src/test/compile-fail/no_send-rc.rs b/src/test/compile-fail/no_send-rc.rs index c05b17afe1d2..004921b1db0d 100644 --- a/src/test/compile-fail/no_send-rc.rs +++ b/src/test/compile-fail/no_send-rc.rs @@ -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 } diff --git a/src/test/compile-fail/no_share-rc.rs b/src/test/compile-fail/no_share-rc.rs index 5572f72d8fe8..ac3b456def52 100644 --- a/src/test/compile-fail/no_share-rc.rs +++ b/src/test/compile-fail/no_share-rc.rs @@ -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 } diff --git a/src/test/compile-fail/regions-bounded-by-send.rs b/src/test/compile-fail/regions-bounded-by-send.rs index 67655f323f06..e15cb25295aa 100644 --- a/src/test/compile-fail/regions-bounded-by-send.rs +++ b/src/test/compile-fail/regions-bounded-by-send.rs @@ -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() { } -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::(); } fn main() { diff --git a/src/test/compile-fail/task-rng-isnt-sendable.rs b/src/test/compile-fail/task-rng-isnt-sendable.rs index e9997083babd..d96599404deb 100644 --- a/src/test/compile-fail/task-rng-isnt-sendable.rs +++ b/src/test/compile-fail/task-rng-isnt-sendable.rs @@ -17,4 +17,5 @@ fn test_send() {} pub fn main() { test_send::(); //~^ ERROR `core::kinds::Send` is not implemented + //~^^ ERROR `core::kinds::Send` is not implemented } diff --git a/src/test/compile-fail/typeck-unsafe-always-share.rs b/src/test/compile-fail/typeck-unsafe-always-share.rs index 7c74cdc890d8..a7911eb791eb 100644 --- a/src/test/compile-fail/typeck-unsafe-always-share.rs +++ b/src/test/compile-fail/typeck-unsafe-always-share.rs @@ -30,12 +30,15 @@ fn test(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); diff --git a/src/test/compile-fail/unique-unique-kind.rs b/src/test/compile-fail/unique-unique-kind.rs index 4c2805bf4bd0..48d5028f4357 100644 --- a/src/test/compile-fail/unique-unique-kind.rs +++ b/src/test/compile-fail/unique-unique-kind.rs @@ -16,5 +16,7 @@ fn f(_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 } diff --git a/src/test/compile-fail/unsendable-class.rs b/src/test/compile-fail/unsendable-class.rs index d988a245700f..cd5918e2f47f 100644 --- a/src/test/compile-fail/unsendable-class.rs +++ b/src/test/compile-fail/unsendable-class.rs @@ -28,6 +28,8 @@ fn foo(i:int, j: Rc) -> 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))); } diff --git a/src/test/run-pass/deriving-bounds.rs b/src/test/run-pass/deriving-bounds.rs index d120b8030c1c..0bf27cfbb241 100644 --- a/src/test/run-pass/deriving-bounds.rs +++ b/src/test/run-pass/deriving-bounds.rs @@ -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() {} diff --git a/src/test/run-pass/issue-17718-static-unsafe-interior.rs b/src/test/run-pass/issue-17718-static-unsafe-interior.rs index a25632b33768..0851f0e367bf 100644 --- a/src/test/run-pass/issue-17718-static-unsafe-interior.rs +++ b/src/test/run-pass/issue-17718-static-unsafe-interior.rs @@ -11,30 +11,34 @@ use std::kinds::marker; use std::cell::UnsafeCell; +struct MyUnsafePack(UnsafeCell); + +unsafe impl Sync for MyUnsafePack {} + struct MyUnsafe { - value: UnsafeCell + value: MyUnsafePack } impl MyUnsafe { fn forbidden(&self) {} } -impl Sync for MyUnsafe {} +unsafe impl Sync for MyUnsafe {} enum UnsafeEnum { VariantSafe, VariantUnsafe(UnsafeCell) } -impl Sync for UnsafeEnum {} +unsafe impl Sync for UnsafeEnum {} static STATIC1: UnsafeEnum = UnsafeEnum::VariantSafe; -static STATIC2: UnsafeCell = UnsafeCell { value: 1 }; -const CONST: UnsafeCell = UnsafeCell { value: 1 }; +static STATIC2: MyUnsafePack = MyUnsafePack(UnsafeCell { value: 1 }); +const CONST: MyUnsafePack = MyUnsafePack(UnsafeCell { value: 1 }); static STATIC3: MyUnsafe = MyUnsafe{value: CONST}; -static STATIC4: &'static UnsafeCell = &STATIC2; +static STATIC4: &'static MyUnsafePack = &STATIC2; struct Wrap { value: T @@ -42,8 +46,8 @@ struct Wrap { unsafe impl Sync for Wrap {} -static UNSAFE: UnsafeCell = UnsafeCell{value: 1}; -static WRAPPED_UNSAFE: Wrap<&'static UnsafeCell> = Wrap { value: &UNSAFE }; +static UNSAFE: MyUnsafePack = MyUnsafePack(UnsafeCell{value: 2}); +static WRAPPED_UNSAFE: Wrap<&'static MyUnsafePack> = Wrap { value: &UNSAFE }; fn main() { let a = &STATIC1;