diff --git a/src/resolve/conform/from_c_integer.rs b/src/resolve/conform/from_c_integer.rs index 5faa670e..cdcf9ce5 100644 --- a/src/resolve/conform/from_c_integer.rs +++ b/src/resolve/conform/from_c_integer.rs @@ -71,6 +71,10 @@ pub fn from_c_integer_to_c_integer( to_sign: Option, source: Source, ) -> ObjectiveResult { + if !mode.allow_lossless_integer() { + return O::fail(); + } + let target_type = TypeKind::CInteger(to_c_integer, to_sign).at(source); let is_smaller_likeness = from_sign == to_sign && from_c_integer <= to_c_integer; diff --git a/src/resolve/conform/from_float.rs b/src/resolve/conform/from_float.rs index 024ecf6a..d44b4a02 100644 --- a/src/resolve/conform/from_float.rs +++ b/src/resolve/conform/from_float.rs @@ -1,4 +1,4 @@ -use super::{Objective, ObjectiveResult}; +use super::{ConformMode, Objective, ObjectiveResult}; use crate::{ ast::FloatSize, resolved::{Cast, Expr, ExprKind, Type, TypeKind, TypedExpr}, @@ -7,9 +7,14 @@ use crate::{ pub fn from_float( expr: &TypedExpr, + mode: ConformMode, from_size: FloatSize, to_type: &Type, ) -> ObjectiveResult { + if !mode.allow_lossless_float() { + return O::fail(); + } + match &to_type.kind { TypeKind::Floating(to_size) => { from_float_to_float::(&expr.expr, from_size, *to_size, to_type.source) diff --git a/src/resolve/conform/from_integer.rs b/src/resolve/conform/from_integer.rs index 144cc6dd..7a97b33f 100644 --- a/src/resolve/conform/from_integer.rs +++ b/src/resolve/conform/from_integer.rs @@ -18,6 +18,7 @@ pub fn from_integer( TypeKind::Integer(to_bits, to_sign) => match behavior { ConformBehavior::Adept(_) => from_integer_adept_mode::( &expr.expr, + mode, from_bits, from_sign, *to_bits, @@ -50,20 +51,24 @@ pub fn from_integer( fn from_integer_c_mode( expr: &Expr, - conform_mode: ConformMode, + mode: ConformMode, from_bits: IntegerBits, from_sign: IntegerSign, to_bits: IntegerBits, to_sign: IntegerSign, type_source: Source, ) -> ObjectiveResult { + if !mode.allow_lossless_integer() { + return O::fail(); + } + let target_type = TypeKind::Integer(to_bits, to_sign).at(type_source); if from_bits == to_bits && from_sign == to_sign { return O::success(|| TypedExpr::new(target_type, expr.clone())); } - if conform_mode.allow_lossy_integer() { + if mode.allow_lossy_integer() { let cast = Cast::new(target_type.clone(), expr.clone()); let kind = if from_bits < to_bits { @@ -83,7 +88,7 @@ fn from_integer_c_mode( }); } - todo!("conform_integer_value_c {:?}", conform_mode); + todo!("conform_integer_value_c {:?}", mode); } fn conform_from_integer_to_c_integer( @@ -96,6 +101,10 @@ fn conform_from_integer_to_c_integer( to_sign: Option, source: Source, ) -> ObjectiveResult { + if !mode.allow_lossless_integer() { + return O::fail(); + } + let target_type = TypeKind::CInteger(to_c_integer, to_sign).at(source); let assumptions = behavior.c_integer_assumptions(); @@ -124,12 +133,17 @@ fn conform_from_integer_to_c_integer( fn from_integer_adept_mode( expr: &Expr, + mode: ConformMode, from_bits: IntegerBits, from_sign: IntegerSign, to_bits: IntegerBits, to_sign: IntegerSign, type_source: Source, ) -> ObjectiveResult { + if !mode.allow_lossless_integer() { + return O::fail(); + } + if to_bits < from_bits || (from_sign != to_sign && to_bits == from_bits) { return O::fail(); } diff --git a/src/resolve/conform/mod.rs b/src/resolve/conform/mod.rs index aa2856c7..c6c230b8 100644 --- a/src/resolve/conform/mod.rs +++ b/src/resolve/conform/mod.rs @@ -76,7 +76,7 @@ pub fn conform_expr( from_integer::(expr, mode, behavior, *from_bits, *from_sign, to_type) } TypeKind::FloatLiteral(from) => from_float_literal::(*from, to_type, conform_source), - TypeKind::Floating(from_size) => from_float::(expr, *from_size, to_type), + TypeKind::Floating(from_size) => from_float::(expr, mode, *from_size, to_type), TypeKind::Pointer(from_inner) => from_pointer::(expr, mode, from_inner, to_type), TypeKind::CInteger(from_size, from_sign) => { from_c_integer::(expr, mode, *from_size, *from_sign, to_type, conform_source) diff --git a/src/resolve/conform/mode.rs b/src/resolve/conform/mode.rs index 7cc0ccca..9fd3253b 100644 --- a/src/resolve/conform/mode.rs +++ b/src/resolve/conform/mode.rs @@ -18,4 +18,12 @@ impl ConformMode { pub fn allow_lossy_integer(&self) -> bool { matches!(self, Self::Explicit) } + + pub fn allow_lossless_integer(&self) -> bool { + matches!(self, Self::Normal | Self::Explicit) + } + + pub fn allow_lossless_float(&self) -> bool { + matches!(self, Self::Normal | Self::Explicit) + } } diff --git a/src/resolve/mod.rs b/src/resolve/mod.rs index a3f8e07c..abe26f52 100644 --- a/src/resolve/mod.rs +++ b/src/resolve/mod.rs @@ -287,9 +287,7 @@ pub fn resolve<'a>( function_search_context .available .entry(name) - .and_modify(|funcs| { - funcs.push(function_ref); - }) + .and_modify(|funcs| funcs.push(function_ref)) .or_insert_with(|| vec![function_ref]); } }