mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
When a generic function declaration was encountered for the second or more time, we would FinishGenericRedecl() for the function decl, but this just popped the generic region stack and moved on. The issue with that is when the stack entry is gone, we lose the symbolic constants from that declaration, and are unable to rewrite them to point to the actual generic. This left us with a function declaration with abstract symbolic values that were not useful, and in a function call we use the declaration attached to the definition, which would be a declaration with broken symbolic values. Then the function would be uncallable since deduce would be unable to determine argument types without the generic bindings. This resolves the issue for functions, as well as ensuring the correct generic id from a previous declaration is used for other generic entity types that have redeclarations. When a function declaration is qualified, such as defining a class method outside the class body, we need only the function declaration to contribute to its generic region stack. The code was collecting constant values from all qualifier segments together incorrectly. So when we PushNameQualifierScope(), we also drop the current generic region stack and rewrite its constant values by calling FinishGenericRedecl(), and open a new stack entry for the next part of the qualified declaration. If a generic declaration somehow has more dependent instruction than a previous declaration, it would add new instructions to its eval block with indices beyond the elements in the actual declaration eval block, since we only store the block from the first declaration found. To avoid this we plumb through that we are in a redeclaration, and terminate with an ICE instead of adding new instructions to crash on later. Fixes #5136.