@@ -45,42 +45,42 @@ bool TxTypeClassHandler::auto_converts_to( const TxActualType* type, const TxAct
45
45
46
46
/* === Array and Reference handlers ===*/
47
47
48
- bool TxArrayTypeClassHandler::auto_converts_to ( const TxActualType* type, const TxActualType* destination ) const {
49
- if ( this != destination->type_class_handler () )
50
- return false ;
51
- if ( this ->inner_equals ( type, destination ) )
52
- return true ;
53
-
54
- // (Array conversion check is stricter than array assignability check, since array assignment code will check
55
- // lengths in runtime, whereas e.g. ref-to-array conversions can't provide that guarantee.)
56
- // if origin has unbound type params that destination does not, origin is more generic and can't be converted to destination
57
- if ( auto toElem = destination->element_type () ) {
58
- if ( auto fromElem = type->element_type () ) {
59
- // note: is-a test insufficient for array elements, since assignable type (same instance data type) required
60
- if ( !fromElem->is_assignable_to ( *toElem ) )
61
- return false ;
62
- }
63
- else
64
- return false ; // origin has not bound E
65
- }
66
- if ( auto lenExpr = destination->capacity () ) {
67
- if ( auto fromLenExpr = type->capacity () ) {
68
- return ( lenExpr->is_statically_constant () && fromLenExpr->is_statically_constant ()
69
- && ( eval_unsigned_int_constant ( lenExpr ) == eval_unsigned_int_constant ( fromLenExpr ) ) );
70
- }
71
- else
72
- return false ; // origin has not bound C
73
- }
74
- return true ;
75
- }
48
+ // bool TxArrayTypeClassHandler::auto_converts_to( const TxActualType* type, const TxActualType* destination ) const {
49
+ // if ( this != destination->type_class_handler() )
50
+ // return false;
51
+ // if ( this->inner_equals( type, destination ) )
52
+ // return true;
53
+ //
54
+ // // if origin has unbound type params that destination does not, origin is more generic and can't be converted to destination
55
+ // if ( auto toElem = destination->element_type() ) {
56
+ // if ( auto fromElem = type->element_type() ) {
57
+ // // note: is-a test insufficient for array elements, since assignable type (same instance data type) required
58
+ // if ( !fromElem->is_assignable_to( *toElem ) )
59
+ // return false;
60
+ // }
61
+ // else
62
+ // return false; // origin has not bound E
63
+ // }
64
+ // if ( auto lenExpr = destination->capacity() ) {
65
+ // if ( auto fromLenExpr = type->capacity() ) {
66
+ // return ( lenExpr->is_statically_constant() && fromLenExpr->is_statically_constant()
67
+ // && ( eval_unsigned_int_constant( lenExpr ) == eval_unsigned_int_constant( fromLenExpr ) ) );
68
+ // }
69
+ // else
70
+ // return false; // origin has not bound C
71
+ // }
72
+ // return true;
73
+ // }
76
74
77
75
bool TxArrayTypeClassHandler::inner_is_assignable_to ( const TxActualType* type, const TxActualType* destination ) const {
78
76
ASSERT ( destination->get_type_class () == TXTC_ARRAY, " destination not an array: " << destination );
79
77
if ( this ->inner_equals ( type, destination ) )
80
78
return true ;
81
79
82
- // This implementation assumes that if lengths/capacities are not statically known, code will be generated
83
- // that checks this in runtime.
80
+ // This check is strict and requires statically verifiable assignability.
81
+ // (e.g. ref-to-array conversions need that guarantee)
82
+ // If origin has unbound type params that destination does not, origin is more generic and can't be converted to destination.
83
+ // (For assignments where lengths/capacities are not statically known, code must be generated to check this in runtime.)
84
84
if ( auto toElem = destination->element_type () ) {
85
85
if ( auto fromElem = type->element_type () ) {
86
86
// note: is-a test insufficient for array elements, since assignable type (same instance data type) required
@@ -92,15 +92,12 @@ bool TxArrayTypeClassHandler::inner_is_assignable_to( const TxActualType* type,
92
92
}
93
93
if ( auto lenExpr = destination->capacity () ) {
94
94
if ( auto fromLenExpr = type->capacity () ) {
95
- if ( lenExpr->is_statically_constant () && fromLenExpr->is_statically_constant () ) {
96
- // TODO: ideally we should check source Length instead of source Capacity
97
- return ( eval_unsigned_int_constant ( lenExpr ) >= eval_unsigned_int_constant ( fromLenExpr ) );
98
- }
99
- else
100
- return true ; // dynamic capacities must be checked in runtime
95
+ // TODO: ideally we should check source Length instead of source Capacity
96
+ return ( lenExpr->is_statically_constant () && fromLenExpr->is_statically_constant ()
97
+ && ( eval_unsigned_int_constant ( lenExpr ) == eval_unsigned_int_constant ( fromLenExpr ) ) );
101
98
}
102
99
else
103
- return true ; // origin has not bound C, dynamic capacities must be checked in runtime
100
+ return false ; // origin has not bound C, dynamic capacities must be checked in runtime
104
101
}
105
102
return true ;
106
103
}
0 commit comments