Skip to content

Tracking issue for std::ptr::eq, Arc::ptr_eq, and Rc::ptr_eq #36497

Description

@SimonSapin

Implemented in #35992 as #[unstable(feature = "ptr_eq")].

std::ptr::eq is rust-lang/rfcs#1155.

Activity

  1. added
    T-libs-api[DEPRECATED; DO NOT USE]
    B-unstableBlocker: Implemented in the nightly compiler and unstable.
    on Sep 15, 2016
  2. vadixidav commented on Nov 25, 2016

    @vadixidav
    Contributor

    I needed Rc::ptr_eq to avoid a double borrow in a recursive data structure with Rc<RefCell< T >>. Thanks a lot!

  3. SimonSapin commented on Nov 25, 2016

    @SimonSapin
    ContributorAuthor

    @vadixidav It can be implemented outside of std by tweaking it a bit. Copy-pasting this into your code can unblock you until Rc::prt_eq is stabilized:

    pub fn rc_ptr_eq<T: ?Sized>(this: &Rc<T>, other: &Rc<T>) -> bool {
        let this_ptr: *const T = &*this;
        let other_ptr: *const T = &*other;
        this_ptr == other_ptr
    }
  4. alexcrichton commented on Feb 14, 2017

    @alexcrichton
    Member

    Seem like good/easy APIs to stabilize!

    @rfcbot fcp merge

  5. rfcbot commented on Feb 14, 2017

    @rfcbot

    Team member @alexcrichton has proposed to merge this. The next step is review by the rest of the tagged teams:

    No concerns currently listed.

    Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

    See this document for info about what commands tagged team members can give me.

  6. federicomenaquintero commented on Feb 17, 2017

    @federicomenaquintero
    Contributor

    FWIW, I just found a good use for this in librsvg's port to Rust.

    Librsvg has a Node structure for the tree of SVG objects. The C code keeps around RsvgNode* values all over the place, including multiple references to the same value.

    Sometimes there is code like if (current_node == tree_root) for special-casing... and you see where this is going.

    The things I expose to the C code are pointers that come from Box<Rc<Node>> I also expose node_ref() and node_unref() functions so that C can get new references to existing nodes and discard them as needed.

    This means that

      RsvgNode *node1 = rsvg_rust_cnode_new (...);  /* returns a Box::into_raw (Box::new (Rc::new (Node))) */
      RsvgNode *node2 = rsvg_node_ref (node1);
    
      assert (node1 == node2);
    

    is invalid now. What I want is to

      assert (rsvg_node_is_same (node1, node2));
    

    and that can be implemented as

    pub type RsvgNode = Rc<Node>;
    
    #[no_mangle]
    pub extern fn rsvg_node_is_same (raw_node1: *const RsvgNode, raw_node2: *const RsvgNode) -> bool {
        if raw_node1.is_null () && raw_node2.is_null () {
            true
        } else if !raw_node1.is_null () && !raw_node2.is_null () {
            let node1: &RsvgNode = unsafe { & *raw_node1 };
            let node2: &RsvgNode = unsafe { & *raw_node2 };
    
            Rc::ptr_eq (node1, node2)
        } else {
            false
        }
    }
    

    For now I'm using @SimonSapin's code (it's missing double asterisks in &**this and &**other), but it would indeed be nice to have an Rc::ptr_eq() in stable!

  7. SimonSapin commented on Feb 17, 2017

    @SimonSapin
    ContributorAuthor

    For now I'm using @SimonSapin's code

    I sometimes find convenient to make it less generic (when it’s only used with one T type):

    fn same_node(a: *const Node, b: *const Node) -> bool {
        a == b
    }

    This looks the same as ==, but since it expects raw pointer they can be coerced implicitly from references. (And, by the way, (*const T)::as_ref() can be more convenient than is_null)

    #[no_mangle]
    pub extern fn rsvg_node_is_same (raw_node1: *const RsvgNode, raw_node2: *const RsvgNode) -> bool {
        match (raw_node1.as_ref(), raw_node2.as_ref()) {
            (Some(node1), Some(node2)) => same_node(&**node1, &**node2),
            (None, None) => true,
            _ => false
        }
    }

    (Of course, Rc::eq is nicer still.)

  8. alexcrichton commented on Feb 28, 2017

    @alexcrichton
    Member

    ping @BurntSushi (checkbox)

  9. rfcbot commented on Feb 28, 2017

    @rfcbot

    🔔 This is now entering its final comment period, as per the review above. 🔔

  10. added
    final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.
    on Feb 28, 2017
  11. rfcbot commented on Mar 10, 2017

    @rfcbot

    The final comment period is now complete.

  12. added a commit that references this issue on Mar 17, 2017
    698c1bb
  13. matklad commented on Dec 31, 2020

    @matklad
    Contributor

    For future GitHub travelers, investigating clippy::vtable_address_comparisons:

    Looks like the methods were stabilized with the ?Sized bound, while the current impl doesn't quite handle them. Specifically, ptr_eq can spuriously return false for identical trait objects. This is being tracked in #69757.

  14. SimonSapin commented on Dec 31, 2020

    @SimonSapin
    ContributorAuthor

    This is not unique to these ptr_eq methods. Wide pointers to trait objects have been comparable with the == operator forever, with the same spurious results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    B-unstableBlocker: Implemented in the nightly compiler and unstable.T-libs-api[DEPRECATED; DO NOT USE]final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions