You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This isn't sound because different types that implement the trait expect Self to be their own type (e.g. String expects a ref String), but in the above code we end up comparing Int == String, which will likely crash the VM.
I'm not sure yet how to best handle this. I believe Rust disallows using traits as objects when they have methods that refer to Self, but I'm not convinced yet that this is the best way of going about it.
The text was updated successfully, but these errors were encountered:
Perhaps a first step is to simply disallow the use of Self in the arguments of trait methods. Allowing Self in return/throw types should still be fine.
In the last week I thought about this a bit more, as working towards a native code compiler revealed just how annoying it is to provide support for Self types. Basically every time we have a type we have to account for that being Self and substitute it with another type.
I'm starting to lean towards just removing Self types outright. Within traits their use is generally unsound, apart from maybe throw/return types. In classes Self is mostly used when you're too lazy to write the type out manually, but this makes the code less clear as, depending on how the code is written, it may not be immediately obvious what Self resolves to.
In case of traits, returning/throwing Self has one benefit over using the trait type explicitly: when the method is used in the context of a class, the type is correctly inferred as that class instead of the trait. That is, if you have -> Self and Int implements the trait, the method's return type is Int not TheTrait. This however isn't that big of a deal: when implementing a trait you can just override the type to be that of the class, and it achieves the same results.
Currently the common use case of Self is for Clone and the various operator traits. In all cases the traits can just be made generic, which also gives you the option to change what the return type is (though at least for Clone it's rare to not want the return type to be the same as the receiver).
Consider this trait definition:
This can lead to soundness holes like so:
This isn't sound because different types that implement the trait expect
Self
to be their own type (e.g.String
expects aref String
), but in the above code we end up comparingInt == String
, which will likely crash the VM.I'm not sure yet how to best handle this. I believe Rust disallows using traits as objects when they have methods that refer to
Self
, but I'm not convinced yet that this is the best way of going about it.The text was updated successfully, but these errors were encountered: