Fix pretty print error for pointer type (#15207)

* Fix by casting Void* to nativeint

Special-case for System.Reflection.Pointer

* Add test

Modifies test framework to add stdout to `runFsi`

---------

Co-authored-by: Adam Boniecki <adboniec@microsoft.com>
This commit is contained in:
Adam Boniecki 2023-05-19 20:11:55 +02:00 коммит произвёл GitHub
Родитель 40178e3cc0
Коммит b456cecba8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 34 добавлений и 7 удалений

Просмотреть файл

@ -6,6 +6,7 @@ module FSharp.Compiler.Interactive.Shell
#nowarn "57"
#nowarn "55"
#nowarn "9"
[<assembly: System.Runtime.InteropServices.ComVisible(false)>]
[<assembly: System.CLSCompliant(true)>]
@ -102,9 +103,25 @@ module internal Utilities =
member _.FsiAnyToLayout(options, o: obj, ty: Type) =
Display.fsi_any_to_layout options ((Unchecked.unbox o: 'T), ty)
let getAnyToLayoutCall ty =
let specialized = typedefof<AnyToLayoutSpecialization<_>>.MakeGenericType [| ty |]
Activator.CreateInstance(specialized) :?> IAnyToLayoutCall
let getAnyToLayoutCall (ty: Type) =
if ty.IsPointer then
let pointerToNativeInt (o: obj) : nativeint =
System.Reflection.Pointer.Unbox o
|> NativeInterop.NativePtr.ofVoidPtr<nativeptr<byte>>
|> NativeInterop.NativePtr.toNativeInt
{ new IAnyToLayoutCall with
member _.AnyToLayout(options, o: obj, ty: Type) =
let n = pointerToNativeInt o
Display.any_to_layout options (n, n.GetType())
member _.FsiAnyToLayout(options, o: obj, ty: Type) =
let n = pointerToNativeInt o
Display.any_to_layout options (n, n.GetType())
}
else
let specialized = typedefof<AnyToLayoutSpecialization<_>>.MakeGenericType [| ty |]
Activator.CreateInstance(specialized) :?> IAnyToLayoutCall
let callStaticMethod (ty: Type) name args =
ty.InvokeMember(

Просмотреть файл

@ -15,6 +15,13 @@ module ``Interactive tests`` =
|> withEvalTypeEquals typeof<int>
|> withEvalValueEquals 2
[<Fact>]
let ``Pretty print void pointer``() =
Fsx "System.IntPtr.Zero.ToPointer()"
|> runFsi
|> shouldSucceed
|> withStdOutContains "val it: voidptr = 0n"
[<Fact>]
let ``EntryPoint attribute in FSI should produce a compiler warning`` () =
Fsx "[<EntryPoint>] let myFunc _ = 0"

Просмотреть файл

@ -962,15 +962,18 @@ module rec Compiler =
opts.Add($"-I:\"{(outputDirectory.Value.FullName)}\"")
| _ -> ()
opts.ToArray()
let errors = CompilerAssert.RunScriptWithOptionsAndReturnResult options source
let errors, stdOut = CompilerAssert.RunScriptWithOptionsAndReturnResult options source
let executionOutputwithStdOut: RunOutput option =
ExecutionOutput { StdOut = stdOut; ExitCode = 0; StdErr = "" }
|> Some
let result =
{ OutputPath = None
Dependencies = []
Adjust = 0
Diagnostics = []
PerFileErrors= []
Output = None
Output = executionOutputwithStdOut
Compilation = cUnit }
if errors.Count > 0 then

Просмотреть файл

@ -940,10 +940,10 @@ Updated automatically, please check diffs in your pull request, changes must be
| Choice2Of2 ex -> errorMessages.Add(ex.Message)
| _ -> ()
errorMessages
errorMessages, outStream.ToString()
static member RunScriptWithOptions options (source: string) (expectedErrorMessages: string list) =
let errorMessages = CompilerAssert.RunScriptWithOptionsAndReturnResult options source
let errorMessages, _ = CompilerAssert.RunScriptWithOptionsAndReturnResult options source
if expectedErrorMessages.Length <> errorMessages.Count then
Assert.Fail(sprintf "Expected error messages: %A \n\n Actual error messages: %A" expectedErrorMessages errorMessages)
else