This question already has answers here:
How can I align a struct to a specified byte boundary?
(2 answers)
Closed 4 years ago.
I want to write a Rust FFI for a C struct using the aligned attribute.
On nightly, one can use #[feature(repr_simd)] as in this question. The same technique without #[repr(simd)] appears to be restricted to a maximum alignment of 8 bytes.
There are various issues and RFCs open for both alignment and SIMD, and the compiler points to tracking issue #27731 which seems to be stalled.
RFC #325 points pretty clearly to no, but it is somewhat old.
Is it possible to do this with the stable compiler, in pure (unsafe?) Rust as of version 1.22?
As of now, the answer is yes, you may specify a type's alignment in stable Rust. This was stabilized in 1.25.0. It is documented under the reference's Type Layout section. Note that the alignment must be a power of 2, you may not mix align and packed representations, and aligning a type may add extra padding to the type. Here's an example of how to use the feature:
#[repr(align(64))]
struct S(u8);
fn main() {
println!("size of S: {}", std::mem::size_of::<S>());
println!("align of S: {}", std::mem::align_of::<S>());
}
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 months ago.
Improve this question
I have an enum, Angle, which has two variants, Degrees and Radians. I wanted to implement From for these, but it doesn't let me:
enum Angle {
Degrees(f64),
Radians(f64)
}
impl From<Angle> for Angle {
fn from(value: Angle) -> Self {
match value {
Angle::Degrees(deg) => Angle::Radians(deg / 180.0 * PI),
Angle::Radians(rad) => Angle::Degrees(rad / PI * 180.0)
}
}
}
which throws
error[E0119]: conflicting implementations of trait `std::convert::From<Angle>` for type `Angle`
--> src\lib.rs:45:1
|
45 | impl From<Angle> for Angle {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> From<T> for T;
Some errors have detailed explanations: E0119, E0412, E0425.
For more information about an error, try `rustc --explain E0119`.
From what I can see there are three options for this:
I clarify this to the compiler in some way
I add two separate functions to_degrees and to_radians
I separate Angle::Degrees and Angle::Radians into two separate structs
If 1 is not possible, which is preferred of 2 and 3?
I wanted to implement From for these
By that code, it appears that you want From::from to turn a value in degrees to a value in radians and vice versa. However, this is not only:
impossible, because any From<T> is already implemented by the core library for T;
but also unintuitive, because this is far from what a From conversion should be doing.
As such, trying to get the compiler to accept this is out of the question. The two alternatives provided are actually good, and are not mutually exclusive.
Whether to define independent structs for angles in degrees and angles in radians is case dependent. For what it's worth, the Rust API guidelines show how the newtype pattern can be used to prevent serious bugs by preventing you from mixing different measures. On the other hand, this type already does that.
#1 is indeed not possible. Rust has a blanket implementation impl<T> From<T> for T and you cannot overwrite it. Besides semantically what you are trying to do is not a From conversion, but rather changing a representation of some type.
I would strongly recommend #2. It is very idiomatic and anyone can tell after a glance what this methods would do (in contrast to what you written in your example).
You could do #3 but it's up to you how you want to design your code. If you already started with an enum it's probably the better fit for your problem, so I would recommend sticking to it. But if you decide that having two different structs is better for you, then #3 is still fine.
This question already has answers here:
What does the exclamation point mean in a trait implementation?
(3 answers)
Closed 9 months ago.
I am unable to locate the documentation for !Unpin referred to here in the docs.
More generally, the ! operator seem to lack corresponding documentation regarding traits. Specifically, it seems to represent Not as in Not Unpin or perhaps Not Unpinable in this case. I suppose it is different from Pin in some way otherwise it would be redundant. Currently, searching for the documentation is challenging since ! occurs so frequently otherwise.
It would be good if the operator behavior of ! on traits could be included in Appendix B: Operators and Symbols of the docs.
Unpin is one of several auto-traits, which are implemented automatically for any type that's compatible with it. And in the case of Unpin, that's, well, basically all of the types.
Auto-traits (and only auto-traits) can have negative implementations written by preceding the trait name with a !.
// By default, A implements Unpin
struct A {}
// But wait! Don't do that! I know something you don't, compiler.
impl !Unpin for A {}
Unpin, specifically, indicates to Rust that it is safe to move values of the implementing type T out of a Pin. Normally, Pin indicates that the thing inside shall not be moved. Unpin is the sort of opposite of that, which says "I know we just pinned this value, but I, as the writer of this type, know it's safe to move it anyway".
Generally, anything in Safe Rust is Unpin. The only time you'd want to mark something as !Unpin is if it's interfacing with something in another language like C. If you have a datatype that you're storing pointers to in C, for instance, then the C code may be written on the assumption that the data never changes addresses. In that case, you'd want to negate the Unpin implementation.
This question already has answers here:
Is this error due to the compiler's special knowledge about RefCell?
(1 answer)
How does the Rust compiler know `Cell` has internal mutability?
(3 answers)
Closed 2 years ago.
In Unsafe Code Guidelines Reference, it says
All interior mutation in Rust has to happen inside an UnsafeCell, so all data structures that have interior mutability must (directly or indirectly) use UnsafeCell for this purpose.
Also, in a discussion about UnsafeCell, it says
UnsafeCell is basically an optimization barrier to the compiler.
It is true that UnsafeCell acts as a compiler optimization barrier in Rust? If yes, which line in the standard library source code emits a barrier and how does it work?
[UPDATE]
The answer of a related question gives a very nice explanation. The TL;DR version is: UnsafeCell<T> is marked with #[lang = "unsafe_cell"] which forces it to be invariant over T.
Now I think this is not very much connected to optimization, but interacts more closely with lifetime analysis.
For the notion of variance in Rust, The Rustonomicon Book gives a detailed explanation.
This question already has answers here:
Why can't I store a value and a reference to that value in the same struct?
(4 answers)
Shared circular references in Rust
(1 answer)
Closed 3 years ago.
I am learning Rust from a C++/Java background, and I have the following pattern
struct Node<'a> {
network_manager: NetworkManager<'a>,
}
struct NetworkManager<'a> {
base_node: &'a Node<'a>,
}
The node contains the threadpool that the NetworkManager uses to "handoff" messages once they've been processed. Because of the recursive call, it is not possible to set the base_node field in the NetworkManager immediately. In Java, I would leave it as null and have a second method that is called after the constructor called initialise(BaseNode node) that would set the base_node field (ensuring that there are no calls to the network manager before initialise is called).
What is the idiomatic way of doing this in Rust? The only way I can think of is to make base_node an Option type, but this seems suboptimal.
In general, what is the "right" way in Rust to deal with situations where A points to B and B points to A, and where (as in my case), refactoring is not possible?
From my experience, these situations are very different from other languages. In "safe, simple, everyday Rust" having backpointers/pointers within the struct is complex since it leads to non-trivial problems. (Consider what would happen if you would move Node around in memory: How would you properly update the backpointer in NetworkManager?)
What I usually resort to is simply passing base_node as a parameter to the functions that need the backpointer. This is sometimes easier said than done, but leads to code that clearly states ownership.
This question already has answers here:
Is it possible to add your own derivable traits, or are these fixed by the compiler?
(2 answers)
Closed 5 years ago.
I have a struct like this
#[derive(CustomTrait)]
struct Sample {
v: Vec<u8>,
}
and my trait goes like this
trait CustomTrait {...}
Can I do the above stuff? It threw an error for me.
I want something similar to the Clone trait. Is this possible with Rust?
#[derive(Foo, Bar)] is sugar for #[derive_Foo] #[derive_Bar], so it is possible to implement your own decorator attribute in the same way as #[derive_Clone] is, but this requires you to write a compiler plugin, which is not a stable part of Rust and will not be stable in 1.0 (and will thus be unavailable in the stable and beta channels).
There is a little documentation on such matters in the book, but not much; you’re largely on your own with it.
Bear in mind that what you can actually do at that stage is limited; you have access to the struct definition only, and know nothing about the actual types mentioned. This is a good fit for all of the traits for which #[derive] support is built in, but is not for many other traits.
No, you can't. derive instructs the compiler to provide a basic implementation of the trait. You can't expect the compiler to magically know how to implement a user-defined trait.
You can only use derive with these traits (taken from http://rustbyexample.com/trait/derive.html):
Comparison traits: Eq, PartialEq, Ord, PartialOrd
Serialization: Encodable, Decodable
Clone, to create T from &T via a copy.
Hash, to compute a hash from &T.
Rand, to create a random instance of a data type.
Default, to create an empty instance of a data type.
Zero, to create a zero instance of a numeric data type.
FromPrimitive, to create an instance from a numeric primitive.
Debug, to format a value using the {:?} formatter.
NOTE: Apparently this was proposed and is being discussed here