Change:
I think it's sound? It seems like a straightforward solution would be to add a attribute. We could also add an marker type, but I think that'd be a bit strange since unlike the other markers, this one would remove_ a restriction on the type, not add one. The current situation requires some gross workarounds like this:
In an opt-in kind world, this would probably be an attribute that would work like .
There is still an issue if the wrapped type is not safe to access from a different thread than the one it was created on. EDIT: mentioned on IRC, which would solve the issue I thought of.
I talked with about this . He thinks that can be special (it's already a lang item), and will be regardless of whether is share. This would fix the inference problem. Assuming an opt-in world, everything would look like: Today's compiler would reject this code because it does not think that is . If the compiler thought that were indeed , then the type would be
Methods on are only implemented for so that shouldn't be an issue.
could be special cased now too. However, given the fact that opt-in kinds are coming, I don't it'd be worth it. I'll make sure to do this as part of the opt-in work.
FWIW, I've updated the RFC to include text about this.
With the removal of (which previously handled this scenario for us - making something that is not into ), this issue is currently blocking Servo's current Rust upgrade, because we cannot simply replace previous uses of with . cc
As mentioned in my previous comment, with few changes could be made always now too. It'll be a couple of weeks before the opt-in work is done. This is probably worth discussing in the next meeting. The issue is already assigned to me, I'm happy to tackle it asap if needed.
Thanks! I think the biggest things we're hoping for are: 1) a workaround that we can use for now until the Right Thing lands that isn't as ugly as copying over all of the old sync crate 2) making sure that this gets fixed at some point in the future I appreciate the offer, but don't need to you drop everything you're doing and work on this, especially since it sounds invasive enough that we probably couldn't cherry-pick it and we would like to finish off this Rust upgrade before we start in on yet another.
if you can pay for an extra allocation, I've worked around this issue for now by representing an as an and casting between and as needed. It's a bit hacky, and you'll need to make sure that there's a destructor that can clean up after it, but it's not too horrible.
Thanks! That seems totally reasonable. We'll just have to make sure to clean it up when the fix lands, which we don't always do :-/

Discussion:
} else if Some(did) == cx.lang_items.no_share_bound() { tc | TC::ReachesNoShare } else if Some(did) == cx.lang_items.unsafe_type() { <del> tc | TC::InteriorUnsafe </del> <ins> // FIXME(#13231): This shouldn't be needed after // opt-in built-in bounds are implemented. (tc | TC::InteriorUnsafe) - TC::Nonsharable </ins> } else { tc }

<ins> // Copyright 2014 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. // Verify that Unsafe is *always* share regardles `T` is share. // ignore-tidy-linelength use std::ty::Unsafe; use std::kinds::marker; struct MyShare<T> { u: Unsafe<T> } struct NoShare { m: marker::NoShare } fn test<T: Share>(s: T){ } fn main() { let us = Unsafe::new(MyShare{u: Unsafe::new(0)}); test(us); let uns = Unsafe::new(NoShare{m: marker::NoShare}); test(uns); let ms = MyShare{u: uns}; test(ms); let ns = NoShare{m: marker::NoShare}; test(ns); //~^ ERROR instantiating a type parameter with an incompatible type `NoShare`, which does not fulfill `Share` } </ins>