-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix array element type algorithm to avoid selecting never #6511
base: master
Are you sure you want to change the base?
Conversation
CodSpeed Performance ReportMerging #6511 will improve performances by 20.79%Comparing Summary
Benchmarks breakdown
|
test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw
Show resolved
Hide resolved
// if the element type is still unknown, and all elements are Never, | ||
// fallback to unit | ||
let initial_type = if matches!(initial_type, TypeInfo::Unknown) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a problem with using Unknown
instead of unit
as the result in this case?
If the type is still Unknown
after unification, then we should throw an error because the type could not be determined. Otherwise it seems to me that using Unknown
here solves the entire issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unit
is how Rust does it.
fn main() {
let mut a = None;
loop {
a = Some([break]);
}
println!("{}", std::any::type_name_of_val(&a));
}
will print core::option::Option<[(); 1]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But giving an error in this case does not seem wrong to me. We just need to decide which we prefer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it matters much so long as we guarantee that the unannotated type of []
is [();0]
.
I suppose in the broadest sense, the programmer's intent with a program like this is unambiguous and so it's not really erroneous. It's just weird, but it's fully deterministic and since the elements aren't used at all, any zero sized type will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so long as we guarantee that the unannotated type of [] is [();0]
But this is not what Rust does. []
is whatever the context says. If there is no context, then it fails.
This "decay" to Unit
only happens for "arrays without typing context and all elements are never".
Changing the program above to an empty array and it fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that in this case ("arrays without typing context and all elements are never") we have four options:
1 - infer the array element as never; so something like [!;1]
;
2 - infer the whole array as never;
3 - decay into a zero-sized type, in this case, unit
;
4 - give an error.
1
and 2
create this complicated case of how to deal with "generic types with never".
I think 4
is totally reasonable in this case.
But I implemented 3
just because it is what Rust does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having thought about it some more I'm ok with either solution TBH.
We're trying to solve a degenerate case where an array of Never
elements is used in a way that is inconsistent with the Never
type. The array will never be constructed (because that's what Never
means), so the inconsistency will also never be executed. Whether the compiler calls that a type error or piece of allowable dead code is really not worth making a big deal out of. It's a type violation in dead code.
test/src/e2e_vm_tests/test_programs/should_fail/array_wrong_elements_types/src/main.sw
Show resolved
Hide resolved
72a6512
to
7d2e15f
Compare
Description
This PR fixes the array element type selection algorithm to avoid selecting
Never
.Checklist
Breaking*
orNew Feature
labels where relevant.