-
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 sound builtin auto trait impls #93367
Comments
I had implemented my own generic collection type containing a NonNull field. I then had implemented Send and Sync for collections of specific types. I'm not sure why this would ever be unsound. |
@jethrogb your case is fairly interesting and would not actually be impacted by this change. The future compat lint should ideally only triggers in cases where:
The lint is not perfect however, so we currently lint all specialized impls if the builtin impl may currently apply to your type in some way. As in your case, the builtin impl only applied for Improving the lint to detect specialized auto trait impls which fully cover the builtin impl for a type isn't trivial. I would much rather lint too much (causing the cases to be mentioned here) than not lint something which later changes behavior, accidentally breaking some code. Note that the lint exists to notify people of a future change which might change the behavior of their code even if it is currently sound. Only changing the behavior for impls which can cause unsoundness seems would afaict be fragile and difficult to understand for users. |
180: Rearrange Send/Sync impls for MbedtlsList/MbedtlsBox r=AdrianCX a=jethrogb See rust-lang/rust#93367 Co-authored-by: Jethro Beekman <jethro@fortanix.com>
Hey, I hit this warning on a struct that uses I don't quite grep the specifics of this issue, but would it make sense to extend the lint / your analysis to "look inside" |
@madsmtm yeah, that's an issue with our implementation of the lint, should be able to fix that one soon |
update auto trait lint for `PhantomData` cc rust-lang#93367 (comment)
update auto trait lint for `PhantomData` cc rust-lang#93367 (comment)
update auto trait lint for `PhantomData` cc rust-lang#93367 (comment)
update auto trait lint for `PhantomData` cc rust-lang#93367 (comment)
update auto trait lint for `PhantomData` cc rust-lang#93367 (comment)
I haven't really looked into it yet, but one of my crates is flagging up this warning: Diggsey/scoped-tls-hkt#2 |
relax `suspicious_auto_trait_impls` lint wrt lifetimes fixes the warning for rust-lang#93367 (comment).
I had this case in matrixmultiply that triggers the warning: /// A Send + Sync raw pointer wrapper
#[derive(Copy, Clone)]
#[repr(transparent)]
pub(crate) struct Ptr<T> { ptr: T }
unsafe impl<T> Sync for Ptr<*const T> { }
unsafe impl<T> Sync for Ptr<*mut T> { }
unsafe impl<T> Send for Ptr<*const T> { }
unsafe impl<T> Send for Ptr<*mut T> { } I believe the code was problem-free because all usage of Would it be ok to assume that this code doesn't change meaning in the future? Or does it need updating? The lint kind of implies that it can be ignored for some cases. |
I run into this issue while trying to exclude a type when implementing a trait. Roughly my code does is something like: auto trait NotEq {}
struct TypeCmp<U, V>(U, V);
impl<T> !NotEq for TypeComp<T, T> {}
impl<T> SomeTrait<T> for MyStruct
where
T: Default,
TypeCmp<T, u8>: NotEq,
TypeCmp<T, u16>: NotEq,
// More types that I want to exclude
{
// ... trait impl
} For excluded types such as |
ignoring the fact that auto traits will probably never get stabilized, you could add a bound
that sounds like you may want specialization, not negative impls though |
But in my case, I think, I still need the
Yes I knew that all along, but I don't know if the |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry for the possible off-topic, but I ran into this issue in the context of another problem. I wanted some trait trait Group {
type Container: AsRef<dyn Item<Self>> + Clone;
}
trait Item<G: Group> {
fn make_owned(&self) -> G::Container;
}
struct View<'a, G> {
item: &'a dyn Item<G>,
}
// Rc
struct RcGroup;
impl Group for RcGroup {
type Container = std::rc::Rc<dyn Item<Self>>;
}
// Arc
struct ArcGroup;
impl Group for ArcGroup {
type Container = std::sync::Arc<dyn Item<Self>>;
}
unsafe impl<'a> Send for (dyn Item<ArcGroup> + 'a) {} // <---
fn test_send<T: Send>() {}
fn should_compile() {
test_send::<View<ArcGroup>>();
}
P.S. Wrapping dyn trait into a newtype also compiles with struct Wrapper<'a, G>(dyn Item<G> + 'a);
unsafe impl<'a> Send for Wrapper<'a, ArcGroup> {} |
180: Rearrange Send/Sync impls for MbedtlsList/MbedtlsBox r=AdrianCX a=jethrogb See rust-lang/rust#93367 Co-authored-by: Jethro Beekman <jethro@fortanix.com>
180: Rearrange Send/Sync impls for MbedtlsList/MbedtlsBox r=AdrianCX a=jethrogb See rust-lang/rust#93367 Co-authored-by: Jethro Beekman <jethro@fortanix.com>
To make my usecase even more clear, I almost copied the idea here. If I'm not wrong, this will also get invalidated in the future. |
Is this lint supposed to trigger on specialized negative impls like the following? #![feature(negative_impls)]
struct A;
struct B;
struct C;
struct Helper<T>(T);
impl !Send for Helper<A> {}
impl !Send for Helper<B> {} If this lint is supposed to cover negative impls like this, the lint message and the description here are kinda confusing. (Though I understand negative impls are unstable so it's not a huge deal) |
yes (though the behavior change has already landed. This lint should be updated) the issue is that |
pub trait Irrelative {
type Type;
}
impl<T> Irrelative for T
where
T: ?Sized,
{
type Type = !;
}
pub struct Equality<X, Y>(<X as Irrelative>::Type, <Y as Irrelative>::Type);
#[rustc_unsafe_specialization_marker]
pub auto trait NotEqual {}
impl<X> !NotEqual for Equality<X, X> {} Given the code above, how can I update the negative impl related logic about Equality? |
Tracking issues are not the right place to ask for help. Please try on Discourse (users.rust-lang.org) or Discord. |
Rollup merge of rust-lang#120716 - spastorino:change-some-lint-msgs, r=lcnr Change leak check and suspicious auto trait lint warning messages The leak check lint message "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" is misleading as some cases may not be phased out and could end being accepted. This is under discussion still. The suspicious auto trait lint the change in behavior already happened, so the new message is probably more accurate. r? `@lcnr` Closes rust-lang#93367
The behavior of auto trait has changed in #113312, so the behavior of auto trait impls will now stay as is for the foreseeable future: If there's any impl whose self type is |
``` error: lint `suspicious_auto_trait_impls` has been removed: no longer needed, see #93367 <rust-lang/rust#93367> for more information ```
``` error: lint `suspicious_auto_trait_impls` has been removed: no longer needed, see #93367 <rust-lang/rust#93367> for more information ```
``` error: lint `suspicious_auto_trait_impls` has been removed: no longer needed, see #93367 <rust-lang/rust#93367> for more information ```
Similarly to @Escapingbug, I feel that inability to write now the following code is extremely limiting: auto trait NotEq {}
struct TypeCmp<U, V>(U, V);
impl<T> !NotEq for TypeCmp<T, T> {}
#[derive(Debug, Clone, Copy)]
struct HCons<H, T> {
head: H,
tail: T,
}
#[derive(Debug, Clone, Copy)]
struct HNil;
#[derive(Debug, Clone, Copy)]
struct Zero;
#[derive(Debug, Clone, Copy)]
struct Succ<N> {
_phantom: PhantomData<N>,
}
// ===============
// === IndexOf ===
// ===============
type IndexOf<T, X> = <T as HasIndexOf<X>>::Index;
trait HasIndexOf<T> {
type Index;
}
impl<H, T> HasIndexOf<H> for HCons<H, T> {
type Index = Zero;
}
impl<H, T, X> HasIndexOf<X> for HCons<H, T>
where
T: HasIndexOf<X>,
TypeCmp<X, H>: NotEq,
{
type Index = <T as HasIndexOf<X>>::Index;
} How can this be expressed (computing indexed of a H-List using associated types)? Edit: Even the Rust Book tells about this use case here: https://doc.rust-lang.org/stable/unstable-book/language-features/negative-impls.html |
This is the summary issue for the
SUSPICIOUS_AUTO_TRAIT_IMPLS
future-compatibility warning. The goal of this page is to describe why this lint was added and how you can fix code that is affected by it. It also provides a place to ask questionsor register a complaint if you feel the change should not be made. For more information on the policy around future-compatibility warnings, see our breaking change policy guidelines.
What is the warning for?
Rust has some special traits, called either "auto traits" or "traits with a default impl", which are automatically implemented for your types under certain conditions. The most notable examples for this are the traits
Send
andSync
. A type implements these trait automatically if all its fields also implement this trait. This means that types likestruct MyData { data: Vec<String> }
automatically implementSend
without the user having to think about it.There are some cases where the builtin impls are not enough. For traits like
Send
,Sync
andUnpin
these builtin impls can even be unsound when implementing abstractions using unsafe code. Because of this, it is allowed to also manually implement these traits, disabling the builtin impl for your type in the process.The way we currently disable builtin impls has some quite subtle bugs, causing unsoundness: #84857. This unsoundness is luckily quite difficult to exploit, but can be triggered under the following conditions:
where
-clauses than the type definition. We consider an impl to be "specialized" here if the generic arguments of theSelf
type of the impl are not simply unique generic parameters.impl Trait for X
is specialized ifX
isVec<i32>
,HashMap<String, V>
or evenHashMap<T, T>
and not specialized forVec<T>
orHashMap<K, V>
.where
-clauses of the explicit implEXAMPLE
To fix this unsoundness, we intend to simplify the rules for builtin auto trait implementations. Right now, we only discard the builtin implementation if an explicit impl applies to the given type while ignoring
where
-clauses of that explicit impl. This will be changed to just always discard the builtin impl once at least one explicit impl for that type exists.As this can cause types to stop implementing auto traits if a specialized impl for that type exists, we now warn again specialized impls if builtin impls could apply for your type. If the builtin impl would definitely not apply for your type, this change will not affect you, and we therefore try to not emit a warning in these cases.
When will this change take effect?
After a crater run detected that our intended change to make builtin auto trait impls sound causes some breakage in the wider ecosystem.
We are currently searching for ways to lessen the impact by modifying the implementation to be more similar to the current situation, while still being sound. If that is not possible, we will introduce this change after the future compatibility lint has been on stable for long enough to reduce the impact of landing this change and if there are existing workarounds for breakage caused by the new rules.
Some of the cases which broke need either marker traits (#29864) or negative impls (#68318) affecting coherence to get back the old behavior. Both of these are currently not too far away from stabilization, so this will probably remain as a future compatibility warning until one of these ends up getting stabilized.
How to fix this?
This depends on why the explicit impl has been added in the first place. If you do not want the builtin impl to apply, you may add a field to your type which definitely does not implement the given auto trait. You may also be able to remove the explicit impl entirely, if that case is already currently covered by the builtin impl. For anything else, please report your case here so that we know about the issue and are able to extend this section.
If your code triggered this lint, please tell us about it in this issue so we may take it into consideration when deciding on how to proceed.
The text was updated successfully, but these errors were encountered: