fn infer_from_expr(all_para: &mut ParaMap, expr: &Expr) {
    //  println!("expr: {:#?}", expr);
    s(expr.span());
    match expr {
        //  `fname( ... )`
        Expr::Call(expr) => { infer_from_call(all_para, &expr); }
        //  `... + ...`
        Expr::Binary(expr) => {
            infer_from_expr(all_para, &expr.left);
            infer_from_expr(all_para, &expr.right);
        }
        //  `- ...`
        Expr::Unary(expr) => {
            infer_from_expr(all_para, &expr.expr);            
        }
        //  `let x = ...`
        Expr::Let(expr) => {
            infer_from_expr(all_para, &expr.expr);            
        }
        //  `if cond { ... } else { ... }`
        Expr::If(expr) => {
            infer_from_expr(all_para, &expr.cond);
            infer_from_block(all_para, &expr.then_branch);
            if let Some((_else, expr)) = &expr.else_branch {
                infer_from_expr(all_para, &expr);
            }
        }
        //  `while cond { ... }`
        Expr::While(expr) => {
            infer_from_expr(all_para, &expr.cond);
            infer_from_block(all_para, &expr.body);
        }
        //  `for i in ... { ... }`
        Expr::ForLoop(expr) => {
            infer_from_expr(all_para, &expr.expr);
            infer_from_block(all_para, &expr.body);
        }
        //  `loop { ... }`
        Expr::Loop(expr) => {
            infer_from_block(all_para, &expr.body);

        }
        //  `( ... )`
        Expr::Paren(expr) => {
            infer_from_expr(all_para, &expr.expr);
        }
        //  `...`
        Expr::Group(expr) => {
            infer_from_expr(all_para, &expr.expr);
        }
        //  `fname( ... ) ?`
        Expr::Try(expr) => { 
            infer_from_expr(all_para, &expr.expr); 
        }
        //  For macro call `coap!( ..., sensor_data )`, infer `sensor_data` as `&SensorValue`
        Expr::Macro(expr) => {
            infer_from_macro(all_para, &expr);
        }

        //  TODO: Box, Array, MethodCall, Tuple, Match, Closure, Unsafe, Block, Assign, AssignOp

        //  Not interested: InPlace, Field, Index, Range, Path, Reference, Break, Continue, Return, Struct, Repeat, Async, TryBlock, Yield, Verbatim
        _ => {}
    };
    s(expr.span());
}
/// Infer the types of the parameters in `all_para` recursively from the expression `expr`
Infer the types of the parameters in `all_para` recursively from the expression `expr`
Infer the types of the parameters in ` all_para ` recursively from the expression ` expr `
fn infer_from_expr(all_para: &mut ParaMap, expr: &Expr) {
    //  println!("expr: {:#?}", expr);
    s(expr.span());
    match expr {
        //  `fname( ... )`
        Expr::Call(expr) => { infer_from_call(all_para, &expr); }
        //  `... + ...`
        Expr::Binary(expr) => {
            infer_from_expr(all_para, &expr.left);
            infer_from_expr(all_para, &expr.right);
        }
        //  `- ...`
        Expr::Unary(expr) => {
            infer_from_expr(all_para, &expr.expr);            
        }
        //  `let x = ...`
        Expr::Let(expr) => {
            infer_from_expr(all_para, &expr.expr);            
        }
        //  `if cond { ... } else { ... }`
        Expr::If(expr) => {
            infer_from_expr(all_para, &expr.cond);
            infer_from_block(all_para, &expr.then_branch);
            if let Some((_else, expr)) = &expr.else_branch {
                infer_from_expr(all_para, &expr);
            }
        }
        //  `while cond { ... }`
        Expr::While(expr) => {
            infer_from_expr(all_para, &expr.cond);
            infer_from_block(all_para, &expr.body);
        }
        //  `for i in ... { ... }`
        Expr::ForLoop(expr) => {
            infer_from_expr(all_para, &expr.expr);
            infer_from_block(all_para, &expr.body);
        }
        //  `loop { ... }`
        Expr::Loop(expr) => {
            infer_from_block(all_para, &expr.body);
        }
        //  `( ... )`
        Expr::Paren(expr) => {
            infer_from_expr(all_para, &expr.expr);
        }
        //  `...`
        Expr::Group(expr) => {
            infer_from_expr(all_para, &expr.expr);
        }
        //  `fname( ... ) ?`
        Expr::Try(expr) => { 
            infer_from_expr(all_para, &expr.expr); 
        }
        //  For macro call `coap!( ..., sensor_data )`, infer `sensor_data` as `&SensorValue`
        Expr::Macro(expr) => {
            infer_from_macro(all_para, &expr);
        }
        //  TODO: Box, Array, MethodCall, Tuple, Match, Closure, Unsafe, Block, Assign, AssignOp
        //  Not interested: InPlace, Field, Index, Range, Path, Reference, Break, Continue, Return, Struct, Repeat, Async, TryBlock, Yield, Verbatim
        _ => {}
    };
    s(expr.span());
}
fn infer_from_expr ( all_para : & mut ParaMap , expr : & Expr ) { //  println!("expr: {:#?}", expr); s ( expr . span ( ) ) ; match expr { //  `fname( ... )` Expr :: Call ( expr ) => { infer_from_call ( all_para , & expr ) ; } //  `... + ...` Expr :: Binary ( expr ) => { infer_from_expr ( all_para , & expr . left ) ; infer_from_expr ( all_para , & expr . right ) ; } //  `- ...` Expr :: Unary ( expr ) => { infer_from_expr ( all_para , & expr . expr ) ; } //  `let x = ...` Expr :: Let ( expr ) => { infer_from_expr ( all_para , & expr . expr ) ; } //  `if cond { ... } else { ... }` Expr :: If ( expr ) => { infer_from_expr ( all_para , & expr . cond ) ; infer_from_block ( all_para , & expr . then_branch ) ; if let Some ( ( _else , expr ) ) = & expr . else_branch { infer_from_expr ( all_para , & expr ) ; } } //  `while cond { ... }` Expr :: While ( expr ) => { infer_from_expr ( all_para , & expr . cond ) ; infer_from_block ( all_para , & expr . body ) ; } //  `for i in ... { ... }` Expr :: ForLoop ( expr ) => { infer_from_expr ( all_para , & expr . expr ) ; infer_from_block ( all_para , & expr . body ) ; } //  `loop { ... }` Expr :: Loop ( expr ) => { infer_from_block ( all_para , & expr . body ) ; } //  `( ... )` Expr :: Paren ( expr ) => { infer_from_expr ( all_para , & expr . expr ) ; } //  `...` Expr :: Group ( expr ) => { infer_from_expr ( all_para , & expr . expr ) ; } //  `fname( ... ) ?` Expr :: Try ( expr ) => { infer_from_expr ( all_para , & expr . expr ) ; } //  For macro call `coap!( ..., sensor_data )`, infer `sensor_data` as `&SensorValue` Expr :: Macro ( expr ) => { infer_from_macro ( all_para , & expr ) ; } //  TODO: Box, Array, MethodCall, Tuple, Match, Closure, Unsafe, Block, Assign, AssignOp //  Not interested: InPlace, Field, Index, Range, Path, Reference, Break, Continue, Return, Struct, Repeat, Async, TryBlock, Yield, Verbatim _ => { } } ; s ( expr . span ( ) ) ; }
Infer the types of the parameters in `all_para` recursively from the expression `expr`
Infer the types of the parameters in ` all_para ` recursively from the expression ` expr `
all_para
&mut ParaMap
expr
&Expr
all_para
&mut ParaMap
expr
&Expr