1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use crate::parser::Parser;
use crate::syntax::entity::LazyParsedEntityDatabase;
use crate::syntax::identifier::SpannedGlobalIdentifier;
use crate::syntax::Syntax;
use lark_debug_derive::DebugWith;
use lark_entity::Entity;
use lark_error::{ErrorReported, ErrorSentinel, WithError};
use lark_intern::Untern;
use lark_span::{FileName, Span, Spanned};
use lark_string::GlobalIdentifier;
use lark_ty as ty;
use lark_ty::declaration::Declaration;
use lark_ty::TypeFamily;
#[derive(DebugWith)]
pub struct TypeReference;
impl Syntax<'parse> for TypeReference {
type Data = ParsedTypeReference;
fn test(&mut self, parser: &Parser<'parse>) -> bool {
parser.test(SpannedGlobalIdentifier)
}
fn expect(
&mut self,
parser: &mut Parser<'parse>,
) -> Result<ParsedTypeReference, ErrorReported> {
let identifier = parser.expect(SpannedGlobalIdentifier)?;
Ok(ParsedTypeReference::Named(NamedTypeReference {
identifier,
}))
}
}
#[derive(Copy, Clone, DebugWith)]
pub enum ParsedTypeReference {
Named(NamedTypeReference),
Elided(Span<FileName>),
Error,
}
impl ParsedTypeReference {
pub fn parse_type(
&self,
entity: Entity,
db: &dyn LazyParsedEntityDatabase,
) -> WithError<ty::Ty<Declaration>> {
match self {
ParsedTypeReference::Named(named) => named.parse_type(entity, db),
ParsedTypeReference::Elided(_span) => {
WithError::ok(crate::type_conversion::unit_ty(db))
}
ParsedTypeReference::Error => WithError::ok(Declaration::error_type(&db)),
}
}
}
impl<Cx> ErrorSentinel<Cx> for ParsedTypeReference {
fn error_sentinel(_cx: Cx, _report: ErrorReported) -> Self {
ParsedTypeReference::Error
}
}
#[derive(Copy, Clone, DebugWith)]
pub struct NamedTypeReference {
pub identifier: Spanned<GlobalIdentifier, FileName>,
}
impl NamedTypeReference {
pub fn parse_type(
&self,
entity: Entity,
db: &dyn LazyParsedEntityDatabase,
) -> WithError<ty::Ty<Declaration>> {
match db.resolve_name(entity, self.identifier.value) {
Some(entity) => {
let ty = crate::type_conversion::declaration_ty_named(
&db,
entity,
ty::declaration::DeclaredPermKind::Own,
ty::ReprKind::Direct,
ty::Generics::empty(),
);
WithError::ok(ty)
}
None => {
let msg = format!("unknown type: `{}`", self.identifier.untern(&db));
WithError::report_error(&db, msg, self.identifier.span)
}
}
}
}