Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/fsharp/PostInferenceChecks.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1543,10 +1543,12 @@ let CheckRecdField isUnion cenv env (tycon:Tycon) (rfield:RecdField) =
(not isUnion && IsHiddenRecdField env.sigToImplRemapInfo (tcref.MakeNestedRecdFieldRef rfield))
let access = AdjustAccess isHidden (fun () -> tycon.CompilationPath) rfield.Accessibility
CheckTypeForAccess cenv env (fun () -> rfield.Name) access m rfield.FormalType

if TyconRefHasAttribute g m g.attrib_IsByRefLikeAttribute tcref then
// Permit Span fields in IsByRefLike types
CheckTypePermitOuterSpanLike cenv env m rfield.FormalType
if cenv.reportErrors then
CheckForByrefType cenv env rfield.FormalType (fun () -> errorR(Error(FSComp.SR.chkCantStoreByrefValue(), tycon.Range)))
else
CheckTypeNoByrefs cenv env m rfield.FormalType
if cenv.reportErrors then
Expand Down
10 changes: 10 additions & 0 deletions tests/fsharp/typecheck/sigs/neg107.bsl
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,13 @@ neg107.fsx(53,34,53,38): typecheck error FS3234: Struct members cannot return th
neg107.fsx(67,34,67,40): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference

neg107.fsx(67,34,67,38): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference

neg107.fsx(71,19,71,20): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.

neg107.fsx(71,14,71,18): typecheck error FS0437: A type would store a byref typed value. This is not permitted by Common IL.

neg107.fsx(71,19,71,20): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.

neg107.fsx(71,19,71,20): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.

neg107.fsx(71,19,71,20): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
7 changes: 7 additions & 0 deletions tests/fsharp/typecheck/sigs/neg107.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,10 @@ namespace Test
val mutable x : TestMut1

member this.XAddr = &this.x.x // not allowed, Struct members cannot return the address of fields of the struct by reference", not entirely clear why C# disallowed this

module DisallowIsByRefLikeWithByRefField =
[<IsByRefLike;Struct>]
type Beef(x: byref<int>) =

member __.X = &x

10 changes: 10 additions & 0 deletions tests/fsharp/typecheck/sigs/neg107.vsbsl
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,13 @@ neg107.fsx(53,34,53,38): typecheck error FS3234: Struct members cannot return th
neg107.fsx(67,34,67,40): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference

neg107.fsx(67,34,67,38): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference

neg107.fsx(71,19,71,20): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.

neg107.fsx(71,14,71,18): typecheck error FS0437: A type would store a byref typed value. This is not permitted by Common IL.

neg107.fsx(71,19,71,20): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.

neg107.fsx(71,19,71,20): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.

neg107.fsx(71,19,71,20): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace Microsoft.VisualStudio.FSharp.Editor

open System
open System.ComponentModel.Composition
open Microsoft.CodeAnalysis.Editor
open Microsoft.FSharp.Compiler.SourceCodeServices
open System.Runtime.InteropServices

[<ExportBraceMatcher(FSharpConstants.FSharpLanguageName)>]
type internal FSharpBraceMatchingService
Expand All @@ -14,19 +14,21 @@ type internal FSharpBraceMatchingService
checkerProvider: FSharpCheckerProvider,
projectInfoManager: FSharpProjectOptionsManager
) =


static let defaultUserOpName = "BraceMatching"

static member GetBraceMatchingResult(checker: FSharpChecker, sourceText, fileName, parsingOptions: FSharpParsingOptions, position: int, userOpName: string) =
static member GetBraceMatchingResult(checker: FSharpChecker, sourceText, fileName, parsingOptions: FSharpParsingOptions, position: int, userOpName: string, [<Optional; DefaultParameterValue(false)>] forFormatting: bool) =
async {
let! matchedBraces = checker.MatchBraces(fileName, sourceText.ToString(), parsingOptions, userOpName)
let isPositionInRange range =
match RoslynHelpers.TryFSharpRangeToTextSpan(sourceText, range) with
| None -> false
| Some range ->
let length = position - range.Start
length >= 0 && length <= range.Length
| Some span ->
if forFormatting then
let length = position - span.Start
length >= 0 && length <= span.Length
else
span.Contains position
return matchedBraces |> Array.tryFind(fun (left, right) -> isPositionInRange left || isPositionInRange right)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type internal FSharpEditorFormattingService
x.Tag <> FSharpTokenTag.LINE_COMMENT)

