Skip to content

Incorrect diagnostics with large (~300 members) union #3178

Closed
@justarandomgeek

Description

@justarandomgeek

How are you using the lua-language-server?

Visual Studio Code Extension (sumneko.lua)

Which OS are you using?

Windows

What is the issue affecting?

Diagnostics/Syntax Checking

Expected Behaviour

In the Factorio API, we have a function used for registering all our data that takes a very wide union type (which gets generated from the api docs):

---@alias data.AnyPrototype (data.AccumulatorPrototype)|(data.AchievementPrototype)|(data.ActiveDefenseEquipmentPrototype)|(data.AgriculturalTowerPrototype)|(data.AirbornePollutantPrototype)|(data.AmbientSound)|(data.AmmoCategory)|(data.AmmoItemPrototype)|(data.AmmoTurretPrototype)|(data.AnimationPrototype)|(data.ArithmeticCombinatorPrototype)|(data.ArmorPrototype)|(data.ArrowPrototype)|(data.ArtilleryFlarePrototype)|(data.ArtilleryProjectilePrototype)|(data.ArtilleryTurretPrototype)|(data.ArtilleryWagonPrototype)|(data.AssemblingMachinePrototype)|(data.AsteroidChunkPrototype)|(data.AsteroidCollectorPrototype)|(data.AsteroidPrototype)|(data.AutoplaceControl)|(data.BatteryEquipmentPrototype)|(data.BeaconPrototype)|(data.BeamPrototype)|(data.BeltImmunityEquipmentPrototype)|(data.BlueprintBookPrototype)|(data.BlueprintItemPrototype)|(data.BoilerPrototype)|(data.BuildEntityAchievementPrototype)|(data.BurnerGeneratorPrototype)|(data.BurnerUsagePrototype)|(data.CapsulePrototype)|(data.CaptureRobotPrototype)|(data.CarPrototype)|(data.CargoBayPrototype)|(data.CargoLandingPadPrototype)|(data.CargoPodPrototype)|(data.CargoWagonPrototype)|(data.ChainActiveTriggerPrototype)|(data.ChangedSurfaceAchievementPrototype)|(data.CharacterCorpsePrototype)|(data.CharacterPrototype)|(data.CliffPrototype)|(data.CollisionLayerPrototype)|(data.CombatRobotCountAchievementPrototype)|(data.CombatRobotPrototype)|(data.CompleteObjectiveAchievementPrototype)|(data.ConstantCombinatorPrototype)|(data.ConstructWithRobotsAchievementPrototype)|(data.ConstructionRobotPrototype)|(data.ContainerPrototype)|(data.CopyPasteToolPrototype)|(data.CorpsePrototype)|(data.CreatePlatformAchievementPrototype)|(data.CurvedRailAPrototype)|(data.CurvedRailBPrototype)|(data.CustomEventPrototype)|(data.CustomInputPrototype)|(data.DamageType)|(data.DeciderCombinatorPrototype)|(data.DeconstructWithRobotsAchievementPrototype)|(data.DeconstructibleTileProxyPrototype)|(data.DeconstructionItemPrototype)|(data.DecorativePrototype)|(data.DelayedActiveTriggerPrototype)|(data.DeliverByRobotsAchievementPrototype)|(data.DeliverCategory)|(data.DeliverImpactCombination)|(data.DepleteResourceAchievementPrototype)|(data.DestroyCliffAchievementPrototype)|(data.DisplayPanelPrototype)|(data.DontBuildEntityAchievementPrototype)|(data.DontCraftManuallyAchievementPrototype)|(data.DontKillManuallyAchievementPrototype)|(data.DontResearchBeforeResearchingAchievementPrototype)|(data.DontUseEntityInEnergyProductionAchievementPrototype)|(data.EditorControllerPrototype)|(data.ElectricEnergyInterfacePrototype)|(data.ElectricPolePrototype)|(data.ElectricTurretPrototype)|(data.ElevatedCurvedRailAPrototype)|(data.ElevatedCurvedRailBPrototype)|(data.ElevatedHalfDiagonalRailPrototype)|(data.ElevatedStraightRailPrototype)|(data.EnemySpawnerPrototype)|(data.EnergyShieldEquipmentPrototype)|(data.EntityGhostPrototype)|(data.EquipArmorAchievementPrototype)|(data.EquipmentCategory)|(data.EquipmentGhostPrototype)|(data.EquipmentGridPrototype)|(data.ExplosionPrototype)|(data.FireFlamePrototype)|(data.FishPrototype)|(data.FluidPrototype)|(data.FluidStreamPrototype)|(data.FluidTurretPrototype)|(data.FluidWagonPrototype)|(data.FontPrototype)|(data.FuelCategory)|(data.FurnacePrototype)|(data.FusionGeneratorPrototype)|(data.FusionReactorPrototype)|(data.GatePrototype)|(data.GeneratorEquipmentPrototype)|(data.GeneratorPrototype)|(data.GodControllerPrototype)|(data.GroupAttackAchievementPrototype)|(data.GunPrototype)|(data.HalfDiagonalRailPrototype)|(data.HeatInterfacePrototype)|(data.HeatPipePrototype)|(data.HighlightBoxEntityPrototype)|(data.ImpactCategory)|(data.InfinityCargoWagonPrototype)|(data.InfinityContainerPrototype)|(data.InfinityPipePrototype)|(data.InserterPrototype)|(data.InventoryBonusEquipmentPrototype)|(data.ItemEntityPrototype)|(data.ItemGroup)|(data.ItemPrototype)|(data.ItemRequestProxyPrototype)|(data.ItemSubGroup)|(data.ItemWithEntityDataPrototype)|(data.ItemWithInventoryPrototype)|(data.ItemWithLabelPrototype)|(data.ItemWithTagsPrototype)|(data.KillAchievementPrototype)|(data.LabPrototype)|(data.LampPrototype)|(data.LandMinePrototype)|(data.LaneSplitterPrototype)|(data.LegacyCurvedRailPrototype)|(data.LegacyStraightRailPrototype)|(data.LightningAttractorPrototype)|(data.LightningPrototype)|(data.LinkedBeltPrototype)|(data.LinkedContainerPrototype)|(data.Loader1x1Prototype)|(data.Loader1x2Prototype)|(data.LocomotivePrototype)|(data.LogisticContainerPrototype)|(data.LogisticRobotPrototype)|(data.MapSettings)|(data.MarketPrototype)|(data.MiningDrillPrototype)|(data.ModuleCategory)|(data.ModulePrototype)|(data.ModuleTransferAchievementPrototype)|(data.MouseCursor)|(data.MovementBonusEquipmentPrototype)|(data.NamedNoiseExpression)|(data.NamedNoiseFunction)|(data.NightVisionEquipmentPrototype)|(data.OffshorePumpPrototype)|(data.ParticlePrototype)|(data.ParticleSourcePrototype)|(data.PipePrototype)|(data.PipeToGroundPrototype)|(data.PlaceEquipmentAchievementPrototype)|(data.PlanetPrototype)|(data.PlantPrototype)|(data.PlayerDamagedAchievementPrototype)|(data.PlayerPortPrototype)|(data.PowerSwitchPrototype)|(data.ProcessionLayerInheritanceGroup)|(data.ProcessionPrototype)|(data.ProduceAchievementPrototype)|(data.ProducePerHourAchievementPrototype)|(data.ProgrammableSpeakerPrototype)|(data.ProjectilePrototype)|(data.ProxyContainerPrototype)|(data.PumpPrototype)|(data.QualityPrototype)|(data.RadarPrototype)|(data.RailChainSignalPrototype)|(data.RailPlannerPrototype)|(data.RailRampPrototype)|(data.RailRemnantsPrototype)|(data.RailSignalPrototype)|(data.RailSupportPrototype)|(data.ReactorPrototype)|(data.RecipeCategory)|(data.RecipePrototype)|(data.RemoteControllerPrototype)|(data.RepairToolPrototype)|(data.ResearchAchievementPrototype)|(data.ResearchWithSciencePackAchievementPrototype)|(data.ResourceCategory)|(data.ResourceEntityPrototype)|(data.RoboportEquipmentPrototype)|(data.RoboportPrototype)|(data.RocketSiloPrototype)|(data.RocketSiloRocketPrototype)|(data.RocketSiloRocketShadowPrototype)|(data.SegmentPrototype)|(data.SegmentedUnitPrototype)|(data.SelectionToolPrototype)|(data.SelectorCombinatorPrototype)|(data.ShootAchievementPrototype)|(data.ShortcutPrototype)|(data.SimpleEntityPrototype)|(data.SimpleEntityWithForcePrototype)|(data.SimpleEntityWithOwnerPrototype)|(data.SmokeWithTriggerPrototype)|(data.SolarPanelEquipmentPrototype)|(data.SolarPanelPrototype)|(data.SoundPrototype)|(data.SpaceConnectionDistanceTraveledAchievementPrototype)|(data.SpaceConnectionPrototype)|(data.SpaceLocationPrototype)|(data.SpacePlatformHubPrototype)|(data.SpacePlatformStarterPackPrototype)|(data.SpectatorControllerPrototype)|(data.SpeechBubblePrototype)|(data.SpiderLegPrototype)|(data.SpiderUnitPrototype)|(data.SpiderVehiclePrototype)|(data.SpidertronRemotePrototype)|(data.SplitterPrototype)|(data.SpritePrototype)|(data.StickerPrototype)|(data.StorageTankPrototype)|(data.StraightRailPrototype)|(data.SurfacePropertyPrototype)|(data.SurfacePrototype)|(data.TechnologyPrototype)|(data.TemporaryContainerPrototype)|(data.ThrusterPrototype)|(data.TileEffectDefinition)|(data.TileGhostPrototype)|(data.TilePrototype)|(data.TipsAndTricksItem)|(data.TipsAndTricksItemCategory)|(data.ToolPrototype)|(data.TrainPathAchievementPrototype)|(data.TrainStopPrototype)|(data.TransportBeltPrototype)|(data.TreePrototype)|(data.TriggerTargetType)|(data.TrivialSmokePrototype)|(data.TurretPrototype)|(data.TutorialDefinition)|(data.UndergroundBeltPrototype)|(data.UnitPrototype)|(data.UpgradeItemPrototype)|(data.UseEntityInEnergyProductionAchievementPrototype)|(data.UseItemAchievementPrototype)|(data.UtilityConstants)|(data.UtilitySounds)|(data.UtilitySprites)|(data.VirtualSignalPrototype)|(data.WallPrototype)

