I am looking at self-referencing structs and I understand how the Sync/Send trait are used to force safety from race conditions, but the Pin use case seems poorly explained.
Basically, this code doesn't not compile because iter
is not Send:
fn main() {
let mut list : LinkedList<RefCell<String>> = LinkedList::new();
list.push_back(RefCell::new("foo".to_string()));
let iterator = list.iter();
thread::spawn(move || {
// Compiler error: iterator is not Send.
for item in iterator {
item.replace("qux".to_string());
}
}).join().unwrap();
}
Is there similar code that doesn't compile because the object to be moved is not Pin or Pin is just a convention that says to the receiving code that the object is sent in a consistent state? Examples out there seem to imply a compiling error, but never been able to see one generated that was obviously due to pinning issues.
To better rephrase the question: Violating Send requirements causes compilation errors. Is it possible to generate compilation errors by violating a Pin contract? I've read that moving an object that requires pinning while not pinned causes an error but I couldn't find a way to cause a compilation error that disappears when the object is pinned.
I am looking at self-referencing structs and I understand how the Sync/Send trait are used to force safety from race conditions, but the Pin use case seems poorly explained.
Basically, this code doesn't not compile because iter
is not Send:
fn main() {
let mut list : LinkedList<RefCell<String>> = LinkedList::new();
list.push_back(RefCell::new("foo".to_string()));
let iterator = list.iter();
thread::spawn(move || {
// Compiler error: iterator is not Send.
for item in iterator {
item.replace("qux".to_string());
}
}).join().unwrap();
}
Is there similar code that doesn't compile because the object to be moved is not Pin or Pin is just a convention that says to the receiving code that the object is sent in a consistent state? Examples out there seem to imply a compiling error, but never been able to see one generated that was obviously due to pinning issues.
To better rephrase the question: Violating Send requirements causes compilation errors. Is it possible to generate compilation errors by violating a Pin contract? I've read that moving an object that requires pinning while not pinned causes an error but I couldn't find a way to cause a compilation error that disappears when the object is pinned.
Share Improve this question edited Nov 18, 2024 at 9:32 Paperino asked Nov 17, 2024 at 12:18 PaperinoPaperino 1,0198 silver badges20 bronze badges 5 |1 Answer
Reset to default 1So ok, I've found it in the official async documentation.
Basically this is a pseudo minimalistic example of compilation error when the comments are removed from the lines containing _marker.
use std::pin::Pin;
use std::marker::PhantomPinned;
#[derive(Debug)]
struct Test {
a: String,
// _marker: PhantomPinned, // remove comment for compilation error
}
impl Test {
fn new(txt: &str) -> Self {
Test {
a: String::from(txt),
// _marker: PhantomPinned, // remove comment for compilation error
}
}
}
pub fn main() {
let mut test1 = Test::new("test1");
let mut test1 = unsafe { Pin::new_unchecked(&mut test1) };
let mut test2 = Test::new("test2");
let mut test2 = unsafe { Pin::new_unchecked(&mut test2) };
// the following line won't compile
std::mem::swap(test1.get_mut(), test2.as_mut().get_mut());
}
Pin
? – kmdreko Commented Nov 17, 2024 at 15:14Pin
wraps some kind of pointer (reference,Box
, etc.) and is a static promise that the referent will never move in memory. That's it. It also has nothing to do with the code in your question, which does not usePin
in any way. – cdhowie Commented Nov 17, 2024 at 15:17Pin
? Pinning has no impact on thread safety. – kmdreko Commented Nov 17, 2024 at 17:54Send
may cause compilation error"). OP asks for a similar code example that demonstrates another concept (in this case the concept is "a type not being insidePin<T>
may cause compilation error"). – m4tx Commented Nov 18, 2024 at 8:31