Repository: rust-lang/rust
File: compiler/rustc_macros/src/query.rs (Rust)

Code before:
        let modifiers = parse_query_modifiers(&content)?;

        // If there are no doc-comments, give at least some idea of what
        // it does by showing the query description.
        if doc_comments.is_empty() {
            doc_comments.push(doc_comment_from_desc(&modifiers.desc.expr_list)?);
        }

        Ok(Query { doc_comments, modifiers, name, key, arg, result })
    }
}

/// A type used to greedily parse another type until the input is empty.
struct List<T>(Vec<T>);

impl<T: Parse> Parse for List<T> {
    fn parse(input: ParseStream<'_>) -> Result<Self> {
        let mut list = Vec::new();
        while !input.is_empty() {
            list.push(input.parse()?);
        }
        Ok(List(list))
    }
}

/// The description of the query.
struct Desc {
    modifier: Ident,
    tcx_binding: Option<Ident>,
    expr_list: Punctuated<Expr, Token![,]>,
}

/// Cache the query to disk if the `Block` returns true.
struct CacheOnDiskIf {
    modifier: Ident,
    tcx_binding: Option<Pat>,
    block: Block,
}

struct QueryModifiers {
    desc: Desc,

    /// Use this type for the in-memory cache.
    arena_cache: Option<Ident>,

    cache_on_disk_if: Option<CacheOnDiskIf>,

    /// A cycle error for this query aborting the compilation with a fatal error.
    cycle_fatal: Option<Ident>,

    /// A cycle error results in a delay_bug call

Review comment (suggestion):
For these structs, I think it would be more helpful to leave the field comments on the `QueryModifiers` fields, and instead document the structs with something like:

```
/// Details of a parsed `desc` modifier.
```

That way the struct docs describe the struct itself, and express a clear connection to the corresponding modifier.

Code after:
        let modifiers = parse_query_modifiers(&content)?;

        // If there are no doc-comments, give at least some idea of what
        // it does by showing the query description.
        if doc_comments.is_empty() {
            doc_comments.push(doc_comment_from_desc(&modifiers.desc.expr_list)?);
        }

        Ok(Query { doc_comments, modifiers, name, key, arg, result })
    }
}

/// A type used to greedily parse another type until the input is empty.
struct List<T>(Vec<T>);

impl<T: Parse> Parse for List<T> {
    fn parse(input: ParseStream<'_>) -> Result<Self> {
        let mut list = Vec::new();
        while !input.is_empty() {
            list.push(input.parse()?);
        }
        Ok(List(list))
    }
}

struct Desc {
    modifier: Ident,
    tcx_binding: Option<Ident>,
    expr_list: Punctuated<Expr, Token![,]>,
}

struct CacheOnDiskIf {
    modifier: Ident,
    tcx_binding: Option<Pat>,
    block: Block,
}

struct QueryModifiers {
    /// The description of the query.
    desc: Desc,

    /// Use this type for the in-memory cache.
    arena_cache: Option<Ident>,

    /// Cache the query to disk if the `Block` returns true.
    cache_on_disk_if: Option<CacheOnDiskIf>,

    /// A cycle error for this query aborting the compilation with a fatal error.
    cycle_fatal: Option<Ident>,

    /// A cycle error results in a delay_bug call