A context is passed basically everywhere in dotc. This is convenient but carries the risk of captured contexts in objects that turn into space leaks. To combat this risk, here are some conventions to follow:
- Never let an implicit context be an argument of a class whose instances live longer than the context.
- Classes that need contexts for their initialization take an explicit parameter
initctx. They pass initctx to all positions where it is needed (and these positions should all be part of the intialization sequence of the class).
- Classes that need contexts that survive initialization are instead passed
a "condensed context", typically named
cctx(or they create one). Condensed contexts just add some basic information to the context base without the risk of capturing complete trees.
- To make sure these rules are kept, it would be good to do a sanity check using bytecode inspection with javap or scalap: Keep track of all class fields of type context; allow them only in whitelisted classes (which should be short-lived).
A context base defines state and associated methods that exist once per compiler run.
The essential mutable state of a context base, collected into a common class
A fresh context allows selective modification of its attributes using the with... methods.
A class defining the initial context with given context base and set of possible settings.