diff --git a/CHANGELOG.md b/CHANGELOG.md index 9494e131..5815f562 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Changed - **aiken-lang**: block `Data` and `String` from unifying when casting +- **aiken-lang**: remove ability for a type with many variants with matching field labels and types to support field access - **aiken-project**: tests filtering with `-m` during check now happens in `Project::collect_tests` ## [v0.0.29] - 2023-MM-DD diff --git a/crates/aiken-lang/src/tipo/environment.rs b/crates/aiken-lang/src/tipo/environment.rs index feb25a5e..2038787a 100644 --- a/crates/aiken-lang/src/tipo/environment.rs +++ b/crates/aiken-lang/src/tipo/environment.rs @@ -177,6 +177,7 @@ impl<'a> Environment<'a> { }, ); } + Ok(Some(fields)) } @@ -1780,44 +1781,22 @@ fn get_compatible_record_fields( ) -> Vec<(usize, &str, &Annotation)> { let mut compatible = vec![]; + if constructors.len() > 1 { + return compatible; + } + let first = match constructors.get(0) { Some(first) => first, None => return compatible, }; - 'next_argument: for (index, first_argument) in first.arguments.iter().enumerate() { + for (index, first_argument) in first.arguments.iter().enumerate() { // Fields without labels do not have accessors let label = match first_argument.label.as_ref() { Some(label) => label.as_str(), - None => continue 'next_argument, + None => continue, }; - // Check each variant to see if they have an field in the same position - // with the same label and the same type - for constructor in constructors.iter().skip(1) { - // The field must exist in all variants - let argument = match constructor.arguments.get(index) { - Some(argument) => argument, - None => continue 'next_argument, - }; - - // The labels must be the same - if argument.label != first_argument.label { - continue 'next_argument; - } - - // The types must be the same - if !argument - .annotation - .is_logically_equal(&first_argument.annotation) - { - continue 'next_argument; - } - } - - // The previous loop did not find any incompatible fields in the other - // variants so this field is compatible across variants and we should - // generate an accessor for it. compatible.push((index, label, &first_argument.annotation)) } diff --git a/crates/aiken-lang/src/tipo/error.rs b/crates/aiken-lang/src/tipo/error.rs index e9adbe94..6aa80597 100644 --- a/crates/aiken-lang/src/tipo/error.rs +++ b/crates/aiken-lang/src/tipo/error.rs @@ -745,7 +745,7 @@ Perhaps, try the following: #[diagnostic(code("unknown::record_field"))] #[diagnostic(help( "{}", - suggest_neighbor(label, fields.iter(), "Did you forget to make it public?") + suggest_neighbor(label, fields.iter(), "Did you forget to make it public?\n\nAlso record access is only supported on types with one constructor.") ))] UnknownRecordField { #[label]