ricosjp / ruststep

A STEP toolkit for Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Revise SUBTYPE handling for multiple inheritance

termoshtt opened this issue · comments

ENTITY a;
  x: REAL;
END_ENTITY;

ENTITY b SUBTYPE OF a;
  y1: REAL;
END_ENTITY;

ENTITY c SUBTYPE OF a;
  y2: REAL;
END_ENTITY;

ENTITY d SUBTYPE OF (b, c);
  z: REAL;
END_ENTITY;

Current master compiles this into following Rust code:

struct A {
  x: f64,
}

struct B {
  a: A,
  y1: f64,
}

struct C {
  a: A,
  y2: f64,
}

struct D {
  b: B,
  c: C,
  z: f64,
}

This is incorrect in terms of STEP because D has two x memory. Rather, expand all components:

struct A {
  x: f64,
}

struct B {
  x: f64,
  y1: f64,
}

struct C {
  x: f64,
  y2: f64,
}

struct D {
  x: f64,
  y1: f64,
  y2: f64,
  z: f64,
}

However, in this case we cannot generate &C from &D since D does not have C compatible memory. Assuming repr(C), the memory of D should be

┌─────┬─────┬─────┬─────┐
│  x  │ y1  │ y2  │  z  │
└─────┴─────┴─────┴─────┘

Thus we can cast &D i.e. a pointer to the head of this struct into &A and &B, but cannot into &C since C does not have y1.

We have two way to resolve it. One is to introduce y1 padding into C

struct C {
  x: f64,
  __y1: f64,
  y2: f64,
}

This can compatible to D memory. Another is defining CRef

struct CRef<'a> {
  x: &'a f64,
  y2: &'a f64,
}

impl D {
  fn as_c(&'a self) -> CRef<'a> {
    CRef { x: self.x, y2: self.y2 }
  }
}

Formal definition of SUBTYPE / SUPERTYPE handling is described in ISO-10303-11 Annex B. I have to implement these algorithm.

Possible partial complex entity list has been resolved in espr::ir layer by #200 #203. Remaining part about memory layout is inherited to #189, and close.