RFC-0088: Updates to RFC-0050: FIDL Bits, Enum, and Constraints Syntax

RFC-0088: Updates to RFC-0050: FIDL Bits, Enum, and Constraints Syntax
StatusRejected
Areas
  • FIDL
Description

Specify two incremental improvements to the new FIDL syntax defined by FTP-050.

Issues
Gerrit change
Authors
Reviewers
Date submitted (year-month-day)2021-02-18
Date reviewed (year-month-day)2021-04-07

Rejection rationale

This proposal was rejected due to neither of the proposed changes being a clear and obvious improvement over the existing state of affairs.

See also:

New separator for bits and enum layouts

This RFC was originally motivated by the observation that RFC-0050: Syntax Revamp states that colons are meant to separate layouts and constraints, but that their use for demarcating wrapped types in bits and enum declarations breaks this rule. Ultimately, this inconsistency was deemed to be insufficiently ambiguous to justify inventing a new syntax solely to remove the colon for just those two use cases.

None of the proposed alternatives was immediately better than the colon. Some options that were considered:

  • Simply removing the colon was judged to be confusing - the second type modifies, or "templates," the bits or enum declaration. There should be syntax indicating that this is the case.
  • Placing the wrapped type in brackets, like bits<uint32> {..., was also rejected, as it was not consistent with the other use of angled brackets in the FIDL language. Angled brackets as they stand today are meant to contain layout parameters, as in the cases of the builtin vector layout being parameterized by vector<TYPE> and the builtin array layout being parameterized by array<TYPE, SIZE>. But putting wrapped types in brackets would be more akin to a template that produces a layout definition, like the (currently unsupported) struct<K,V>{...}. Mixing the meaning of angled brackets in this manner was judged to be too subtle and confusing.
  • Finally, simply replacing the colon with a new keyword of was considered. This too was deemed unsatisfactory, as introducing the cognitive overhead of a new keyword for FIDL authors to learn in order to accommodate two very minor edge cases is a bad trade. Additionally, this deviates from the syntax style used to date, which leans toward more of a C-like flavor, as opposed to an ALGOL influenced one.

In the end, it's likely that most users will figure out fairly quickly that these two cases are a special exception to the layout : constraints rule described in RFC-0050: Syntax Revamp.

Wrapping constraint lists in square brackets

There were two reasons for rejecting this change:

  • The language sets an expectation that parameters appear inside of angled brackets, regardless of what kind of parameter (layout or constraint) they happen to be. Using square brackets would have broken this expectation.
  • With RFC-0086: Updates to FTP-050: FIDL Attributes Syntax, square brackets are no longer used in FIDL syntax. It would have been wasteful to "burn" this bracket type (one of only four available to us: rounded, curly, angled, and square) to describe a syntax that is already sufficiently clear with angled brackets. This was simply a very small change whose existing state is unlikely to cause much confusion in practice.

This was simply a very small change whose existing state is unlikely to cause much confusion in practice.

Summary

This document proposes two minor updates to the syntax described in RFC-0050: Syntax Revamp. Specifically:

  • Wrapped type definitions for bits and enum layouts no longer require a colon to separate the layout specifier and the wrapped type. Instead, the newly introduced of keyword is used as the separator.
  • Constraint lists are now wrapped in square, instead of angled, brackets.

Motivation

Implementation of the new syntax defined by RFC-0050 is ongoing, which presents a good opportunity to make final updates to that standard. It is preferable to do large syntax migrations as a single "one fell swoop" effort, rather than sprinkling the changes across many projects (RFC-0038: Separating Layout from Constraints and RFC-0039: Types Come Second were rejected on that basis, which led to a larger overhaul culminating in RFC-0050 for exactly this reason). It is thus desirable to roll any final syntax tweaks into the broader RFC-0050 migration effort.

New separator for bits and enum layouts

RFC-0050 mandates the form layout:constraints; that is, that FIDL file readers should expect that everything to the left of the colon in a type declaration affects how bytes are organized on the wire, while everything to the right is a runtime-enforced constraint on the values that type may contain. Currently, we have one exception to this convention: bits/enums declarations, which do place layout affecting information to the right of the colon. This creates inconsistency in the FIDL syntax's underlying logic.

Wrapping constraint lists in square brackets

In the case of the second change, consider the following type declaration:

vector<vector<zx.handle:<VMO,zx.READ,optional>>>

This is currently difficult to parse visually. Generic type specifications and constraint lists are fundamentally different in a number of ways (one affects layout, the other does not; one is a required fixed size list, the other is optional and of variable length, and so on), yet they are currently rendered using the same syntax. This overloads the <...> syntax, and is difficult to read for deeply nested definitions.

Design

This RFC specifies two changes to the FIDL syntax.

New separator for bits and enum layouts

Wrapped type definitions for bits and enum declarations no longer require preceding colons. Instead, the new of keyword is introduced as a separator, valid only when placed between a bits or enum keyword and its wrapped type. Thus, a declaration previously written as:

type Foo = bits : uint32 {...

is now written as:

type Foo = bits of uint32 {...

Wrapping constraint lists in square brackets

Constraints lists are now wrapped in square, instead of angled, brackets. Thus, a type declaration previously written as:

vector<vector<zx.handle:<VMO,zx.READ,optional>>>

is now written as

vector<vector<zx.handle:[VMO,zx.READ,optional]>>

Implementation

This proposal will be implemented as part of the broader RFC-0050 FIDL syntax conversion. All FIDL files written in the "new" syntax will be expected to conform to the changes laid out in this RFC, and the formal FIDL grammar will be updated to reflect its design at the same time as the rest of RFC-0050.

Performance

These syntax changes are unlikely to have a performance impact.

Security considerations

These syntax changes are unlikely to have a security impact.

Privacy considerations

These syntax changes are unlikely to have a privacy impact.

Testing

These syntax changes will be tested as part of the broader suite of tests covering RFC-0050.

Documentation

All relevant documentation and examples will be updated to feature the new syntax as part of the broader RFC-0050 documentation update.

Drawbacks, Alternatives, and Unknowns

New separator for bits and enum layouts

An alternative formulation of the new bits/enum syntax, where the wrapped type is encased in angled brackets, was considered: type E = enum<int32> {.... It was decided that this use of the parameterized type syntax wouldn't quite conform to its existing meaning for vector and array: enum<int32> is an actual int32 on the wire (ie, the wrapped type and the wire type are identical), whereas the inner type for vector<int32> describes the payload of some encompassing wire container (ie, the wrapped type is only a portion of the full wire type). Further, where vector<int32> a valid type constructor, neither bits nor bits<int32> are. Using the angled bracket syntax for this case would overload its meaning in a subtle but confusing way.

Wrapping constraint lists in square brackets

There are two alternatives to the proposed constraints syntax: leave the current angled brackets notation, or remove brackets altogether. Both of these are judged to be difficult for readers to parse visually: vector<vector<zx.handle:<VMO,zx.READ,optional>>> contains many nested angle brackets with different types of argument lists, while vector<vector<zx.handle:VMO,zx.READ,optional>> makes it difficult to spot where layouts stop and constraints begin.

Prior art and references

This RFC is an evolution of the syntax defined in RFC-0050: Syntax Revamp.