carbon-lang
carbon-lang copied to clipboard
Restructure decl and pattern blocks
Currently, every function declaration is associated with two blocks, the decl block and the pattern block. The pattern block contains the pattern insts that define the entity's parameter list. The decl block contains two things:
- The non-pattern insts that are part of the entity's parameter list (most notably, the insts that make up the type expressions of binding patterns).
- The insts that implement callee-side pattern matching on the parameter list.
This structure is non-ideal for several reasons:
- There are logical if not physical dependencies between the two blocks in both directions: binding pattern insts depend on the decl block for their types, and the pattern insts are a key input for generating the pattern matching insts.
- Logically, callee-side pattern matching belongs with the function body, because it's not relevant to the function's callers; its job is to take the raw
paraminsts that correspond to the arguments of thecallinst, and package them in the form that the language-level function body expects (e.g. by binding names to them). This is particularly awkward in the textual SemIR, where the function definition is presented as a signature that declares theparaminsts, followed by the function body, but the pattern-match IR that connects the two is in an entirely separate section. - I understand that thunking (e.g. for virtual functions) would be easier if there were a single decl block, although I'm not clear on the specifics.
- The toolchain implementation is substantially complicated by the need to emit insts in two different blocks simultaneously, depending on the inst kind.
The current structure emerged from the decision to keep pattern insts in separate blocks from non-pattern insts. This was largely intended to make it easier to break cycles caused by "forward references" from pattern insts to the corresponding pattern-match insts, but those forward references have now been removed. As a result, I think it would be feasible to address those problems by having a function decl to consist of a single block, containing all the insts necessary to fully represent the pattern (including non-pattern insts for things like type expressions), but none of the pattern-matching insts.