1use 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];