Correctly print wildcards as appropriate in error messages

This commit is contained in:
Ayaz Hafiz 2022-10-25 14:56:38 -05:00
parent d77080529a
commit 3c15ff4694
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
4 changed files with 293 additions and 108 deletions

View file

@ -3710,7 +3710,7 @@ fn content_to_err_type(
Some(name_index) => subs.field_names[name_index.index as usize].clone(),
None => {
// set the name so when this variable occurs elsewhere in the type it gets the same name
let name = get_fresh_var_name(state);
let name = get_fresh_error_var_name(state);
let name_index = SubsIndex::push_new(&mut subs.field_names, name.clone());
subs.set_content(var, FlexVar(Some(name_index)));
@ -3732,7 +3732,7 @@ fn content_to_err_type(
Some(name_index) => subs.field_names[name_index.index as usize].clone(),
None => {
// set the name so when this variable occurs elsewhere in the type it gets the same name
let name = get_fresh_var_name(state);
let name = get_fresh_error_var_name(state);
let name_index = SubsIndex::push_new(&mut subs.field_names, name.clone());
subs.set_content(var, FlexVar(Some(name_index)));
@ -3758,7 +3758,7 @@ fn content_to_err_type(
let name = match opt_name {
Some(name_index) => subs.field_names[name_index.index as usize].clone(),
None => {
let name = get_fresh_var_name(state);
let name = get_fresh_error_var_name(state);
let name_index = SubsIndex::push_new(&mut subs.field_names, name.clone());
subs.set_content(var, FlexVar(Some(name_index)));
@ -4014,7 +4014,12 @@ fn union_tags_to_err_tags(
err_tags
}
fn get_fresh_var_name(state: &mut ErrorTypeState) -> Lowercase {
fn get_fresh_error_var_name(state: &mut ErrorTypeState) -> Lowercase {
// Auto-generated unbound variable names in error types start with `#`, so we can see later
// that they are auto-generated, and decide whether they should become wildcards contextually.
//
// We want to claim both the "#name" and "name" forms, because if "#name" appears multiple
// times during error type reporting, we'll use "name" for display.
let (name, new_index) =
name_type_var(state.letters_used, &mut state.taken.iter(), |var, str| {
var.as_str() == str
@ -4022,9 +4027,15 @@ fn get_fresh_var_name(state: &mut ErrorTypeState) -> Lowercase {
state.letters_used = new_index;
state.taken.insert(name.clone());
let mut gen_name = String::with_capacity(name.as_str().len() + 1);
gen_name.push('#');
gen_name.push_str(name.as_str());
let gen_name = Lowercase::from(gen_name);
name
state.taken.insert(name);
state.taken.insert(gen_name.clone());
gen_name
}
/// Exposed types in a module, captured in a storage subs. Includes

View file

@ -2294,8 +2294,10 @@ pub type DoesNotImplementAbility = Vec<(ErrorType, Symbol)>;
pub enum ErrorType {
Infinite,
Type(Symbol, Vec<ErrorType>),
/// If the name was auto-generated, it will start with a `#`.
FlexVar(Lowercase),
RigidVar(Lowercase),
/// If the name was auto-generated, it will start with a `#`.
FlexAbleVar(Lowercase, AbilitySet),
RigidAbleVar(Lowercase, AbilitySet),
Record(SendMap<Lowercase, RecordField<ErrorType>>, TypeExt),