rustc_builtin_macros/
view_type.rs1use rustc_ast::token::TokenKind;
2use rustc_ast::tokenstream::TokenStream;
3use rustc_ast::{Ty, ast};
4use rustc_errors::PResult;
5use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
6use rustc_parse::parser::{ExpTokenPair, TokenType};
7use rustc_span::{Ident, Span};
8use thin_vec::ThinVec;
9
10pub(crate) fn expand<'cx>(
11 cx: &'cx mut ExtCtxt<'_>,
12 sp: Span,
13 tts: TokenStream,
14) -> MacroExpanderResult<'cx> {
15 let (ty, pat) = match parse_view_ty(cx, tts) {
16 Ok(parsed) => parsed,
17 Err(err) => {
18 return ExpandResult::Ready(DummyResult::any(sp, err.emit()));
19 }
20 };
21
22 ExpandResult::Ready(base::MacEager::ty(cx.ty(sp, ast::TyKind::View(ty, pat))))
23}
24
25fn parse_view_ty<'a>(
26 cx: &mut ExtCtxt<'a>,
27 stream: TokenStream,
28) -> PResult<'a, (Box<Ty>, ThinVec<Ident>)> {
29 let mut parser = cx.new_parser_from_tts(stream);
30
31 let ty = parser.parse_ty()?;
32
33 parser.expect(ExpTokenPair { tok: TokenKind::Dot, token_type: TokenType::Dot })?;
34
35 let fields = match parser.parse_delim_comma_seq(
36 ExpTokenPair { tok: TokenKind::OpenBrace, token_type: TokenType::OpenBrace },
37 ExpTokenPair { tok: TokenKind::CloseBrace, token_type: TokenType::CloseBrace },
38 |p| p.parse_field_name(),
39 ) {
40 Ok((fields, _)) => fields,
41 Err(diag) => {
42 return Err(diag);
43 }
44 };
45
46 Ok((ty, fields))
47}