-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tracking Issue for auto traits (auto_traits) -- formerly called opt-in built-in traits (optin_builtin_traits) #13231
Comments
Marking 1.0, P-backcompat-lang. |
cc me |
I'm actively working on this. Unfortunately, I've moved quite slowly because of other bugs I had to fix. I hope to be able to submit a PR this week. |
I am adding a note to the checklist that the interaction between auto traits and Currently with the following code: auto trait AutoTrait {}
impl<T> !AutoTrait for [T] {} we get Under a different libcore-based If we want to ever be able to push something like #70911 through in the future, there may need to be |
…or-auto, r=lcnr Treat `str` as containing `[u8]` for auto trait purposes Wanted to gauge `@rust-lang/lang` and `@rust-lang/types` teams' thoughts on treating `str` as "containing" a `[u8]` slice for auto-trait purposes. `@dtolnay` brought this up in rust-lang#13231 (comment) as a blocker for future `str` type librarification, and I think it's both a valid concern and very easy to fix. I'm interested in actually doing that `str` type librarification (rust-lang#107939), but this probably should be considered in the mean time regardless of that PR. r? types for the impl, though this definitely needs an FCP.
…or-auto, r=lcnr Treat `str` as containing `[u8]` for auto trait purposes Wanted to gauge `@rust-lang/lang` and `@rust-lang/types` teams' thoughts on treating `str` as "containing" a `[u8]` slice for auto-trait purposes. `@dtolnay` brought this up in rust-lang#13231 (comment) as a blocker for future `str` type librarification, and I think it's both a valid concern and very easy to fix. I'm interested in actually doing that `str` type librarification (rust-lang#107939), but this probably should be considered in the mean time regardless of that PR. r? types for the impl, though this definitely needs an FCP.
…or-auto, r=lcnr Treat `str` as containing `[u8]` for auto trait purposes Wanted to gauge ``@rust-lang/lang`` and ``@rust-lang/types`` teams' thoughts on treating `str` as "containing" a `[u8]` slice for auto-trait purposes. ``@dtolnay`` brought this up in rust-lang#13231 (comment) as a blocker for future `str` type librarification, and I think it's both a valid concern and very easy to fix. I'm interested in actually doing that `str` type librarification (rust-lang#107939), but this probably should be considered in the mean time regardless of that PR. r? types for the impl, though this definitely needs an FCP.
This RFC is a little dated and concerns multiple topics ("auto trait", other automatically-implemented marker traits, MotivationTo paraphrase (with comments):
Detailed designDefault and negative impls
(This is now just
This is reliant on having a specified "default impl", as above (not just
Aha, the (informal) definition of an Modeling Send and Share using default traitsThe RFC details how to define (The private trait ( The Copy and Sized traits
My thoughts follow. "auto trait" in conjunction with negative impls are a niche solution to moving a few trait definitions from the language to the standard library:
"auto trait" does not allow all "automatically defined traits" to be offloaded from the compiler: e.g. The RFC mentions a few other uses of auto traits:
The only other possible usage I can think of:
Hence it remains unclear whether there is sufficient utility for "auto traits". The other angle for auto-traits is as an opt-out marker trait (i.e. negative impls #68318). These do not require any rules pertaining to component types, thus, for simplicity, should not use "auto traits" as defined by RFC 19. My hesitant recommendationDo not make "auto traits" a public feature and close this issue. They have recognised utility within the standard library but likely very little utility otherwise. (Perhaps in the future a more general form of blanket impls able to emulate the logic of auto traits will be possible. In the mean-time, I simply don't think auto traits have sufficient utility to become a fully fledged language feature.) Possibly rename the existing "auto traits" to allow the term to be used for a simple "opt-out" trait for use with negative implementations (but this would be the topic of negative impls or a whole new RFC). |
To me, it mostly has value for checking whether the types involved in a closure satisfy a specific property. A perfect example of this, outside the usual Concretely, I'm using it (behind a feature flag) to make autorelease pools in Objective-C sound, just as a data point for how it's useful. |
Thanks for the examples, adding motivation for this feature. The aspects of this feature I'm least comfortable with are:
|
My best recollection of current lang consensus is that |
how about coupling the auto traits so that they only get auto-used when the crate defining them is a direct dependency of the current crate (so no automatic spill of auto traits happens)? (making it crate-level opt-in, trait-level opt-out instead of pure opt-out) |
I think pyo3 usecase wasn’t mentioned here, so I’ll bring it as a data point. pyo3 needs to track which types can only be accessed when Python’s GIL is held. Currently it uses I think that this is an evidence that auto traits currently have usecases outside of standard library. Maybe these usecases could be covered by another feature, maybe they’re not enough to sway the decision, but I think it should be recognized that auto traits have utility outside of standard library, and making them perma-unstable will probably make some usecases perma-unsound, unless some other solution is found. I feel like if this issue is to be closed, this tradeoff (“we’re OK with these cases having no known sound solution”) should be explicitly made in the final decision. https://docs.rs/pyo3/latest/pyo3/marker/trait.Ungil.html — trait in pyo3 that should be auto |
I’d also like to address this point specifically wrt
Opting out of |
In my case too, you'd only need to opt out of I'll add that if a library wanted to make sure to opt out of all auto traits (e.g. if it implemented some sort of dynamic type), even for generic structs, they could do: trait HelperTrait {}
struct MyTypeThatOptsOutOfEverything<T> {
inner: T,
p: PhantomData<dyn HelperTrait>,
} Of course this is yet another SemVer footgun to be aware of, but fortunately we have tools for that now. |
Oops, I mixed up “opting out” and “opting in” in my original message. Either way, the point stands: I don’t see a reason to opt out of arbitrary auto traits unless you’re doing something that can affect this particular system. Author of the auto trait guarantees that it’s safe to impl it if all the fields impl it. |
For which is that an auto-trait is unable to restrict access to certain types even if those types always feature a non- I’m relatively certain that the Of course one approach would be to declare |
Oh, that’s really sad. If |
Hmm, I don't think that's a problem for So even though we can access the pool, we can't actually do anything bad with it, since it's only the lifetime that we care about, and that is still correctly bounded. See the following example for details. ```cargo
[dependencies]
# requires `auto_traits` feature
objc2 = { version = "0.5", features = ["unstable-autoreleasesafe"] }
scoped-tls-hkt = "0.1"
```
use objc2::rc::{autoreleasepool, AutoreleasePool, Id};
use objc2::runtime::NSObject;
use scoped_tls_hkt::scoped_thread_local;
fn main() {
autoreleasepool(|pool1| {
scoped_thread_local!(static POOL: for<'pool> AutoreleasePool<'pool>);
POOL.set(pool1, || {
let obj = autoreleasepool(|_pool2| {
POOL.with(|pool1| {
Id::autorelease(NSObject::new(), pool1)
})
});
// If we manage to get here, then that's unsound, since the object
// would have been released in the second autorelease pool.
println!("{obj:?}");
});
});
} If you manage to produce a similar example that does compile, then I'd love to know! |
@madsmtm Here we go: use std::cell::Cell;
use objc2::rc::{autoreleasepool, AutoreleasePool, Id};
use objc2::runtime::NSObject;
use scoped_tls_hkt::scoped_thread_local;
struct PoolHolder<'p> {
pool1: AutoreleasePool<'p>,
obj_cell: &'p Cell<Option<&'p NSObject>>,
}
trait IPoolHolder {
fn autorelease(&self, id: Id<NSObject>);
}
impl<'pool> IPoolHolder for PoolHolder<'pool> {
fn autorelease(&self, id: Id<NSObject>) {
self.obj_cell.set(Some(Id::autorelease(id, self.pool1)));
}
}
fn main() {
autoreleasepool(|pool1| {
scoped_thread_local!(static POOL_HOLDER: for<'p> &'p dyn IPoolHolder);
let obj_cell = &Cell::new(None);
POOL_HOLDER.set(&PoolHolder { pool1, obj_cell }, || {
autoreleasepool(|_pool2| {
POOL_HOLDER.with(|pool1_holder| pool1_holder.autorelease(NSObject::new()))
});
let obj: &NSObject = obj_cell.get().unwrap();
// If we manage to get here, then that's unsound, since the object
// would have been released in the second autorelease pool.
println!("{obj:?}");
});
});
} |
…ndoo Don't walk the HIR tree when checking for a const context changelog: none
This is the tracking issue for RFC 19.
Checklist
Here is a check-list of code to write and tricky scenarios to be sure we handle:
impl !Pod for ..
should not be legal Negative blanket OIBIT impl treated as positive #28475impl Foo for ..
impl Trait for .. {} does not require a feature gate #23225impl Trait for .. {}
#23080 / Check that traits with default impls have no methods #23117impl Foo for ..
Send/Sync
to use new infrastructure internallyunsafe impl Send for ..
/unsafe impl Sync for ..
constituent_types
PhantomData<T>
checkT
rather than the struct itself #23091impl AutoTrait for dyn Trait
legal? Tracking Issue for auto traits (auto_traits) -- formerly called opt-in built-in traits (optin_builtin_traits) #13231 (comment)[u8]
negative impls affectstr
. Tracking Issue for auto traits (auto_traits) -- formerly called opt-in built-in traits (optin_builtin_traits) #13231 (comment)The text was updated successfully, but these errors were encountered: