|
| 1 | +#![allow(missing_docs, missing_debug_implementations)] |
| 2 | +// Poor man's `k#autoref` operator. |
| 3 | +// |
| 4 | +// See https://github.com/rust-lang/rust/issues/99684 |
| 5 | +// and https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Desired.20behavior.20of.20.60write!.60.20is.20unimplementable |
| 6 | +// for some more context about this idea. |
| 7 | +// |
| 8 | +// Right now we polyfill this idea, by reducing support to `&mut`-autoref-only |
| 9 | +// (effectively "just" preventing an unnecessary `&mut` level of indirection |
| 10 | +// from being applied for a thing already behind a `&mut …`), which happens to |
| 11 | +// work for `&mut`-based `.write_fmt()` methods, and some cases of `&`-based |
| 12 | +// `.write_fmt()` —the whole duck-typed design / API of `write!` is asking for |
| 13 | +// trouble—, but won't work for a `self`-based `.write_fmt()`, as pointed out |
| 14 | +// here: https://github.com/rust-lang/rust/pull/100202#pullrequestreview-1064499226 |
| 15 | +// |
| 16 | +// Finally, in order to reduce the chances of name conflicts as much as |
| 17 | +// possible, the method name is a bit mangled, and to prevent usage of this |
| 18 | +// method in stable-rust, an unstable const generic parameter that needs to be |
| 19 | +// turbofished is added to it as well. |
| 20 | + |
| 21 | +/// The unstable const generic parameter achieving the "unstable seal" effect. |
| 22 | +#[unstable(feature = "autoref", issue = "none")] |
| 23 | +#[derive(Eq, PartialEq)] |
| 24 | +pub struct UnstableMethodSeal; |
| 25 | + |
| 26 | +#[unstable(feature = "autoref", issue = "none")] |
| 27 | +pub trait AutoRef { |
| 28 | + #[unstable(feature = "autoref", issue = "none")] |
| 29 | + #[inline(always)] |
| 30 | + fn __rustc_unstable_auto_ref_mut_helper<const _SEAL: UnstableMethodSeal>( |
| 31 | + &mut self, |
| 32 | + ) -> &mut Self { |
| 33 | + self |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +#[unstable(feature = "autoref", issue = "none")] |
| 38 | +impl<T: ?Sized> AutoRef for T {} |
| 39 | + |
| 40 | +#[unstable(feature = "autoref", issue = "none")] |
| 41 | +#[allow_internal_unstable(autoref)] |
| 42 | +#[rustc_macro_transparency = "semitransparent"] |
| 43 | +pub macro autoref_mut($x:expr) {{ |
| 44 | + use $crate::ops::autoref::AutoRef as _; |
| 45 | + $x.__rustc_unstable_auto_ref_mut_helper::<{ $crate::ops::autoref::UnstableMethodSeal }>() |
| 46 | +}} |
0 commit comments