Skip to content

future: provide infrastructure to print shared-ownership types in a way that reflects the shared graph structure #6187

Closed
@pnkfelix

Description

@pnkfelix

Old title: future: extend %? printing to reflect shared graph structure of @-referenced objects

Previously this bug was just covering @mut T (now Gc<RefCell<T>>) and described overriding the reflection-based {:?} printer. Old text below.

Some types like Rc and Gc provide the ability to share state, it would be neat if we could print values that reflected this (see below for some examples). Providing a general interface that types can use to get equivalent printing would be optimal, but, if necessary, we can restrict it to just being implemented for Rc and Gc (although of course others would be welcome to borrow/adjust the implementation for their use case).

This may end up requiring some special formatting traits (or something like ~[Rc<T>] will not be printed properly), and so may be better suited to an external library.

Old text.

Discussions on Issue #3768 made me wonder about how we might extend Rust to precisely (and succinctly) print out structure with shared state.

Consider for example this code:

fn main() {
    struct two<L,R> { l:L, r:R };
    let a = two{ l:0, r:0 };
    let b = @mut a;
    let c = two{ l:&b, r: b};
    let g = two{ l:&c, r: @mut a };
    io::println(fmt!(" pre g: %?", g));
    io::println("now set g.l.l.l = 1;");
    g.l.l.l = 1;
    io::println(fmt!("post g: %?", g));
}

the print out you get is:

 pre g: {l: &{l: &@mut {l: 0, r: 0}, r: @mut {l: 0, r: 0}}, r: @mut {l: 0, r: 0}}
now set g.l.l.l = 1;
post g: {l: &{l: &@mut {l: 1, r: 0}, r: @mut {l: 1, r: 0}}, r: @mut {l: 0, r: 0}}

It might be nice if we extended the notation for @-references so that if there is shared substructure, it is annotated to reflect the shared objects' identities. As inspired by say Lisp/Scheme, many dialects of which use #n=<foo> as a binder and #n# as a reference, we might print:

 pre g: {l: &{l: &@mut #1={l: 0, r: 0}, r: @mut #1#}, r: @mut {l: 0, r: 0}}
now set g.l.l.l = 1;
post g: {l: &{l: &@mut #1={l: 1, r: 0}, r: @mut #1#}, r: @mut {l: 0, r: 0}}

Caveat: I'm not wedded to any particular notation, and perhaps this job is better left to an end-user library to handle, rather than coupling it to %?.

But since some people do want %? to be robust in the face of cycles, we might consider also keeping it honest? Just a thought.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-prettyArea: Pretty printing (including `-Z unpretty`)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions