From 9fe108d3775072ec02c41b4abae31042bb12362b Mon Sep 17 00:00:00 2001 From: ASDAlexander77 Date: Sun, 12 Jul 2026 13:50:20 +0100 Subject: [PATCH] Remove gratuitous const_cast casts; legalize stop() (A6 phases 0-1) - stop() is now const with mutable stopProcess - it is an out-of-band cancellation signal; the two casting call sites and the internal rootContext cast disappear - Nine casts were not mutations at all: non-const method calls on the copyable funcOp op handle (getSymName/getCallableResults/ getCallableRegion/setPersonalityAttr) now copy the handle; the inferTypes pointer deref never needed a cast (pointee is not const); getConditionalType cast a local non-const context - Review doc A6 updated with phase 0/1 status and the remaining census (all genuine mutations, for phases 2-4) Co-Authored-By: Claude Fable 5 --- docs/MLIRGen-refactoring-review.md | 2 ++ .../TypeScript/MLIRLogic/MLIRGenContext.h | 7 +++-- tslang/lib/TypeScript/MLIRGen.cpp | 29 ++++++++++--------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/docs/MLIRGen-refactoring-review.md b/docs/MLIRGen-refactoring-review.md index 80a6998f..6b6012a3 100644 --- a/docs/MLIRGen-refactoring-review.md +++ b/docs/MLIRGen-refactoring-review.md @@ -193,3 +193,5 @@ Proposed phases, each independently shippable: 4. **Parameterize `MLIRCodeLogic.h`.** The two casts there poke values into the context that could be plain function parameters. Order: 1 (trivial) → 3 (bounded signature ripple) → 2 (site-by-site, one PR per field group) → 4. + +*Status update:* phase 1 is done, plus a discovered **phase 0**: nine of the 31 casts were gratuitous — non-const method calls on the copyable `funcOp` op handle (`getSymName`/`getCallableResults`/`getCallableRegion`/`setPersonalityAttr`), a deref of the `inferTypes` pointer member (pointee was never const), and a cast on a local non-const context in `getConditionalType`. Remaining casts are all genuine mutations for phases 2–4: `thisType` ×2, `typeAliasMap` ×2, loop flags ×3 sites, `generatedStatements` ×4, `typeParamsWithArgs` ×3 (`zipTypeParameterWithArgument` at ~16587, `processConditionalForType`, mapped-type erase), plus `MLIRCodeLogic.h`. diff --git a/tslang/include/TypeScript/MLIRLogic/MLIRGenContext.h b/tslang/include/TypeScript/MLIRLogic/MLIRGenContext.h index 2d8b88c0..b7bac412 100644 --- a/tslang/include/TypeScript/MLIRLogic/MLIRGenContext.h +++ b/tslang/include/TypeScript/MLIRLogic/MLIRGenContext.h @@ -124,11 +124,11 @@ struct GenContext } } - void stop() + void stop() const { if (stopProcess) return; stopProcess = true; - if (rootContext) const_cast(rootContext)->stop(); + if (rootContext) rootContext->stop(); } bool isStopped() const @@ -169,7 +169,8 @@ struct GenContext const GenContext* rootContext = nullptr; bool isLoop = false; std::string loopLabel; - bool stopProcess = false; + // out-of-band cancellation signal; mutable so stop() stays callable through the const& threading + mutable bool stopProcess = false; mlir::SmallVector> *postponedMessages = nullptr; bool specialization = false; // TODO: special hack to detect initializing specialized class and see that generic methods are not initialized at the same time diff --git a/tslang/lib/TypeScript/MLIRGen.cpp b/tslang/lib/TypeScript/MLIRGen.cpp index 9545a7a4..470ee213 100644 --- a/tslang/lib/TypeScript/MLIRGen.cpp +++ b/tslang/lib/TypeScript/MLIRGen.cpp @@ -5227,8 +5227,8 @@ class MLIRGenImpl } else if (genContext.funcOp) { - auto funcName = const_cast(genContext).funcOp.getSymName().str(); - objectOwnerName = funcName; + mlir_ts::FuncOp funcOp = genContext.funcOp; + objectOwnerName = funcOp.getSymName().str(); } if (signatureDeclarationBaseAST == SyntaxKind::MethodDeclaration) @@ -6320,7 +6320,8 @@ class MLIRGenImpl mlir::LogicalResult mlirGenFunctionExit(mlir::Location location, const GenContext &genContext) { - auto callableResult = const_cast(genContext).funcOp.getCallableResults(); + mlir_ts::FuncOp contextFuncOp = genContext.funcOp; + auto callableResult = contextFuncOp.getCallableResults(); auto retType = callableResult.size() > 0 ? callableResult.front() : mlir::Type(); auto hasReturn = retType && !isa(retType); if (hasReturn) @@ -7185,7 +7186,7 @@ class MLIRGenImpl mlir::Type getExplicitReturnTypeOfCurrentFunction(const GenContext &genContext) { - auto funcOp = const_cast(genContext).funcOp; + mlir_ts::FuncOp funcOp = genContext.funcOp; if (funcOp) { auto countResults = funcOp.getCallableResults().size(); @@ -8829,7 +8830,10 @@ class MLIRGenImpl } if (genContext.funcOp) - const_cast(genContext).funcOp.setPersonalityAttr(builder.getBoolAttr(true)); + { + mlir_ts::FuncOp funcOp = genContext.funcOp; + funcOp.setPersonalityAttr(builder.getBoolAttr(true)); + } auto tryOp = builder.create(location); @@ -11214,7 +11218,7 @@ class MLIRGenImpl if (mlir::failed(result) && !accessFailed) { - const_cast(genContext).stop(); + genContext.stop(); return mlir::Value(); } @@ -11257,7 +11261,7 @@ class MLIRGenImpl if (mlir::failed(result) && !accessFailed) { - const_cast(genContext).stop(); + genContext.stop(); return mlir::Value(); } @@ -15781,8 +15785,8 @@ class MLIRGenImpl if (genContext.funcOp && genContext.funcOp != tempFuncOp && valueRegion && valueRegion->getParentOp() /* && valueRegion->getParentOp()->getParentOp()*/) { - // auto funcRegion = const_cast(genContext).funcOp.getCallableRegion(); - auto funcRegion = const_cast(genContext).funcOp.getCallableRegion(); + mlir_ts::FuncOp contextFuncOp = genContext.funcOp; + auto funcRegion = contextFuncOp.getCallableRegion(); isOuterVar = !funcRegion->isAncestor(valueRegion); // TODO: HACK @@ -15794,7 +15798,7 @@ class MLIRGenImpl LLVM_DEBUG(if (isOuterVar) dbgs() << "\n!! outer var: [" << value.second->getName() << "] \n\n\tvalue region: " << *valueRegion->getParentOp() - << " \n\n\tFuncOp: " << const_cast(genContext).funcOp << "";); + << " \n\n\tFuncOp: " << contextFuncOp << "";); } if (isOuterVar && genContext.passResult && !isGenericFunctionReference(value.first)) @@ -15807,7 +15811,6 @@ class MLIRGenImpl assert(!isa(value.second->getType())); // valueRegion->viewGraph(); - // const_cast(genContext).funcOpVarScope.getCallableRegion()->viewGraph(); // special case, to prevent capturing ".a" because of reference to outer VaribleOp, which is hack (review // solution for it) @@ -22509,7 +22512,7 @@ genContext); return mlir::Type(); } - auto &typeParamsWithArgs = *(const_cast(genContext).inferTypes); + auto &typeParamsWithArgs = *genContext.inferTypes; mth.appendInferTypeToContext(location, type, inferType, typeParamsWithArgs); return inferType; @@ -24004,7 +24007,7 @@ genContext); mlir::Type getConditionalType(ConditionalTypeNode conditionalTypeNode, const GenContext &genContext) { GenContext condTypeGenContext(genContext); - condTypeGenContext.inferTypes = &const_cast(condTypeGenContext).typeParamsWithArgs; + condTypeGenContext.inferTypes = &condTypeGenContext.typeParamsWithArgs; auto checkType = getType(conditionalTypeNode->checkType, condTypeGenContext); auto extendsType = getType(conditionalTypeNode->extendsType, condTypeGenContext);