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(incrate::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<Vec<Rule>>,
}
impl List { pub(incrate::proc::overloads) fn from_rules(rules: Vec<Rule>) -> List {
List {
members: len_to_full_mask(rules.len()),
rules: Rc::new(rules),
}
}
fn members(&self) -> impl Iterator<Item = (u64, &Rule)> {
OneBitsIter::new(self.members).map(|mask| { let index = mask.trailing_zeros() as usize;
(mask, &self.rules[index])
})
}
fn filter<F>(&self, mut pred: F) -> List where
F: FnMut(&Rule) -> bool,
{ letmut filtered_members = 0; for (mask, rule) inself.members() { if pred(rule) {
filtered_members |= mask;
}
}
List {
members: filtered_members,
rules: self.rules.clone(),
}
}
}
implcrate::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 // `<Option as PartialOrd>` doesn't work the way we'd like. let len = rule.arguments.len();
Some(match best {
Some(best) => core::cmp::max(best, len),
None => len,
})
})
.unwrap()
}
fn most_preferred(&self) -> Rule { // As documented for `Self::rules`, whatever rule is first is // the most preferred. `OverloadSet` documents this method to // panic if the set is empty. let (_, rule) = self.members().next().unwrap();
rule.clone()
}
constfn len_to_full_mask(n: usize) -> u64 { #[expect(
clippy::allow_attributes,
reason = "This is a const function, which _sometimes_ gets called, \
so this lint is _sometimes_ triggered, depending on feature set."
)] #[allow(clippy::panic)] if n >= 64 {
panic!("List::rules can only hold up to 63 rules");
}
(1_u64 << n) - 1
}
impl ForDebugWithTypes for &List {}
impl fmt::Debug for DiagnosticDebug<(&List, &crate::UniqueArena<ir::Type>)> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let (list, types) = self.0;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.