Fix type display on error. (#1631)

This commit is contained in:
chriseth
2024-07-30 15:57:17 +02:00
committed by GitHub
parent 2e7c473413
commit 4e6187a200
4 changed files with 29 additions and 16 deletions

View File

@@ -1019,17 +1019,13 @@ pub fn format_type_scheme_around_name<E: Display, N: Display>(
impl Display for TypeBounds {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
fn format_var((var, bounds): (&String, &BTreeSet<String>)) -> 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(", ")
)
}
}

View File

@@ -441,4 +441,20 @@ impl TypeBounds {
pub fn bounds(&self) -> impl Iterator<Item = (&String, &BTreeSet<String>)> {
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>) -> String {
if bounds.is_empty() {
var.clone()
} else {
format!("{var}: {}", bounds.iter().join(" + "))
}
}
}

View File

@@ -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,)
}
}

View File

@@ -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| {