mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
Create new operator Num.mulSaturated
This commit is contained in:
parent
e356f1c33f
commit
74f946b1aa
11 changed files with 191 additions and 68 deletions
|
@ -82,6 +82,7 @@ interface Num
|
||||||
subChecked,
|
subChecked,
|
||||||
subSaturated,
|
subSaturated,
|
||||||
mulWrap,
|
mulWrap,
|
||||||
|
mulSaturated,
|
||||||
mulChecked,
|
mulChecked,
|
||||||
intCast,
|
intCast,
|
||||||
bytesToU16,
|
bytesToU16,
|
||||||
|
@ -862,7 +863,14 @@ subSaturated : Num a, Num a -> Num a
|
||||||
subChecked : Num a, Num a -> Result (Num a) [Overflow]*
|
subChecked : Num a, Num a -> Result (Num a) [Overflow]*
|
||||||
|
|
||||||
mulWrap : Int range, Int range -> Int range
|
mulWrap : Int range, Int range -> Int range
|
||||||
# mulSaturated : Num a, Num a -> Num a
|
|
||||||
|
## Multiply two numbers, clamping on the maximum representable number rather than
|
||||||
|
## overflowing.
|
||||||
|
##
|
||||||
|
## This is the same as [Num.mul] except for the saturating behavior if the
|
||||||
|
## addition is to overflow.
|
||||||
|
mulSaturated : Num a, Num a -> Num a
|
||||||
|
|
||||||
## Multiply two numbers and check for overflow.
|
## Multiply two numbers and check for overflow.
|
||||||
##
|
##
|
||||||
## This is the same as [Num.mul] except if the operation overflows, instead of
|
## This is the same as [Num.mul] except if the operation overflows, instead of
|
||||||
|
|
|
@ -199,6 +199,13 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(result_type(num_type(flex(TVAR1)), overflow())),
|
Box::new(result_type(num_type(flex(TVAR1)), overflow())),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// mulSaturated : Int range, Int range -> Int range
|
||||||
|
add_top_level_function_type!(
|
||||||
|
Symbol::NUM_MUL_SATURATED,
|
||||||
|
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
||||||
|
Box::new(int_type(flex(TVAR1))),
|
||||||
|
);
|
||||||
|
|
||||||
// abs : Num a -> Num a
|
// abs : Num a -> Num a
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::NUM_ABS,
|
Symbol::NUM_ABS,
|
||||||
|
|
|
@ -187,6 +187,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
||||||
NUM_SUB_SATURATED => num_sub_saturated,
|
NUM_SUB_SATURATED => num_sub_saturated,
|
||||||
NUM_MUL => num_mul,
|
NUM_MUL => num_mul,
|
||||||
NUM_MUL_WRAP => num_mul_wrap,
|
NUM_MUL_WRAP => num_mul_wrap,
|
||||||
|
NUM_MUL_SATURATED => num_mul_saturated,
|
||||||
NUM_MUL_CHECKED => num_mul_checked,
|
NUM_MUL_CHECKED => num_mul_checked,
|
||||||
NUM_GT => num_gt,
|
NUM_GT => num_gt,
|
||||||
NUM_GTE => num_gte,
|
NUM_GTE => num_gte,
|
||||||
|
@ -909,6 +910,11 @@ fn num_mul_wrap(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_binop(symbol, var_store, LowLevel::NumMulWrap)
|
num_binop(symbol, var_store, LowLevel::NumMulWrap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Num.mulSaturated : Num a, Num a -> Num a
|
||||||
|
fn num_mul_saturated(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
|
num_binop(symbol, var_store, LowLevel::NumMulSaturated)
|
||||||
|
}
|
||||||
|
|
||||||
/// Num.mulChecked : Num a, Num a -> Result (Num a) [Overflow]*
|
/// Num.mulChecked : Num a, Num a -> Result (Num a) [Overflow]*
|
||||||
fn num_mul_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_mul_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_overflow_checked(symbol, var_store, LowLevel::NumMulChecked)
|
num_overflow_checked(symbol, var_store, LowLevel::NumMulChecked)
|
||||||
|
|
|
@ -5952,7 +5952,7 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
NumAdd | NumSub | NumMul | NumLt | NumLte | NumGt | NumGte | NumRemUnchecked
|
NumAdd | NumSub | NumMul | NumLt | NumLte | NumGt | NumGte | NumRemUnchecked
|
||||||
| NumIsMultipleOf | NumAddWrap | NumAddChecked | NumAddSaturated | NumDivUnchecked
|
| NumIsMultipleOf | NumAddWrap | NumAddChecked | NumAddSaturated | NumDivUnchecked
|
||||||
| NumDivCeilUnchecked | NumPow | NumPowInt | NumSubWrap | NumSubChecked
|
| NumDivCeilUnchecked | NumPow | NumPowInt | NumSubWrap | NumSubChecked
|
||||||
| NumSubSaturated | NumMulWrap | NumMulChecked => {
|
| NumSubSaturated | NumMulWrap | NumMulSaturated | NumMulChecked => {
|
||||||
debug_assert_eq!(args.len(), 2);
|
debug_assert_eq!(args.len(), 2);
|
||||||
|
|
||||||
let (lhs_arg, lhs_layout) = load_symbol_and_layout(scope, &args[0]);
|
let (lhs_arg, lhs_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||||
|
@ -6719,6 +6719,11 @@ fn build_int_binop<'a, 'ctx, 'env>(
|
||||||
throw_on_overflow(env, parent, result, "integer multiplication overflowed!")
|
throw_on_overflow(env, parent, result, "integer multiplication overflowed!")
|
||||||
}
|
}
|
||||||
NumMulWrap => bd.build_int_mul(lhs, rhs, "mul_int").into(),
|
NumMulWrap => bd.build_int_mul(lhs, rhs, "mul_int").into(),
|
||||||
|
NumMulSaturated => call_bitcode_fn(
|
||||||
|
env,
|
||||||
|
&[lhs.into(), rhs.into()],
|
||||||
|
&bitcode::NUM_MUL_SATURATED_INT[int_width],
|
||||||
|
),
|
||||||
NumMulChecked => env.call_intrinsic(
|
NumMulChecked => env.call_intrinsic(
|
||||||
&LLVM_MUL_WITH_OVERFLOW[int_width],
|
&LLVM_MUL_WITH_OVERFLOW[int_width],
|
||||||
&[lhs.into(), rhs.into()],
|
&[lhs.into(), rhs.into()],
|
||||||
|
@ -6988,6 +6993,7 @@ fn build_float_binop<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
NumSubWrap => unreachable!("wrapping subtraction is not defined on floats"),
|
NumSubWrap => unreachable!("wrapping subtraction is not defined on floats"),
|
||||||
NumMul => bd.build_float_mul(lhs, rhs, "mul_float").into(),
|
NumMul => bd.build_float_mul(lhs, rhs, "mul_float").into(),
|
||||||
|
NumMulSaturated => bd.build_float_mul(lhs, rhs, "mul_float").into(),
|
||||||
NumMulChecked => {
|
NumMulChecked => {
|
||||||
let context = env.context;
|
let context = env.context;
|
||||||
|
|
||||||
|
|
|
@ -549,6 +549,24 @@ impl<'a> LowLevelCall<'a> {
|
||||||
}
|
}
|
||||||
_ => panic_ret_type(),
|
_ => panic_ret_type(),
|
||||||
},
|
},
|
||||||
|
NumMulSaturated => match self.ret_layout {
|
||||||
|
Layout::Builtin(Builtin::Int(width)) => {
|
||||||
|
self.load_args_and_call_zig(backend, &bitcode::NUM_MUL_SATURATED_INT[width])
|
||||||
|
}
|
||||||
|
Layout::Builtin(Builtin::Float(FloatWidth::F32)) => {
|
||||||
|
self.load_args(backend);
|
||||||
|
backend.code_builder.f32_mul()
|
||||||
|
}
|
||||||
|
Layout::Builtin(Builtin::Float(FloatWidth::F64)) => {
|
||||||
|
self.load_args(backend);
|
||||||
|
backend.code_builder.f64_mul()
|
||||||
|
}
|
||||||
|
Layout::Builtin(Builtin::Decimal) => {
|
||||||
|
self.load_args_and_call_zig(backend, bitcode::DEC_MUL_SATURATED)
|
||||||
|
}
|
||||||
|
_ => panic_ret_type(),
|
||||||
|
},
|
||||||
|
|
||||||
NumMulChecked => {
|
NumMulChecked => {
|
||||||
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
|
||||||
match arg_layout {
|
match arg_layout {
|
||||||
|
|
|
@ -78,6 +78,7 @@ pub enum LowLevel {
|
||||||
NumSubSaturated,
|
NumSubSaturated,
|
||||||
NumMul,
|
NumMul,
|
||||||
NumMulWrap,
|
NumMulWrap,
|
||||||
|
NumMulSaturated,
|
||||||
NumMulChecked,
|
NumMulChecked,
|
||||||
NumGt,
|
NumGt,
|
||||||
NumGte,
|
NumGte,
|
||||||
|
@ -284,6 +285,7 @@ impl LowLevelWrapperType {
|
||||||
Symbol::NUM_SUB_SATURATED => CanBeReplacedBy(NumSubSaturated),
|
Symbol::NUM_SUB_SATURATED => CanBeReplacedBy(NumSubSaturated),
|
||||||
Symbol::NUM_MUL => CanBeReplacedBy(NumMul),
|
Symbol::NUM_MUL => CanBeReplacedBy(NumMul),
|
||||||
Symbol::NUM_MUL_WRAP => CanBeReplacedBy(NumMulWrap),
|
Symbol::NUM_MUL_WRAP => CanBeReplacedBy(NumMulWrap),
|
||||||
|
Symbol::NUM_MUL_SATURATED => CanBeReplacedBy(NumMulSaturated),
|
||||||
Symbol::NUM_MUL_CHECKED => WrapperIsRequired,
|
Symbol::NUM_MUL_CHECKED => WrapperIsRequired,
|
||||||
Symbol::NUM_GT => CanBeReplacedBy(NumGt),
|
Symbol::NUM_GT => CanBeReplacedBy(NumGt),
|
||||||
Symbol::NUM_GTE => CanBeReplacedBy(NumGte),
|
Symbol::NUM_GTE => CanBeReplacedBy(NumGte),
|
||||||
|
|
|
@ -1075,66 +1075,67 @@ define_builtins! {
|
||||||
77 NUM_SUB_SATURATED: "subSaturated"
|
77 NUM_SUB_SATURATED: "subSaturated"
|
||||||
78 NUM_MUL_WRAP: "mulWrap"
|
78 NUM_MUL_WRAP: "mulWrap"
|
||||||
79 NUM_MUL_CHECKED: "mulChecked"
|
79 NUM_MUL_CHECKED: "mulChecked"
|
||||||
80 NUM_INT: "Int"
|
80 NUM_MUL_SATURATED: "mulSaturated"
|
||||||
81 NUM_FRAC: "Frac"
|
81 NUM_INT: "Int"
|
||||||
82 NUM_NATURAL: "Natural"
|
82 NUM_FRAC: "Frac"
|
||||||
83 NUM_NAT: "Nat"
|
83 NUM_NATURAL: "Natural"
|
||||||
84 NUM_INT_CAST: "intCast"
|
84 NUM_NAT: "Nat"
|
||||||
85 NUM_IS_MULTIPLE_OF: "isMultipleOf"
|
85 NUM_INT_CAST: "intCast"
|
||||||
86 NUM_DECIMAL: "Decimal"
|
86 NUM_IS_MULTIPLE_OF: "isMultipleOf"
|
||||||
87 NUM_DEC: "Dec" // the Num.Dectype alias
|
87 NUM_DECIMAL: "Decimal"
|
||||||
88 NUM_BYTES_TO_U16: "bytesToU16"
|
88 NUM_DEC: "Dec" // the Num.Dectype alias
|
||||||
89 NUM_BYTES_TO_U32: "bytesToU32"
|
89 NUM_BYTES_TO_U16: "bytesToU16"
|
||||||
90 NUM_CAST_TO_NAT: "#castToNat"
|
90 NUM_BYTES_TO_U32: "bytesToU32"
|
||||||
91 NUM_DIV_CEIL: "divCeil"
|
91 NUM_CAST_TO_NAT: "#castToNat"
|
||||||
92 NUM_DIV_CEIL_CHECKED: "divCeilChecked"
|
92 NUM_DIV_CEIL: "divCeil"
|
||||||
93 NUM_TO_STR: "toStr"
|
93 NUM_DIV_CEIL_CHECKED: "divCeilChecked"
|
||||||
94 NUM_MIN_I8: "minI8"
|
94 NUM_TO_STR: "toStr"
|
||||||
95 NUM_MAX_I8: "maxI8"
|
95 NUM_MIN_I8: "minI8"
|
||||||
96 NUM_MIN_U8: "minU8"
|
96 NUM_MAX_I8: "maxI8"
|
||||||
97 NUM_MAX_U8: "maxU8"
|
97 NUM_MIN_U8: "minU8"
|
||||||
98 NUM_MIN_I16: "minI16"
|
98 NUM_MAX_U8: "maxU8"
|
||||||
99 NUM_MAX_I16: "maxI16"
|
99 NUM_MIN_I16: "minI16"
|
||||||
100 NUM_MIN_U16: "minU16"
|
100 NUM_MAX_I16: "maxI16"
|
||||||
101 NUM_MAX_U16: "maxU16"
|
101 NUM_MIN_U16: "minU16"
|
||||||
102 NUM_MIN_I32: "minI32"
|
102 NUM_MAX_U16: "maxU16"
|
||||||
103 NUM_MAX_I32: "maxI32"
|
103 NUM_MIN_I32: "minI32"
|
||||||
104 NUM_MIN_U32: "minU32"
|
104 NUM_MAX_I32: "maxI32"
|
||||||
105 NUM_MAX_U32: "maxU32"
|
105 NUM_MIN_U32: "minU32"
|
||||||
106 NUM_MIN_I64: "minI64"
|
106 NUM_MAX_U32: "maxU32"
|
||||||
107 NUM_MAX_I64: "maxI64"
|
107 NUM_MIN_I64: "minI64"
|
||||||
108 NUM_MIN_U64: "minU64"
|
108 NUM_MAX_I64: "maxI64"
|
||||||
109 NUM_MAX_U64: "maxU64"
|
109 NUM_MIN_U64: "minU64"
|
||||||
110 NUM_MIN_I128: "minI128"
|
110 NUM_MAX_U64: "maxU64"
|
||||||
111 NUM_MAX_I128: "maxI128"
|
111 NUM_MIN_I128: "minI128"
|
||||||
112 NUM_TO_I8: "toI8"
|
112 NUM_MAX_I128: "maxI128"
|
||||||
113 NUM_TO_I8_CHECKED: "toI8Checked"
|
113 NUM_TO_I8: "toI8"
|
||||||
114 NUM_TO_I16: "toI16"
|
114 NUM_TO_I8_CHECKED: "toI8Checked"
|
||||||
115 NUM_TO_I16_CHECKED: "toI16Checked"
|
115 NUM_TO_I16: "toI16"
|
||||||
116 NUM_TO_I32: "toI32"
|
116 NUM_TO_I16_CHECKED: "toI16Checked"
|
||||||
117 NUM_TO_I32_CHECKED: "toI32Checked"
|
117 NUM_TO_I32: "toI32"
|
||||||
118 NUM_TO_I64: "toI64"
|
118 NUM_TO_I32_CHECKED: "toI32Checked"
|
||||||
119 NUM_TO_I64_CHECKED: "toI64Checked"
|
119 NUM_TO_I64: "toI64"
|
||||||
120 NUM_TO_I128: "toI128"
|
120 NUM_TO_I64_CHECKED: "toI64Checked"
|
||||||
121 NUM_TO_I128_CHECKED: "toI128Checked"
|
121 NUM_TO_I128: "toI128"
|
||||||
122 NUM_TO_U8: "toU8"
|
122 NUM_TO_I128_CHECKED: "toI128Checked"
|
||||||
123 NUM_TO_U8_CHECKED: "toU8Checked"
|
123 NUM_TO_U8: "toU8"
|
||||||
124 NUM_TO_U16: "toU16"
|
124 NUM_TO_U8_CHECKED: "toU8Checked"
|
||||||
125 NUM_TO_U16_CHECKED: "toU16Checked"
|
125 NUM_TO_U16: "toU16"
|
||||||
126 NUM_TO_U32: "toU32"
|
126 NUM_TO_U16_CHECKED: "toU16Checked"
|
||||||
127 NUM_TO_U32_CHECKED: "toU32Checked"
|
127 NUM_TO_U32: "toU32"
|
||||||
128 NUM_TO_U64: "toU64"
|
128 NUM_TO_U32_CHECKED: "toU32Checked"
|
||||||
129 NUM_TO_U64_CHECKED: "toU64Checked"
|
129 NUM_TO_U64: "toU64"
|
||||||
130 NUM_TO_U128: "toU128"
|
130 NUM_TO_U64_CHECKED: "toU64Checked"
|
||||||
131 NUM_TO_U128_CHECKED: "toU128Checked"
|
131 NUM_TO_U128: "toU128"
|
||||||
132 NUM_TO_NAT: "toNat"
|
132 NUM_TO_U128_CHECKED: "toU128Checked"
|
||||||
133 NUM_TO_NAT_CHECKED: "toNatChecked"
|
133 NUM_TO_NAT: "toNat"
|
||||||
134 NUM_TO_F32: "toF32"
|
134 NUM_TO_NAT_CHECKED: "toNatChecked"
|
||||||
135 NUM_TO_F32_CHECKED: "toF32Checked"
|
135 NUM_TO_F32: "toF32"
|
||||||
136 NUM_TO_F64: "toF64"
|
136 NUM_TO_F32_CHECKED: "toF32Checked"
|
||||||
137 NUM_TO_F64_CHECKED: "toF64Checked"
|
137 NUM_TO_F64: "toF64"
|
||||||
138 NUM_MAX_F64: "maxF64"
|
138 NUM_TO_F64_CHECKED: "toF64Checked"
|
||||||
139 NUM_MIN_F64: "minF64"
|
139 NUM_MAX_F64: "maxF64"
|
||||||
|
140 NUM_MIN_F64: "minF64"
|
||||||
}
|
}
|
||||||
2 BOOL: "Bool" => {
|
2 BOOL: "Bool" => {
|
||||||
0 BOOL_BOOL: "Bool" // the Bool.Bool type alias
|
0 BOOL_BOOL: "Bool" // the Bool.Bool type alias
|
||||||
|
|
|
@ -938,12 +938,11 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
||||||
Eq | NotEq => arena.alloc_slice_copy(&[borrowed, borrowed]),
|
Eq | NotEq => arena.alloc_slice_copy(&[borrowed, borrowed]),
|
||||||
|
|
||||||
And | Or | NumAdd | NumAddWrap | NumAddChecked | NumAddSaturated | NumSub | NumSubWrap
|
And | Or | NumAdd | NumAddWrap | NumAddChecked | NumAddSaturated | NumSub | NumSubWrap
|
||||||
| NumSubChecked | NumSubSaturated | NumMul | NumMulWrap | NumMulChecked | NumGt
|
| NumSubChecked | NumSubSaturated | NumMul | NumMulWrap | NumMulSaturated
|
||||||
| NumGte | NumLt | NumLte | NumCompare | NumDivUnchecked | NumDivCeilUnchecked
|
| NumMulChecked | NumGt | NumGte | NumLt | NumLte | NumCompare | NumDivUnchecked
|
||||||
| NumRemUnchecked | NumIsMultipleOf | NumPow | NumPowInt | NumBitwiseAnd
|
| NumDivCeilUnchecked | NumRemUnchecked | NumIsMultipleOf | NumPow | NumPowInt
|
||||||
| NumBitwiseXor | NumBitwiseOr | NumShiftLeftBy | NumShiftRightBy | NumShiftRightZfBy => {
|
| NumBitwiseAnd | NumBitwiseXor | NumBitwiseOr | NumShiftLeftBy | NumShiftRightBy
|
||||||
arena.alloc_slice_copy(&[irrelevant, irrelevant])
|
| NumShiftRightZfBy => arena.alloc_slice_copy(&[irrelevant, irrelevant]),
|
||||||
}
|
|
||||||
|
|
||||||
NumToStr | NumAbs | NumNeg | NumSin | NumCos | NumSqrtUnchecked | NumLogUnchecked
|
NumToStr | NumAbs | NumNeg | NumSin | NumCos | NumSqrtUnchecked | NumLogUnchecked
|
||||||
| NumRound | NumCeiling | NumFloor | NumToFrac | Not | NumIsFinite | NumAtan | NumAcos
|
| NumRound | NumCeiling | NumFloor | NumToFrac | Not | NumIsFinite | NumAtan | NumAcos
|
||||||
|
|
|
@ -165,6 +165,7 @@ enum FirstOrder {
|
||||||
NumSubChecked,
|
NumSubChecked,
|
||||||
NumMul,
|
NumMul,
|
||||||
NumMulWrap,
|
NumMulWrap,
|
||||||
|
NumMulSaturated,
|
||||||
NumMulChecked,
|
NumMulChecked,
|
||||||
NumGt,
|
NumGt,
|
||||||
NumGte,
|
NumGte,
|
||||||
|
|
|
@ -3180,6 +3180,76 @@ fn sub_saturated() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||||
|
fn mul_saturated() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
x : U8
|
||||||
|
x = 20
|
||||||
|
y : U8
|
||||||
|
y = 20
|
||||||
|
Num.mulSaturated x y
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
255,
|
||||||
|
u8
|
||||||
|
);
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
x : I8
|
||||||
|
x = -20
|
||||||
|
y : I8
|
||||||
|
y = -20
|
||||||
|
Num.mulSaturated x y
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
127,
|
||||||
|
i8
|
||||||
|
);
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
x : I8
|
||||||
|
x = 20
|
||||||
|
y : I8
|
||||||
|
y = -20
|
||||||
|
Num.mulSaturated x y
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
-128,
|
||||||
|
i8
|
||||||
|
);
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
x : I8
|
||||||
|
x = -20
|
||||||
|
y : I8
|
||||||
|
y = 20
|
||||||
|
Num.mulSaturated x y
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
-128,
|
||||||
|
i8
|
||||||
|
);
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
x : I8
|
||||||
|
x = 20
|
||||||
|
y : I8
|
||||||
|
y = 20
|
||||||
|
Num.mulSaturated x y
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
127,
|
||||||
|
i8
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn monomorphized_ints() {
|
fn monomorphized_ints() {
|
||||||
|
|
|
@ -348,6 +348,11 @@ fn num_mul_wrap() {
|
||||||
expect_success("Num.mulWrap Num.maxI64 2", "-2 : I64");
|
expect_success("Num.mulWrap Num.maxI64 2", "-2 : I64");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn num_mul_saturated() {
|
||||||
|
expect_success("Num.mulSaturated Num.maxI64 2", "9223372036854775807 : I64");
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "wasm"))]
|
#[cfg(not(feature = "wasm"))]
|
||||||
#[test]
|
#[test]
|
||||||
fn num_add_checked() {
|
fn num_add_checked() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue