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

Improve documentation for the position field of the QSelf type, which is difficult to understand. #1386

Open
Luro02 opened this issue Mar 3, 2023 · 0 comments
Labels

Comments

@Luro02
Copy link

Luro02 commented Mar 3, 2023

I struggled for quite a while to understand how to deal with the position field of the
syn::QSelf type. I understand that as an author it is difficult to see parts in a project
that are not understandable, so I made this issue.

I had a few questions that I think the documentation should answer:
The docs mention that the as trait and associated item are stored separately,
but there is no mention of where that is.

It also mentions that the position for AssociatedItem in <Vec<T> as a::b::Trait>::AssociatedItem
is 3, but not how this number changes depending on the type. For example, what would be the position of
the a::b::Trait be? How could one obtain this? An example code would be immensely helpful. I am not good with writing examples, but here is something as an idea:

use quote::ToTokens;
use syn::punctuated::Punctuated;

let ty: syn::TypePath = syn::parse_quote!(<Vec<T> as a::b::Trait>::AssociatedItem);

// the ty.path looks like this a::b::Trait::AssociatedItem
// therefore when a qualified self is involved, it can not
// be treated as a normal path.

// this checks if the ty is cast to a trait and if so, prints
// that trait
if let Some(syn::QSelf {
    ty: sub_ty,
    as_token,
    position,
    ..
}) = &ty.qself
{
    if as_token.is_some() {
        // the type has been cast to another trait
        // the position is the index where the associated item
        // starts in the ty.path
        //
        // everything up to position (0..position) is the trait
        // that it is cast to
        let mut trait_path = syn::Path {
            leading_colon: None,
            segments: Punctuated::new(),
        };

        for i in 0..*position {
            trait_path.segments.push(ty.path.segments[i].clone());
        }

        // a :: b :: Trait
        println!("the ty is cast to {}", trait_path.to_token_stream());
    } else {
        println!("ty has not been casted");
    }
}
@dtolnay dtolnay added the docs label May 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants