Skip to content

Commit 81186b0

Browse files
rchen152meta-codesync[bot]
authored andcommitted
Add a pluralize helper
Summary: We have three different occurrences of the same pluralization logic now; we might as well consolidate them. If this gets any more complicated, we should probably look for a library to handle this rather than continuing to reinvent the grammar wheel ^^; Reviewed By: fangyi-zhou Differential Revision: D91756391 fbshipit-source-id: cff4a1db4e48c8366bde7dd131c12c760dd6823a
1 parent 1c1623e commit 81186b0

File tree

3 files changed

+25
-21
lines changed

3 files changed

+25
-21
lines changed

crates/pyrefly_util/src/display.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,19 @@ pub fn number_thousands(x: usize) -> impl Display {
136136
.join(",")
137137
}
138138

139+
/// Pluralizes by tacking on an "s".
140+
pub fn pluralize(n: usize, descriptor: &str) -> String {
141+
if n == 1 {
142+
descriptor.to_owned()
143+
} else {
144+
format!("{}s", descriptor)
145+
}
146+
}
147+
139148
/// Format the number and descriptor word with the right pluralization.
140149
/// E.g., count(2, "cat") -> "2 cats". Pluralizes by tacking on an "s".
141150
pub fn count(n: usize, descriptor: &str) -> String {
142-
format!(
143-
"{} {descriptor}{}",
144-
number_thousands(n),
145-
if n == 1 { "" } else { "s" }
146-
)
151+
format!("{} {}", number_thousands(n), pluralize(n, descriptor))
147152
}
148153

149154
#[cfg(test)]

pyrefly/lib/alt/callable.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use pyrefly_types::typed_dict::ExtraItems;
1212
use pyrefly_types::types::TArgs;
1313
use pyrefly_types::types::TParams;
1414
use pyrefly_util::display::count;
15+
use pyrefly_util::display::pluralize;
1516
use pyrefly_util::owner::Owner;
1617
use pyrefly_util::prelude::SliceExt;
1718
use pyrefly_util::prelude::VecExt;
@@ -888,12 +889,8 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
888889
let range = keywords.first().map_or(arguments_range, |kw| kw.range);
889890
let msg = if missing_unnamed_posonly == 0 {
890891
format!(
891-
"Missing positional argument{} {}",
892-
if missing_named_posonly.len() == 1 {
893-
""
894-
} else {
895-
"s"
896-
},
892+
"Missing {} {}",
893+
pluralize(missing_named_posonly.len(), "positional argument"),
897894
missing_named_posonly
898895
.iter()
899896
.map(|name| format!("`{name}`"))

pyrefly/lib/alt/solve.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use pyrefly_types::type_info::JoinStyle;
2020
use pyrefly_types::typed_dict::ExtraItems;
2121
use pyrefly_types::typed_dict::TypedDict;
2222
use pyrefly_types::types::Union;
23+
use pyrefly_util::display::pluralize;
2324
use pyrefly_util::prelude::SliceExt;
2425
use pyrefly_util::visit::Visit;
2526
use pyrefly_util::visit::VisitMut;
@@ -1521,16 +1522,17 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
15211522
default.collect_raw_legacy_type_variables(&mut out_of_scope_names);
15221523
out_of_scope_names.retain(|name| !seen.contains(name));
15231524
if !out_of_scope_names.is_empty() {
1524-
self.error(errors, range, ErrorInfo::Kind(ErrorKind::InvalidTypeVar), format!(
1525-
"Default of type parameter `{}` refers to out-of-scope type parameter{} {}",
1526-
tparam.quantified.name(),
1527-
if out_of_scope_names.len() != 1 {
1528-
"s"
1529-
} else {
1530-
""
1531-
},
1532-
out_of_scope_names.map(|n| format!("`{n}`")).join(", "),
1533-
));
1525+
self.error(
1526+
errors,
1527+
range,
1528+
ErrorInfo::Kind(ErrorKind::InvalidTypeVar),
1529+
format!(
1530+
"Default of type parameter `{}` refers to out-of-scope {} {}",
1531+
tparam.quantified.name(),
1532+
pluralize(out_of_scope_names.len(), "type parameter"),
1533+
out_of_scope_names.map(|n| format!("`{n}`")).join(", "),
1534+
),
1535+
);
15341536
}
15351537
if tparam.quantified.is_type_var()
15361538
&& let Some(tvt) = &typevartuple

0 commit comments

Comments
 (0)