&&&&&&&&&&&&&&str
102 points by ohrv
102 points by ohrv
In a similar vein, a friend of mine once tried to determine the deepest pointer type that gcc could compile. That is, he wrote a script that used binary search to find the longest int**...* type that could be compiled. I don't remember exactly but I think it was between 1000 and 2000 stars.
He then proceeded to use the group's cluster to compile an even larger and deeper pointer type. I don't remember how deep he got but it definitely helped. Fun times.
The actual limit here is 12—it looks like 13 because the .to_string() method takes &self, consuming one ampersand. (And the SpecToString implementation likewise takes &self, adding it back, if you like.)
Tuples get various trait implementations for up to 12 elements:
In this documentation the shorthand
(T₁, T₂, …, Tₙ)is used to represent tuples of varying length. When that is used, any trait bound expressed onTapplies to each element of the tuple independently. Note that this is a convenience notation to avoid repetitive documentation, not valid Rust syntax.Due to a temporary restriction in Rust’s type system, the following traits are only implemented on tuples of arity 12 or less. In the future, this may change:
Trait implementations on arrays used to be manual too, from [T; 0] to [T; 32], but const generics allowed that to be expanded to [T; N]… except for Default:
The Default impls cannot be done with const generics because
[T; 0]doesn't require Default to be implemented, and having different impl blocks for different numbers isn't supported yet.Trying to improve the
[T; 0]situation has proven to be difficult. Please see these issues for more context on past attempts and crater runs:
Various libraries have similar limitations. Axum’s Handler, for example, for example, works with tuples of up to 16 elements, and functions with up to 16 arguments. Variadic generics is a commonly desired feature, but there are issues to be worked through.
Reminds me of how in Haskell you're limited to 62-tuples!
Aha! Many years ago I stumbled into the source to GHC.Tuple and found that 63-tuples and above were commented out with this note and no further explanation:
{- Manuel says: Including one more declaration gives a segmentation fault.
Thanks for the pointer to the explanation I was missing 14 years ago!
Tangentially reminds me of the debate leading to Array#forty_two. (Which should be Array#forty_second…kinda spoils the joke really.)
"13 references ought to be enough for anybody".
Logically that's true. They turned it up to 11 and went two steps further.
Relatedly the C standard says a compiler must support at least “12 pointer, array, and function declarators (in any combinations) modifying an arithmetic, structure, union, or void type in a declaration”
Reminds me of all the stuff in Haskell around tuples, where for some stuff it really is just "well we copied these typeclass instances for up to 64-uples...." ... I remember feeling quite incensed at the "unprincipled" nature of it all, but I'm sure it has lead to way less compiler churning.
The consistent alternative is adding support for variadic templates - I guess you could special case tuples but that seems silly - but you have to work out a consistent syntax to make that possible - bother the definition and access of such types. C++ has packs and fold expressions, which are somewhat weird but work, swift has a syntax that I cannot for the life of me recall. I don’t know if rust does? I last used rust many years ago so even if it did have support then (if it does have support now) I wasn’t doing anything so novel as to require them as so wouldn’t know if they existed.