---@param otherdata (data.AnyPrototype)[] 
function data.extend(otherdata) ... end;

This causes spurious diagnostics when calling it with values of a known type that is within that union, if it's too far down the list:

-- data.raw has defined types, so this comes out as a data.LampPrototype
local lamp = util.table.deepcopy(data.raw["lamp"]["small-lamp"])

-- (do some stuff to it that you don't care about...)

-- then extend it
data.extend{ lamp }

Actual Behaviour

this produces the diagnostic:

Cannot assign `data.LampPrototype` to `data.AccumulatorPrototype|data.AchievementPrototype|data.ActiveDefenseEquipmentPrototype|data.AgriculturalTowerPrototype|data.AirbornePollutantPrototype...(+255)`.
- `data.LampPrototype` cannot match `data.AccumulatorPrototype|data.AchievementPrototype|data.ActiveDefenseEquipmentPrototype|data.AgriculturalTowerPrototype|data.AirbornePollutantPrototype...(+255)`
- `data.LampPrototype` cannot match any subtypes in `data.AccumulatorPrototype|data.AchievementPrototype|data.ActiveDefenseEquipmentPrototype|data.AgriculturalTowerPrototype|data.AirbornePollutantPrototype...(+255)`
- Type `data.LampPrototype` cannot match `data.ExplosionPrototype`
- Type `data.EntityWithOwnerPrototype` cannot match `data.ExplosionPrototype`
- Type `data.EntityWithHealthPrototype` cannot match `data.ExplosionPrototype`
- Type `data.EntityPrototype` cannot match `data.ExplosionPrototype`
- Type `data.Prototype` cannot match `data.ExplosionPrototype`
- Type `data.PrototypeBase` cannot match `data.ExplosionPrototype`
- Type `data.LampPrototype` cannot match `data.EquipmentGridPrototype`
- Type `data.EntityWithOwnerPrototype` cannot match `data.EquipmentGridPrototype`
- Type `data.EntityWithHealthPrototype` cannot match `data.EquipmentGridPrototype`
- Type `data.EntityPrototype` cannot match `data.EquipmentGridPrototype`
...(+575)
- Type `data.EntityPrototype` cannot match `data.ModBoolSettingPrototype`
- Type `data.Prototype` cannot match `data.ModBoolSettingPrototype`
- Type `data.PrototypeBase` cannot match `data.ModBoolSettingPrototype`

Reproduction steps

  1. Go to '...'
  2. Click '...'
  3. See error '...'

Additional Notes

No response

Log File

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions