Using closure in function scope to make "real" private class members

H. S. Teoh hsteoh at qfbox.info
Wed Jun 1 01:54:52 UTC 2022


So today, I thought I wanted to explore how far I can push the idea of
using closures over local variables in function scope to simulate
class-private field, i.e.:

--------
auto makeObj() {
	int realPrivateX;
	class C {
		int modulePrivateX;
		void func() {
			realPrivateX++;
		}
	}
	return new C;
}
void main() {
	auto obj = makeObj();
	obj.modulePrivateX++; // OK
	obj.realPrivateX++; // NG
}
--------

So far so good.  Next, I wondered if this could actually be extended to
handle an inheritance hierarchy too.  Here was my attempt:

------
interface I {
	void intfunc(int x);
}

auto makeBaseObj() {
	int realPrivateX;
	class Base : I {
		private int modulePrivateX;
		int publicX;
		override void intfunc(int x) {
			realPrivateX++; // expected OK
		}
	}
	return new Base;
}

auto makeDerivedObj() {
	int realPrivateY;
	class Derived : typeof(makeBaseObj()) {
		private int modulePrivateY;
		int publicY;
		override void intfunc(int x) {
			realPrivateX++; // expected NG
			modulePrivateX++;
		}
	}
	return new Derived;
}
------


When I tried to compile this, however, the compiler said:

------
/tmp/test.d(20): Error: class `test.makeDerivedObj.Derived` is nested within `makeDerivedObj`, but super class `Base` is nested within `makeBaseObj`
---
ERROR: This is a compiler bug.
Please report it via https://issues.dlang.org/enter_bug.cgi
with, preferably, a reduced, reproducible example and the information below.
DustMite (https://github.com/CyberShadow/DustMite/wiki) can help with the reduction.
---
DMD v2.098.1-1176-g005d97cb4
predefs   DigitalMars LittleEndian D_Version2 all D_SIMD Posix ELFv1 linux CRuntime_Glibc CppRuntime_Gcc D_InlineAsm_X86_64 X86_64 D_LP64 D_PIC assert D_PreConditions D_PostConditions D_Invariants D_ModuleInfo D_Exceptions D_TypeInfo D_HardFloat
binary    dmd
version   v2.098.1-1176-g005d97cb4
config    /usr/src/d/bin/dmd.conf
DFLAGS    -I/usr/src/d/druntime/import -I/usr/src/d/druntime/src -I/usr/src/d/phobos -L-L/usr/src/d/phobos/generated/linux/release/32 -L-L/usr/src/d/phobos/generated/linux/release/64 -L--no-warn-search-mismatch -L--export-dynamic -fPIC
---
core.exception.AssertError at src/dmd/aggregate.d(678): Assertion failure
----------------
??:? _d_assertp [0x55672da66de1]
??:? void dmd.aggregate.AggregateDeclaration.makeNested() [0x55672d752f64]
??:? _ZN22DsymbolSemanticVisitor23funcDeclarationSemanticEP15FuncDeclaration [0x55672d7e2c80]
??:? _ZN22DsymbolSemanticVisitor5visitEP15FuncDeclaration [0x55672d7e5d78]
??:? _ZN15FuncDeclaration6acceptEP7Visitor [0x55672d857f61]
??:? _Z15dsymbolSemanticP7DsymbolP5Scope [0x55672d7d9b09]
??:? void dmd.dsymbolsem.DsymbolSemanticVisitor.visit(dmd.dclass.ClassDeclaration).__lambda9!(dmd.dsymbol.Dsymbol).__lambda9(dmd.dsymbol.Dsymbol) [0x55672d7ea933]
??:? void dmd.dsymbol.foreachDsymbol(dmd.root.array.Array!(dmd.dsymbol.Dsymbol).Array*, void delegate(dmd.dsymbol.Dsymbol)) [0x55672d7d3293]
??:? _ZN22DsymbolSemanticVisitor5visitEP16ClassDeclaration [0x55672d7e9e04]
??:? _ZN16ClassDeclaration6acceptEP7Visitor [0x55672d794b85]
??:? _Z15dsymbolSemanticP7DsymbolP5Scope [0x55672d7d9b09]
??:? _ZN25ExpressionSemanticVisitor5visitEP14DeclarationExp [0x55672d837165]
??:? _ZN14DeclarationExp6acceptEP7Visitor [0x55672d81ca21]
??:? _Z18expressionSemanticP10ExpressionP5Scope [0x55672d84d50f]
??:? _ZN24StatementSemanticVisitor5visitEP12ExpStatement [0x55672d8ce49f]
??:? _ZN12ExpStatement6acceptEP7Visitor [0x55672d8caad5]
??:? _Z17statementSemanticP9StatementP5Scope [0x55672d8ce383]
??:? _ZN24StatementSemanticVisitor5visitEP17CompoundStatement [0x55672d8ce766]
??:? _ZN17CompoundStatement6acceptEP7Visitor [0x55672d8cafd1]
??:? _Z17statementSemanticP9StatementP5Scope [0x55672d8ce383]
??:? _ZN16Semantic3Visitor5visitEP15FuncDeclaration [0x55672d8c5206]
??:? _ZN15FuncDeclaration6acceptEP7Visitor [0x55672d857f61]
??:? _Z9semantic3P7DsymbolP5Scope [0x55672d8c3c4d]
??:? _ZN16Semantic3Visitor5visitEP6Module [0x55672d8c404e]
??:? _ZN6Module6acceptEP7Visitor [0x55672d7bb6d9]
??:? _Z9semantic3P7DsymbolP5Scope [0x55672d8c3c4d]
??:? int dmd.mars.tryMain(ulong, const(char)**, ref dmd.globals.Param) [0x55672d7441f8]
??:? _Dmain [0x55672d745e35]
------

Oops. :-D


T

-- 
If it's green, it's biology, If it stinks, it's chemistry, If it has numbers it's math, If it doesn't work, it's technology.


More information about the Digitalmars-d mailing list