@@ -7219,3 +7219,162 @@ fn typeIsPointerAtRuntime(analyser: *Analyser, ty: Type) bool {
72197219 .one , .many = > ! ptr_info .is_optional or ! ptr_info .flags .is_allowzero ,
72207220 };
72217221}
7222+
7223+ fn typeIsSlice (analyser : * Analyser , ty : Type ) bool {
7224+ const ptr_info = analyser .typePointerInfo (ty ) orelse return false ;
7225+ if (ptr_info .is_optional ) return false ;
7226+ return switch (ptr_info .flags .size ) {
7227+ .slice = > true ,
7228+ .one , .many , .c = > false ,
7229+ };
7230+ }
7231+
7232+ fn typePointerOrOptionalPointerType (analyser : * Analyser , ty : Type ) ! ? Type {
7233+ return switch (ty .data ) {
7234+ .pointer = > | ptr_info | switch (ptr_info .size ) {
7235+ .one , .many , .c = > ty ,
7236+ .slice = > null ,
7237+ },
7238+ .optional = > | opt_child | {
7239+ const ptr_info = analyser .typePointerInfo (ty ) orelse return null ;
7240+ return switch (ptr_info .flags .size ) {
7241+ .slice , .c = > null ,
7242+ .many , .one = > {
7243+ if (ptr_info .flags .is_allowzero ) return null ;
7244+
7245+ if (try analyser .typeHasOnePossibleValue (opt_child .* ) != null ) {
7246+ return null ;
7247+ }
7248+
7249+ return opt_child .* ;
7250+ },
7251+ };
7252+ },
7253+ .ip_index = > null , // TODO
7254+ else = > null ,
7255+ };
7256+ }
7257+
7258+ fn typeHasOnePossibleValue (analyser : * Analyser , ty : Type ) ! ? InternPool.Index {
7259+ std .debug .assert (ty .is_type_val );
7260+ const ip_index = switch (ty .data ) {
7261+ .ip_index = > | payload | payload .index orelse return null ,
7262+ else = > return null ,
7263+ };
7264+ if (ip_index == .unknown_type ) return null ;
7265+ return analyser .ip .onePossibleValue (ip_index );
7266+ }
7267+
7268+ fn resolvePairInMemoryCoercible (analyser : * Analyser , ty_a : Type , ty_b : Type ) ! ? Type {
7269+ if (try analyser .coerceInMemoryAllowed (ty_a , ty_b , false )) {
7270+ return ty_a ;
7271+ }
7272+
7273+ if (try analyser .coerceInMemoryAllowed (ty_b , ty_a , false )) {
7274+ return ty_b ;
7275+ }
7276+
7277+ return null ;
7278+ }
7279+
7280+ fn coerceInMemoryAllowed (
7281+ analyser : * Analyser ,
7282+ dest_ty : Type ,
7283+ src_ty : Type ,
7284+ dest_is_mut : bool ,
7285+ ) error {OutOfMemory }! bool {
7286+ std .debug .assert (dest_ty .is_type_val );
7287+ std .debug .assert (src_ty .is_type_val );
7288+
7289+ if (dest_ty .eql (src_ty ))
7290+ return true ;
7291+
7292+ // Primitives / Error Sets
7293+ if (dest_ty .data == .ip_index and src_ty .data == .ip_index ) {
7294+ const dest_ip_index = dest_ty .data .ip_index .index orelse return false ;
7295+ const src_ip_index = src_ty .data .ip_index .index orelse return false ;
7296+ const result = try analyser .ip .coerceInMemoryAllowed (analyser .gpa , analyser .arena , dest_ip_index , src_ip_index , ! dest_is_mut , builtin .target );
7297+ return result == .ok ;
7298+ }
7299+
7300+ // Pointers / Pointer-like Optionals
7301+ const maybe_dest_ptr_ty = try analyser .typePointerOrOptionalPointerType (dest_ty );
7302+ const maybe_src_ptr_ty = try analyser .typePointerOrOptionalPointerType (src_ty );
7303+ if (maybe_dest_ptr_ty ) | dest_ptr_ty | {
7304+ if (maybe_src_ptr_ty ) | src_ptr_ty | {
7305+ return try analyser .coerceInMemoryAllowedPtrs (dest_ty , src_ty , dest_ptr_ty , src_ptr_ty , dest_is_mut );
7306+ }
7307+ }
7308+
7309+ // Slices
7310+ if (analyser .typeIsSlice (dest_ty ) and analyser .typeIsSlice (src_ty )) {
7311+ return try analyser .coerceInMemoryAllowedPtrs (dest_ty , src_ty , dest_ty , src_ty , dest_is_mut );
7312+ }
7313+
7314+ // Functions
7315+ if (dest_ty .data == .function and src_ty .data == .function ) {
7316+ return try analyser .coerceInMemoryAllowedFns (dest_ty , src_ty , dest_is_mut );
7317+ }
7318+
7319+ // Error Unions
7320+ if (dest_ty .data == .error_union and src_ty .data == .error_union ) {
7321+ // TODO
7322+ return false ;
7323+ }
7324+
7325+ // Arrays
7326+ if (dest_ty .data == .array and src_ty .data == .array ) {
7327+ // TODO
7328+ return false ;
7329+ }
7330+
7331+ // TODO: coerce non-primitive vectors/arrays
7332+
7333+ // Optionals
7334+ if (dest_ty .data == .optional and src_ty .data == .optional ) {
7335+ // TODO
7336+ return false ;
7337+ }
7338+
7339+ // Tuples (with in-memory-coercible fields)
7340+ if (dest_ty .data == .tuple and src_ty .data == .tuple ) {
7341+ // TODO
7342+ return false ;
7343+ }
7344+
7345+ return false ;
7346+ }
7347+
7348+ fn coerceInMemoryAllowedErrorSets (
7349+ analyser : * Analyser ,
7350+ dest_ty : Type ,
7351+ src_ty : Type ,
7352+ ) ! bool {
7353+ // TODO
7354+ _ = .{ analyser , dest_ty , src_ty };
7355+ return false ;
7356+ }
7357+
7358+ fn coerceInMemoryAllowedFns (
7359+ analyser : * Analyser ,
7360+ dest_ty : Type ,
7361+ src_ty : Type ,
7362+ dest_is_mut : bool ,
7363+ ) ! bool {
7364+ // TODO
7365+ _ = .{ analyser , dest_ty , src_ty , dest_is_mut };
7366+ return false ;
7367+ }
7368+
7369+ fn coerceInMemoryAllowedPtrs (
7370+ analyser : * Analyser ,
7371+ dest_ty : Type ,
7372+ src_ty : Type ,
7373+ dest_ptr_ty : Type ,
7374+ src_ptr_ty : Type ,
7375+ dest_is_mut : bool ,
7376+ ) ! bool {
7377+ // TODO
7378+ _ = .{ analyser , dest_ty , src_ty , dest_ptr_ty , src_ptr_ty , dest_is_mut };
7379+ return false ;
7380+ }
0 commit comments