@@ -337,6 +337,8 @@ def set_sources(self, new: list[Value]) -> None:
337337 (self .src ,) = new
338338
339339 def stolen (self ) -> list [Value ]:
340+ if not self .dest .type .is_refcounted :
341+ return []
340342 return [self .src ]
341343
342344 def accept (self , visitor : OpVisitor [T ]) -> T :
@@ -1679,9 +1681,36 @@ def accept(self, visitor: OpVisitor[T]) -> T:
16791681 return visitor .visit_set_mem (self )
16801682
16811683
1684+ @final
1685+ class GetElement (RegisterOp ):
1686+ """Get the value of a struct element from a struct value."""
1687+
1688+ error_kind = ERR_NEVER
1689+ is_borrowed = True
1690+
1691+ def __init__ (self , src : Value , field : str , line : int = - 1 ) -> None :
1692+ super ().__init__ (line )
1693+ assert isinstance (src .type , RStruct )
1694+ self .type = src .type .field_type (field )
1695+ self .src = src
1696+ self .src_type = src .type
1697+ self .field = field
1698+
1699+ def sources (self ) -> list [Value ]:
1700+ return [self .src ]
1701+
1702+ def set_sources (self , new : list [Value ]) -> None :
1703+ (self .src ,) = new
1704+
1705+ def accept (self , visitor : OpVisitor [T ]) -> T :
1706+ return visitor .visit_get_element (self )
1707+
1708+
16821709@final
16831710class GetElementPtr (RegisterOp ):
1684- """Get the address of a struct element.
1711+ """Get the address of a struct element from a pointer to a struct.
1712+
1713+ If you have a struct value, use GetElement instead.
16851714
16861715 Note that you may need to use KeepAlive to avoid the struct
16871716 being freed, if it's reference counted, such as PyObject *.
@@ -1691,6 +1720,7 @@ class GetElementPtr(RegisterOp):
16911720
16921721 def __init__ (self , src : Value , src_type : RType , field : str , line : int = - 1 ) -> None :
16931722 super ().__init__ (line )
1723+ assert not isinstance (src .type , RStruct )
16941724 self .type = pointer_rprimitive
16951725 self .src = src
16961726 self .src_type = src_type
@@ -2008,6 +2038,10 @@ def visit_load_mem(self, op: LoadMem) -> T:
20082038 def visit_set_mem (self , op : SetMem ) -> T :
20092039 raise NotImplementedError
20102040
2041+ @abstractmethod
2042+ def visit_get_element (self , op : GetElement ) -> T :
2043+ raise NotImplementedError
2044+
20112045 @abstractmethod
20122046 def visit_get_element_ptr (self , op : GetElementPtr ) -> T :
20132047 raise NotImplementedError
0 commit comments