pub fn check_term(
    context: &TermContext<'_>,
    surface_term: &surface::Term,
    expected_ty: &core::Value,
    report: &mut dyn FnMut(Diagnostic),
) -> core::Term {
    match (surface_term, expected_ty) {
        (surface::Term::Error(span), _) => core::Term::Error(*span),
        (surface_term, core::Value::Error) => core::Term::Error(surface_term.span()),
        (surface::Term::Paren(_, surface_term), expected_ty) => {
            check_term(context, surface_term, expected_ty, report)
        }
        (surface::Term::NumberLiteral(span, literal), _) => match expected_ty {
            core::Value::IntType => match literal.parse_big_int(context.file_id, report) {
                Some(value) => core::Term::IntConst(*span, value),
                None => core::Term::Error(*span),
            },
            core::Value::F32Type => match literal.parse_float(context.file_id, report) {
                Some(value) => core::Term::F32Const(*span, value),
                None => core::Term::Error(*span),
            },
            core::Value::F64Type => match literal.parse_float(context.file_id, report) {
                Some(value) => core::Term::F64Const(*span, value),
                None => core::Term::Error(*span),
            },
            _ => {
                report(diagnostics::error::numeric_literal_not_supported(
                    context.file_id,
                    *span,
                    expected_ty,
                ));
                core::Term::Error(surface_term.span())
            }
        },
        (surface::Term::If(span, surface_term, surface_if_true, surface_if_false), _) => {
            let term = check_term(context, surface_term, &core::Value::BoolType, report);
            let if_true = check_term(context, surface_if_true, expected_ty, report);
            let if_false = check_term(context, surface_if_false, expected_ty, report);

            core::Term::BoolElim(*span, Arc::new(term), Arc::new(if_true), Arc::new(if_false))
        }
        (surface_term, expected_ty) => {
            let (core_term, synth_ty) = synth_term(context, surface_term, report);

            if core::semantics::equal(&synth_ty, expected_ty) {
                core_term
            } else {
                report(diagnostics::type_mismatch(
                    Severity::Error,
                    context.file_id,
                    surface_term.span(),
                    expected_ty,
                    &synth_ty,
                ));
                core::Term::Error(surface_term.span())
            }
        }
    }
}
/// Check a surface term against the given type, and elaborate it into the core syntax.
Check a surface term against the given type, and elaborate it into the core syntax.
Check a surface term against the given type and elaborate it into the core syntax .
pub fn check_term(
    context: &TermContext<'_>,
    surface_term: &surface::Term,
    expected_ty: &core::Value,
    report: &mut dyn FnMut(Diagnostic),
) -> core::Term {
    match (surface_term, expected_ty) {
        (surface::Term::Error(span), _) => core::Term::Error(*span),
        (surface_term, core::Value::Error) => core::Term::Error(surface_term.span()),
        (surface::Term::Paren(_, surface_term), expected_ty) => {
            check_term(context, surface_term, expected_ty, report)
        }
        (surface::Term::NumberLiteral(span, literal), _) => match expected_ty {
            core::Value::IntType => match literal.parse_big_int(context.file_id, report) {
                Some(value) => core::Term::IntConst(*span, value),
                None => core::Term::Error(*span),
            },
            core::Value::F32Type => match literal.parse_float(context.file_id, report) {
                Some(value) => core::Term::F32Const(*span, value),
                None => core::Term::Error(*span),
            },
            core::Value::F64Type => match literal.parse_float(context.file_id, report) {
                Some(value) => core::Term::F64Const(*span, value),
                None => core::Term::Error(*span),
            },
            _ => {
                report(diagnostics::error::numeric_literal_not_supported(
                    context.file_id,
                    *span,
                    expected_ty,
                ));
                core::Term::Error(surface_term.span())
            }
        },
        (surface::Term::If(span, surface_term, surface_if_true, surface_if_false), _) => {
            let term = check_term(context, surface_term, &core::Value::BoolType, report);
            let if_true = check_term(context, surface_if_true, expected_ty, report);
            let if_false = check_term(context, surface_if_false, expected_ty, report);
            core::Term::BoolElim(*span, Arc::new(term), Arc::new(if_true), Arc::new(if_false))
        }
        (surface_term, expected_ty) => {
            let (core_term, synth_ty) = synth_term(context, surface_term, report);
            if core::semantics::equal(&synth_ty, expected_ty) {
                core_term
            } else {
                report(diagnostics::type_mismatch(
                    Severity::Error,
                    context.file_id,
                    surface_term.span(),
                    expected_ty,
                    &synth_ty,
                ));
                core::Term::Error(surface_term.span())
            }
        }
    }
}
pub fn check_term ( context : & TermContext < ' _ > , surface_term : & surface :: Term , expected_ty : & core :: Value , report : & mut dyn FnMut ( Diagnostic ) , ) -> core :: Term { match ( surface_term , expected_ty ) { ( surface :: Term :: Error ( span ) , _ ) => core :: Term :: Error ( * span ) , ( surface_term , core :: Value :: Error ) => core :: Term :: Error ( surface_term . span ( ) ) , ( surface :: Term :: Paren ( _ , surface_term ) , expected_ty ) => { check_term ( context , surface_term , expected_ty , report ) } ( surface :: Term :: NumberLiteral ( span , literal ) , _ ) => match expected_ty { core :: Value :: IntType => match literal . parse_big_int ( context . file_id , report ) { Some ( value ) => core :: Term :: IntConst ( * span , value ) , None => core :: Term :: Error ( * span ) , } , core :: Value :: F32Type => match literal . parse_float ( context . file_id , report ) { Some ( value ) => core :: Term :: F32Const ( * span , value ) , None => core :: Term :: Error ( * span ) , } , core :: Value :: F64Type => match literal . parse_float ( context . file_id , report ) { Some ( value ) => core :: Term :: F64Const ( * span , value ) , None => core :: Term :: Error ( * span ) , } , _ => { report ( diagnostics :: error :: numeric_literal_not_supported ( context . file_id , * span , expected_ty , ) ) ; core :: Term :: Error ( surface_term . span ( ) ) } } , ( surface :: Term :: If ( span , surface_term , surface_if_true , surface_if_false ) , _ ) => { let term = check_term ( context , surface_term , & core :: Value :: BoolType , report ) ; let if_true = check_term ( context , surface_if_true , expected_ty , report ) ; let if_false = check_term ( context , surface_if_false , expected_ty , report ) ; core :: Term :: BoolElim ( * span , Arc :: new ( term ) , Arc :: new ( if_true ) , Arc :: new ( if_false ) ) } ( surface_term , expected_ty ) => { let ( core_term , synth_ty ) = synth_term ( context , surface_term , report ) ; if core :: semantics :: equal ( & synth_ty , expected_ty ) { core_term } else { report ( diagnostics :: type_mismatch ( Severity :: Error , context . file_id , surface_term . span ( ) , expected_ty , & synth_ty , ) ) ; core :: Term :: Error ( surface_term . span ( ) ) } } } }
Check a surface term against the given type, and elaborate it into the core syntax.
Check a surface term against the given type and elaborate it into the core syntax .
context
&TermContext<'_>
surface_term
&surface::Term
expected_ty
&core::Value
report
&mut dyn FnMut(Diagnostic)
context
&TermContext<'_>
surface_term
&surface::Term
expected_ty
&core::Value
report
&mut dyn FnMut(Diagnostic)