@@ -1107,7 +1107,19 @@ impl<T: ArrayValue> Array<T> {
11071107 if !forward && env. scalar_unfill :: < T > ( ) . is_ok ( ) {
11081108 return Err ( env. error ( "Cannot invert filled rotation" ) ) ;
11091109 }
1110- let fill = env. scalar_fill :: < T > ( ) . ok ( ) ;
1110+ let fill = env. array_fill :: < T > ( ) . ok ( ) . map ( |fv| fv. value ) ;
1111+ if let Some ( fill) = & fill {
1112+ let by_dims = by. shape . last ( ) . copied ( ) . unwrap_or ( 1 ) ;
1113+ let end_dims = & self . shape [ self . rank ( ) . min ( depth + by_dims) ..] ;
1114+ if fill. rank ( ) > end_dims. len ( ) || !end_dims. ends_with ( & fill. shape ) {
1115+ return Err ( env. error ( format ! (
1116+ "Rotated rows each have shape {}, \
1117+ but the fill value has incompatible shape {}",
1118+ FormatShape ( end_dims) ,
1119+ fill. shape
1120+ ) ) ) ;
1121+ }
1122+ }
11111123
11121124 // Expand the array if doing multiple rotations
11131125 if self . rank ( ) > by. rank ( ) && self . shape . contains ( & 1 ) {
@@ -1144,7 +1156,7 @@ impl<T: ArrayValue> Array<T> {
11441156 shape : & [ usize ] ,
11451157 rotated : & mut [ T ] ,
11461158 depth : usize ,
1147- fill : Option < & T > ,
1159+ fill : Option < & [ T ] > ,
11481160 env : & Uiua ,
11491161 ) -> UiuaResult {
11501162 if by. is_empty ( ) || rotated. is_empty ( ) {
@@ -1205,7 +1217,7 @@ impl<T: ArrayValue> Array<T> {
12051217 & self . shape ,
12061218 self . data . as_mut_slice ( ) ,
12071219 depth,
1208- fill. as_ref ( ) . map ( |fv| & fv. value ) ,
1220+ fill. as_ref ( ) . map ( |fv| fv. data . as_slice ( ) ) ,
12091221 env,
12101222 ) ?;
12111223
@@ -1225,10 +1237,10 @@ impl<T: ArrayValue> Array<T> {
12251237 }
12261238}
12271239
1228- fn rotate_maybe_fill < T : Clone > ( by : & [ isize ] , shape : & [ usize ] , data : & mut [ T ] , fill : Option < & T > ) {
1240+ fn rotate_maybe_fill < T : Clone > ( by : & [ isize ] , shape : & [ usize ] , data : & mut [ T ] , fill : Option < & [ T ] > ) {
12291241 rotate ( by, shape, data) ;
12301242 if let Some ( fill) = fill {
1231- fill_shift ( by, shape, data, fill. clone ( ) ) ;
1243+ fill_shift ( by, shape, data, fill) ;
12321244 }
12331245}
12341246
@@ -1257,7 +1269,7 @@ fn rotate<T>(by: &[isize], shape: &[usize], data: &mut [T]) {
12571269 }
12581270}
12591271
1260- fn fill_shift < T : Clone > ( by : & [ isize ] , shape : & [ usize ] , data : & mut [ T ] , fill : T ) {
1272+ fn fill_shift < T : Clone > ( by : & [ isize ] , shape : & [ usize ] , data : & mut [ T ] , fill : & [ T ] ) {
12611273 if by. is_empty ( ) || shape. is_empty ( ) {
12621274 return ;
12631275 }
@@ -1270,13 +1282,17 @@ fn fill_shift<T: Clone>(by: &[isize], shape: &[usize], data: &mut [T], fill: T)
12701282 if offset != 0 {
12711283 let abs_offset = offset. unsigned_abs ( ) * row_len;
12721284 let data_len = data. len ( ) ;
1273- if offset > 0 {
1274- for val in & mut data[ data_len. saturating_sub ( abs_offset) ..] {
1275- * val = fill. clone ( ) ;
1276- }
1277- } else {
1278- for val in & mut data[ ..abs_offset. min ( data_len) ] {
1279- * val = fill. clone ( ) ;
1285+ if !fill. is_empty ( ) {
1286+ if offset > 0 {
1287+ for slice in
1288+ data[ data_len. saturating_sub ( abs_offset) ..] . chunks_exact_mut ( fill. len ( ) )
1289+ {
1290+ slice. clone_from_slice ( fill) ;
1291+ }
1292+ } else {
1293+ for slice in data[ ..abs_offset. min ( data_len) ] . chunks_exact_mut ( fill. len ( ) ) {
1294+ slice. clone_from_slice ( fill) ;
1295+ }
12801296 }
12811297 }
12821298 }
@@ -1286,7 +1302,7 @@ fn fill_shift<T: Clone>(by: &[isize], shape: &[usize], data: &mut [T], fill: T)
12861302 return ;
12871303 }
12881304 for cell in data. chunks_mut ( row_len) {
1289- fill_shift ( index, shape, cell, fill. clone ( ) ) ;
1305+ fill_shift ( index, shape, cell, fill) ;
12901306 }
12911307}
12921308
0 commit comments