ide_completion/completions/attribute/
repr.rs

1//! Completion for representations.
2
3use ide_db::SymbolKind;
4use syntax::ast;
5
6use crate::{Completions, context::CompletionContext, item::CompletionItem};
7
8pub(super) fn complete_repr(
9    acc: &mut Completions,
10    ctx: &CompletionContext<'_>,
11    input: ast::TokenTree,
12) {
13    if let Some(existing_reprs) = super::parse_comma_sep_expr(input) {
14        for &ReprCompletion { label, snippet, lookup, collides } in REPR_COMPLETIONS {
15            let repr_already_annotated = existing_reprs
16                .iter()
17                .filter_map(|expr| match expr {
18                    ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
19                    ast::Expr::CallExpr(call) => match call.expr()? {
20                        ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
21                        _ => None,
22                    },
23                    _ => None,
24                })
25                .any(|it| {
26                    let text = it.text();
27                    lookup.unwrap_or(label) == text || collides.contains(&text.as_str())
28                });
29            if repr_already_annotated {
30                continue;
31            }
32
33            let mut item = CompletionItem::new(
34                SymbolKind::BuiltinAttr,
35                ctx.source_range(),
36                label,
37                ctx.edition,
38            );
39            if let Some(lookup) = lookup {
40                item.lookup_by(lookup);
41            }
42            if let Some((snippet, cap)) = snippet.zip(ctx.config.snippet_cap) {
43                item.insert_snippet(cap, snippet);
44            }
45            item.add_to(acc, ctx.db);
46        }
47    }
48}
49
50struct ReprCompletion {
51    label: &'static str,
52    snippet: Option<&'static str>,
53    lookup: Option<&'static str>,
54    collides: &'static [&'static str],
55}
56
57const fn attr(label: &'static str, collides: &'static [&'static str]) -> ReprCompletion {
58    ReprCompletion { label, snippet: None, lookup: None, collides }
59}
60
61#[rustfmt::skip]
62const REPR_COMPLETIONS: &[ReprCompletion] = &[
63    ReprCompletion { label: "align($0)", snippet: Some("align($0)"), lookup: Some("align"), collides: &["transparent", "packed"] },
64    attr("packed", &["transparent", "align"]),
65    attr("transparent", &["C", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
66    attr("C", &["transparent"]),
67    attr("u8",     &["transparent", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
68    attr("u16",    &["transparent", "u8", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
69    attr("u32",    &["transparent", "u8", "u16", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
70    attr("u64",    &["transparent", "u8", "u16", "u32", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
71    attr("u128",   &["transparent", "u8", "u16", "u32", "u64", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
72    attr("usize",  &["transparent", "u8", "u16", "u32", "u64", "u128", "i8", "i16", "i32", "i64", "i128", "isize"]),
73    attr("i8",     &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i16", "i32", "i64", "i128", "isize"]),
74    attr("i16",    &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i32", "i64", "i128", "isize"]),
75    attr("i32",    &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i64", "i128", "isize"]),
76    attr("i64",    &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i128", "isize"]),
77    attr("i28",    &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "isize"]),
78    attr("isize",  &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128"]),
79];