You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Type printer prints wider types on non_empty_list forms #15837
Module.Types.Descr printer emits non_empty_list/2 representation that when used directly produces a wider type.
The list representation stores the type of the terminator. The non_empty_list/2 constructor instead accepts a tail type and folds any list-valued part of that tail into the element type.
Repro:
When printed and reconstructed the reconstructed type admits proper lists when the original type only admits improper ones
original=opt_difference(non_empty_list(none(),term()),list(dynamic()))to_quoted_string(original)# => "dynamic(non_empty_list(term())) or non_empty_list(term(), not empty_list())"reconstructed=opt_union(dynamic(non_empty_list(term())),non_empty_list(term(),opt_negation(empty_list())))to_quoted_string(reconstructed)# => "non_empty_list(term(), term())"equal?(original,reconstructed)# => falsesubtype?(original,reconstructed)# => truesubtype?(reconstructed,original)# => falseproper_list=non_empty_list(integer())subtype?(proper_list,original)# => falsesubtype?(proper_list,reconstructed)# => true
Expected behavior
Printed form should reconstruct the same type. Widening in the constructor is intentional and documented. Printer only documents "print the last type as term() if it only misses non empty lists." which suggests the current behavior is an unsafe optimization
Activity