ReaderResult should be bounded by Sync
Currently `ReaderResult` has the bounds: ```rust unsafe impl<T, E> Sync for ReaderResult<T, E> where T: Send, E: Send, { } ``` However, I think this should be `T: Sync` and `E: Sync`, otherwise there is a potential soundness issue with references to `ReaderResult`. These will get marked as `Sync` because `ReaderResult` is `Sync` but allow the underlying non-Sync types to be accessed. Here's a demonstration of sending `Cell` across threads using this: ```rust use lexer::ReaderResult; use std::cell::Cell; use crossbeam_utils::thread; #[derive(Debug, Clone, Copy)] enum RefOrInt<'a> { Ref(&'a u64), Int(u64), } static SOME_INT: u64 = 123; fn main() { let reader_result : ReaderResult<_, ()> = ReaderResult::Some( Cell::new(RefOrInt::Ref(&SOME_INT))); thread::scope(|s| { let reader_result_ref = &reader_result; s.spawn(move |_| { let sent_ref = reader_result_ref; if let ReaderResult::Some(smuggled_cell) = sent_ref { loop { // Repeatedly write Ref(&addr) and Int(0xdeadbeef) into the cell. smuggled_cell.set(RefOrInt::Ref(&SOME_INT)); smuggled_cell.set(RefOrInt::Int(0xdeadbeef)); } } }); if let ReaderResult::Some(cell) = reader_result_ref { loop { if let RefOrInt::Ref(addr) = cell.get() { // Hope that between the time we pattern match the object as a // `Ref`, it gets written to by the other thread. if addr as *const u64 == &SOME_INT as *const u64 { continue; } // Due to the data race, obtaining Ref(0xdeadbeef) is possible println!("Pointer is now: {:p}", addr); println!("Dereferencing addr will now segfault: {}", *addr); } } } }); } ``` This outputs: ``` Pointer is now: 0xdeadbeef Return Code: -11 (SIGSEGV) ``` (Issue found by [sslab-gatech](https://github.com/sslab-gatech)'s Rust group)
issue