wright/parser/
ty.rs

1//! Parser implementation for parsing types.
2
3use crate::ast::ty::{AtomicTy, ReferenceTy, Type};
4
5use super::{
6    Parser,
7    error::{ParserError, ParserErrorKind},
8};
9
10mod primitive;
11mod reference;
12
13impl Type {
14    /// Parse a type signature in source code.
15    pub fn parse(parser: &mut Parser) -> Result<Self, ParserError> {
16        // Atempt to parse atomic types first -- they're the simplest. If we fail to parse, the parser doesn't advance.
17        // Since they're all keywords we don't have to worry at all about under-greedy parsing (yet).
18        if let Ok(atomic) = AtomicTy::parse(parser) {
19            return Ok(Type::Atomic(atomic));
20        }
21
22        let bytes_remaining = parser.bytes_remaining();
23
24        match ReferenceTy::parse(parser) {
25            Ok(reference_ty) => return Ok(Type::Reference(reference_ty)),
26
27            Err(err) => {
28                // If the parser was advanced in parsing the reference type, error out here.
29                if bytes_remaining != parser.bytes_remaining() {
30                    return Err(
31                        err.with_help("encountered error while parsing reference type signature")
32                    );
33                }
34
35                // If we didn't advance we can just ignore the error and try parsing other type signature
36                // forms or fall through to the catch all "expected type signature" error (since it means
37                // we would have not seen an `@` to start a reference type signature).
38            }
39        }
40
41        Err(ParserErrorKind::ExpectedTypeSignature.at(parser.peek_fragment_or_rest_cloned()))
42    }
43}