Skip to content

Commit 9fadb2e

Browse files
authored
Import IEnumerable as seq (#18865)
1 parent 4ded394 commit 9fadb2e

File tree

7 files changed

+84
-37
lines changed

7 files changed

+84
-37
lines changed

docs/release-notes/.FSharp.Compiler.Service/10.0.100.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
* Use `errorR` instead of `error` in `CheckDeclarations.fs` when possible. ([PR #18645](https://github.com/dotnet/fsharp/pull/18645))
3232
* Parser: Capture named fields block separators. ([PR #18857](https://github.com/dotnet/fsharp/pull/18857))
3333
* Type checker: use inner expr range in upcast constraints errors ([PR #18850](https://github.com/dotnet/fsharp/pull/18850))
34+
* Import `IEnumerable` as `seq`. ([PR #18865](https://github.com/dotnet/fsharp/pull/18865))
3435
* Parser: Capture multiple block separators ([PR #18899](https://github.com/dotnet/fsharp/pull/18899))
3536

3637
### Breaking Changes

src/Compiler/TypedTree/TcGlobals.fs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -966,30 +966,33 @@ type TcGlobals(
966966
let mkDebuggerTypeProxyAttribute (ty : ILType) = mkILCustomAttribute (findSysILTypeRef tname_DebuggerTypeProxyAttribute, [ilg.typ_Type], [ILAttribElem.TypeRef (Some ty.TypeRef)], [])
967967

968968
let betterTyconEntries =
969-
[| "Int32" , v_int_tcr
970-
"IntPtr" , v_nativeint_tcr
971-
"UIntPtr" , v_unativeint_tcr
972-
"Int16" , v_int16_tcr
973-
"Int64" , v_int64_tcr
974-
"UInt16" , v_uint16_tcr
975-
"UInt32" , v_uint32_tcr
976-
"UInt64" , v_uint64_tcr
977-
"SByte" , v_sbyte_tcr
978-
"Decimal" , v_decimal_tcr
979-
"Byte" , v_byte_tcr
980-
"Boolean" , v_bool_tcr
981-
"String" , v_string_tcr
982-
"Object" , v_obj_tcr
983-
"Exception", v_exn_tcr
984-
"Char" , v_char_tcr
985-
"Double" , v_float_tcr
986-
"Single" , v_float32_tcr |]
987-
|> Array.map (fun (nm, tcr) ->
969+
[| yield sys, "Int32" , v_int_tcr
970+
yield sys, "IntPtr" , v_nativeint_tcr
971+
yield sys, "UIntPtr" , v_unativeint_tcr
972+
yield sys, "Int16" , v_int16_tcr
973+
yield sys, "Int64" , v_int64_tcr
974+
yield sys, "UInt16" , v_uint16_tcr
975+
yield sys, "UInt32" , v_uint32_tcr
976+
yield sys, "UInt64" , v_uint64_tcr
977+
yield sys, "SByte" , v_sbyte_tcr
978+
yield sys, "Decimal" , v_decimal_tcr
979+
yield sys, "Byte" , v_byte_tcr
980+
yield sys, "Boolean" , v_bool_tcr
981+
yield sys, "String" , v_string_tcr
982+
yield sys, "Object" , v_obj_tcr
983+
yield sys, "Exception", v_exn_tcr
984+
yield sys, "Char" , v_char_tcr
985+
yield sys, "Double" , v_float_tcr
986+
yield sys, "Single" , v_float32_tcr
987+
if not compilingFSharpCore then
988+
yield sysGenerics, "IEnumerable`1", v_seq_tcr |]
989+
|> Array.map (fun (qualifier, nm, tcr) ->
988990
let ty = mkNonGenericTy tcr
989-
nm, findSysTyconRef sys nm, (fun _ nullness ->
990-
match nullness with
991-
| Nullness.Known NullnessInfo.WithoutNull -> ty
992-
| _ -> mkNonGenericTyWithNullness tcr nullness))
991+
nm, findSysTyconRef qualifier nm, (fun typars nullness ->
992+
match typars, nullness with
993+
| [], Nullness.Known NullnessInfo.WithoutNull -> ty
994+
| [], nullness -> mkNonGenericTyWithNullness tcr nullness
995+
| _ -> TType_app(tcr, typars, nullness)))
993996

994997
let decompileTyconEntries =
995998
[|

tests/FSharp.Compiler.Service.Tests/EditorTests.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,15 +130,15 @@ let ``GetMethodsAsSymbols should return all overloads of a method as FSharpSymbo
130130
yield ms.Symbol.DisplayName, extractCurriedParams ms ]
131131
|> List.sortBy (fun (_name, parameters) -> parameters.Length, (parameters |> List.map snd ))
132132
let expected =
133-
[("Concat", [("values", "Collections.Generic.IEnumerable<'T>")]);
134-
("Concat", [("values", "Collections.Generic.IEnumerable<string>")]);
133+
[("Concat", [("values", "'T seq")]);
135134
#if NETCOREAPP
136135
("Concat", [("args", "ReadOnlySpan<obj>")]);
137136
("Concat", [("values", "ReadOnlySpan<string>")]);
138137
#endif
139138
("Concat", [("arg0", "obj")]);
140139
("Concat", [("args", "obj array")]);
141-
("Concat", [("values", "string array")]);
140+
("Concat", [("values", "string array")])
141+
("Concat", [("values", "string seq")])
142142
#if NETCOREAPP
143143
("Concat", [("str0", "ReadOnlySpan<char>");("str1", "ReadOnlySpan<char>")]);
144144
#endif

tests/FSharp.Compiler.Service.Tests/ProjectAnalysisTests.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3216,7 +3216,7 @@ let ``Test Project22 IList contents`` () =
32163216
set [ for x in ilistTypeDefn.AllInterfaces -> x.TypeDefinition.DisplayName, attribsOfSymbol x.TypeDefinition ]
32173217
|> shouldEqual
32183218
(set [("IList", ["interface"]); ("ICollection", ["interface"]);
3219-
("IEnumerable", ["interface"]); ("IEnumerable", ["interface"])])
3219+
("IEnumerable", ["interface"]); ("seq", ["abbrev"])])
32203220

32213221
arrayTypes |> shouldEqual [|("[]", 1); ("[,,]", 3)|]
32223222

tests/FSharp.Compiler.Service.Tests/Symbols.fs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,20 @@ let f2 b1 b2 b3 b4 b5 =
521521
let ``Nullable types`` declaredType formattedType =
522522
let _, checkResults = getParseAndCheckResults $"""
523523
let f (x: {declaredType}) = ()
524+
"""
525+
let symbolUse = findSymbolUseByName "x" checkResults
526+
let symbol = symbolUse.Symbol :?> FSharpMemberOrFunctionOrValue
527+
let typeArg = symbol.FullType
528+
typeArg.Format(symbolUse.DisplayContext) |> shouldEqual formattedType
529+
530+
[<Theory>]
531+
[<InlineData("let x: IEnumerable<int> = []", "IEnumerable<int>")>]
532+
[<InlineData("let x = [1].AsEnumerable()", "int seq")>]
533+
let ``Format IEnumerable`` code formattedType =
534+
let _, checkResults = getParseAndCheckResults $"""
535+
open System.Collections.Generic
536+
open System.Linq
537+
{code}
524538
"""
525539
let symbolUse = findSymbolUseByName "x" checkResults
526540
let symbol = symbolUse.Symbol :?> FSharpMemberOrFunctionOrValue

vsintegration/tests/FSharp.Editor.Tests/QuickInfoProviderTests.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ let res8 = abs 5.0<kg>
226226
[
227227
mkDesc
228228
"GroupBy"
229-
"(extension) System.Collections.Generic.IEnumerable.GroupBy<'TSource,'TKey>(keySelector: System.Func<'TSource,'TKey>) : System.Collections.Generic.IEnumerable<IGrouping<'TKey,'TSource>>
229+
"(extension) System.Collections.Generic.IEnumerable.GroupBy<'TSource,'TKey>(keySelector: System.Func<'TSource,'TKey>) : IGrouping<'TKey,'TSource> seq
230230
'TSource is int * string
231231
'TKey is int"
232232
mkDesc

vsintegration/tests/FSharp.Editor.Tests/Refactors/AddReturnTypeTests.fs

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ let ``Binding linq function doesnt crash`` () =
298298
let code =
299299
$"""
300300
let skip1 elements =
301-
System.Linq.Enumerable.Skip(elements, 1)
301+
System.Linq.Enumerable.Skip(elements, 1).GetEnumerator()
302302
"""
303303

304304
use context = TestContext.CreateWithCode code
@@ -309,8 +309,8 @@ let skip1 elements =
309309

310310
let expectedCode =
311311
$"""
312-
let skip1 elements : System.Collections.Generic.IEnumerable<'a> =
313-
System.Linq.Enumerable.Skip(elements, 1)
312+
let skip1 elements : System.Collections.Generic.IEnumerator<'a> =
313+
System.Linq.Enumerable.Skip(elements, 1).GetEnumerator()
314314
"""
315315

316316
let resultText = newDoc.GetTextAsync() |> GetTaskResult
@@ -325,7 +325,7 @@ let ``Handle already existing opens on Linq`` () =
325325
open System
326326
327327
let skip1 elements =
328-
Linq.Enumerable.Skip(elements, 1)
328+
Linq.Enumerable.Skip(elements, 1).GetEnumerator()
329329
"""
330330

331331
use context = TestContext.CreateWithCode code
@@ -338,8 +338,8 @@ let skip1 elements =
338338
$"""
339339
open System
340340
341-
let skip1 elements : Collections.Generic.IEnumerable<'a> =
342-
Linq.Enumerable.Skip(elements, 1)
341+
let skip1 elements : Collections.Generic.IEnumerator<'a> =
342+
Linq.Enumerable.Skip(elements, 1).GetEnumerator()
343343
"""
344344

345345
let resultText = newDoc.GetTextAsync() |> GetTaskResult
@@ -355,7 +355,7 @@ open System
355355
open System.Linq
356356
357357
let skip1 elements =
358-
Enumerable.Skip(elements, 1)
358+
Enumerable.Skip(elements, 1).GetEnumerator()
359359
"""
360360

361361
use context = TestContext.CreateWithCode code
@@ -369,8 +369,37 @@ let skip1 elements =
369369
open System
370370
open System.Linq
371371
372-
let skip1 elements : Collections.Generic.IEnumerable<'a> =
373-
Enumerable.Skip(elements, 1)
372+
let skip1 elements : Collections.Generic.IEnumerator<'a> =
373+
Enumerable.Skip(elements, 1).GetEnumerator()
374+
"""
375+
376+
let resultText = newDoc.GetTextAsync() |> GetTaskResult
377+
Assert.Equal(expectedCode, resultText.ToString())
378+
379+
[<Fact>]
380+
let ``Handle seq`` () =
381+
let symbolName = "skip1"
382+
383+
let code =
384+
$"""
385+
open System
386+
387+
let skip1 elements =
388+
Linq.Enumerable.Skip(elements, 1)
389+
"""
390+
391+
use context = TestContext.CreateWithCode code
392+
393+
let spanStart = code.IndexOf symbolName
394+
395+
let newDoc = tryRefactor code spanStart context (new AddReturnType())
396+
397+
let expectedCode =
398+
$"""
399+
open System
400+
401+
let skip1 elements : 'a seq =
402+
Linq.Enumerable.Skip(elements, 1)
374403
"""
375404

376405
let resultText = newDoc.GetTextAsync() |> GetTaskResult

0 commit comments

Comments
 (0)