Return-position impl Trait leaks Send/Sync, allowing API breaks without changing any signatures.
At the moment, abstract type does that as well:
#![feature(existential_type)]
pub trait MyTrait{}
#[allow(unused)]
pub mod qqq {
pub existential type Lol: super::MyTrait /* + !Send + !Sync */;
pub fn lol() -> Lol {
4u32
// Impending API break even though signatures stay the same:
//NonSync(::std::cell::RefCell::new(4u32))
}
impl super::MyTrait for u32{}
struct NonSync(::std::cell::RefCell<u32>);
impl super::MyTrait for NonSync{}
}
fn assert_sync<T:Sync+Send>(_x:T) {}
fn main() {
let q : qqq::Lol = qqq::lol();
assert_sync(q); // I want it to be bannable by mod qqq
}
Maybe abstract type, unlike return-position impl Trait, may require + Send + Sync to be Send + Sync for better APIs evolution?
Alternatively, maybe it can support + !Send + !Sync (or + ?Send + ?Sync) to explicitly tell users not to rely on accidental Send/Sync (and ban NotSync in the example above unless !Sync+!Send is added)?
In any case, either assert_sync or returning NotSync should be banned without changing signature of the existential type, not both allowed.
Personally I think this inconsistency between impl Trait and existential type would not be a good idea due to the surprises it will lead to.
But existential type may fix what impl Trait has broken.
Public APIs may be adviced to favour existential type instead of impl Trait, maybe with a clippy lint or some.
But existential type may fix what impl Trait has broken.
impl Trait did not break anything; This was an intentional decision to leak auto traits in impl Trait.
cc https://github.com/rust-lang/rust/issues/34511
closing this issue in favor of the tracking issue.
Most helpful comment
impl Trait did not break anything; This was an intentional decision to leak auto traits in impl Trait.