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
Member type of bare type variable bound to self-reference isResolvedRecursiveType (unlike T[] or List<T>) #133
When a member's type is a bare type variable bound to a self-reference, the resolved member type is a ResolvedRecursiveType (whose getParentClass() is null and getImplementedInterfaces() empty), whereas uses of the same variable within other types (T[], List<T>) resolve to fully resolved types.
Reproduction
publicstaticclassBase<X> { publicXvalue; publicX[] arr; }
publicstaticclassSym<TextendsSym<T>> extendsBase<T> { }
TypeResolverr = newTypeResolver();
ResolvedTypeWithMemberssym = newMemberResolver(r).resolve(r.resolve(Sym.class), null, null);
// field `value`: ResolvedRecursiveType `Sym<Object>`, getParentClass() == null// field `arr`: element type is ResolvedObjectType `Sym<Sym<Object>>`// -> value type not equal to `arr` element type
Same happens with raw self-references, like field X value of RB for RA<T extends RB> / RB extends Base<RA>.
On 1.7 / current main both value and arr element types are ResolvedRecursiveTypes (so they are at least consistent); with 1.8 (#128) incomplete types are re-resolved when obtained via TypeResolver.resolve(TypeBindings, Type) (as done by MemberResolver), except for bare self-references, which are left as-is.
Expected
Member type for value is a stand-alone (fully resolved) type, same as arr element type, so that member types can be navigated (parent class, interfaces) and compared consistently.
Notes
Likely fix: in TypeResolver.resolve(TypeBindings, Type) (_completeType()), replace a top-level self-reference with the type it represents (_selfReferenceTarget(), as resolveSubtype() already does). This changes member types that are currently ResolvedRecursiveTypes, so it is a behavioral change (although equality with fully resolved types is retained).
changed the title [-]Member type of bare type variable bound to self-reference is ResolvedRecursiveType (unlike T[] or List<T>)[/-][+]Member type of bare type variable bound to self-reference is`ResolvedRecursiveType` (unlike `T[]` or `List<T>`)[/+]on Oct 11, 2026
Activity
[-]Member type of bare type variable bound to self-reference is ResolvedRecursiveType (unlike T[] or List<T>)[/-][+]Member type of bare type variable bound to self-reference is`ResolvedRecursiveType` (unlike `T[]` or `List<T>`)[/+]Fix #133: Member type of bare type variable bound to self-reference i…