diff --git a/crates/swc_ecma_minifier/src/compress/optimize/props.rs b/crates/swc_ecma_minifier/src/compress/optimize/props.rs index c4fbc9df3e393..23ab7cbe74c96 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/props.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/props.rs @@ -46,6 +46,7 @@ impl Optimizer<'_> { || usage.used_as_arg || usage.indexed_with_dynamic_key || usage.used_recursively + || usage.used_with_in { log_abort!("hoist_props: Variable `{}` is not a candidate", name.id); return None; diff --git a/crates/swc_ecma_minifier/src/program_data.rs b/crates/swc_ecma_minifier/src/program_data.rs index aba70b53b36ae..c2a5872b30866 100644 --- a/crates/swc_ecma_minifier/src/program_data.rs +++ b/crates/swc_ecma_minifier/src/program_data.rs @@ -124,6 +124,8 @@ pub(crate) struct VarUsageInfo { pub(crate) accessed_props: Box>, pub(crate) used_recursively: bool, + + pub(crate) used_with_in: bool, } impl Default for VarUsageInfo { @@ -162,6 +164,7 @@ impl Default for VarUsageInfo { is_top_level: Default::default(), assigned_fn_local: true, used_as_ref: false, + used_with_in: false, } } } @@ -292,6 +295,8 @@ impl Storage for ProgramData { e.get_mut().assigned_fn_local &= var_info.assigned_fn_local; + e.get_mut().used_with_in |= var_info.used_with_in; + for (k, v) in *var_info.accessed_props { *e.get_mut().accessed_props.entry(k).or_default() += v; } @@ -571,6 +576,10 @@ impl VarDataLike for VarUsageInfo { fn mark_used_recursively(&mut self) { self.used_recursively = true; } + + fn mark_used_with_in(&mut self) { + self.used_with_in = true; + } } impl ProgramData { diff --git a/crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs b/crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs index c901df71a48b3..3cd157dc481c9 100644 --- a/crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs +++ b/crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs @@ -340,6 +340,7 @@ where if e.op == op!("in") { for_each_id_ref_in_expr(&e.right, &mut |obj| { let var = self.data.var_or_default(obj.to_id()); + var.mark_used_with_in(); match &*e.left { Expr::Lit(Lit::Str(prop)) if prop.value.parse::().is_err() => { diff --git a/crates/swc_ecma_usage_analyzer/src/analyzer/storage.rs b/crates/swc_ecma_usage_analyzer/src/analyzer/storage.rs index 5b2209c89dbb1..6555edce3860e 100644 --- a/crates/swc_ecma_usage_analyzer/src/analyzer/storage.rs +++ b/crates/swc_ecma_usage_analyzer/src/analyzer/storage.rs @@ -82,4 +82,6 @@ pub trait VarDataLike: Sized { fn mark_used_above_decl(&mut self); fn mark_used_recursively(&mut self); + + fn mark_used_with_in(&mut self); }