Rustdoc considers *const T and *mut T different

82f2413
Opened by Jesse Ruderman at 2022-01-18 21:36:13

https://doc.rust-lang.org/core/ptr/struct.Unique.html

is_null, offset, and as_ref are listed twice. This is confusing and makes the HTML invalid. I'm not sure what's going on here.

  1. The bug here is that *const T and *mut T are classified as the same kind of pointer, so when the Deref implementation is seen it inlines the inherent methods from those two pointer types, and both have an is_null method. This would likely be dealt by not having both pointer types be represented as the same type in rustdoc.

    Alex Crichton at 2015-04-28 16:42:53

  2. Unique changed, so this specific issue is no longer relevant.

    Marcell Pardavi at 2016-03-29 22:31:59

  3. So, in attempting to recreate this bug, I first looked at https://doc.rust-lang.org/1.0.0/core/ptr/struct.Unique.html to see what it looked like when Unique existed. I then used this code:

    use std::ops::Deref;
    
    pub struct Unique<T: ?Sized> {
        pointer: *const T,
    }
    
    impl<T:?Sized> Deref for Unique<T> {
        type Target = *mut T;
    
        #[inline]
        fn deref<'a>(&'a self) -> &'a *mut T {
            unsafe { mem::transmute(&*self.pointer) }
        }
    }
    

    This gives

    image

    with no methods at all! That seems... strange?

    Steve Klabnik at 2018-10-31 14:33:38

  4. I spent some time looking into this, and there are a couple of intertwined issues.

    • First, we don't seem to properly add the relevant Deref targets to the set of implementations that should be displayed, in particular when those targets are primitives. I tried the same example mentioned above and it works with slices and str, but not with any other primitive. This happens in the collect-trait-impls pass.
    • Also, even when hacking a bit to make it find the relevant targets, we end up not displaying any methods: Screenshot at 2019-12-07 11:16:37 This happens because (almost?) all methods in primitives have by-value self, and we don't show those methods in "Methods from Deref" blocks.

    So it seems that the first issue to solve is to make rustdoc display Deref-inherited methods with by-value self when the target is Copy. This, however, has been discussed before (https://github.com/rust-lang/rust/issues/30607, https://github.com/rust-lang/rust/pull/33396, https://github.com/rust-lang/rust/issues/39550, https://github.com/rust-lang/rust/pull/45645) and deemed too difficult.

    Roberto Vidal at 2019-12-07 10:22:55