diff --git a/compiler/constrain/src/builtins.rs b/compiler/constrain/src/builtins.rs index 2987bfa174..f799db9438 100644 --- a/compiler/constrain/src/builtins.rs +++ b/compiler/constrain/src/builtins.rs @@ -44,8 +44,6 @@ pub fn float_literal( let num_type = Variable(num_var); let reason = Reason::FloatLiteral; - dbg!(&expected); - exists( vec![num_var], And(vec![ diff --git a/compiler/constrain/src/uniq.rs b/compiler/constrain/src/uniq.rs index 916c0e7150..f854bdc925 100644 --- a/compiler/constrain/src/uniq.rs +++ b/compiler/constrain/src/uniq.rs @@ -426,11 +426,8 @@ fn unique_int( let num_uvar1 = var_store.fresh(); let num_uvar2 = var_store.fresh(); let num_uvar3 = var_store.fresh(); - let num_uvar4 = var_store.fresh(); - let inner_type = Type::Variable(inner_var); - let attr_inner_type = attr_type(Bool::variable(num_uvar1), inner_type); - let integer = num_integer(attr_inner_type); + let integer = num_integer(Type::Variable(inner_var)); let attr_int = attr_type(Bool::variable(num_uvar2), integer); let num = num_num(attr_int); let attr_num = attr_type(Bool::variable(num_uvar3), num); @@ -445,11 +442,8 @@ fn unique_float( let num_uvar1 = var_store.fresh(); let num_uvar2 = var_store.fresh(); let num_uvar3 = var_store.fresh(); - let num_uvar4 = var_store.fresh(); - let inner_type = Type::Variable(inner_var); - let attr_inner_type = attr_type(Bool::variable(num_uvar1), inner_type); - let fp = num_floatingpoint(attr_inner_type); + let fp = num_floatingpoint(Type::Variable(inner_var)); let attr_fp = attr_type(Bool::variable(num_uvar2), fp); let num = num_num(attr_fp); let attr_num = attr_type(Bool::variable(num_uvar3), num); diff --git a/compiler/mono/src/decision_tree.rs b/compiler/mono/src/decision_tree.rs index 314566d7ec..13d11b2616 100644 --- a/compiler/mono/src/decision_tree.rs +++ b/compiler/mono/src/decision_tree.rs @@ -445,7 +445,7 @@ fn test_at_path<'a>(selected_path: &Path, branch: &Branch<'a>, all_tests: &mut V num_alts: union.alternatives.len(), }); } - IntLiteral(v) => { + IntLiteral(_, v) => { all_tests.push(guarded(IsInt(*v))); } FloatLiteral(_, v) => { @@ -636,7 +636,7 @@ fn to_relevant_branch_help<'a>( _ => None, }, - IntLiteral(int) => match test { + IntLiteral(_, int) => match test { IsInt(is_int) if int == *is_int => { start.extend(end); Some(Branch { @@ -740,7 +740,7 @@ fn needs_tests<'a>(pattern: &Pattern<'a>) -> bool { | AppliedTag { .. } | BitLiteral { .. } | EnumLiteral { .. } - | IntLiteral(_) + | IntLiteral(_, _) | FloatLiteral(_, _) | StrLiteral(_) => true, } diff --git a/compiler/mono/src/exhaustive.rs b/compiler/mono/src/exhaustive.rs index 7a626b0ef2..f942d57073 100644 --- a/compiler/mono/src/exhaustive.rs +++ b/compiler/mono/src/exhaustive.rs @@ -48,7 +48,7 @@ fn simplify<'a>(pattern: &crate::ir::Pattern<'a>) -> Pattern { use crate::ir::Pattern::*; match pattern { - IntLiteral(v) => Literal(Literal::Int(*v)), + IntLiteral(_, v) => Literal(Literal::Int(*v)), FloatLiteral(_, v) => Literal(Literal::Float(*v)), StrLiteral(v) => Literal(Literal::Str(v.clone())), diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index 5b3058627d..eac076e4b2 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -2308,7 +2308,7 @@ pub fn with_hole<'a>( let arena = env.arena; match can_expr { - Int(_, precision, num) => match num_argument_to_int_or_float(env.subs, precision) { + Int(_, precision, num) => match num_argument_to_int_or_float(env.subs, precision, false) { IntOrFloat::SignedIntType(precision) => Stmt::Let( assigned, Expr::Literal(Literal::Int(num)), @@ -2324,7 +2324,7 @@ pub fn with_hole<'a>( _ => unreachable!("unexpected float precision for integer"), }, - Float(_, precision, num) => match num_argument_to_int_or_float(env.subs, precision) { + Float(_, precision, num) => match num_argument_to_int_or_float(env.subs, precision, true) { IntOrFloat::BinaryFloatType(precision) => Stmt::Let( assigned, Expr::Literal(Literal::Float(num as f64)), @@ -2347,7 +2347,7 @@ pub fn with_hole<'a>( hole, ), - Num(var, num) => match num_argument_to_int_or_float(env.subs, var) { + Num(var, num) => match num_argument_to_int_or_float(env.subs, var, false) { IntOrFloat::SignedIntType(precision) => Stmt::Let( assigned, Expr::Literal(Literal::Int(num)), @@ -4739,7 +4739,7 @@ fn store_pattern<'a>( Underscore => { // do nothing } - IntLiteral(_) + IntLiteral(_, _) | FloatLiteral(_, _) | EnumLiteral { .. } | BitLiteral { .. } @@ -4779,7 +4779,7 @@ fn store_pattern<'a>( Underscore => { // ignore } - IntLiteral(_) + IntLiteral(_, _) | FloatLiteral(_, _) | EnumLiteral { .. } | BitLiteral { .. } @@ -4874,7 +4874,7 @@ fn store_record_destruct<'a>( // // internally. But `y` is never used, so we must make sure it't not stored/loaded. } - IntLiteral(_) + IntLiteral(_, _) | FloatLiteral(_, _) | EnumLiteral { .. } | BitLiteral { .. } @@ -5544,8 +5544,7 @@ fn call_by_name<'a>( pub enum Pattern<'a> { Identifier(Symbol), Underscore, - - IntLiteral(i64), + IntLiteral(Variable, i64), FloatLiteral(Variable, u64), BitLiteral { value: bool, @@ -5619,8 +5618,8 @@ fn from_can_pattern_help<'a>( match can_pattern { Underscore => Ok(Pattern::Underscore), Identifier(symbol) => Ok(Pattern::Identifier(*symbol)), - IntLiteral(_, v) => Ok(Pattern::IntLiteral(*v)), - FloatLiteral(var, float) => Pattern::FloatLiteral(*var, f64::to_bits(*float)), + IntLiteral(var, v) => Ok(Pattern::IntLiteral(*var, *v)), + FloatLiteral(var, float) => Ok(Pattern::FloatLiteral(*var, f64::to_bits(*float))), StrLiteral(v) => Ok(Pattern::StrLiteral(v.clone())), Shadowed(region, ident) => Err(RuntimeError::Shadowing { original_region: *region, @@ -5632,11 +5631,11 @@ fn from_can_pattern_help<'a>( // TODO preserve malformed problem information here? Err(RuntimeError::UnsupportedPattern(*region)) } - NumLiteral(var, num) => match num_argument_to_int_or_float(env.subs, *var) { - IntOrFloat::SignedIntType(_) => Pattern::IntLiteral(*num), - IntOrFloat::UnsignedIntType(_) => Pattern::IntLiteral(*num), - IntOrFloat::BinaryFloatType(_) => Pattern::FloatLiteral(*var, *num as u64), - IntOrFloat::DecimalFloatType(_) => Pattern::FloatLiteral(*var, *num as u64), + NumLiteral(var, num) => match num_argument_to_int_or_float(env.subs, *var, false) { + IntOrFloat::SignedIntType(_) => Ok(Pattern::IntLiteral(*var, *num)), + IntOrFloat::UnsignedIntType(_) => Ok(Pattern::IntLiteral(*var, *num)), + IntOrFloat::BinaryFloatType(_) => Ok(Pattern::FloatLiteral(*var, *num as u64)), + IntOrFloat::DecimalFloatType(_) => Ok(Pattern::FloatLiteral(*var, *num as u64)), }, AppliedTag { @@ -6051,15 +6050,21 @@ fn int_precision_to_builtin(precision: IntPrecision) -> Builtin<'static> { } /// Given the `a` in `Num a`, determines whether it's an int or a float -pub fn num_argument_to_int_or_float(subs: &Subs, var: Variable) -> IntOrFloat { +pub fn num_argument_to_int_or_float( + subs: &Subs, + var: Variable, + known_to_be_float: bool, +) -> IntOrFloat { match subs.get_without_compacting(var).content { + Content::FlexVar(_) if known_to_be_float => IntOrFloat::BinaryFloatType(FloatPrecision::F64), Content::FlexVar(_) => IntOrFloat::SignedIntType(IntPrecision::I64), // We default (Num *) to I64 Content::Alias(Symbol::NUM_I128, _, _) | Content::Alias(Symbol::NUM_SIGNED128, _, _) | Content::Alias(Symbol::NUM_AT_SIGNED128, _, _) => { IntOrFloat::SignedIntType(IntPrecision::I128) } - Content::Alias(Symbol::NUM_INTEGER, _, _) // We default Integer to I64 + Content::Alias(Symbol::NUM_INT, _, _) + | Content::Alias(Symbol::NUM_INTEGER, _, _) // We default Integer to I64 | Content::Alias(Symbol::NUM_I64, _, _) | Content::Alias(Symbol::NUM_SIGNED64, _, _) | Content::Alias(Symbol::NUM_AT_SIGNED64, _, _) => { @@ -6110,9 +6115,10 @@ pub fn num_argument_to_int_or_float(subs: &Subs, var: Variable) -> IntOrFloat { debug_assert!(attr_args.len() == 2); // Recurse on the second argument - num_argument_to_int_or_float(subs, attr_args[1]) + num_argument_to_int_or_float(subs, attr_args[1], false) } - Content::Alias(Symbol::NUM_FLOATINGPOINT, _, _) // We default FloatingPoint to F64 + Content::Alias(Symbol::NUM_FLOAT, _, _) + | Content::Alias(Symbol::NUM_FLOATINGPOINT, _, _) // We default FloatingPoint to F64 | Content::Alias(Symbol::NUM_F64, _, _) | Content::Alias(Symbol::NUM_BINARY64, _, _) | Content::Alias(Symbol::NUM_AT_BINARY64, _, _) => {