fn match_bad_type_equality()

in starlark/src/analysis/incompatible.rs [57:99]


fn match_bad_type_equality(
    codemap: &CodeMap,
    x: &AstExpr,
    types: &HashMap<&str, &str>,
    res: &mut Vec<LintT<Incompatibility>>,
) {
    fn lookup_type<'a>(x: &AstExpr, types: &HashMap<&str, &'a str>) -> Option<&'a str> {
        match &**x {
            Expr::Identifier(name, _) => types.get(name.node.as_str()).copied(),
            _ => None,
        }
    }

    // Return true if this expression matches `type($x)`
    fn is_type_call(x: &AstExpr) -> bool {
        match &**x {
            Expr::Call(fun, args) if args.len() == 1 => match &***fun {
                Expr::Identifier(x, _) => x.node == "type",
                _ => false,
            },
            _ => false,
        }
    }

    // If we see type(x) == y (or negated), where y is in our types table, suggest a replacement
    match &**x {
        Expr::Op(lhs, op, rhs)
            if (*op == BinOp::Equal || *op == BinOp::NotEqual) && is_type_call(lhs) =>
        {
            if let Some(replacement) = lookup_type(rhs, types) {
                res.push(LintT::new(
                    codemap,
                    x.span,
                    Incompatibility::IncompatibleTypeCheck(
                        x.to_string(),
                        format!("{}{}type({})", lhs.node, op, replacement),
                    ),
                ))
            }
        }
        _ => {}
    }
}