let! (left, right) =
FSharpBraceMatchingService.GetBraceMatchingResult(checker, sourceText, filePath, parsingOptions, position, "FormattingService")
FSharpBraceMatchingService.GetBraceMatchingResult(checker, sourceText, filePath, parsingOptions, position, "FormattingService", forFormatting=true)

if right.StartColumn = firstMeaningfulToken.LeftColumn then
// Replace the indentation on this line with the indentation of the left bracket
Expand Down
25 changes: 11 additions & 14 deletions vsintegration/tests/UnitTests/BraceMatchingServiceTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -161,26 +161,23 @@ let main argv =
0 // return an integer exit code"""
this.VerifyBraceMatch(code, "(printfn", ")endBrace")

[<TestCase ("let a1 = [ 0 .. 100 ]", [|9;10;20;21|])>]
[<TestCase ("let a2 = [| 0 .. 100 |]", [|9;10;11;21;22;23|])>]
[<TestCase ("let a3 = <@ 0 @>", [|9;10;11;14;15;16|])>]
[<TestCase ("let a4 = <@@ 0 @@>", [|9;10;11;12;15;15;16;17|])>]
[<TestCase ("let a6 = ( () )", [|9;10;16;17|])>]
[<TestCase ("[<ReflectedDefinition>]\nlet a7 = 70", [|0;1;2;21;22;23|])>]
[<TestCase ("let a8 = seq { yield() }", [|13;14;23;24|])>]
member this.BraceMatchingBothSides_Bug2092(fileContents: string, matchingPositions: int[]) =
// https://github.com/Microsoft/visualfsharp/issues/2092
[<TestCase ("let a1 = [ 0 .. 100 ]", [|9;20|])>]
[<TestCase ("let a2 = [| 0 .. 100 |]", [|9;10;22|])>]
[<TestCase ("let a3 = <@ 0 @>", [|9;10;15|])>]
[<TestCase ("let a4 = <@@ 0 @@>", [|9;10;11;15;16|])>]
[<TestCase ("let a6 = ( () )", [|9;16|])>]
[<TestCase ("[<ReflectedDefinition>]\nlet a7 = 70", [|0;1;22|])>]
[<TestCase ("let a8 = seq { yield() }", [|13;23|])>]
member this.DoNotMatchOnInnerSide(fileContents: string, matchingPositions: int[]) =
let sourceText = SourceText.From(fileContents)

let parsingOptions, _ = checker.GetParsingOptionsFromProjectOptions projectOptions
matchingPositions
|> Array.iter (fun position ->

for position in matchingPositions do
match FSharpBraceMatchingService.GetBraceMatchingResult(checker, sourceText, fileName, parsingOptions, position, "UnitTest") |> Async.RunSynchronously with
| Some _ -> ()
| None ->
match position with
| 0 -> ""
| _ -> fileContents.[position - 1] |> sprintf " (previous character '%c')"
|> sprintf "Didn't find a matching brace at position '%d', character '%c'%s" position fileContents.[position]
|> sprintf "Didn't find a matching brace at position '%d' %s" position
|> Assert.Fail
)
4 changes: 3 additions & 1 deletion vsintegration/tests/UnitTests/IndentationServiceTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ while true do
|> Array.map (fun (lineNumber, expectedIndentation) ->
( Some(expectedIndentation), lineNumber, autoIndentTemplate ))

[<Test>]
member this.TestIndentation() =
for (expectedIndentation, lineNumber, template) in testCases do
let sourceText = SourceText.From(template)
Expand All @@ -179,7 +180,8 @@ while true do
match expectedIndentation with
| None -> Assert.IsTrue(actualIndentation.IsNone, "No indentation was expected at line {0}", lineNumber)
| Some indentation -> Assert.AreEqual(expectedIndentation.Value, actualIndentation.Value, "Indentation on line {0} doesn't match", lineNumber)


[<Test>]
member this.TestAutoIndentation() =
for (expectedIndentation, lineNumber, template) in autoIndentTestCases do

Expand Down