fi-0057: Includes cycle {:#fi-0057}

There are a number of situations that could cause this problem to occur, but all of them basically boil down to a FIDL declaration referring to itself in an unresolvable way. The simplest form of this error is when a type or protocol refers directly to itself in its own definition:

{% include “docs/reference/fidl/language/error-catalog/label/_bad.md” %}

{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="tools/fidl/fidlc/tests/fidl/bad/fi-0057-c.test.fidl" exclude_regexp="\/\/ (Copyright 20|Use of|found in).*" %}

More complex failure cases are possible when a type or protocol transitively refers to itself via at least one level of indirection:

{% include “docs/reference/fidl/language/error-catalog/label/_bad.md” %}

{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="tools/fidl/fidlc/tests/fidl/bad/fi-0057-a.test.fidl" exclude_regexp="\/\/ (Copyright 20|Use of|found in).*" %}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="tools/fidl/fidlc/tests/fidl/bad/fi-0057-b.test.fidl" exclude_regexp="\/\/ (Copyright 20|Use of|found in).*" %}

This error can be resolved by adding an envelope (aka, optionality) somewhere in the inclusion cycle, as this allows the cycle to be “broken” at encode/decode time:

{% include “docs/reference/fidl/language/error-catalog/label/_good.md” %}

{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="tools/fidl/fidlc/tests/fidl/good/fi-0057.test.fidl" exclude_regexp="\/\/ (Copyright 20|Use of|found in).*" %}

Caution: This feature is not yet implemented for all viable cases; for instance, the following code will currently fail, despite including the requisite envelope between the recursive reference and its definition. This is because recursive types have not yet fully implemented: https://fxbug.dev/42110612.

{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="tools/fidl/fidlc/tests/fidl/bad/fi-0057-d.test.fidl" exclude_regexp="\/\/ (Copyright 20|Use of|found in).*" %}

Recursive types that are unbroken by envelopes are disallowed because they would be impossible to encode. In the first example above, encoding MySelf would require first encoding an instance of MySelf, which would in turn require encoding an instance of MySelf, ad inifitum. A solution to this problem is to add a “break” in this chain via optionality, where one may choose to either encode another nested instance of MySelf, or otherwise encode a null envelope with no further data.