diff --git a/ast/src/parsed/display.rs b/ast/src/parsed/display.rs index 3ce6964de..bd80067d7 100644 --- a/ast/src/parsed/display.rs +++ b/ast/src/parsed/display.rs @@ -1019,17 +1019,13 @@ pub fn format_type_scheme_around_name( impl Display for TypeBounds { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - fn format_var((var, bounds): (&String, &BTreeSet)) -> String { - format!( - "{var}{}", - if bounds.is_empty() { - String::new() - } else { - format!(": {}", bounds.iter().join(" + ")) - } - ) - } - write!(f, "{}", self.bounds().map(format_var).format(", ")) + write!( + f, + "{}", + self.bounds() + .map(|(var, bounds)| TypeBounds::format_var_bound(var, bounds)) + .format(", ") + ) } } diff --git a/ast/src/parsed/types.rs b/ast/src/parsed/types.rs index 272236cd8..a618e8536 100644 --- a/ast/src/parsed/types.rs +++ b/ast/src/parsed/types.rs @@ -441,4 +441,20 @@ impl TypeBounds { pub fn bounds(&self) -> impl Iterator)> { self.0.iter().map(|(n, x)| (n, x)) } + + pub fn format_vars_with_nonempty_bounds(&self) -> String { + self.0 + .iter() + .filter(|(_, b)| !b.is_empty()) + .map(|(var, b)| Self::format_var_bound(var, b)) + .join(", ") + } + + pub fn format_var_bound(var: &String, bounds: &BTreeSet) -> String { + if bounds.is_empty() { + var.clone() + } else { + format!("{var}: {}", bounds.iter().join(" + ")) + } + } } diff --git a/pil-analyzer/src/type_inference.rs b/pil-analyzer/src/type_inference.rs index 23bb2b83e..18406b1a3 100644 --- a/pil-analyzer/src/type_inference.rs +++ b/pil-analyzer/src/type_inference.rs @@ -950,12 +950,13 @@ impl TypeChecker { fn format_type_with_bounds(&self, ty: Type) -> String { let scheme = self.to_type_scheme(ty); - if scheme.vars.is_empty() { - format!("{}", scheme.ty) + let bounds = scheme.vars.format_vars_with_nonempty_bounds(); + if bounds.is_empty() { + scheme.ty.to_string() } else if let Type::TypeVar(_) = &scheme.ty { - format!("{}", scheme.vars) + bounds } else { - format!("{}, {}", scheme.ty, scheme.vars) + format!("{} with {bounds}", scheme.ty,) } } diff --git a/pil-analyzer/tests/types.rs b/pil-analyzer/tests/types.rs index 24c142676..f967d7cf9 100644 --- a/pil-analyzer/tests/types.rs +++ b/pil-analyzer/tests/types.rs @@ -588,7 +588,7 @@ fn type_vars_in_block_let() { } #[test] -#[should_panic = "Expected type: int -> T, T\\nInferred type: int\\n"] +#[should_panic = "Expected type: int -> T\\nInferred type: int\\n"] fn new_fixed_column_wrong_value_type() { let input = r#"namespace N(16); let f = constr |j| {