//! An [`OverloadSet`] represented as a vector of rules. //! //! [`OverloadSet`]: crate::proc::overloads::OverloadSet use crate::common::{DiagnosticDebug, ForDebug, ForDebugWithTypes}; use crate::ir; use crate::proc::overloads::one_bits_iter::OneBitsIter; use crate::proc::overloads::Rule; use crate::proc::{GlobalCtx, TypeResolution}; use alloc::rc::Rc; use alloc::vec::Vec; use core::fmt; /// A simple list of overloads. /// /// Note that this type is not quite as general as it looks, in that /// the implementation of `most_preferred` doesn't work for arbitrary /// lists of overloads. See the documentation for [`List::rules`] for /// details. #[derive(Clone)] pub(in crate::proc::overloads) struct List { /// A bitmask of which elements of `rules` are included in the set. members: u64, /// A list of type rules that are members of the set. /// /// These must be listed in order such that every rule in the list /// is always more preferred than all subsequent rules in the /// list. If there is no such arrangement of rules, then you /// cannot use `List` to represent the overload set. rules: Rc>, } impl List { pub(in crate::proc::overloads) fn from_rules(rules: Vec) -> List { List { members: len_to_full_mask(rules.len()), rules: Rc::new(rules), } } fn members(&self) -> impl Iterator { OneBitsIter::new(self.members).map(|mask| { let index = mask.trailing_zeros() as usize; (mask, &self.rules[index]) }) } fn filter(&self, mut pred: F) -> List where F: FnMut(&Rule) -> bool, { let mut filtered_members = 0; for (mask, rule) in self.members() { if pred(rule) { filtered_members |= mask; } } List { members: filtered_members, rules: self.rules.clone(), } } } impl crate::proc::overloads::OverloadSet for List { fn is_empty(&self) -> bool { self.members == 0 } fn min_arguments(&self) -> usize { self.members() .fold(None, |best, (_, rule)| { // This is different from `max_arguments` because // `