@@ -303,15 +303,11 @@ pub(crate) type TupleSpec<'db> = Tuple<Type<'db>>;
303303/// Our tuple representation can hold instances of any Rust type. For tuples containing Python
304304/// types, use [`TupleSpec`], which defines some additional type-specific methods.
305305#[ derive( Clone , Debug , Eq , Hash , PartialEq , get_size2:: GetSize ) ]
306- pub struct FixedLengthTuple < T > ( Vec < T > ) ;
306+ pub struct FixedLengthTuple < T > ( Box < [ T ] > ) ;
307307
308308impl < T > FixedLengthTuple < T > {
309309 fn empty ( ) -> Self {
310- Self ( Vec :: new ( ) )
311- }
312-
313- pub ( crate ) fn with_capacity ( capacity : usize ) -> Self {
314- Self ( Vec :: with_capacity ( capacity) )
310+ Self ( Box :: default ( ) )
315311 }
316312
317313 fn from_elements ( elements : impl IntoIterator < Item = T > ) -> Self {
@@ -338,27 +334,9 @@ impl<T> FixedLengthTuple<T> {
338334 pub ( crate ) fn len ( & self ) -> usize {
339335 self . 0 . len ( )
340336 }
341-
342- pub ( crate ) fn push ( & mut self , element : T ) {
343- self . 0 . push ( element) ;
344- }
345337}
346338
347339impl < ' db > FixedLengthTuple < Type < ' db > > {
348- fn concat ( & self , other : & Tuple < Type < ' db > > ) -> Tuple < Type < ' db > > {
349- match other {
350- TupleSpec :: Fixed ( other) => TupleSpec :: Fixed ( FixedLengthTuple :: from_elements (
351- self . elements ( ) . chain ( other. elements ( ) ) . copied ( ) ,
352- ) ) ,
353-
354- TupleSpec :: Variable ( other) => VariableLengthTuple :: mixed (
355- self . elements ( ) . chain ( other. prefix_elements ( ) ) . copied ( ) ,
356- other. variable ,
357- other. suffix_elements ( ) . copied ( ) ,
358- ) ,
359- }
360- }
361-
362340 fn resize (
363341 & self ,
364342 db : & ' db dyn Db ,
@@ -482,7 +460,7 @@ where
482460 unsafe fn maybe_update ( old_pointer : * mut Self , new_value : Self ) -> bool {
483461 unsafe {
484462 let old_value = & mut * old_pointer;
485- Vec :: maybe_update ( & raw mut old_value. 0 , new_value. 0 )
463+ Box :: maybe_update ( & raw mut old_value. 0 , new_value. 0 )
486464 }
487465 }
488466}
@@ -491,7 +469,7 @@ impl<'db> PyIndex<'db> for &FixedLengthTuple<Type<'db>> {
491469 type Item = Type < ' db > ;
492470
493471 fn py_index ( self , db : & ' db dyn Db , index : i32 ) -> Result < Self :: Item , OutOfBoundsError > {
494- self . 0 . as_slice ( ) . py_index ( db, index) . copied ( )
472+ self . 0 . py_index ( db, index) . copied ( )
495473 }
496474}
497475
@@ -518,9 +496,9 @@ impl<'db> PySlice<'db> for FixedLengthTuple<Type<'db>> {
518496/// types, use [`TupleSpec`], which defines some additional type-specific methods.
519497#[ derive( Clone , Debug , Eq , Hash , PartialEq , get_size2:: GetSize ) ]
520498pub struct VariableLengthTuple < T > {
521- pub ( crate ) prefix : Vec < T > ,
499+ pub ( crate ) prefix : Box < [ T ] > ,
522500 pub ( crate ) variable : T ,
523- pub ( crate ) suffix : Vec < T > ,
501+ pub ( crate ) suffix : Box < [ T ] > ,
524502}
525503
526504impl < T > VariableLengthTuple < T > {
@@ -569,10 +547,6 @@ impl<T> VariableLengthTuple<T> {
569547 fn len ( & self ) -> TupleLength {
570548 TupleLength :: Variable ( self . prefix . len ( ) , self . suffix . len ( ) )
571549 }
572-
573- fn push ( & mut self , element : T ) {
574- self . suffix . push ( element) ;
575- }
576550}
577551
578552impl < ' db > VariableLengthTuple < Type < ' db > > {
@@ -639,30 +613,6 @@ impl<'db> VariableLengthTuple<Type<'db>> {
639613 . copied ( )
640614 }
641615
642- fn concat ( & self , db : & ' db dyn Db , other : & Tuple < Type < ' db > > ) -> Tuple < Type < ' db > > {
643- match other {
644- TupleSpec :: Fixed ( other) => VariableLengthTuple :: mixed (
645- self . prefix_elements ( ) . copied ( ) ,
646- self . variable ,
647- self . suffix_elements ( ) . chain ( other. elements ( ) ) . copied ( ) ,
648- ) ,
649-
650- Tuple :: Variable ( other) => {
651- let variable = UnionType :: from_elements (
652- db,
653- ( self . suffix_elements ( ) . copied ( ) )
654- . chain ( [ self . variable , other. variable ] )
655- . chain ( other. prefix_elements ( ) . copied ( ) ) ,
656- ) ;
657- VariableLengthTuple :: mixed (
658- self . prefix_elements ( ) . copied ( ) ,
659- variable,
660- other. suffix_elements ( ) . copied ( ) ,
661- )
662- }
663- }
664- }
665-
666616 fn resize (
667617 & self ,
668618 db : & ' db dyn Db ,
@@ -711,13 +661,17 @@ impl<'db> VariableLengthTuple<Type<'db>> {
711661 let prefix = self
712662 . prenormalized_prefix_elements ( db, None )
713663 . map ( |ty| ty. normalized_impl ( db, visitor) )
714- . collect :: < Vec < _ > > ( ) ;
664+ . collect :: < Box < _ > > ( ) ;
715665 let suffix = self
716666 . prenormalized_suffix_elements ( db, None )
717667 . map ( |ty| ty. normalized_impl ( db, visitor) )
718- . collect :: < Vec < _ > > ( ) ;
668+ . collect :: < Box < _ > > ( ) ;
719669 let variable = self . variable . normalized_impl ( db, visitor) ;
720- Self :: mixed ( prefix, variable, suffix)
670+ TupleSpec :: Variable ( Self {
671+ prefix,
672+ variable,
673+ suffix,
674+ } )
721675 }
722676
723677 fn materialize ( & self , db : & ' db dyn Db , variance : TypeVarVariance ) -> TupleSpec < ' db > {
@@ -901,9 +855,9 @@ where
901855 unsafe fn maybe_update ( old_pointer : * mut Self , new_value : Self ) -> bool {
902856 let old_value = unsafe { & mut * old_pointer } ;
903857 let mut changed = false ;
904- changed |= unsafe { Vec :: maybe_update ( & raw mut old_value. prefix , new_value. prefix ) } ;
858+ changed |= unsafe { Box :: maybe_update ( & raw mut old_value. prefix , new_value. prefix ) } ;
905859 changed |= unsafe { T :: maybe_update ( & raw mut old_value. variable , new_value. variable ) } ;
906- changed |= unsafe { Vec :: maybe_update ( & raw mut old_value. suffix , new_value. suffix ) } ;
860+ changed |= unsafe { Box :: maybe_update ( & raw mut old_value. suffix , new_value. suffix ) } ;
907861 changed
908862 }
909863}
@@ -971,10 +925,6 @@ impl<T> Tuple<T> {
971925 FixedLengthTuple :: from_elements ( elements) . into ( )
972926 }
973927
974- pub ( crate ) fn with_capacity ( capacity : usize ) -> Self {
975- Tuple :: Fixed ( FixedLengthTuple :: with_capacity ( capacity) )
976- }
977-
978928 /// Returns an iterator of all of the fixed-length element types of this tuple.
979929 pub ( crate ) fn fixed_elements ( & self ) -> impl Iterator < Item = & T > + ' _ {
980930 match self {
@@ -1017,13 +967,6 @@ impl<T> Tuple<T> {
1017967 _ => Truthiness :: Ambiguous ,
1018968 }
1019969 }
1020-
1021- pub ( crate ) fn push ( & mut self , element : T ) {
1022- match self {
1023- Tuple :: Fixed ( tuple) => tuple. push ( element) ,
1024- Tuple :: Variable ( tuple) => tuple. push ( element) ,
1025- }
1026- }
1027970}
1028971
1029972impl < ' db > Tuple < Type < ' db > > {
@@ -1033,10 +976,7 @@ impl<'db> Tuple<Type<'db>> {
1033976
1034977 /// Concatenates another tuple to the end of this tuple, returning a new tuple.
1035978 pub ( crate ) fn concat ( & self , db : & ' db dyn Db , other : & Self ) -> Self {
1036- match self {
1037- Tuple :: Fixed ( tuple) => tuple. concat ( other) ,
1038- Tuple :: Variable ( tuple) => tuple. concat ( db, other) ,
1039- }
979+ TupleSpecBuilder :: from ( self ) . concat ( db, other) . build ( )
1040980 }
1041981
1042982 /// Resizes this tuple to a different length, if possible. If this tuple cannot satisfy the
@@ -1349,3 +1289,120 @@ pub(crate) enum ResizeTupleError {
13491289 TooFewValues ,
13501290 TooManyValues ,
13511291}
1292+
1293+ /// A builder for creating a new [`TupleSpec`]
1294+ pub ( crate ) enum TupleSpecBuilder < ' db > {
1295+ Fixed ( Vec < Type < ' db > > ) ,
1296+ Variable {
1297+ prefix : Vec < Type < ' db > > ,
1298+ variable : Type < ' db > ,
1299+ suffix : Vec < Type < ' db > > ,
1300+ } ,
1301+ }
1302+
1303+ impl < ' db > TupleSpecBuilder < ' db > {
1304+ pub ( crate ) fn with_capacity ( capacity : usize ) -> Self {
1305+ TupleSpecBuilder :: Fixed ( Vec :: with_capacity ( capacity) )
1306+ }
1307+
1308+ pub ( crate ) fn push ( & mut self , element : Type < ' db > ) {
1309+ match self {
1310+ TupleSpecBuilder :: Fixed ( elements) => elements. push ( element) ,
1311+ TupleSpecBuilder :: Variable { suffix, .. } => suffix. push ( element) ,
1312+ }
1313+ }
1314+
1315+ /// Concatenates another tuple to the end of this tuple, returning a new tuple.
1316+ pub ( crate ) fn concat ( mut self , db : & ' db dyn Db , other : & TupleSpec < ' db > ) -> Self {
1317+ match ( & mut self , other) {
1318+ ( TupleSpecBuilder :: Fixed ( left_tuple) , TupleSpec :: Fixed ( right_tuple) ) => {
1319+ left_tuple. extend_from_slice ( & right_tuple. 0 ) ;
1320+ self
1321+ }
1322+
1323+ (
1324+ TupleSpecBuilder :: Fixed ( left_tuple) ,
1325+ TupleSpec :: Variable ( VariableLengthTuple {
1326+ prefix,
1327+ variable,
1328+ suffix,
1329+ } ) ,
1330+ ) => {
1331+ left_tuple. extend_from_slice ( prefix) ;
1332+ TupleSpecBuilder :: Variable {
1333+ prefix : std:: mem:: take ( left_tuple) ,
1334+ variable : * variable,
1335+ suffix : suffix. to_vec ( ) ,
1336+ }
1337+ }
1338+
1339+ (
1340+ TupleSpecBuilder :: Variable {
1341+ prefix : _,
1342+ variable : _,
1343+ suffix,
1344+ } ,
1345+ TupleSpec :: Fixed ( right) ,
1346+ ) => {
1347+ suffix. extend_from_slice ( & right. 0 ) ;
1348+ self
1349+ }
1350+
1351+ (
1352+ TupleSpecBuilder :: Variable {
1353+ prefix : left_prefix,
1354+ variable : left_variable,
1355+ suffix : left_suffix,
1356+ } ,
1357+ TupleSpec :: Variable ( VariableLengthTuple {
1358+ prefix : right_prefix,
1359+ variable : right_variable,
1360+ suffix : right_suffix,
1361+ } ) ,
1362+ ) => {
1363+ let variable = UnionType :: from_elements (
1364+ db,
1365+ left_suffix
1366+ . iter ( )
1367+ . chain ( [ left_variable, right_variable] )
1368+ . chain ( right_prefix) ,
1369+ ) ;
1370+ TupleSpecBuilder :: Variable {
1371+ prefix : std:: mem:: take ( left_prefix) ,
1372+ variable,
1373+ suffix : right_suffix. to_vec ( ) ,
1374+ }
1375+ }
1376+ }
1377+ }
1378+
1379+ pub ( super ) fn build ( self ) -> TupleSpec < ' db > {
1380+ match self {
1381+ TupleSpecBuilder :: Fixed ( elements) => {
1382+ TupleSpec :: Fixed ( FixedLengthTuple ( elements. into_boxed_slice ( ) ) )
1383+ }
1384+ TupleSpecBuilder :: Variable {
1385+ prefix,
1386+ variable,
1387+ suffix,
1388+ } => TupleSpec :: Variable ( VariableLengthTuple {
1389+ prefix : prefix. into_boxed_slice ( ) ,
1390+ variable,
1391+ suffix : suffix. into_boxed_slice ( ) ,
1392+ } ) ,
1393+ }
1394+ }
1395+ }
1396+
1397+ impl < ' db > From < & TupleSpec < ' db > > for TupleSpecBuilder < ' db > {
1398+ fn from ( tuple : & TupleSpec < ' db > ) -> Self {
1399+ match tuple {
1400+ TupleSpec :: Fixed ( fixed) => TupleSpecBuilder :: Fixed ( fixed. 0 . to_vec ( ) ) ,
1401+ TupleSpec :: Variable ( variable) => TupleSpecBuilder :: Variable {
1402+ prefix : variable. prefix . to_vec ( ) ,
1403+ variable : variable. variable ,
1404+ suffix : variable. suffix . to_vec ( ) ,
1405+ } ,
1406+ }
1407+ }
1408+ }
0 commit comments