@@ -560,6 +560,8 @@ fn type_check_func(func: &Function, prog: &Program) -> Result<(), PositionalInte
560560 . map_err ( |e| e. add_pos ( func. pos . clone ( ) ) ) ;
561561 }
562562
563+ let mut has_return_type_should_have_return = func. return_type . is_none ( ) ;
564+
563565 let mut env: FxHashMap < & str , Type > =
564566 FxHashMap :: with_capacity_and_hasher ( 20 , fxhash:: FxBuildHasher :: default ( ) ) ;
565567 func. args . iter ( ) . for_each ( |a| {
@@ -598,21 +600,34 @@ fn type_check_func(func: &Function, prog: &Program) -> Result<(), PositionalInte
598600 func. instrs . iter ( ) . try_for_each ( |i| match i {
599601 bril_rs:: Code :: Label { .. } => Ok ( ( ) ) ,
600602 bril_rs:: Code :: Instruction ( instr) => {
603+ if matches ! (
604+ instr,
605+ Instruction :: Effect {
606+ op: EffectOps :: Return ,
607+ ..
608+ }
609+ ) {
610+ has_return_type_should_have_return = true ;
611+ }
601612 type_check_instruction ( instr, func, prog, & mut env) . map_err ( |e| e. add_pos ( instr. get_pos ( ) ) )
602613 }
603614 } ) ?;
604615
605- Ok ( ( ) )
616+ if has_return_type_should_have_return {
617+ Ok ( ( ) )
618+ } else {
619+ Err ( InterpError :: NonVoidFuncNoRet ( func. return_type . clone ( ) . unwrap ( ) ) . add_pos ( func. pos . clone ( ) ) )
620+ }
606621}
607622
608623/// Provides validation of Bril programs. This involves
609624/// statically checking the types and number of arguments to Bril
610625/// instructions.
611626/// # Errors
612627/// Will return an error if typechecking fails or if the input program is not well-formed.
613- pub fn type_check ( bbprog : & Program ) -> Result < ( ) , PositionalInterpError > {
614- bbprog
628+ pub fn type_check ( prog : & Program ) -> Result < ( ) , PositionalInterpError > {
629+ prog
615630 . functions
616631 . iter ( )
617- . try_for_each ( |bbfunc| type_check_func ( bbfunc, bbprog ) )
632+ . try_for_each ( |bbfunc| type_check_func ( bbfunc, prog ) )
618633}
0 commit comments