Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd8ee80f

Browse files
committed
[F#] Slicing and range expression inconsistent
Slice expressions (ex., e1.[e1..e2]) looks similar to range expression (ex., [| e1 .. e2 |] ) but their behaviors are not consistent when length < 0. For example, [| 1..10 |].[3..1] raises overflow exception while [| 3..1 |] evaluates [| |]. In this shelveset, length check is added consistently for array/string slice expressions, so their behaviors looks consistent.Additionally, for open-ended slices (e.g., m.[1..] or m.[..5]), exception would raise for invalid range. (changeset 1231622)
1 parentebf2bc4 commitd8ee80f

File tree

2 files changed

+99
-57
lines changed

2 files changed

+99
-57
lines changed

‎src/fsharp/FSharp.Core/prim-types.fs‎

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,7 @@ namespace Microsoft.FSharp.Core
797797

798798

799799
let inlineGetArraySub arr(start:int)(len:int)=
800+
letlen=if len<0then0else len
800801
letdst= zeroCreate len
801802
for i=0to len-1do
802803
SetArray dst i(GetArray arr(start+ i))
@@ -4929,41 +4930,42 @@ namespace Microsoft.FSharp.Core
49294930
[<CodeAnalysis.SuppressMessage("Microsoft.Naming","CA1709:IdentifiersShouldBeCasedCorrectly"); CodeAnalysis.SuppressMessage("Microsoft.Naming","CA1704:IdentifiersShouldBeSpelledCorrectly")>]
49304931
letPowGeneric(one,mul,x:'T,n)= ComputePowerGenericInlined one mul x n
49314932

4932-
4933+
let inlineComputeSlice start finish length=
4934+
match start, finishwith
4935+
| None, None->0, length-1
4936+
| None, Some nwhen n>=0->0, n
4937+
| Some m, Nonewhen m<= length-> m, length-1
4938+
| Some m, Some n-> m, n
4939+
|_-> raise(System.IndexOutOfRangeException())
49334940

4934-
let inlineGetArraySlice(arr:_[])start finish=
4935-
letstart=(match startwith None->0| Some n-> n)
4936-
letfinish=(match finishwith None-> arr.Length-1| Some n-> n)
4941+
let inlineGetArraySlice(arr:_[])start finish=
4942+
letstart,finish= ComputeSlice start finish arr.Length
49374943
GetArraySub arr start(finish- start+1)
49384944

49394945
let inlineSetArraySlice(dst:_[])start finish(src:_[])=
49404946
letstart=(match startwith None->0| Some n-> n)
49414947
letfinish=(match finishwith None-> dst.Length-1| Some n-> n)
49424948
SetArraySub dst start(finish- start+1) src
49434949

4944-
letGetArraySlice2D(arr:_[,])start1 finish1 start2 finish2=
4945-
letstart1=(match start1with None->0| Some n-> n)
4946-
letstart2=(match start2with None->0| Some n-> n)
4947-
letfinish1=(match finish1with None-> GetArray2DLength1 arr-1| Some n-> n)
4948-
letfinish2=(match finish2with None-> GetArray2DLength2 arr-1| Some n-> n)
4950+
letGetArraySlice2D(arr:_[,])start1 finish1 start2 finish2=
4951+
letstart1,finish1= ComputeSlice start1 finish1(GetArray2DLength1 arr)
4952+
letstart2,finish2= ComputeSlice start2 finish2(GetArray2DLength2 arr)
49494953
letlen1=(finish1- start1+1)
49504954
letlen2=(finish2- start2+1)
49514955
GetArray2DSub arr start1 start2 len1 len2
49524956

49534957
let inlineGetArraySlice2DFixed1(arr:_[,])fixed1 start2 finish2=
4954-
letstart2=(match start2with None->0| Some n-> n)
4955-
letfinish2=(match finish2with None-> GetArray2DLength2 arr-1| Some n-> n)
4958+
letstart2,finish2= ComputeSlice start2 finish2(GetArray2DLength2 arr)
49564959
letlen2=(finish2- start2+1)
4957-
letdst= zeroCreate len2
4960+
letdst= zeroCreate(iflen2<0then0else len2)
49584961
for j=0to len2-1do
49594962
SetArray dst j(GetArray2D arr fixed1(start2+j))
49604963
dst
49614964

4962-
let inlineGetArraySlice2DFixed2(arr:_[,])start1 finish1 fixed2=
4963-
letstart1=(match start1with None->0| Some n-> n)
4964-
letfinish1=(match finish1with None-> GetArray2DLength1 arr-1| Some n-> n)
4965+
let inlineGetArraySlice2DFixed2(arr:_[,])start1 finish1 fixed2=
4966+
letstart1,finish1= ComputeSlice start1 finish1(GetArray2DLength1 arr)
49654967
letlen1=(finish1- start1+1)
4966-
letdst= zeroCreate len1
4968+
letdst= zeroCreate(iflen1<0then0else len1)
49674969
for i=0to len1-1do
49684970
SetArray dst i(GetArray2D arr(start1+i) fixed2)
49694971
dst
@@ -4989,13 +4991,10 @@ namespace Microsoft.FSharp.Core
49894991
letfinish2=(match finish2with None-> GetArray2DLength2 dst-1| Some n-> n)
49904992
SetArray2DSub dst start1 start2(finish1- start1+1)(finish2- start2+1) src
49914993

4992-
letGetArraySlice3D(arr:_[,,])start1 finish1 start2 finish2 start3 finish3=
4993-
letstart1=(match start1with None->0| Some n-> n)
4994-
letstart2=(match start2with None->0| Some n-> n)
4995-
letstart3=(match start3with None->0| Some n-> n)
4996-
letfinish1=(match finish1with None-> GetArray3DLength1 arr-1| Some n-> n)
4997-
letfinish2=(match finish2with None-> GetArray3DLength2 arr-1| Some n-> n)
4998-
letfinish3=(match finish3with None-> GetArray3DLength3 arr-1| Some n-> n)
4994+
letGetArraySlice3D(arr:_[,,])start1 finish1 start2 finish2 start3 finish3=
4995+
letstart1,finish1= ComputeSlice start1 finish1(GetArray3DLength1 arr)
4996+
letstart2,finish2= ComputeSlice start2 finish2(GetArray3DLength2 arr)
4997+
letstart3,finish3= ComputeSlice start3 finish3(GetArray3DLength3 arr)
49994998
letlen1=(finish1- start1+1)
50004999
letlen2=(finish2- start2+1)
50015000
letlen3=(finish3- start3+1)
@@ -5011,14 +5010,10 @@ namespace Microsoft.FSharp.Core
50115010
SetArray3DSub dst start1 start2 start3(finish1- start1+1)(finish2- start2+1)(finish3- start3+1) src
50125011

50135012
letGetArraySlice4D(arr:_[,,,])start1 finish1 start2 finish2 start3 finish3 start4 finish4=
5014-
letstart1=(match start1with None->0| Some n-> n)
5015-
letstart2=(match start2with None->0| Some n-> n)
5016-
letstart3=(match start3with None->0| Some n-> n)
5017-
letstart4=(match start4with None->0| Some n-> n)
5018-
letfinish1=(match finish1with None-> Array4DLength1 arr-1| Some n-> n)
5019-
letfinish2=(match finish2with None-> Array4DLength2 arr-1| Some n-> n)
5020-
letfinish3=(match finish3with None-> Array4DLength3 arr-1| Some n-> n)
5021-
letfinish4=(match finish4with None-> Array4DLength4 arr-1| Some n-> n)
5013+
letstart1,finish1= ComputeSlice start1 finish1(Array4DLength1 arr)
5014+
letstart2,finish2= ComputeSlice start2 finish2(Array4DLength2 arr)
5015+
letstart3,finish3= ComputeSlice start3 finish3(Array4DLength3 arr)
5016+
letstart4,finish4= ComputeSlice start4 finish4(Array4DLength4 arr)
50225017
letlen1=(finish1- start1+1)
50235018
letlen2=(finish2- start2+1)
50245019
letlen3=(finish3- start3+1)
@@ -5036,11 +5031,11 @@ namespace Microsoft.FSharp.Core
50365031
letfinish4=(match finish4with None-> Array4DLength4 dst-1| Some n-> n)
50375032
SetArray4DSub dst start1 start2 start3 start4(finish1- start1+1)(finish2- start2+1)(finish3- start3+1)(finish4- start4+1) src
50385033

5039-
let inlineGetStringSlice(str:string)start finish=
5040-
letstart=(match startwith None->0| Some n-> n)
5041-
letfinish=(matchfinishwith None-> str.Length-1| Some n-> n)
5042-
str.Substring(start, finish-start+1)
5043-
5034+
let inlineGetStringSlice(str:string)start finish=
5035+
letstart,finish=ComputeSlice startfinish str.Length
5036+
letlen= finish-start+1
5037+
if len<0then String.Empty
5038+
else str.Substring(start, len)
50445039

50455040
[<NoDynamicInvocation>]
50465041
let inlineabsImpl(x:^T):^T=

‎tests/fsharp/core/array/test.fsx‎

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -730,38 +730,53 @@ module StringSlicingTest =
730730
test"slice1914"(s1.[..4]="abcde")
731731
test"slice1915"(s1.[..5]="abcdef")
732732
test"slice1918"(try s1.[..6]|> ignore;falsewith_->true)
733+
test"slice1919"(try s1.[..-1]|> ignore;falsewith_->true)
733734
test"slice1817"(s1.[1..0]="")
734735
test"slice1811"(s1.[1..1]="b")
735736
test"slice1812"(s1.[1..2]="bc")
736737
test"slice1813"(s1.[1..3]="bcd")
737738
test"slice1814"(s1.[1..4]="bcde")
738739
test"slice1815"(s1.[1..5]="bcdef")
739740
test"slice1818"(try s1.[1..6]|> ignore;falsewith_->true)
741+
test"slice1940"(s1.[0..1]="ab")
742+
test"slice1941"(s1.[1..1]="b")
743+
test"slice1942"(s1.[2..1]="")
744+
test"slice1943"(s1.[3..1]="")
745+
test"slice1944"(s1.[4..1]="")
746+
740747

741748
moduleArraySlicingTestBytes=
742749

743750
lets1="abcdef"B
744-
test"aslice1923"(s1.[0..]= s1)
745-
test"aslice1924"(s1.[1..]="bcdef"B)
746-
test"aslice1925"(s1.[2..]="cdef"B)
747-
test"aslice1926"(s1.[5..]="f"B)
748-
test"aslice1927"(s1.[6..]=""B)
749-
test"aslice1928"(try s1.[7..]|> ignore;falsewith_->true)
750-
test"aslice1929"(try s1.[-1..]|> ignore;falsewith_->true)
751-
test"aslice1917"(s1.[..0]="a"B)
752-
test"aslice1911"(s1.[..1]="ab"B)
753-
test"aslice1912"(s1.[..2]="abc"B)
754-
test"aslice1913"(s1.[..3]="abcd"B)
755-
test"aslice1914"(s1.[..4]="abcde"B)
756-
test"aslice1915"(s1.[..5]="abcdef"B)
757-
test"aslice1918"(try s1.[..6]|> ignore;falsewith_->true)
758-
test"aslice1817"(s1.[1..0]=""B)
759-
test"aslice1811"(s1.[1..1]="b"B)
760-
test"aslice1812"(s1.[1..2]="bc"B)
761-
test"aslice1813"(s1.[1..3]="bcd"B)
762-
test"aslice1814"(s1.[1..4]="bcde"B)
763-
test"aslice1815"(s1.[1..5]="bcdef"B)
764-
test"aslice1818"(try s1.[1..6]|> ignore;falsewith_->true)
751+
test"bslice1923"(s1.[0..]= s1)
752+
test"bslice1924"(s1.[1..]="bcdef"B)
753+
test"bslice1925"(s1.[2..]="cdef"B)
754+
test"bslice1926"(s1.[5..]="f"B)
755+
test"bslice1927"(s1.[6..]=""B)
756+
test"bslice1928"(try s1.[7..]|> ignore;falsewith_->true)
757+
test"bslice1929"(try s1.[-1..]|> ignore;falsewith_->true)
758+
test"bslice1917"(s1.[..0]="a"B)
759+
test"bslice1911"(s1.[..1]="ab"B)
760+
test"bslice1912"(s1.[..2]="abc"B)
761+
test"bslice1913"(s1.[..3]="abcd"B)
762+
test"bslice1914"(s1.[..4]="abcde"B)
763+
test"bslice1915"(s1.[..5]="abcdef"B)
764+
test"bslice1918"(try s1.[..6]|> ignore;falsewith_->true)
765+
test"bslice1919"(try s1.[..-1]|> ignore;falsewith_->true)
766+
test"bslice1817"(s1.[1..0]=""B)
767+
test"bslice1811"(s1.[1..1]="b"B)
768+
test"bslice1812"(s1.[1..2]="bc"B)
769+
test"bslice1813"(s1.[1..3]="bcd"B)
770+
test"bslice1814"(s1.[1..4]="bcde"B)
771+
test"bslice1815"(s1.[1..5]="bcdef"B)
772+
test"bslice1818"(try s1.[1..6]|> ignore;falsewith_->true)
773+
test"bslice1940"(s1.[0..1]="ab"B)
774+
test"bslice1941"(s1.[1..1]="b"B)
775+
test"bslice1942"(s1.[2..1]=""B)
776+
test"bslice1943"(s1.[3..1]=""B)
777+
test"bslice1944"(s1.[4..1]=""B)
778+
779+
765780

766781
moduleArraySlicingTestInts=
767782

@@ -780,13 +795,19 @@ module ArraySlicingTestInts =
780795
test"aslice1914"(s1.[..4]=[|1;2;3;4;5|])
781796
test"aslice1915"(s1.[..5]=[|1;2;3;4;5;6|])
782797
test"aslice1918"(try s1.[..6]|> ignore;falsewith_->true)
798+
test"aslice1919"(try s1.[..-1]|> ignore;falsewith_->true)
783799
test"aslice1817"(s1.[1..0]=[||])
784800
test"aslice1811"(s1.[1..1]=[|2|])
785801
test"aslice1812"(s1.[1..2]=[|2;3|])
786802
test"aslice1813"(s1.[1..3]=[|2;3;4|])
787803
test"aslice1814"(s1.[1..4]=[|2;3;4;5|])
788804
test"aslice1815"(s1.[1..5]=[|2;3;4;5;6|])
789805
test"aslice1818"(try s1.[1..6]|> ignore;falsewith_->true)
806+
test"aslice1940"(s1.[0..1]=[|1;2|])
807+
test"aslice1941"(s1.[1..1]=[|2|])
808+
test"aslice1942"(s1.[2..1]=[||])
809+
test"aslice1943"(s1.[3..1]=[||])
810+
test"aslice1944"(s1.[4..1]=[||])
790811

791812

792813
moduleArray2DSlicingTests=
@@ -825,6 +846,12 @@ module Array2DSlicingTests =
825846
test"a2slice1931"(m1.[1..,3]=[|40.0|])
826847
test"a2slice1932"(m1.[1,*]=[|10.0;20.0;30.0;40.0;50.0;60.0|])
827848
test"a2slice1933"(m1.[0,..3]=[|1.0;2.0;3.0;4.0|])
849+
test"a2slice1940"(m1.[1,3..1]=[||])
850+
test"a2slice1941"(m1.[3..1,1]=[||])
851+
test"a2slice1942"(try m1.[1,10..]|> ignore;falsewith_->true)
852+
test"a2slice1943"(try m1.[10..,1]|> ignore;falsewith_->true)
853+
test"a2slice1944"(try m1.[1,..-1]|> ignore;falsewith_->true)
854+
test"a2slice1945"(try m1.[..-1,1]|> ignore;falsewith_->true)
828855

829856
letarr2D1= array2d[|[|1.;2.;3.;4.|];
830857
[|5.;6.;7.;8.|];
@@ -895,6 +922,14 @@ module Array3DSlicingTests =
895922
[|[|10.0;20.0;30.0;40.0;50.0;60.0|];
896923
[|100.0;200.0;300.0;400.0;500.0;600.0|]|]|])
897924

925+
test"a3slice1933"(try m1.[*,*,7..]|> ignore;falsewith_->true)
926+
test"a3slice1934"(try m1.[*,*,..-1]|> ignore;falsewith_->true)
927+
928+
test"a3slice1935"(try m1.[*,3..,*]|> ignore;falsewith_->true)
929+
test"a3slice1936"(try m1.[*,..-1,*]|> ignore;falsewith_->true)
930+
931+
test"a3slice1937"(try m1.[3..,*,*]|> ignore;falsewith_->true)
932+
test"a3slice1938"(try m1.[..-1,*,*]|> ignore;falsewith_->true)
898933

899934
moduleArray4DSlicingTests=
900935

@@ -990,6 +1025,18 @@ module Array4DSlicingTests =
9901025
|]
9911026
|])
9921027

1028+
test"a4slice1931"(try m1.[*,*,*,7..]|> ignore;falsewith_->true)
1029+
test"a4slice1932"(try m1.[*,*,*,..-1]|> ignore;falsewith_->true)
1030+
1031+
test"a4slice1933"(try m1.[*,*,3..,*]|> ignore;falsewith_->true)
1032+
test"a4slice1934"(try m1.[*,*,..-1,*]|> ignore;falsewith_->true)
1033+
1034+
test"a4slice1935"(try m1.[*,3..,*,*]|> ignore;falsewith_->true)
1035+
test"a4slice1936"(try m1.[*,..-1,*,*]|> ignore;falsewith_->true)
1036+
1037+
test"a4slice1937"(try m1.[3..,*,*,*]|> ignore;falsewith_->true)
1038+
test"a4slice1938"(try m1.[..-1,*,*,*]|> ignore;falsewith_->true)
1039+
9931040
moduleArrayStructMutation=
9941041
moduleArray1D=
9951042
moduleTest1=

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp