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))
}
})
}