aardappel / lobster

The Lobster Programming Language

Home Page:http://strlen.com/lobster

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SpecializationIsCompatible assertion with implicit type in method parameter.

MortimerSnerd opened this issue · comments

I'm on commit 7646612

This is actually the assertion I mentioned in discord. For the collision_shape class and it's subclass csphere below, having the body parameter with no explicit type will cause an assertion in lobster debug. The 4 uses of for_brushes_colliding_with_shape towards the bottom of the file are necessary to get the assertion to happen. The rest of the defs are to make it happy enough to get to the type checking phase.

When the code runs without an assertion, it's just going to pop an index out of range error.

Here is the one file repro code:

import vec

   
def entry(bsp, orc, h):
   perform_model_collisions(bsp, orc, h)
   perform_trigger_collisions(bsp, orc, h)

class bsp_file:
   a: int

class orchestrator:
   a: int

//REPRODUCTION NOTE adding this as the type annotation to the body parameter in on_brush_collision
//     will make the assert go away.
def on_brush_collision_body(plane: int, pos: xyz_f, overlap: xyz_f) -> void

class collision_shape:
   def overlaps_aabb(minc: xyz_f, maxc: xyz_f) -> bool:
      return true

   def plane_split(plane_normal: xyz_f, plane_dist: float, body):
      pass()

   def on_brush_collision(bsp: bsp_file, brush: int, area_mins: xyz_f, area_maxs: xyz_f, body):
      pass()

   def bounding_sphere_radius() -> float:
      return 0.0
      
class csphere: collision_shape
   def on_brush_collision(bsp: bsp_file, brush: int, area_mins: xyz_f, area_maxs: xyz_f, body):
      body(4, xyz_1, xyz_0)


class brush_area:
   // bak_* constants
   kind: int
   mins: xyz_f
   maxs: xyz_f
   brushes: [int]
   model_ix: int

   is_trigger: bool

   meshes = [] :: [resource<mesh>]

   clusters = [] :: int

   def centroid() -> xyz_f:
      return mins + (maxs-mins)*0.5

   def contains(p):
      return (p >= mins) == xyz{true,true,true} and (p <= maxs) == xyz{true, true, true}

struct physics_object:
   h:int

struct shape_contact:
   face: int
   pos: xyz_f
   overlap: xyz_f  
   plane: int = -1

struct model_collision_info:
   obj: physics_object
   model: brush_area
   contact: shape_contact

struct trigger_collision_info:
   obj: physics_object
   trigger: brush_area

private let po_shape = [] :: collision_shape
private let po_overlap = [] :: xyzw_f
private let py_triggers = [] :: brush_area
private let py_models   = [] :: brush_area

def mag_squared(x):
   return x.x

private def for_brushes_colliding_with_shape(bsp: bsp_file, brush_areas: [brush_area], shape: collision_shape, body):
   for(brush_areas) area:
      if shape.overlaps_aabb(area.mins, area.maxs):
         for(area.brushes) brush_ix:
            shape.on_brush_collision(bsp, brush_ix, area.mins, area.maxs) plane_no, pos, ovlp:
               body(area, plane_no, pos, ovlp)

private def perform_model_collisions(bsp: bsp_file, orc: orchestrator, h: int):
   let reportables = []
   for_brushes_colliding_with_shape(bsp, py_models, po_shape[h]) model, plane_no, pos, ovlp:
      po_overlap[h] += xyzw(ovlp, 1.0)
      if mag_squared(ovlp) > 0.0:
         let norm = normalize(ovlp)
         push(reportables, model_collision_info{physics_object{h}, model,
                                                shape_contact{-1, pos, ovlp, plane: plane_no}})

private def perform_trigger_collisions(bsp: bsp_file, orc: orchestrator, h: int):
   let reportables = []
   for_brushes_colliding_with_shape(bsp, py_triggers, po_shape[h]) trigger, pno, pos, ovlap:
      push(reportables,
           trigger_collision_info{physics_object{h}, trigger})


def on_collisions_with_model_brushes(bsp: bsp_file, shape: collision_shape, body):
   for_brushes_colliding_with_shape(bsp, py_models, shape, body)

def doit():
   let bsp = bsp_file{1}
   let orc = orchestrator{1}

   entry(bsp, orc, 0)
   on_collisions_with_model_brushes(bsp, collision_shape{}) area, plane, pos, ovlp:
      pass()

doit()

Thanks for the repro, fixed here: 02b117c

Are you ok me adding your repro to tests/misc ?

Yes, that's fine. Thanks for looking at it.