Here, we have two functions, case1 and case that invoke generic in different contexts. In one of those contexts, the Outermost.foo procedure is define on Outermost, and found via POI when resolving the body of generic. In the other context, there is no defined foo, and as a result, generic cannot be resolved. We obtain an error:
poitest.chpl:3: In function 'generic':
poitest.chpl:5: error: unresolved call 'Outermost.foo()'
poitest.chpl:5: note: because no functions named foo found in scope
poitest.chpl:5: note: unresolved call had id 2032505
poitest.chpl:14: called as generic(x: Outermost)
note: generic instantiations are underlined in the above callstack
This is good. However, let's now make use of reflection to see if foo is available in the scope of generic:
This compiles, and somehow tells us that foo is available in both scopes. Surely that can't be right, since we just got an error about foo not being available!
This is because generic caches are only updated when we "normally resolve a call", and not when we "see if a call is resolvable":
This is improper because (via "can resolve" queries and branching), even speculatively resolved calls can affect function behavior, as I have demonstrated here.