You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A getter returning a map's mutable element: wrongly @UnmodifiableView, and modifying the element does not reach the owner #100
Two findings from one fernflower shape, StructContext.instanceOf: it takes a class from its map through a getter and calls a lazily-loading method on it.
1. A getter handing out a mutable element is @UnmodifiableView
getClass (and list.get(0) the same way) got unmodifiableViewMethod = true. TypeModIndyAnalyzerImpl.unmodifiableValue falls back to the callee's own verdict, and Map.get's IMMUTABLE_METHOD is immutable-HC: its result is a type parameter, the map's hidden content. Here the concrete element type C is mutable, so the result is no view. The IDE shows the wrong annotation.
Fixed on ws/maddi-bug: when the callee's formal result is a type parameter, the concrete type decides (at least immutable-HC: a view; otherwise not). Gate NOVIEWOFTYPEPARAMETER. Test TestUnmodifiableView.element (red with the gate).
2. Modifying an element handed out by a getter does not reach the map's owner (open)
method
fixpoint
MODREACH
direct (classes.get(n), then modified)
modifying (deep)
modifying (deep)
viaGetter (getClass(n) into a local, then modified)
non-modifying
modifying (deep)
viaGetterChain (getClass(n).getPool())
non-modifying
non-modifying
The element is in this.classes' hidden content, so modifying it modifies this, deep-only, as direct shows. Through the getter the modification is lost: unsound. It is the element (∈) counterpart of #80 and #98, which handled a getter returning a field (≺). Not affected by fix 1.
How it was found
The rust-llvm oracle (maddi#167) on fernflower: StructContext::instance_of(&self) borrowed cl.get_pool() mutably through a shared borrow (E0596).
Both halves fixed on devel: 4477b1b (modifying an element a getter hands out modifies the owner, deep-only; /Users/bnaudts/git/jfocus-devops/scripts/boxlock nice -n 10 gate NOELEMENTOWNER; TestModificationOfElementFromGetter with this issue's getClass(n).getPool() shape, direct, via getter, via chain, via first(), and a read-only control; TestCallResultElementOfReceiver in the link module), and a5eed0e (a callee whose result is a type parameter is no view of a mutable element; /Users/bnaudts/git/jfocus-devops/scripts/boxlock nice -n 10 gate NOVIEWOFTYPEPARAMETER; TestUnmodifiableView.element). All pass on devel (2026-11-13).
Activity
UnmodifiableView: a callee whose result is a type parameter is no vie…
Modifying an element a getter hands out modifies the owner (#100)
TestShadowCloneBench: re-baselined after the 2026-11-11 gate (reverse…
bnaudts commentedon Nov 13, 2026
Both halves fixed on devel: 4477b1b (modifying an element a getter hands out modifies the owner, deep-only; /Users/bnaudts/git/jfocus-devops/scripts/boxlock nice -n 10 gate NOELEMENTOWNER; TestModificationOfElementFromGetter with this issue's getClass(n).getPool() shape, direct, via getter, via chain, via first(), and a read-only control; TestCallResultElementOfReceiver in the link module), and a5eed0e (a callee whose result is a type parameter is no view of a mutable element; /Users/bnaudts/git/jfocus-devops/scripts/boxlock nice -n 10 gate NOVIEWOFTYPEPARAMETER; TestUnmodifiableView.element). All pass on devel (2026-11-13).