Appearance
| 1 | namespace Syntax.Process is | |
| 2 | use Logging; | |
| 3 | use Trees; | |
| 4 | use Source; | |
| 5 | ||
| 6 | // Enforces the pure-override contract after infer-store-free has | |
| 7 | // settled the store-free bits: a function that overrides or | |
| 8 | // implements a declared-pure base must itself be pure — declared | |
| 9 | // or proven. The declared bit on the base is what call sites | |
| 10 | // trust across dispatch, including dispatch to overrides this | |
| 11 | // compilation is introducing, so an unprovable, undeclared | |
| 12 | // override is a hole in that trust and is rejected. Bases can be | |
| 13 | // local or imported: a PURE_ATTRIBUTE read on import marks the | |
| 14 | // reflected base declared-pure, so overriding a pure member from | |
| 15 | // another assembly is checked here in the overriding assembly. | |
| 16 | class CHECK_PURE_OVERRIDES: ScopedVisitor is | |
| 17 | _logger: Logger; | |
| 18 | ||
| 19 | init( | |
| 20 | logger: Logger, | |
| 21 | symbol_table: Semantic.SYMBOL_TABLE, | |
| 22 | namespaces: Semantic.NAMESPACES | |
| 23 | ) | |
| 24 | is | |
| 25 | super.init(logger, symbol_table, namespaces); | |
| 26 | ||
| 27 | _logger = logger; | |
| 28 | si | |
| 29 | ||
| 30 | apply(root: Trees.Node) is | |
| 31 | root.walk(self); | |
| 32 | si | |
| 33 | ||
| 34 | visit(function: Definitions.FUNCTION) is | |
| 35 | super.visit(function); | |
| 36 | ||
| 37 | let symbol = symbol_for(function); | |
| 38 | ||
| 39 | if !symbol? \/ !isa Semantic.Symbols.Function(symbol) then | |
| 40 | return; | |
| 41 | fi | |
| 42 | ||
| 43 | let function_symbol = cast Semantic.Symbols.Function(symbol); | |
| 44 | ||
| 45 | let overridees = function_symbol.overridees; | |
| 46 | ||
| 47 | if !overridees? \/ function_symbol.is_store_free then | |
| 48 | return; | |
| 49 | fi | |
| 50 | ||
| 51 | for base in overridees do | |
| 52 | if isa Semantic.Symbols.Function(base) /\ (cast Semantic.Symbols.Function(base)).is_declared_pure then | |
| 53 | _logger.error( | |
| 54 | function.name!.location, | |
| 55 | "{function_symbol.name} overrides pure {base.qualified_name} so must be declared pure or provably store-free" | |
| 56 | ); | |
| 57 | ||
| 58 | return; | |
| 59 | fi | |
| 60 | od | |
| 61 | si | |
| 62 | si | |
| 63 | si |