On Tue, 21 Jul 2026, Martin Uecker via Gcc wrote: > > In each location where 'tree' is listed as a parameter or declared as a > > local, one would also list the expected tree codes or similar, just as > > they do today (except in the declaration instead of in an assert below a > > declaration, which seems to me like a strict improvement, as it moves > > relevant information from function bodies to function signatures, > > without relying on bit-rotting comments; where there isn't such a check, > > 'auto' suffices). > > An assertion also does not rely on comments. The thing is that > a function which works for three random tree codes is weird anyhow. > Types should carry some useful semantics, and then they help > readability when expressed explicitely. > > foo(tree< one_of<FUNCTION_DECL, PLUS_EXPR> > x) > > May be amazing technology, but just tells me the function should > not exist in this form. So it only helps writing bad code.
Indeed, I certainly hope we don't have code that takes a random combination like that. > foo(expression *e) > > on the other hand, is very readable and would tell me something > useful. Whereas I do think that for most code, it *is* statically defined that it can only take one of * expression / statement (these two are largely considered the same), or declaration (because tree nodes for declarations are used directly in expressions when a declared object / function is an operand); * declaration; * type; * identifier; * TREE_LIST; * (... others ...). With an understanding in each case that error_mark_node is also a possibility, and static typing means having separate versions of it for each static type. So I think we should aim for static typing in the cases where we expect that the code is already quite close to having exactly one static type for each place using "tree" (but still expect to need to clean up interfaces in cases that can use e.g. "declaration or type", and maybe in the first pass still have the same static type for both expressions and declarations even though that's not ideal, because of how declarations and expressions both get used as operands of expressions). Whether static typing for such thing as "this must be a POINTER_TYPE" would make the code cleaner on top of that is less clear to me. Note that TREE_LIST should not be one static type but many, for each separate thing TREE_LISTs are used for. And I think people have run into complications when trying and failing to make identifiers statically typed in the past (with tricky interactions with the garbage collector and preprocessor). C++ tools might well be used for an incremental conversion to e.g. "type" being statically different from "expression / statement / declaration", but it's important that it should be clear which places in the source tree still need to be reviewed / fixed to make those types statically different, and which have already been fixed, so there is a clear path to being done (no places where the choice between those types is dynamic and adding such a place would result in a build failure) and it's clear how far along that path we are and how to make progress on it. -- Joseph S. Myers [email protected]
