@@ -313,11 +313,13 @@ fn parse_function_body(body_str: &str) -> Vec<String> {
313313/// Same rules as variable names: starts with letter or underscore,
314314/// then alphanumeric or underscore.
315315pub fn is_valid_function_name ( name : & str ) -> bool {
316- if name. is_empty ( ) {
317- return false ;
318- }
316+ // `let-else` covers the empty- name case directly: chars.next () returns
317+ // None on an empty &str, which is the same outcome as the previous
318+ // explicit `if name.is_empty()` guard. One construct, no panic site.
319319 let mut chars = name. chars ( ) ;
320- let first = chars. next ( ) . expect ( "TODO: handle error" ) ;
320+ let Some ( first) = chars. next ( ) else {
321+ return false ;
322+ } ;
321323 if !first. is_alphabetic ( ) && first != '_' {
322324 return false ;
323325 }
@@ -336,7 +338,7 @@ mod tests {
336338 fn test_parse_posix_function_def ( ) {
337339 let result = parse_function_def ( "greet() { echo hello; }" ) ;
338340 assert ! ( result. is_some( ) ) ;
339- let ( name, body, raw_body) = result. expect ( "TODO: handle error" ) ;
341+ let ( name, body, raw_body) = result. unwrap ( ) ;
340342 assert_eq ! ( name, "greet" ) ;
341343 assert_eq ! ( body, vec![ "echo hello" ] ) ;
342344 // raw_body preserves the trailing `;` — that's harmless.
@@ -347,7 +349,7 @@ mod tests {
347349 fn test_parse_posix_function_multi_commands ( ) {
348350 let result = parse_function_def ( "setup() { mkdir src; touch src/main.rs; echo done; }" ) ;
349351 assert ! ( result. is_some( ) ) ;
350- let ( name, body, raw_body) = result. expect ( "TODO: handle error" ) ;
352+ let ( name, body, raw_body) = result. unwrap ( ) ;
351353 assert_eq ! ( name, "setup" ) ;
352354 assert_eq ! ( body, vec![ "mkdir src" , "touch src/main.rs" , "echo done" ] ) ;
353355 assert_eq ! ( raw_body, "mkdir src; touch src/main.rs; echo done;" ) ;
@@ -357,7 +359,7 @@ mod tests {
357359 fn test_parse_bash_function_def ( ) {
358360 let result = parse_function_def ( "function greet { echo hello; }" ) ;
359361 assert ! ( result. is_some( ) ) ;
360- let ( name, body, raw_body) = result. expect ( "TODO: handle error" ) ;
362+ let ( name, body, raw_body) = result. unwrap ( ) ;
361363 assert_eq ! ( name, "greet" ) ;
362364 assert_eq ! ( body, vec![ "echo hello" ] ) ;
363365 assert_eq ! ( raw_body, "echo hello;" ) ;
@@ -367,7 +369,7 @@ mod tests {
367369 fn test_parse_bash_function_with_parens ( ) {
368370 let result = parse_function_def ( "function greet() { echo hello; }" ) ;
369371 assert ! ( result. is_some( ) ) ;
370- let ( name, body, raw_body) = result. expect ( "TODO: handle error" ) ;
372+ let ( name, body, raw_body) = result. unwrap ( ) ;
371373 assert_eq ! ( name, "greet" ) ;
372374 assert_eq ! ( body, vec![ "echo hello" ] ) ;
373375 assert_eq ! ( raw_body, "echo hello;" ) ;
@@ -379,7 +381,7 @@ mod tests {
379381 // execution can parse `if/fi`, `for/done`, etc. as single commands.
380382 let result = parse_function_def ( "ifunc() { if true; then mkdir d; fi; }" ) ;
381383 assert ! ( result. is_some( ) ) ;
382- let ( name, _body, raw_body) = result. expect ( "TODO: handle error" ) ;
384+ let ( name, _body, raw_body) = result. unwrap ( ) ;
383385 assert_eq ! ( name, "ifunc" ) ;
384386 assert_eq ! ( raw_body, "if true; then mkdir d; fi;" ) ;
385387 }
@@ -389,7 +391,7 @@ mod tests {
389391 // A `}` inside a quoted string must NOT be treated as the closing brace.
390392 let result = parse_function_def ( "lit() { echo '}'; }" ) ;
391393 assert ! ( result. is_some( ) ) ;
392- let ( _name, _body, raw_body) = result. expect ( "TODO: handle error" ) ;
394+ let ( _name, _body, raw_body) = result. unwrap ( ) ;
393395 assert_eq ! ( raw_body, "echo '}';" ) ;
394396 }
395397
@@ -476,7 +478,7 @@ mod tests {
476478 line : 5 ,
477479 } ,
478480 } ) ;
479- let def = table. get ( "greet" ) . expect ( "TODO: handle error" ) ;
481+ let def = table. get ( "greet" ) . unwrap ( ) ;
480482 assert_eq ! ( def. body, vec![ "echo goodbye" ] ) ;
481483 }
482484
@@ -495,11 +497,11 @@ mod tests {
495497 table. push_frame ( vec ! [ "nested_arg" . to_string( ) ] ) ;
496498 assert_eq ! ( table. call_depth( ) , 2 ) ;
497499
498- let frame = table. pop_frame ( ) . expect ( "TODO: handle error" ) ;
500+ let frame = table. pop_frame ( ) . unwrap ( ) ;
499501 assert_eq ! ( frame. saved_params, vec![ "nested_arg" ] ) ;
500502 assert_eq ! ( table. call_depth( ) , 1 ) ;
501503
502- let frame = table. pop_frame ( ) . expect ( "TODO: handle error" ) ;
504+ let frame = table. pop_frame ( ) . unwrap ( ) ;
503505 assert_eq ! ( frame. saved_params, vec![ "arg1" , "arg2" ] ) ;
504506 assert_eq ! ( table. call_depth( ) , 0 ) ;
505507
@@ -514,7 +516,7 @@ mod tests {
514516 table. declare_local ( "x" , Some ( "old_value" . to_string ( ) ) ) ;
515517 table. declare_local ( "y" , None ) ;
516518
517- let frame = table. pop_frame ( ) . expect ( "TODO: handle error" ) ;
519+ let frame = table. pop_frame ( ) . unwrap ( ) ;
518520 assert_eq ! ( frame. local_vars, vec![ "x" , "y" ] ) ;
519521 assert_eq ! (
520522 frame. saved_vars. get( "x" ) ,
@@ -533,7 +535,7 @@ mod tests {
533535 // Second declaration in same frame should NOT overwrite the saved value
534536 table. declare_local ( "x" , Some ( "modified" . to_string ( ) ) ) ;
535537
536- let frame = table. pop_frame ( ) . expect ( "TODO: handle error" ) ;
538+ let frame = table. pop_frame ( ) . unwrap ( ) ;
537539 // The saved value should be "original", not "modified"
538540 assert_eq ! (
539541 frame. saved_vars. get( "x" ) ,
0 commit comments