From 8378ac24fd4e440025cdf2363769b96a85128cda Mon Sep 17 00:00:00 2001 From: Matt Brown Date: Fri, 16 Aug 2024 16:33:03 -0400 Subject: [PATCH] Fix bad arithmetic --- .../expr/binop/arithmetic_analyzer.rs | 44 +++++++++++++++---- .../expr/fetch/array_fetch_analyzer.rs | 8 ++-- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/analyzer/expr/binop/arithmetic_analyzer.rs b/src/analyzer/expr/binop/arithmetic_analyzer.rs index 6f71654c..3704040d 100644 --- a/src/analyzer/expr/binop/arithmetic_analyzer.rs +++ b/src/analyzer/expr/binop/arithmetic_analyzer.rs @@ -5,8 +5,8 @@ use hakana_type::template::TemplateBound; use rustc_hash::FxHashMap; use crate::function_analysis_data::FunctionAnalysisData; -use crate::scope_analyzer::ScopeAnalyzer; use crate::scope::BlockContext; +use crate::scope_analyzer::ScopeAnalyzer; use crate::statements_analyzer::StatementsAnalyzer; use crate::stmt_analyzer::AnalysisError; use crate::{expr::expression_identifier, expression_analyzer}; @@ -92,15 +92,28 @@ pub(crate) fn analyze<'expr: 'tast, 'tast>( let mut results = vec![]; - for mut e1_type_atomic in &e1_type.types { + let mut e1_types = e1_type.types.clone(); + + while let Some(mut e1_type_atomic) = e1_types.pop() { + if let TAtomic::TGenericParam { as_type, .. } + | TAtomic::TClassTypeConstant { as_type, .. } + | TAtomic::TTypeAlias { + as_type: Some(as_type), + .. + } = e1_type_atomic + { + e1_types.extend(as_type.types); + continue; + } + if let TAtomic::TFalse = e1_type_atomic { if e1_type.ignore_falsable_issues { continue; } - e1_type_atomic = &zero; + e1_type_atomic = zero.clone(); } - if let TAtomic::TTypeVariable { name } = e1_type_atomic { + if let TAtomic::TTypeVariable { name } = &e1_type_atomic { results.push(e1_type_atomic.clone()); if let Some((_, upper_bounds)) = analysis_data.type_variable_bounds.get_mut(name) { let mut bound = TemplateBound::new(get_num(), 0, None, None); @@ -111,15 +124,28 @@ pub(crate) fn analyze<'expr: 'tast, 'tast>( continue; } - for mut e2_type_atomic in &e2_type.types { + let mut e2_types = e2_type.types.clone(); + + while let Some(mut e2_type_atomic) = e2_types.pop() { + if let TAtomic::TGenericParam { ref as_type, .. } + | TAtomic::TClassTypeConstant { ref as_type, .. } + | TAtomic::TTypeAlias { + as_type: Some(ref as_type), + .. + } = e1_type_atomic + { + e1_types.extend(as_type.types.clone()); + continue; + } + if let TAtomic::TFalse = e2_type_atomic { if e2_type.ignore_falsable_issues { continue; } - e2_type_atomic = &zero; + e2_type_atomic = zero.clone(); } - if let TAtomic::TTypeVariable { name } = e2_type_atomic { + if let TAtomic::TTypeVariable { name } = &e2_type_atomic { results.push(e2_type_atomic.clone()); if let Some((_, upper_bounds)) = analysis_data.type_variable_bounds.get_mut(name) { @@ -132,7 +158,7 @@ pub(crate) fn analyze<'expr: 'tast, 'tast>( } results.push(if has_loop_variable { - match (e1_type_atomic, e2_type_atomic) { + match (&e1_type_atomic, &e2_type_atomic) { ( TAtomic::TInt | TAtomic::TLiteralInt { .. }, TAtomic::TInt | TAtomic::TLiteralInt { .. }, @@ -143,7 +169,7 @@ pub(crate) fn analyze<'expr: 'tast, 'tast>( _ => TAtomic::TFloat, } } else { - match (e1_type_atomic, e2_type_atomic) { + match (&e1_type_atomic, &e2_type_atomic) { ( TAtomic::TLiteralInt { value: e1_value }, TAtomic::TLiteralInt { value: e2_value }, diff --git a/src/analyzer/expr/fetch/array_fetch_analyzer.rs b/src/analyzer/expr/fetch/array_fetch_analyzer.rs index 53217fde..9af469c4 100644 --- a/src/analyzer/expr/fetch/array_fetch_analyzer.rs +++ b/src/analyzer/expr/fetch/array_fetch_analyzer.rs @@ -320,14 +320,12 @@ pub(crate) fn get_array_access_type_given_offset( let mut stmt_type = None; while let Some(mut atomic_var_type) = array_atomic_types.pop() { - if let TAtomic::TTypeAlias { + if let TAtomic::TGenericParam { as_type, .. } + | TAtomic::TClassTypeConstant { as_type, .. } + | TAtomic::TTypeAlias { as_type: Some(as_type), .. } = atomic_var_type - { - atomic_var_type = as_type.get_single() - } else if let TAtomic::TGenericParam { as_type, .. } - | TAtomic::TClassTypeConstant { as_type, .. } = atomic_var_type { array_atomic_types.extend(&as_type.types); continue;