最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Generating an error for Pinned objects in Rust - Stack Overflow

programmeradmin1浏览0评论

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 What does this code have to do with Pin? – kmdreko Commented Nov 17, 2024 at 15:14
  • Pin 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 use Pin in any way. – cdhowie Commented Nov 17, 2024 at 15:17
  • Please read the question carefully. The code is an example of compilation error due to the type being not Send. – Paperino Commented Nov 17, 2024 at 16:47
  • 1 Right, but what does that have to do with Pin? Pinning has no impact on thread safety. – kmdreko Commented Nov 17, 2024 at 17:54
  • 1 @kmdreko if I understand the question correctly, this code is just an example to demonstrate a concept (the concept being "a type not being Send 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 inside Pin<T> may cause compilation error"). – m4tx Commented Nov 18, 2024 at 8:31
Add a comment  | 

1 Answer 1

Reset to default 1

So 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());
}
发布评论

评论列表(0)

  1. 暂无评论