λ Support functions! #5
@@ -330,7 +330,7 @@ pub fn solve_constraints(
|
|||||||
loc, from_type, to_type,
|
loc, from_type, to_type,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
tracing::trace!(form = %from_type, to = %to_type, "changed something because we can determine if we can do the cast");
|
tracing::trace!(form = %from_type, to = %to_type, "we can determine if we can do the cast");
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,7 +352,7 @@ pub fn solve_constraints(
|
|||||||
TypeOrVar::Function(args2, ret2),
|
TypeOrVar::Function(args2, ret2),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
tracing::trace!("changed something because we transferred CanCastTo to equivalence checks for function types");
|
tracing::trace!("we transferred CanCastTo to equivalence checks for function types");
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,7 +361,7 @@ pub fn solve_constraints(
|
|||||||
ft @ TypeOrVar::Function(_, _),
|
ft @ TypeOrVar::Function(_, _),
|
||||||
pt @ TypeOrVar::Primitive(_),
|
pt @ TypeOrVar::Primitive(_),
|
||||||
) => {
|
) => {
|
||||||
tracing::trace!(function_type = %ft, primitive_type = %pt, "changed something because we can't cast a function type to a primitive type");
|
tracing::trace!(function_type = %ft, primitive_type = %pt, "we can't cast a function type to a primitive type");
|
||||||
errors.push(TypeInferenceError::CannotCastFromFunctionType(loc, pt));
|
errors.push(TypeInferenceError::CannotCastFromFunctionType(loc, pt));
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
}
|
}
|
||||||
@@ -371,14 +371,14 @@ pub fn solve_constraints(
|
|||||||
pt @ TypeOrVar::Primitive(_),
|
pt @ TypeOrVar::Primitive(_),
|
||||||
ft @ TypeOrVar::Function(_, _),
|
ft @ TypeOrVar::Function(_, _),
|
||||||
) => {
|
) => {
|
||||||
tracing::trace!(function_type = %ft, primitive_type = %pt, "changed something because we can't cast a primitive type to a function type");
|
tracing::trace!(function_type = %ft, primitive_type = %pt, "we can't cast a primitive type to a function type");
|
||||||
errors.push(TypeInferenceError::CannotCastToFunctionType(loc, pt));
|
errors.push(TypeInferenceError::CannotCastToFunctionType(loc, pt));
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're testing if an actual primitive type is numeric, that's pretty easy
|
// if we're testing if an actual primitive type is numeric, that's pretty easy
|
||||||
Constraint::ConstantNumericType(loc, TypeOrVar::Primitive(pt)) => {
|
Constraint::ConstantNumericType(loc, TypeOrVar::Primitive(pt)) => {
|
||||||
tracing::trace!(primitive_type = %pt, "changed something because its easy to tell if a constant number can be a primitive type");
|
tracing::trace!(primitive_type = %pt, "its easy to tell if a constant number can be a primitive type");
|
||||||
if pt.max_value().is_none() {
|
if pt.max_value().is_none() {
|
||||||
errors.push(TypeInferenceError::NotANumber(loc, pt))
|
errors.push(TypeInferenceError::NotANumber(loc, pt))
|
||||||
}
|
}
|
||||||
@@ -387,7 +387,7 @@ pub fn solve_constraints(
|
|||||||
|
|
||||||
// if we're testing if a function type is numeric, then throw a useful warning
|
// if we're testing if a function type is numeric, then throw a useful warning
|
||||||
Constraint::ConstantNumericType(loc, t @ TypeOrVar::Function(_, _)) => {
|
Constraint::ConstantNumericType(loc, t @ TypeOrVar::Function(_, _)) => {
|
||||||
tracing::trace!(function_type = %t, "changed something because functions can't be constant numbers");
|
tracing::trace!(function_type = %t, "functions can't be constant numbers");
|
||||||
errors.push(TypeInferenceError::CannotMakeNumberAFunction(loc, t, None));
|
errors.push(TypeInferenceError::CannotMakeNumberAFunction(loc, t, None));
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
}
|
}
|
||||||
@@ -404,12 +404,12 @@ pub fn solve_constraints(
|
|||||||
Some(_) => {}
|
Some(_) => {}
|
||||||
}
|
}
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
tracing::trace!(primitive_type = %ctype, value = val, "changed something because we can test for a value fitting in a primitive type");
|
tracing::trace!(primitive_type = %ctype, value = val, "we can test for a value fitting in a primitive type");
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're testing if a function type can fit into a numeric type, that's a problem
|
// if we're testing if a function type can fit into a numeric type, that's a problem
|
||||||
Constraint::FitsInNumType(loc, t @ TypeOrVar::Function(_, _), val) => {
|
Constraint::FitsInNumType(loc, t @ TypeOrVar::Function(_, _), val) => {
|
||||||
tracing::trace!(function_type = %t, "changed something because values don't fit in function types");
|
tracing::trace!(function_type = %t, "values don't fit in function types");
|
||||||
errors.push(TypeInferenceError::CannotMakeNumberAFunction(
|
errors.push(TypeInferenceError::CannotMakeNumberAFunction(
|
||||||
loc,
|
loc,
|
||||||
t,
|
t,
|
||||||
@@ -421,13 +421,13 @@ pub fn solve_constraints(
|
|||||||
// if we want to know if a type is something, and it is something, then we're done
|
// if we want to know if a type is something, and it is something, then we're done
|
||||||
Constraint::IsSomething(_, t @ TypeOrVar::Function(_, _))
|
Constraint::IsSomething(_, t @ TypeOrVar::Function(_, _))
|
||||||
| Constraint::IsSomething(_, t @ TypeOrVar::Primitive(_)) => {
|
| Constraint::IsSomething(_, t @ TypeOrVar::Primitive(_)) => {
|
||||||
tracing::trace!(tested_type = %t, "changed something because type is definitely something");
|
tracing::trace!(tested_type = %t, "type is definitely something");
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we want to know if something is signed, we can check its primitive type
|
// if we want to know if something is signed, we can check its primitive type
|
||||||
Constraint::IsSigned(loc, TypeOrVar::Primitive(pt)) => {
|
Constraint::IsSigned(loc, TypeOrVar::Primitive(pt)) => {
|
||||||
tracing::trace!(primitive_type = %pt, "changed something because we can check if a primitive is signed");
|
tracing::trace!(primitive_type = %pt, "we can check if a primitive is signed");
|
||||||
if !pt.valid_operators().contains(&("-", 1)) {
|
if !pt.valid_operators().contains(&("-", 1)) {
|
||||||
errors.push(TypeInferenceError::IsNotSigned(loc, pt));
|
errors.push(TypeInferenceError::IsNotSigned(loc, pt));
|
||||||
}
|
}
|
||||||
@@ -436,14 +436,14 @@ pub fn solve_constraints(
|
|||||||
|
|
||||||
// again with the functions and the numbers
|
// again with the functions and the numbers
|
||||||
Constraint::IsSigned(loc, t @ TypeOrVar::Function(_, _)) => {
|
Constraint::IsSigned(loc, t @ TypeOrVar::Function(_, _)) => {
|
||||||
tracing::trace!(function_type = %t, "changed something because functions are not signed");
|
tracing::trace!(function_type = %t, "functions are not signed");
|
||||||
errors.push(TypeInferenceError::CannotCastFromFunctionType(loc, t));
|
errors.push(TypeInferenceError::CannotCastFromFunctionType(loc, t));
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're testing if an actual primitive type is numeric, that's pretty easy
|
// if we're testing if an actual primitive type is numeric, that's pretty easy
|
||||||
Constraint::NumericType(loc, TypeOrVar::Primitive(pt)) => {
|
Constraint::NumericType(loc, TypeOrVar::Primitive(pt)) => {
|
||||||
tracing::trace!(primitive_type = %pt, "changed something because its easy to tell if a primitive type is numeric");
|
tracing::trace!(primitive_type = %pt, "its easy to tell if a primitive type is numeric");
|
||||||
if pt.max_value().is_none() {
|
if pt.max_value().is_none() {
|
||||||
errors.push(TypeInferenceError::NotANumber(loc, pt))
|
errors.push(TypeInferenceError::NotANumber(loc, pt))
|
||||||
}
|
}
|
||||||
@@ -452,20 +452,20 @@ pub fn solve_constraints(
|
|||||||
|
|
||||||
// if we're testing if a function type is numeric, then throw a useful warning
|
// if we're testing if a function type is numeric, then throw a useful warning
|
||||||
Constraint::NumericType(loc, t @ TypeOrVar::Function(_, _)) => {
|
Constraint::NumericType(loc, t @ TypeOrVar::Function(_, _)) => {
|
||||||
tracing::trace!(function_type = %t, "changed something because function types aren't numeric");
|
tracing::trace!(function_type = %t, "function types aren't numeric");
|
||||||
errors.push(TypeInferenceError::CannotMakeNumberAFunction(loc, t, None));
|
errors.push(TypeInferenceError::CannotMakeNumberAFunction(loc, t, None));
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// all of our primitive types are printable
|
// all of our primitive types are printable
|
||||||
Constraint::Printable(_, TypeOrVar::Primitive(pt)) => {
|
Constraint::Printable(_, TypeOrVar::Primitive(pt)) => {
|
||||||
tracing::trace!(primitive_type = %pt, "changed something because primitive types are printable");
|
tracing::trace!(primitive_type = %pt, "primitive types are printable");
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// function types are definitely not printable
|
// function types are definitely not printable
|
||||||
Constraint::Printable(loc, ft @ TypeOrVar::Function(_, _)) => {
|
Constraint::Printable(loc, ft @ TypeOrVar::Function(_, _)) => {
|
||||||
tracing::trace!(function_type = %ft, "changed something because function types are not printable");
|
tracing::trace!(function_type = %ft, "function types are not printable");
|
||||||
errors.push(TypeInferenceError::FunctionsAreNotPrintable(loc));
|
errors.push(TypeInferenceError::FunctionsAreNotPrintable(loc));
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
}
|
}
|
||||||
@@ -486,7 +486,7 @@ pub fn solve_constraints(
|
|||||||
new_constraints.push(Constraint::Equivalent(loc.clone(), left, ret));
|
new_constraints.push(Constraint::Equivalent(loc.clone(), left, ret));
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
all_constraints_solved = false;
|
all_constraints_solved = false;
|
||||||
tracing::trace!(primitive = %prim, "changed something because we expanded out a binary primitive operation");
|
tracing::trace!(primitive = %prim, "we expanded out a binary primitive operation");
|
||||||
}
|
}
|
||||||
|
|
||||||
Primitive::Minus if args.len() == 1 => {
|
Primitive::Minus if args.len() == 1 => {
|
||||||
@@ -496,7 +496,7 @@ pub fn solve_constraints(
|
|||||||
new_constraints.push(Constraint::Equivalent(loc, value, ret));
|
new_constraints.push(Constraint::Equivalent(loc, value, ret));
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
all_constraints_solved = false;
|
all_constraints_solved = false;
|
||||||
tracing::trace!(primitive = %prim, "changed something because we expanded out a unary primitive operation");
|
tracing::trace!(primitive = %prim, "we expanded out a unary primitive operation");
|
||||||
}
|
}
|
||||||
|
|
||||||
Primitive::Plus | Primitive::Times | Primitive::Divide => {
|
Primitive::Plus | Primitive::Times | Primitive::Divide => {
|
||||||
@@ -508,7 +508,7 @@ pub fn solve_constraints(
|
|||||||
args.len(),
|
args.len(),
|
||||||
));
|
));
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
tracing::trace!(primitive = %prim, provided_arity = args.len(), "changed something because binary primitive operation arity is wrong");
|
tracing::trace!(primitive = %prim, provided_arity = args.len(), "binary primitive operation arity is wrong");
|
||||||
}
|
}
|
||||||
|
|
||||||
Primitive::Minus => {
|
Primitive::Minus => {
|
||||||
@@ -520,7 +520,7 @@ pub fn solve_constraints(
|
|||||||
args.len(),
|
args.len(),
|
||||||
));
|
));
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
tracing::trace!(primitive = %prim, provided_arity = args.len(), "changed something because unary primitive operation arity is wrong");
|
tracing::trace!(primitive = %prim, provided_arity = args.len(), "unary primitive operation arity is wrong");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -538,7 +538,7 @@ pub fn solve_constraints(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
tracing::trace!(primitive_type1 = %pt1, primitive_type2 = %pt2, "changed something because we checked for primitive type equivalence");
|
tracing::trace!(primitive_type1 = %pt1, primitive_type2 = %pt2, "we checked for primitive type equivalence");
|
||||||
}
|
}
|
||||||
|
|
||||||
Constraint::Equivalent(
|
Constraint::Equivalent(
|
||||||
@@ -551,7 +551,7 @@ pub fn solve_constraints(
|
|||||||
ft @ TypeOrVar::Function(_, _),
|
ft @ TypeOrVar::Function(_, _),
|
||||||
pt @ TypeOrVar::Primitive(_),
|
pt @ TypeOrVar::Primitive(_),
|
||||||
) => {
|
) => {
|
||||||
tracing::trace!(primitive_type = %pt, function_type = %ft, "changed something because function and primitive types cannot be equivalent");
|
tracing::trace!(primitive_type = %pt, function_type = %ft, "function and primitive types cannot be equivalent");
|
||||||
errors.push(TypeInferenceError::NotEquivalent(loc, pt, ft));
|
errors.push(TypeInferenceError::NotEquivalent(loc, pt, ft));
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
}
|
}
|
||||||
@@ -561,7 +561,7 @@ pub fn solve_constraints(
|
|||||||
TypeOrVar::Variable(_, name1),
|
TypeOrVar::Variable(_, name1),
|
||||||
TypeOrVar::Variable(_, name2),
|
TypeOrVar::Variable(_, name2),
|
||||||
) if name1 == name2 => {
|
) if name1 == name2 => {
|
||||||
tracing::trace!(name = %name1, "changed something because variable is equivalent to itself");
|
tracing::trace!(name = %name1, "variable is equivalent to itself");
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -583,7 +583,7 @@ pub fn solve_constraints(
|
|||||||
}
|
}
|
||||||
|
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
tracing::trace!("changed something because we checked/rewrote if function types are equivalent");
|
tracing::trace!("we checked/rewrote if function types are equivalent");
|
||||||
}
|
}
|
||||||
|
|
||||||
Constraint::Equivalent(_, TypeOrVar::Variable(_, ref name), ref rhs) => {
|
Constraint::Equivalent(_, TypeOrVar::Variable(_, ref name), ref rhs) => {
|
||||||
@@ -591,13 +591,13 @@ pub fn solve_constraints(
|
|||||||
changed_something |= replace_variable(&mut new_constraints, name, rhs);
|
changed_something |= replace_variable(&mut new_constraints, name, rhs);
|
||||||
all_constraints_solved &= rhs.is_resolved();
|
all_constraints_solved &= rhs.is_resolved();
|
||||||
if changed_something {
|
if changed_something {
|
||||||
tracing::trace!(%name, new_type = %rhs, "changed something because we were able to rewrite name somewhere");
|
tracing::trace!(%name, new_type = %rhs, "we were able to rewrite name somewhere");
|
||||||
}
|
}
|
||||||
new_constraints.push(constraint);
|
new_constraints.push(constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
Constraint::Equivalent(loc, lhs, rhs @ TypeOrVar::Variable(_, _)) => {
|
Constraint::Equivalent(loc, lhs, rhs @ TypeOrVar::Variable(_, _)) => {
|
||||||
tracing::trace!(new_left = %rhs, new_right = %lhs, "changed something because we flipped the order on an equivalence");
|
tracing::trace!(new_left = %rhs, new_right = %lhs, "we flipped the order on an equivalence");
|
||||||
new_constraints.push(Constraint::Equivalent(loc, rhs, lhs));
|
new_constraints.push(Constraint::Equivalent(loc, rhs, lhs));
|
||||||
changed_something = true;
|
changed_something = true;
|
||||||
all_constraints_solved = false;
|
all_constraints_solved = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user