Steps to reproduce
- Access
RenderObject.debugNeedsPaint (or debugNeedsLayout, debugNeedsCompositedLayerUpdate) in app code — e.g. to guard a RenderRepaintBoundary.toImage() call
- Build in release mode
- The getter throws
LateInitializationError: Local 'result' has not been initialized
Expected behavior
These properties should return false in release mode, like debugNeedsSemanticsUpdate already does:
// debugNeedsSemanticsUpdate — correct, works in release:
bool get debugNeedsSemanticsUpdate {
if (kReleaseMode) {
return false;
}
return _semantics.parentDataDirty;
}
// debugNeedsPaint — crashes in release:
bool get debugNeedsPaint {
late bool result;
assert(() {
result = _needsPaint;
return true;
}());
return result; // LateInitializationError in release!
}
Proposal
Apply the same kReleaseMode guard to debugNeedsPaint, debugNeedsLayout, and debugNeedsCompositedLayerUpdate:
bool get debugNeedsPaint {
if (kReleaseMode) {
return false;
}
return _needsPaint;
}
Alternatively, annotate them with @visibleForTesting so the analyzer warns when they're used outside of tests.
Context
debugNeedsPaint, debugNeedsLayout, and debugNeedsCompositedLayerUpdate all use the late bool result + assert() pattern, while debugNeedsSemanticsUpdate in the same class uses a kReleaseMode guard. The inconsistency is the issue — a developer seeing one debug* property work safely might reasonably expect the others to behave the same way.
Flutter version
Flutter 3.41.2 • channel stable
Framework • revision 90673a4eef
Engine • hash d96704abcce17ff165bbef9d77123407ef961017
Steps to reproduce
RenderObject.debugNeedsPaint(ordebugNeedsLayout,debugNeedsCompositedLayerUpdate) in app code — e.g. to guard aRenderRepaintBoundary.toImage()callLateInitializationError: Local 'result' has not been initializedExpected behavior
These properties should return
falsein release mode, likedebugNeedsSemanticsUpdatealready does:Proposal
Apply the same
kReleaseModeguard todebugNeedsPaint,debugNeedsLayout, anddebugNeedsCompositedLayerUpdate:Alternatively, annotate them with
@visibleForTestingso the analyzer warns when they're used outside of tests.Context
debugNeedsPaint,debugNeedsLayout, anddebugNeedsCompositedLayerUpdateall use thelate bool result+assert()pattern, whiledebugNeedsSemanticsUpdatein the same class uses akReleaseModeguard. The inconsistency is the issue — a developer seeing onedebug*property work safely might reasonably expect the others to behave the same way.Flutter version