Received: by 2002:a05:7412:6592:b0:d7:7d3a:4fe2 with SMTP id m18csp2468623rdg; Mon, 14 Aug 2023 03:43:35 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHTd1UrUWvNxRHfyEuspedfIa1TjFZIVyBzWqZhUCKEruJA/IgY8IUlmQy5ZxxU61irJfHn X-Received: by 2002:a17:907:270b:b0:99d:6b79:6eda with SMTP id w11-20020a170907270b00b0099d6b796edamr6924195ejk.45.1692009815061; Mon, 14 Aug 2023 03:43:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1692009815; cv=none; d=google.com; s=arc-20160816; b=0/nIGSQf5cVAPEGRc19RV6Y/ZskyTIuWMACVs8CFbMjxyUY7gaOZ4o9eXU4VCWAafR ObQgRvG6PqpsZ7Jiap5xSG8cy0OrsGnqT+53A0Jhb816znEjlLC70ZY1HdcSZZVJUOZi gi9Woip79/Dfr6msmYPHGg6vFz3kVIJNlOYOHWPnsea3SyPr7MySkwic6A9b2VNNvHVC JRQdn6oiwjjZgDWbTXCeuvy+dCYYsJdtUpsiqQQ4XjyeUjPUg8xywMgMMLAgSG8K3Hb8 AFSu5w9EWp0hGSMwmoCssz+3OROzUSOOYJH7ZcAKd5CZRLELRAo5dNzlHolFKcYGy6xl 6J5w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :feedback-id:references:in-reply-to:message-id:subject:cc:from:to :dkim-signature:date; bh=OzxRk04kug+IJRfrdZ4RG1rImHgGnATYUlRMhZsCbwM=; fh=TE4onW3Du2FQ1EsedDK8TzgRHOYndfJXYpOtlseWrM0=; b=VgviWJQ/6uv8mHGsCGQjVD4/bVRiCfahWsYsbqBXiS2kqpPIWhOUQfAiCQmk7aCEty ljqOmUKiqGlfGgOAeLLv6IXgBcncetP0j+RS0cXwbWzUaeXVwhVVDLond4LZGhKbKOkk 9Aj0+0m+FGe8pK8TtWz6RI/G1Zt96knyq9yRGMW4xKd0+E0KxViA6rxR8vrOOpRIMAiI 2QBlJentqvRhmFFa4LMNxZuFZO/Zpeys6BO6zW8Jgr8vQ2ybbqUMa/9znN5ZFbVKPZqs gkDl1UTav9G6Xx83ytLyeHT8vXwmS0J/1lOFP9zPnkSnF3KEmebm8CcwStPZQczsOyeN xRfg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@proton.me header.s=bo4g63vkczak7fgpnjhlhxuidy.protonmail header.b=adOP9C1Y; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e2-20020a170906080200b00992b6af11f0si7868102ejd.362.2023.08.14.03.43.07; Mon, 14 Aug 2023 03:43:35 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@proton.me header.s=bo4g63vkczak7fgpnjhlhxuidy.protonmail header.b=adOP9C1Y; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232729AbjHNItU (ORCPT + 99 others); Mon, 14 Aug 2023 04:49:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33660 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235014AbjHNIs1 (ORCPT ); Mon, 14 Aug 2023 04:48:27 -0400 Received: from mail-40131.protonmail.ch (mail-40131.protonmail.ch [185.70.40.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E599A129 for ; Mon, 14 Aug 2023 01:48:10 -0700 (PDT) Date: Mon, 14 Aug 2023 08:47:54 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=bo4g63vkczak7fgpnjhlhxuidy.protonmail; t=1692002889; x=1692262089; bh=OzxRk04kug+IJRfrdZ4RG1rImHgGnATYUlRMhZsCbwM=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=adOP9C1YTvn8M30AMLGzIRm+gphZgiEIRlaXXyyFcXWSLiB7LephdMV2rjPC+9PbN Yk0RbqjI9j/I4yf8CwUxh8tGA1mDACVsjc5VqEAsWkqEpj1c5nAbO5hJ5EPZavYJAP Np1owH85fWpYFWeRwh32HbRNTLg7Uhl8kYDJqZpUikR+LRD+Y75E8TMMYoxPPdJLyq oo1kj63I/SfwyniZC9HkWktw23LMenkVQYqSg74RTUp3xopZoRmgmPGyQDqNBvTV/8 ZeAYPKqS+vSWTDnm4J/e1JRSmzenAWItm33JYSYZG97+B0Am9erprq/bDLyX9Pow+F OlZLcZhMAkCVQ== To: Miguel Ojeda , Wedson Almeida Filho , Alex Gaynor From: Benno Lossin Cc: Boqun Feng , Gary Guo , =?utf-8?Q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Alice Ryhl , Andreas Hindborg , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, patches@lists.linux.dev, Martin Rodriguez Reboredo Subject: [PATCH v4 13/13] rust: init: update expanded macro explanation Message-ID: <20230814084602.25699-14-benno.lossin@proton.me> In-Reply-To: <20230814084602.25699-1-benno.lossin@proton.me> References: <20230814084602.25699-1-benno.lossin@proton.me> Feedback-ID: 71780778:user:proton MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The previous patches changed the internals of the macros resulting in the example expanded code being outdated. This patch updates the example and only changes documentation. Reviewed-by: Martin Rodriguez Reboredo Signed-off-by: Benno Lossin --- v3 -> v4: No changes. v2 -> v3: - added Reviewed-by's from Martin. rust/kernel/init/macros.rs | 126 ++++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 57 deletions(-) diff --git a/rust/kernel/init/macros.rs b/rust/kernel/init/macros.rs index d54243cd3c82..bee172e8599e 100644 --- a/rust/kernel/init/macros.rs +++ b/rust/kernel/init/macros.rs @@ -45,7 +45,7 @@ //! #[pinned_drop] //! impl PinnedDrop for Foo { //! fn drop(self: Pin<&mut Self>) { -//! println!("{self:p} is getting dropped."); +//! pr_info!("{self:p} is getting dropped."); //! } //! } //! @@ -170,8 +170,10 @@ //! t: T, //! } //! #[doc(hidden)] -//! impl<'__pin, T> -//! ::core::marker::Unpin for Bar where __Unpin<'__pin, T>: ::c= ore::marker::Unpin {} +//! impl<'__pin, T> ::core::marker::Unpin for Bar +//! where +//! __Unpin<'__pin, T>: ::core::marker::Unpin, +//! {} //! // Now we need to ensure that `Bar` does not implement `Drop`, sin= ce that would give users //! // access to `&mut self` inside of `drop` even if the struct was p= inned. This could lead to //! // UB with only safe code, so we disallow this by giving a trait i= mplementation error using @@ -188,8 +190,9 @@ //! // for safety, but a good sanity check, since no normal code calls= `PinnedDrop::drop`. //! #[allow(non_camel_case_types)] //! trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {} -//! impl -//! UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {} +//! impl< +//! T: ::kernel::init::PinnedDrop, +//! > UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for T {} //! impl UselessPinnedDropImpl_you_need_to_specify_PinnedDrop for B= ar {} //! }; //! ``` @@ -219,7 +222,7 @@ //! // return type and shadow it later when we insert the arbi= trary user code. That way //! // there will be no possibility of returning without `unsa= fe`. //! struct __InitOk; -//! // Get the pin-data type from the initialized type. +//! // Get the data about fields from the supplied type. //! // - the function is unsafe, hence the unsafe block //! // - we `use` the `HasPinData` trait in the block, it is o= nly available in that //! // scope. @@ -227,8 +230,7 @@ //! use ::kernel::init::__internal::HasPinData; //! Self::__pin_data() //! }; -//! // Use `data` to help with type inference, the closure sup= plied will have the type -//! // `FnOnce(*mut Self) -> Result<__InitOk, Infallible>`. +//! // Ensure that `data` really is of type `PinData` and help= with type inference: //! let init =3D ::kernel::init::__internal::PinData::make_clo= sure::< //! _, //! __InitOk, @@ -236,71 +238,75 @@ //! >(data, move |slot| { //! { //! // Shadow the structure so it cannot be used to re= turn early. If a user -//! // tries to write `return Ok(__InitOk)`, then they= get a type error, since -//! // that will refer to this struct instead of the o= ne defined above. +//! // tries to write `return Ok(__InitOk)`, then they= get a type error, +//! // since that will refer to this struct instead of= the one defined +//! // above. //! struct __InitOk; //! // This is the expansion of `t,`, which is syntact= ic sugar for `t: t,`. -//! unsafe { ::core::ptr::write(::core::addr_of_mut!((= *slot).t), t) }; -//! // Since initialization could fail later (not in t= his case, since the error -//! // type is `Infallible`) we will need to drop this= field if there is an -//! // error later. This `DropGuard` will drop the fie= ld when it gets dropped -//! // and has not yet been forgotten. We make a refer= ence to it, so users -//! // cannot `mem::forget` it from the initializer, s= ince the name is the same -//! // as the field (including hygiene). -//! let t =3D &unsafe { -//! ::kernel::init::__internal::DropGuard::new( -//! ::core::addr_of_mut!((*slot).t), -//! ) +//! { +//! unsafe { ::core::ptr::write(::core::addr_of_mu= t!((*slot).t), t) }; +//! } +//! // Since initialization could fail later (not in t= his case, since the +//! // error type is `Infallible`) we will need to dro= p this field if there +//! // is an error later. This `DropGuard` will drop t= he field when it gets +//! // dropped and has not yet been forgotten. +//! let t =3D unsafe { +//! ::pinned_init::__internal::DropGuard::new(::co= re::addr_of_mut!((*slot).t)) //! }; //! // Expansion of `x: 0,`: -//! // Since this can be an arbitrary expression we ca= nnot place it inside of -//! // the `unsafe` block, so we bind it here. -//! let x =3D 0; -//! unsafe { ::core::ptr::write(::core::addr_of_mut!((= *slot).x), x) }; +//! // Since this can be an arbitrary expression we ca= nnot place it inside +//! // of the `unsafe` block, so we bind it here. +//! { +//! let x =3D 0; +//! unsafe { ::core::ptr::write(::core::addr_of_mu= t!((*slot).x), x) }; +//! } //! // We again create a `DropGuard`. -//! let x =3D &unsafe { -//! ::kernel::init::__internal::DropGuard::new( -//! ::core::addr_of_mut!((*slot).x), -//! ) +//! let x =3D unsafe { +//! ::kernel::init::__internal::DropGuard::new(::c= ore::addr_of_mut!((*slot).x)) //! }; -//! +//! // Since initialization has successfully completed= , we can now forget +//! // the guards. This is not `mem::forget`, since we= only have +//! // `&DropGuard`. +//! ::core::mem::forget(x); +//! ::core::mem::forget(t); //! // Here we use the type checker to ensure that eve= ry field has been //! // initialized exactly once, since this is `if fal= se` it will never get //! // executed, but still type-checked. -//! // Additionally we abuse `slot` to automatically i= nfer the correct type for -//! // the struct. This is also another check that eve= ry field is accessible -//! // from this scope. +//! // Additionally we abuse `slot` to automatically i= nfer the correct type +//! // for the struct. This is also another check that= every field is +//! // accessible from this scope. //! #[allow(unreachable_code, clippy::diverging_sub_ex= pression)] -//! if false { +//! let _ =3D || { //! unsafe { //! ::core::ptr::write( //! slot, //! Self { -//! // We only care about typecheck fi= nding every field here, -//! // the expression does not matter,= just conjure one using -//! // `panic!()`: +//! // We only care about typecheck fi= nding every field +//! // here, the expression does not m= atter, just conjure +//! // one using `panic!()`: //! t: ::core::panic!(), //! x: ::core::panic!(), //! }, //! ); //! }; -//! } -//! // Since initialization has successfully completed= , we can now forget the -//! // guards. This is not `mem::forget`, since we onl= y have `&DropGuard`. -//! unsafe { ::kernel::init::__internal::DropGuard::fo= rget(t) }; -//! unsafe { ::kernel::init::__internal::DropGuard::fo= rget(x) }; +//! }; //! } //! // We leave the scope above and gain access to the pre= viously shadowed //! // `__InitOk` that we need to return. //! Ok(__InitOk) //! }); //! // Change the return type from `__InitOk` to `()`. -//! let init =3D move |slot| -> ::core::result::Result<(), ::c= ore::convert::Infallible> { +//! let init =3D move | +//! slot, +//! | -> ::core::result::Result<(), ::core::convert::Infallibl= e> { //! init(slot).map(|__InitOk| ()) //! }; //! // Construct the initializer. //! let init =3D unsafe { -//! ::kernel::init::pin_init_from_closure::<_, ::core::con= vert::Infallible>(init) +//! ::kernel::init::pin_init_from_closure::< +//! _, +//! ::core::convert::Infallible, +//! >(init) //! }; //! init //! } @@ -374,7 +380,10 @@ //! b: Bar, //! } //! #[doc(hidden)] -//! impl<'__pin> ::core::marker::Unpin for Foo where __Unpin<'__pin>: = ::core::marker::Unpin {} +//! impl<'__pin> ::core::marker::Unpin for Foo +//! where +//! __Unpin<'__pin>: ::core::marker::Unpin, +//! {} //! // Since we specified `PinnedDrop` as the argument to `#[pin_data]= `, we expect `Foo` to //! // implement `PinnedDrop`. Thus we do not need to prevent `Drop` i= mplementations like //! // before, instead we implement `Drop` here and delegate to `Pinne= dDrop`. @@ -403,7 +412,7 @@ //! #[pinned_drop] //! impl PinnedDrop for Foo { //! fn drop(self: Pin<&mut Self>) { -//! println!("{self:p} is getting dropped."); +//! pr_info!("{self:p} is getting dropped."); //! } //! } //! ``` @@ -414,7 +423,7 @@ //! // `unsafe`, full path and the token parameter are added, everything e= lse stays the same. //! unsafe impl ::kernel::init::PinnedDrop for Foo { //! fn drop(self: Pin<&mut Self>, _: ::kernel::init::__internal::OnlyC= allFromDrop) { -//! println!("{self:p} is getting dropped."); +//! pr_info!("{self:p} is getting dropped."); //! } //! } //! ``` @@ -449,18 +458,21 @@ //! >(data, move |slot| { //! { //! struct __InitOk; -//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).a= ), a) }; -//! let a =3D &unsafe { +//! { +//! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slo= t).a), a) }; +//! } +//! let a =3D unsafe { //! ::kernel::init::__internal::DropGuard::new(::core::add= r_of_mut!((*slot).a)) //! }; -//! let b =3D Bar::new(36); +//! let init =3D Bar::new(36); //! unsafe { data.b(::core::addr_of_mut!((*slot).b), b)? }; -//! let b =3D &unsafe { +//! let b =3D unsafe { //! ::kernel::init::__internal::DropGuard::new(::core::add= r_of_mut!((*slot).b)) //! }; -//! +//! ::core::mem::forget(b); +//! ::core::mem::forget(a); //! #[allow(unreachable_code, clippy::diverging_sub_expression= )] -//! if false { +//! let _ =3D || { //! unsafe { //! ::core::ptr::write( //! slot, @@ -470,13 +482,13 @@ //! }, //! ); //! }; -//! } -//! unsafe { ::kernel::init::__internal::DropGuard::forget(a) = }; -//! unsafe { ::kernel::init::__internal::DropGuard::forget(b) = }; +//! }; //! } //! Ok(__InitOk) //! }); -//! let init =3D move |slot| -> ::core::result::Result<(), ::core::con= vert::Infallible> { +//! let init =3D move | +//! slot, +//! | -> ::core::result::Result<(), ::core::convert::Infallible> { //! init(slot).map(|__InitOk| ()) //! }; //! let init =3D unsafe { --=20 2.41.0