Skip to content

add a trait for smart pointer dereference #7141

Closed
@thestinger

Description

@thestinger
Contributor

At a minimum, a trait for obtaining an immutable reference from a type used to overload *x and &*x.

Obtaining mutable references and moving out of pointers can be left out, as they're only useful on a unique pointer type. It can be revisited in the future if a compelling use case ever comes up.

Activity

pnkfelix

pnkfelix commented on Aug 22, 2013

@pnkfelix
Member

Visiting for bug triage, email from 2013-08-12
@thestinger : My best guess is that you want a trait that provides something analogous to operator new(size_t) allocation static method in C++, and then when one uses the ~<expr> or @<expr> forms, it would implicitly call out to the trait's implementation of that allocation method? Can you confirm this, or provide more specific information on what you are proposing?

(Thinking off the top of my head, the GC guy in me figures we might need or at least want to have two methods in the Trait, or via some other analogous manner provide information about whether the context of the invocation is ~ or @.)

pnkfelix

pnkfelix commented on Aug 23, 2013

@pnkfelix
Member

Also, I think pcwalton's blog post and his plans for smart-pointers, moving GC to a library, etc, are relevant material here.

brson

brson commented on Oct 30, 2013

@brson
Contributor

Being able to override dereference is looking increasingly important as we jettison pointer types, and probably newtype dereferencing (#6246), from the language. Nominating.

nikomatsakis

nikomatsakis commented on Oct 31, 2013

@nikomatsakis
Contributor

cc me

pnkfelix

pnkfelix commented on Nov 1, 2013

@pnkfelix
Member

i'm not sure what I was thinking in my first comment above, since @thestinger is clearly talking about pointer-dereference, not memory allocation.

pnkfelix

pnkfelix commented on Nov 7, 2013

@pnkfelix
Member

accepted for 1.0 backcompat lang.

pcwalton

pcwalton commented on Nov 22, 2013

@pcwalton
Contributor

Nominating as I believe this is out of scope for 1.0. We can just special case GC.

huonw

huonw commented on Nov 22, 2013

@huonw
Member

What about Rc?

pnkfelix

pnkfelix commented on Dec 19, 2013

@pnkfelix
Member

deferring decision about any change in p-status for this bug until we can meet with pcwalton

pnkfelix

pnkfelix commented on Jan 9, 2014

@pnkfelix
Member

leaving on 1.0 for now. (If later work with box construct proves it to be unneeded, we'll remove it then.)

larsbergstrom

larsbergstrom commented on Feb 13, 2014

@larsbergstrom
Contributor

I'd love to see this for use in Rc and Cell \ RefCell scenarios. We have code all over Servo post-@mut removal that looks like source_frame.borrow().children.borrow_mut().get().mut_iter() and reads much better as source_frame.children.mut_iter().

nikomatsakis

nikomatsakis commented on Feb 14, 2014

@nikomatsakis
Contributor

I've been wanting to write up something more detailed but failing, so let me sketch out the design I had in mind.

Basically we had two traits:

trait DerefImm<E> {
    fn deref<'a>(&'a self) -> &'a E;
}

trait DerefMut<E> : DerefImm<E> {
    fn deref<'a>(&'a mut self) -> &'a mut E;
}

The structure of these traits encodes an "inherited mutability" like structure -- in other words, these traits can faithfully model Rc<T>, Gc<T>, and ~T but not &mut T nor RefCell<T>, which each have their own complications.

I don't intend to ever permit smart pointers that act like &mut T. Basically an &mut T is mutable if it's in a unique location, whereas these smart pointers (like ~T) are mutable if they are in a mutable (note: implies unique) location. At worst this means smart pointers need an extra mut declaration.

RefCell<T> we might like to support someday but I'm not sure. There is value in having the fallible borrows be highlighted. Note however that we can use this trait for the Ref and RefMut types that RefCell returns (in fact, RefMut is a good example of a case where it might be nice to act like &mut but oh well).

I think the implementation here has to go in two phases:

  1. Add support for explicit uses, e.g. *x, &*x, or (*x).method().
  2. Add support for implicit autoderefs. This has additional complications I don't want to go into just yet since I don't have time.

For step 1, one challenge is that we have to instrument type check to pass down more context. In particular, to type check an expression, we have to know whether it is in a "mutable lvalue" context or not. For example, when we type check the expression *E in &mut *E, we will want to use the DerefMut trait. But if we type check the same *E in the context of &*E it will use the DerefImm trait.

The other challenge is that the trait returns a reference &T, but the "type" of *E is T. That means we need to insert an autoderef adjustment. Currently our system is geared to the idea that when we type check an expression there are no adjustments, and then the context may add adjustments. In this case, the type check of the expression itself would insert an adjustment. This means we have to modify the various routines in the function context to take into account the possible presence of an adjustment:

  • write_autoderef_adjustment()
  • write_adjustment()
  • expr_ty() probably wants to return the adjusted type (and maybe to be renamed to reflect that)

The adjustment data structure itself could be refactored to make this nicer (into something more layerable, like a cons list of adjustments), but I'd hold off on that since it's adequate for the current purpose.

OK, that's a high-level sketch, happy to provide more details on request.

nikomatsakis

nikomatsakis commented on Feb 14, 2014

@nikomatsakis
Contributor

(And I do plan to write up a proper RFC with more details and examples... but I'm working on several of those)

45 remaining items

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

    C-enhancementCategory: An issue proposing an enhancement or a PR with one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @brson@nikomatsakis@pcwalton@pnkfelix@larsbergstrom

        Issue actions

          add a trait for smart pointer dereference · Issue #7141 · rust-lang/rust