Having too many Luau types that have cyclical references causes intellisense to break

I have a very complex project involving hundreds/thousands of different types floating around. It is common where I need a defined type to be able to reference itself. Example given:

export type common_schema<T> = {
	Get: (self: common_schema<T>) -> T,
	Set: (self: common_schema<T>, newValue: T) -> nil,
}

export type checked_schema<T> = common_schema<T> & {
	Unchecked: (self: checked_schema<T>) -> unchecked_schema<T>,
}

export type unchecked_schema<T> = common_schema<T?> & {
	Checked: (self: unchecked_schema<T>) -> checked_schema<T>,
}

This is used for an AI framework for the blackboard, where types can be “checked” or “unchecked”. I have multiple scenarios where this occurs in my project, and is primarily used to define Objects which require a self reference (basic object oriented design).

Normally, this type definition behaves perfectly normal and intellisense works fine.

The issue occurs when I have a namespace in a project that requires many different types like this. All of the sudden, out of nowhere, intellisense will just break. I can solve this by commenting ANY self referencing type definitions, even if it’s completely unrelated to the code in question. It seems like there is some kind of artificial limitation on the resolver for a certain depth where it will just give up and fail. Almost like a “stack overflow” situation…

Expected behavior

I expect to be able to have any number of cyclical referencing types, which more/less mean - Object Oriented typed. Object oriented types always have the first argument “self” as the reference to itself. This is essential.

Additionally, if there is such an error being caused it is not displayed to me (the user of studio) as to what the error is. The error is completely silent. No red underlines, nothing. This is bad UX.

A private message is associated with this bug report

3 Likes

Here is another example of a type which works fine by itself, but contributes to this “stack overflow” / artificial limit on self referencing types:

export type schema = {
	-- FIELDS
	typename: string,
	uid: string,
	id: string,
	requiredZoneID: string,
	health: number,
	maxHealth: number,
	isDeleted: boolean,
	pets: { [string]: PetTypes.equipped_pet_schema },
	petUIDs: { [string]: boolean },
	damageTable: { [Player]: number },

	-- METHODS
	IsMineable: (self: schema, player: Player) -> boolean,
	HasTypename: (self: schema, typename: string) -> boolean,
	Join: (self: schema, ePet: PetTypes.equipped_pet_schema) -> (),
	Unjoin: (self: schema, ePet: PetTypes.equipped_pet_schema) -> (),
	IsBeingMinedByPet: (self: schema, uid: string) -> boolean,
	Cleanup: (self: schema) -> (),
	Destroyed: (self: schema) -> (),
	TakeDamage: (self: schema, amount: number, player: Player, wasPet: boolean, wasCrit: boolean) -> (),
	TakeDamageFromPet: (self: schema, ePet: PetTypes.equipped_pet_schema, amount: number, wasCrit: boolean) -> (),
	TakeDamageFromPlayer: (self: schema, player: Player) -> (),
	StartDamageLoop: (self: schema) -> (),
	GetContributingPlayers: (self: schema) -> { [Player]: number },
	ToNetworkPacket: (self: schema) -> network_packet_schema,
	--[[@virtual]] CalculateDamageFromPet: (self: schema, ePet: PetTypes.equipped_pet_schema) -> (number, boolean),
	--[[@virtual]] CalculateDamageFromPlayer: (self: schema, player: Player) -> (number, boolean),
}

As you can see, this is just a very basic object oriented definition.

1 Like

It seems to also be related to anything that just has generic types AT ALL. Not just self referencing types. Anything with generic types, regardless of whether it has cycles will eventually cause intellisense and type checking to fail.

1 Like

Hello, we have diagnosed the issue which is indeed caused by an internal limit.
We are planning to increase the limit without a full Studio update as soon as possible.

This is strange, you should have seen an error like


It might be not very precise in this situation, but having it in the report would offer up more hints.

2 Likes

We have increased the relevant limit in the current version of Roblox Studio.
A restart of Roblox Studio is required.

This should fix most of the issues you are experiencing, but you might find that auto-complete information is still limited in specific large files (but not in all of them that just import a complex module).

We will have follow-up improvements next week to compress large types and a performance optimization for one of the issues we found the week after that.

Of course, let us know if the issue didn’t get resolved for you today.

This looks to allow more of our types to work now, but when I start uncommenting all of our code, it still occurs. It has improved, but it still has a limit that we are able to reach.

We have enabled a feature that reduces complexity of some of the types, for the largest type in your placefile it makes it almost two times smaller, effectively raising the limit higher.

The impact on performance in the placefile you provided is minimal and we have a 30% performance improvement ready next week to make type inference run even faster than it was before the limit increase.

If this doesn’t match your experience, you should share an example that still has issues (you can send a message privately).

It starts to look like you introduced some new type construct that exploded the complexity of the types.
Because it’s unusual to lose intellisense by jumping from under 10k type element to over 15k type elements with gradual complexity increase and not notice it for a long time.
Was it caused by introduction of generic common_schema/checked_schema/unchecked_schema that wasn’t used before?

Yes that was the main culprit. How do you recommend going about that to not “explode” the types?

Unfortunately, you might have to temporarily step away from the plan that you had in mind until the issue is fixed.
You should always report it (we are glad you did), but sometimes it will take a while for us to implement a solution for complex cases. We hope that the changes we already made will allow you to achieve your goals right now.

We will be taking an extra look at your previous example in the coming weeks.

1 Like