1- use crate :: common:: Span ;
21use crate :: common:: diagnostics:: * ;
32use crate :: semantics:: {
43 resolver:: SymbolTable ,
54 resolved_ast as r,
65 typed_ast as t,
76} ;
87
9- pub fn check ( resolved_ast : r:: ResolvedAst , symbols : & mut SymbolTable , _diagnostics : & mut impl DiagnosticSink ) -> t:: TypedAst {
10- let mut tc = TypeChecker :: new ( symbols) ;
8+ pub fn check ( resolved_ast : r:: ResolvedAst , symbols : & mut SymbolTable , diagnostics : & mut impl DiagnosticSink ) -> t:: TypedAst {
9+ let mut tc = TypeChecker :: new ( symbols, diagnostics ) ;
1110 tc. type_check ( resolved_ast)
1211}
1312
@@ -19,21 +18,16 @@ pub enum Type {
1918 Error ,
2019}
2120
22- pub enum TypeError {
23- Mismatch ( Type , Type , Span ) ,
24- UntypedSymbol ( Span ) ,
25- }
26-
27- struct TypeChecker < ' a > {
21+ struct TypeChecker < ' a , ' d , D : DiagnosticSink > {
2822 symbols : & ' a mut SymbolTable ,
29- errors : Vec < TypeError >
23+ diags : & ' d mut D ,
3024}
3125
32- impl < ' a > TypeChecker < ' a > {
33- fn new ( symbols : & ' a mut SymbolTable ) -> Self {
26+ impl < ' a , ' d , D : DiagnosticSink > TypeChecker < ' a , ' d , D > {
27+ fn new ( symbols : & ' a mut SymbolTable , diags : & ' d mut D ) -> Self {
3428 Self {
3529 symbols,
36- errors : Vec :: new ( ) ,
30+ diags ,
3731 }
3832 }
3933
@@ -49,8 +43,7 @@ impl<'a> TypeChecker<'a> {
4943 }
5044}
5145
52-
53- impl TypeChecker < ' _ > {
46+ impl < D : DiagnosticSink > TypeChecker < ' _ , ' _ , D > {
5447 fn check_stmt ( & mut self , stmt : r:: Stmt ) -> t:: Stmt {
5548 let kind = match stmt. kind {
5649 r:: StmtKind :: Let { sym, value } => {
@@ -78,10 +71,7 @@ impl TypeChecker<'_> {
7871 let ty = self . symbols
7972 . get ( sym) . ty
8073 . clone ( )
81- . unwrap_or_else ( || {
82- self . errors . push ( TypeError :: UntypedSymbol ( expr. span ) ) ;
83- Type :: Error
84- } ) ;
74+ . expect ( & format ! ( "[Typechecker] Internal error: tried to get type of the untyped symbol {:?}" , sym) ) ;
8575
8676 t:: Expr {
8777 kind : t:: ExprKind :: Identifier { sym } ,
@@ -132,12 +122,16 @@ impl TypeChecker<'_> {
132122 let mut t_expr = self . infer ( expr) ;
133123
134124 if t_expr. ty != expected && !matches ! ( t_expr. ty, Type :: Error | Type :: Never ) {
135- self . errors . push ( TypeError :: Mismatch ( t_expr. ty . clone ( ) , expected, t_expr. span ) ) ;
125+ self . diags . emit (
126+ Diagnostic :: error ( "type mismatch" )
127+ . with_span ( t_expr. span )
128+ . note ( format ! ( "expected type: {:?}" , expected) )
129+ . note ( format ! ( "actual type: {:?}" , t_expr. ty) )
130+ ) ;
136131 t_expr. ty = Type :: Error
137132 }
138133
139134 t_expr
140135 }
141136}
142137
143-
0 commit comments