diff --git a/compiler/can/src/constraint_soa.rs b/compiler/can/src/constraint_soa.rs index 26f7a6a0b8..df1c478fd5 100644 --- a/compiler/can/src/constraint_soa.rs +++ b/compiler/can/src/constraint_soa.rs @@ -217,6 +217,7 @@ impl Constraints { where I: IntoIterator, C: IntoIterator, + C::IntoIter: ExactSizeIterator, { let defs_constraint = self.and_constraint(defs_constraint); @@ -268,20 +269,28 @@ impl Constraints { Constraint::Let(let_index) } - #[must_use] pub fn and_constraint(&mut self, constraints: I) -> Constraint where I: IntoIterator, + I::IntoIter: ExactSizeIterator, { - let start = self.constraints.len() as u32; + let mut it = constraints.into_iter(); - self.constraints.extend(constraints); + match it.len() { + 0 => Constraint::True, + 1 => it.next().unwrap(), + _ => { + let start = self.constraints.len() as u32; - let end = self.constraints.len() as u32; + self.constraints.extend(it); - let slice = Slice::new(start, (end - start) as u16); + let end = self.constraints.len() as u32; - Constraint::And(slice) + let slice = Slice::new(start, (end - start) as u16); + + Constraint::And(slice) + } + } } pub fn lookup( diff --git a/compiler/constrain/src/soa_expr.rs b/compiler/constrain/src/soa_expr.rs index 9d8bd17b19..ae483e1fae 100644 --- a/compiler/constrain/src/soa_expr.rs +++ b/compiler/constrain/src/soa_expr.rs @@ -1091,8 +1091,10 @@ pub fn constrain_expr( let category = Category::LowLevelOpResult(*op); + // Deviation: elm uses an additional And here let eq = constraints.equal_types(ret_type, expected, category, region); - constraints.exists_many(vars, arg_cons.into_iter().chain(std::iter::once(eq))) + arg_cons.push(eq); + constraints.exists_many(vars, arg_cons) } ForeignCall { args, @@ -1132,8 +1134,10 @@ pub fn constrain_expr( let category = Category::ForeignCall; + // Deviation: elm uses an additional And here let eq = constraints.equal_types(ret_type, expected, category, region); - constraints.exists_many(vars, arg_cons.into_iter().chain(std::iter::once(eq))) + arg_cons.push(eq); + constraints.exists_many(vars, arg_cons) } RuntimeError(_) => { // Runtime Errors have no constraints because they're going to crash.