fn is_safe_to_inline_expr()

in starlark/src/eval/fragment/def.rs [305:373]


    fn is_safe_to_inline_expr(expr: &ExprCompiled) -> Option<ExprCompiled> {
        Some(match expr {
            e @ ExprCompiled::Value(..) => e.clone(),
            ExprCompiled::Local(..)
            | ExprCompiled::LocalCaptured(..)
            | ExprCompiled::Module(..)
            | ExprCompiled::Equals(..)
            | ExprCompiled::Compare(..)
            | ExprCompiled::Len(..)
            | ExprCompiled::Compr(..)
            | ExprCompiled::Dot(..)
            | ExprCompiled::ArrayIndirection(..)
            | ExprCompiled::Slice(..)
            | ExprCompiled::Op(..)
            | ExprCompiled::UnOp(..)
            | ExprCompiled::Call(..)
            | ExprCompiled::Def(..) => return None,
            ExprCompiled::Type(v) => {
                ExprCompiled::Type(box Compiler::is_safe_to_inline_expr_spanned(v)?)
            }
            ExprCompiled::TypeIs(ref v, t) => {
                ExprCompiled::TypeIs(box Compiler::is_safe_to_inline_expr_spanned(v)?, *t)
            }
            ExprCompiled::Tuple(xs) => ExprCompiled::Tuple(
                xs.try_map(|x| Compiler::is_safe_to_inline_expr_spanned(x).ok_or(()))
                    .ok()?,
            ),
            ExprCompiled::List(xs) => ExprCompiled::List(
                xs.try_map(|x| Compiler::is_safe_to_inline_expr_spanned(x).ok_or(()))
                    .ok()?,
            ),
            ExprCompiled::Dict(xs) if xs.is_empty() => ExprCompiled::Dict(Vec::new()),
            ExprCompiled::Dict(..) => {
                // Dict construction may fail if keys are not hashable.
                return None;
            }
            ExprCompiled::If(box (ref c, ref t, ref f)) => {
                let c = Compiler::is_safe_to_inline_expr_spanned(c)?;
                let t = Compiler::is_safe_to_inline_expr_spanned(t)?;
                let f = Compiler::is_safe_to_inline_expr_spanned(f)?;
                ExprCompiled::If(box (c, t, f))
            }
            ExprCompiled::Not(ref x) => {
                let x = Compiler::is_safe_to_inline_expr_spanned(x)?;
                ExprCompiled::Not(box x)
            }
            ExprCompiled::And(box (ref x, ref y)) => {
                let x = Compiler::is_safe_to_inline_expr_spanned(x)?;
                let y = Compiler::is_safe_to_inline_expr_spanned(y)?;
                ExprCompiled::And(box (x, y))
            }
            ExprCompiled::Or(box (ref x, ref y)) => {
                let x = Compiler::is_safe_to_inline_expr_spanned(x)?;
                let y = Compiler::is_safe_to_inline_expr_spanned(y)?;
                ExprCompiled::Or(box (x, y))
            }
            ExprCompiled::Seq(box (ref x, ref y)) => {
                let x = Compiler::is_safe_to_inline_expr_spanned(x)?;
                let y = Compiler::is_safe_to_inline_expr_spanned(y)?;
                ExprCompiled::Seq(box (x, y))
            }
            ExprCompiled::PercentSOne(..) => return None,
            ExprCompiled::FormatOne(box (before, ref v, after)) => {
                // `FormatOne` is infallible, unlike `PercentSOne`.
                let v = Compiler::is_safe_to_inline_expr_spanned(v)?;
                ExprCompiled::FormatOne(box (*before, v, *after))
            }
        })
    }