Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rust: trait for impl to inherits and end fields #1604

Conversation

ithinuel
Copy link

@ithinuel ithinuel commented Nov 22, 2017

This PR follows #1603 #1601.

The intent is to have fully qualified trait names associated to type for implementations.

A good use case is vec.rs from rust's sources.
Drop, FromIter and other traits are implemented multiple times for the same type but with different type arguments.

masatake and others added 3 commits November 21, 2017 19:50
(This is based on pull request universal-ctags#1601 submitted by @ithinuel.)

For the input

    impl A for B {

Rust parser emits:

     B	foo.rs	/^impl A for B {$/;"	kind:implementation	inherits:A

This on on the analogy of what Java parser does:

    interface A {
    }
    class B implements A {
    }

For the above input ctags emits for class B:

    B	foo.java	/^class B implements A {$/;"	inherits:A

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.01%) to 86.06% when pulling 3926107 on ithinuel:rust-record-trait-for-impl-to-inherits-field into 157918c on universal-ctags:master.

@masatake
Copy link
Member

 ...
-C	input.rs	/^impl<T> D<T> for C<T> where T: Send$/;"	c	inherits:D	end:42
 C	input.rs	/^pub struct C<T> where T: Send$/;"	s
 D	input.rs	/^pub trait D<T> where T: Send$/;"	i
+D<T> for C<T>	input.rs	/^impl<T> D<T> for C<T> where T: Send$/;"	c	end:42
...

With your change, a user cannot find the following line of source code from search word 'C':

impl<T> D<T> for C<T> where T: Send

A user must specify D<T> for C<T> to find it.
This is not a small regression.

What we have to think first is a newly defined name.

impl<T> D<T> for C<T> where T: Send
  • Though T may have a small scope, T is the newly defined name.
  • D is not a new name. It is defined somewhere. It is rather a reference to the definition.
    However, we can assume it as a new name.
  • C is not a new name.It is defined somewhere. It is rather reference to the name.
    However, we can assume it as a new name. Actually, the current code treats it
    as a definition.

Next what we can add as fields to the tag.

  • For the tag T, Send can be added to a field, where: for example.
  • For the tag C, T can be added to a filed. template: signature? Needs more thinking.
  • For the tag C, D can be added to a field, inherits: or trait:. My choice is inherits:.
    This one is already implemented in my pull request.
  • For the tag D, T can be added to a filed. templateSignature:? Needs more thinking.
  • For the tag D, D can be added to a field. traitTarget: or something?

If we implemented all the above well, enough intelligent editor can make a string

impl<T> D<T> for C<T> where T: Send

So the editor can use the string as it wants.

Providing such low-level information to client tools is a design principle in uctags. Rich information like you want comes after that.

uctags has an infrastructure for providing such rich information.

What I'm thinking of is tagging D<T> for C<T> as an extra tag which is only tagged only when
--extras=+q option is given. q means extra class-qualified tag entry. I wonder we call
call

impl<T> D<T> for C<T> where T: Send

as extra class-qualified tag. I don't know Rust but my initial idea is introducing new Rust parser
specific extra named extra trait-qualified tag.

The following page and commits tell how to add a parser specific extra tag.

I still think adding "trait:" field to method kind tag is not a bad idea as I described in #1603.

@ithinuel
Copy link
Author

Indeed, and the fun really comes for

impl<T: Clone> SpecFromElem for T {
    default fn from_elem(elem: Self, n: usize) -> Vec<Self> { /* ... */ }
}

which means that we provide/implement SpecFromElement for any type which also implement Clone.
T here is not a type we can reference for the implementation.
Creating a tag T which inherit from SpecFromElement makes little sense IHMO.

impl<'a, T: 'a, I> SpecExtend<&'a T, I> for Vec<T>
    where I: Iterator<Item=&'a T>,
          T: Clone

which means implement SpecExtend with the signature SpecExtend<&'a T, I> for the type Vec<T> where T implements Clone and I implements Iterator where Item is &T living for 'a.

impl<T> SpecExtend<T, IntoIter<T>> for Vec<T>

which means implement SpecExtend with the signature SpecExtend<T, IntoIter<T>> (IntoIter being a type) for the type Vec<T>.
This is also different from :

impl<T, I> SpecExtend<T, I> for Vec<T>
    where I: Iterator<Item=T>

which means implement SpecExtend with the signature SpecExtend<T, I> for the type Vec<T> where I implements Iterator where Item is T.

This gets too complicated for me in regards to my knowledge on uctags.
Unfortunatly I cannot spend more time working on this.

Taking a step back, I'm not even sure that the "scope" approach is the right one for this and I don't know who the rust's compiler handle this.

@masatake
Copy link
Member

masatake commented Nov 23, 2017

@ithinuel, thank you very much for taking time.
I understand the reason why you want "full qualified name"; splitting impl line(s) into tags are too complicated.

I will think more about how to handle impl lines.

@masatake masatake self-assigned this Nov 23, 2017
@ithinuel
Copy link
Author

ithinuel commented Apr 16, 2018

I close this as I can't plan to work on that in the next few month.

Thank you for the feedback though !

@masatake
Copy link
Member

This article, https://joshleeb.com/posts/surprising-ctags.html is related to this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants