From 6d5f43d77d2209741fc9103096a554366f38993d Mon Sep 17 00:00:00 2001 From: Gray Olson Date: Thu, 28 Sep 2023 16:11:43 +0200 Subject: [PATCH] edit new section for typos and better wording --- library/core/src/pin.rs | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 19beaf2a6745c..9eea37c62f9a1 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -184,22 +184,27 @@ //! provide a safe interface on top. //! //! There are a couple of linked disadvantages to using this model. The core issue is a lack -//! of generality. This is an issue first because it means hat each individual type that -//! implements such an interface does so on its own. Each individual developer must themselves -//! think through all the guarantees needed to ensure the API they present is sound. This puts -//! a greater burden on each developer, rather than allowing building a shared understanding of the -//! problem space, encoded into a shared interface to solve it. In addition, and the key issue that -//! drove Rust towards another solution, is that each individual object must assume it is on its -//! own in ensuring that its data does not become *moved* or otherwise invalidated. Since there is -//! no shared contract between values of different types, an object cannot assume that others -//! interacting with it will be a good citizen with its data. Because of this, *composition* of -//! address-sensitive types requires at least a level of pointer indirection (and, practically, a -//! heap allocation) each time a new object is added to the mix. This is particularly a problem -//! when one considers the implications of composing together the [`Future`]s which will eventaully -//! make up an asynchronous task (including address-sensitive `async fn` state machines). -//! It is plausible that there could be many layers of [`Future`]s composed together, including -//! multiple layers of `async fn`s handling different parts of a task, and it was deemed -//! unacceptable to force indirection and allocation for each layer of composition in this case. +//! of generality. This is an issue because it means that each individual type that implements +//! such an interface does so on its own. Each developer implementing such a type must themselves +//! think through all the guarantees needed to ensure the API they present is sound. We would +//! rather build a shared understanding of the problem space and encode that understanding into a +//! shared interface to solve it which everyone helps validate. +//! +//! In addition, and the key issue that drove Rust towards developing another solution, is that +//! in this model, each individual object must assume it is *on its own* to ensure that its data +//! does not become *moved* or otherwise invalidated. Since there is no shared contract between +//! values of different types, an object cannot assume that others interacting with it will +//! properly respect the invariants around interacting with its data and must therefore protect +//! it from everyone. Because of this, *composition* of address-sensitive types requires at least +//! a level of pointer indirection each time a new object is added to the mix (and, practically, a +//! heap allocation). +//! +//! This is particularly a problem when one considers, for exapmle, the implications of composing +//! together the [`Future`]s which will eventaully make up an asynchronous task (including +//! address-sensitive `async fn` state machines). It is plausible that there could be many layers +//! of [`Future`]s composed together, including multiple layers of `async fn`s handling different +//! parts of a task. It was deemed unacceptable to force indirection and allocation for each layer +//! of composition in this case. //! //! [`Pin`] is an implementation of the third option. It allows us to solve the issues //! discussed with the second option by building a *shared contractual language* around the