Skip to content

Commit d51f910

Browse files
authored
Merge branch 'dev16.0' into suggested-names-optional
2 parents c93c9e2 + 7b73f62 commit d51f910

File tree

11 files changed

+136
-74
lines changed

11 files changed

+136
-74
lines changed

src/fsharp/ConstraintSolver.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1886,7 +1886,7 @@ and SolveTypeIsNonNullableValueType (csenv:ConstraintSolverEnv) ndeep m2 trace t
18861886
| _ ->
18871887
let underlyingTy = stripTyEqnsAndMeasureEqns g ty
18881888
if isStructTy g underlyingTy then
1889-
if tyconRefEq g g.system_Nullable_tcref (tcrefOfAppTy g underlyingTy) then
1889+
if isAppTy g underlyingTy && tyconRefEq g g.system_Nullable_tcref (tcrefOfAppTy g underlyingTy) then
18901890
return! ErrorD (ConstraintSolverError(FSComp.SR.csTypeParameterCannotBeNullable(), m, m))
18911891
else
18921892
return! ErrorD (ConstraintSolverError(FSComp.SR.csGenericConstructRequiresStructType(NicePrint.minimalStringOfType denv ty), m, m2))

src/fsharp/Optimizer.fs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,16 +1763,23 @@ let TryDetectQueryQuoteAndRun cenv (expr:Expr) =
17631763
| _ ->
17641764
//printfn "Not eliminating because no Run found"
17651765
None
1766+
1767+
let IsILMethodRefDeclaringTypeSystemString (ilg: ILGlobals) (mref: ILMethodRef) =
1768+
mref.DeclaringTypeRef.Scope.IsAssemblyRef &&
1769+
mref.DeclaringTypeRef.Scope.AssemblyRef.Name = ilg.typ_String.TypeRef.Scope.AssemblyRef.Name &&
1770+
mref.DeclaringTypeRef.BasicQualifiedName = ilg.typ_String.BasicQualifiedName
17661771

1767-
let IsSystemStringConcatOverload (methRef: ILMethodRef) =
1768-
methRef.Name = "Concat" && methRef.DeclaringTypeRef.FullName = "System.String" &&
1769-
methRef.ReturnType.BasicQualifiedName = "System.String" &&
1770-
methRef.ArgTypes |> List.forall(fun ilty -> ilty.BasicQualifiedName = "System.String")
1771-
1772-
let IsSystemStringConcatArray (methRef: ILMethodRef) =
1773-
methRef.Name = "Concat" && methRef.DeclaringTypeRef.FullName = "System.String" &&
1774-
methRef.ReturnType.BasicQualifiedName = "System.String" &&
1775-
methRef.ArgTypes.Length = 1 && methRef.ArgTypes.Head.BasicQualifiedName = "System.String[]"
1772+
let IsILMethodRefSystemStringConcatOverload (ilg: ILGlobals) (mref: ILMethodRef) =
1773+
IsILMethodRefDeclaringTypeSystemString ilg mref &&
1774+
mref.Name = "Concat" &&
1775+
mref.ReturnType.BasicQualifiedName = ilg.typ_String.BasicQualifiedName &&
1776+
mref.ArgCount >= 2 && mref.ArgCount <= 4 && mref.ArgTypes |> List.forall(fun ilty -> ilty.BasicQualifiedName = ilg.typ_String.BasicQualifiedName)
1777+
1778+
let IsILMethodRefSystemStringConcatArray (ilg: ILGlobals) (mref: ILMethodRef) =
1779+
IsILMethodRefDeclaringTypeSystemString ilg mref &&
1780+
mref.Name = "Concat" &&
1781+
mref.ReturnType.BasicQualifiedName = ilg.typ_String.BasicQualifiedName &&
1782+
mref.ArgCount = 1 && mref.ArgTypes.Head.BasicQualifiedName = "System.String[]"
17761783

17771784
//-------------------------------------------------------------------------
17781785
// The traversal
@@ -1887,10 +1894,10 @@ and OptimizeInterfaceImpl cenv env baseValOpt (ty, overrides) =
18871894
and MakeOptimizedSystemStringConcatCall cenv env m args =
18881895
let rec optimizeArg e accArgs =
18891896
match e, accArgs with
1890-
| Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, methRef, _, _, _), _, [ Expr.Op(TOp.Array, _, args, _) ], _), _ when IsSystemStringConcatArray methRef ->
1897+
| Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, mref, _, _, _), _, [ Expr.Op(TOp.Array, _, args, _) ], _), _ when IsILMethodRefSystemStringConcatArray cenv.g.ilg mref ->
18911898
optimizeArgs args accArgs
18921899

1893-
| Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, methRef, _, _, _), _, args, _), _ when IsSystemStringConcatOverload methRef ->
1900+
| Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, mref, _, _, _), _, args, _), _ when IsILMethodRefSystemStringConcatOverload cenv.g.ilg mref ->
18941901
optimizeArgs args accArgs
18951902

18961903
// Optimize string constants, e.g. "1" + "2" will turn into "12"
@@ -1920,7 +1927,7 @@ and MakeOptimizedSystemStringConcatCall cenv env m args =
19201927
mkStaticCall_String_Concat_Array cenv.g m arg
19211928

19221929
match e with
1923-
| Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, methRef, _, _, _) as op, tyargs, args, m) when IsSystemStringConcatOverload methRef || IsSystemStringConcatArray methRef ->
1930+
| Expr.Op(TOp.ILCall(_, _, _, _, _, _, _, mref, _, _, _) as op, tyargs, args, m) when IsILMethodRefSystemStringConcatOverload cenv.g.ilg mref || IsILMethodRefSystemStringConcatArray cenv.g.ilg mref ->
19241931
OptimizeExprOpReductions cenv env (op, tyargs, args, m)
19251932
| _ ->
19261933
OptimizeExpr cenv env e
@@ -1993,9 +2000,9 @@ and OptimizeExprOp cenv env (op, tyargs, args, m) =
19932000
| TOp.ILAsm([], [ty]), _, [a] when typeEquiv cenv.g (tyOfExpr cenv.g a) ty -> OptimizeExpr cenv env a
19942001

19952002
// Optimize calls when concatenating strings, e.g. "1" + "2" + "3" + "4" .. etc.
1996-
| TOp.ILCall(_, _, _, _, _, _, _, methRef, _, _, _), _, [ Expr.Op(TOp.Array, _, args, _) ] when IsSystemStringConcatArray methRef ->
2003+
| TOp.ILCall(_, _, _, _, _, _, _, mref, _, _, _), _, [ Expr.Op(TOp.Array, _, args, _) ] when IsILMethodRefSystemStringConcatArray cenv.g.ilg mref ->
19972004
MakeOptimizedSystemStringConcatCall cenv env m args
1998-
| TOp.ILCall(_, _, _, _, _, _, _, methRef, _, _, _), _, args when IsSystemStringConcatOverload methRef ->
2005+
| TOp.ILCall(_, _, _, _, _, _, _, mref, _, _, _), _, args when IsILMethodRefSystemStringConcatOverload cenv.g.ilg mref ->
19992006
MakeOptimizedSystemStringConcatCall cenv env m args
20002007

20012008
| _ ->

src/fsharp/service/service.fs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,17 +2189,17 @@ module Helpers =
21892189
&& FSharpProjectOptions.UseSameProject(o1,o2)
21902190

21912191
/// Determine whether two (fileName,sourceText,options) keys should be identical w.r.t. parsing
2192-
let AreSameForParsing((fileName1: string, source1: ISourceText, options1), (fileName2, source2, options2)) =
2193-
fileName1 = fileName2 && options1 = options2 && source1.ContentEquals(source2)
2192+
let AreSameForParsing((fileName1: string, source1Hash: int, options1), (fileName2, source2Hash, options2)) =
2193+
fileName1 = fileName2 && options1 = options2 && source1Hash = source2Hash
21942194

21952195
let AreSimilarForParsing((fileName1, _, _), (fileName2, _, _)) =
21962196
fileName1 = fileName2
21972197

21982198
/// Determine whether two (fileName,sourceText,options) keys should be identical w.r.t. checking
2199-
let AreSameForChecking3((fileName1: string, source1: ISourceText, options1: FSharpProjectOptions), (fileName2, source2, options2)) =
2199+
let AreSameForChecking3((fileName1: string, source1Hash: int, options1: FSharpProjectOptions), (fileName2, source2Hash, options2)) =
22002200
(fileName1 = fileName2)
22012201
&& FSharpProjectOptions.AreSameForChecking(options1,options2)
2202-
&& source1.ContentEquals(source2)
2202+
&& source1Hash = source2Hash
22032203

22042204
/// Determine whether two (fileName,sourceText,options) keys should be identical w.r.t. resource usage
22052205
let AreSubsumable3((fileName1:string,_,o1:FSharpProjectOptions),(fileName2:string,_,o2:FSharpProjectOptions)) =
@@ -2315,7 +2315,7 @@ module CompileHelpers =
23152315
System.Console.SetError error
23162316
| None -> ()
23172317

2318-
2318+
type SourceTextHash = int
23192319
type FileName = string
23202320
type FilePath = string
23212321
type ProjectPath = string
@@ -2461,7 +2461,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
24612461

24622462
// Also keyed on source. This can only be out of date if the antecedent is out of date
24632463
let checkFileInProjectCache =
2464-
MruCache<ParseCacheLockToken,FileName * ISourceText * FSharpProjectOptions, FSharpParseFileResults * FSharpCheckFileResults * FileVersion * DateTime>
2464+
MruCache<ParseCacheLockToken,FileName * SourceTextHash * FSharpProjectOptions, FSharpParseFileResults * FSharpCheckFileResults * FileVersion * DateTime>
24652465
(keepStrongly=checkFileInProjectCacheSize,
24662466
areSame=AreSameForChecking3,
24672467
areSimilar=AreSubsumable3)
@@ -2512,13 +2512,14 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
25122512

25132513
member bc.ParseFile(filename: string, sourceText: ISourceText, options: FSharpParsingOptions, userOpName: string) =
25142514
async {
2515-
match parseCacheLock.AcquireLock(fun ltok -> parseFileCache.TryGet(ltok, (filename, sourceText, options))) with
2515+
let hash = sourceText.GetHashCode()
2516+
match parseCacheLock.AcquireLock(fun ltok -> parseFileCache.TryGet(ltok, (filename, hash, options))) with
25162517
| Some res -> return res
25172518
| None ->
25182519
foregroundParseCount <- foregroundParseCount + 1
25192520
let parseErrors, parseTreeOpt, anyErrors = Parser.parseFile(sourceText, filename, options, userOpName, suggestNamesForErrors)
25202521
let res = FSharpParseFileResults(parseErrors, parseTreeOpt, anyErrors, options.SourceFiles)
2521-
parseCacheLock.AcquireLock(fun ltok -> parseFileCache.Set(ltok, (filename, sourceText, options), res))
2522+
parseCacheLock.AcquireLock(fun ltok -> parseFileCache.Set(ltok, (filename, hash, options), res))
25222523
return res
25232524
}
25242525

@@ -2537,9 +2538,9 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
25372538
}
25382539
)
25392540

2540-
member bc.GetCachedCheckFileResult(builder: IncrementalBuilder,filename,sourceText,options) =
2541+
member bc.GetCachedCheckFileResult(builder: IncrementalBuilder,filename,sourceText: ISourceText,options) =
25412542
// Check the cache. We can only use cached results when there is no work to do to bring the background builder up-to-date
2542-
let cachedResults = parseCacheLock.AcquireLock (fun ltok -> checkFileInProjectCache.TryGet(ltok, (filename,sourceText,options)))
2543+
let cachedResults = parseCacheLock.AcquireLock (fun ltok -> checkFileInProjectCache.TryGet(ltok, (filename,sourceText.GetHashCode(),options)))
25432544

25442545
match cachedResults with
25452546
// | Some (parseResults, checkResults, _, _) when builder.AreCheckResultsBeforeFileInProjectReady(filename) ->
@@ -2599,7 +2600,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
25992600
tcPrior.TcState, loadClosure, tcPrior.TcErrors, reactorOps, (fun () -> builder.IsAlive), textSnapshotInfo, userOpName, suggestNamesForErrors)
26002601
let parsingOptions = FSharpParsingOptions.FromTcConfig(tcPrior.TcConfig, Array.ofList builder.SourceFiles, options.UseScriptResolutionRules)
26012602
let checkAnswer = MakeCheckFileAnswer(fileName, tcFileResult, options, builder, Array.ofList tcPrior.TcDependencyFiles, creationErrors, parseResults.Errors, tcErrors)
2602-
bc.RecordTypeCheckFileInProjectResults(fileName, options, parsingOptions, parseResults, fileVersion, tcPrior.TimeStamp, Some checkAnswer, sourceText)
2603+
bc.RecordTypeCheckFileInProjectResults(fileName, options, parsingOptions, parseResults, fileVersion, tcPrior.TimeStamp, Some checkAnswer, sourceText.GetHashCode())
26032604
return checkAnswer
26042605
finally
26052606
let dummy = ref ()
@@ -2615,7 +2616,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
26152616
}
26162617

26172618
/// Type-check the result obtained by parsing, but only if the antecedent type checking context is available.
2618-
member bc.CheckFileInProjectAllowingStaleCachedResults(parseResults: FSharpParseFileResults, filename, fileVersion, sourceText, options, textSnapshotInfo: obj option, userOpName) =
2619+
member bc.CheckFileInProjectAllowingStaleCachedResults(parseResults: FSharpParseFileResults, filename, fileVersion, sourceText: ISourceText, options, textSnapshotInfo: obj option, userOpName) =
26192620
let execWithReactorAsync action = reactor.EnqueueAndAwaitOpAsync(userOpName, "CheckFileInProjectAllowingStaleCachedResults ", filename, action)
26202621
async {
26212622
try
@@ -2658,7 +2659,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
26582659
}
26592660

26602661
/// Type-check the result obtained by parsing. Force the evaluation of the antecedent type checking context if needed.
2661-
member bc.CheckFileInProject(parseResults: FSharpParseFileResults, filename, fileVersion, sourceText, options, textSnapshotInfo, userOpName) =
2662+
member bc.CheckFileInProject(parseResults: FSharpParseFileResults, filename, fileVersion, sourceText: ISourceText, options, textSnapshotInfo, userOpName) =
26622663
let execWithReactorAsync action = reactor.EnqueueAndAwaitOpAsync(userOpName, "CheckFileInProject", filename, action)
26632664
async {
26642665
try
@@ -2686,7 +2687,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
26862687
}
26872688

26882689
/// Parses and checks the source file and returns untyped AST and check results.
2689-
member bc.ParseAndCheckFileInProject (filename:string, fileVersion, sourceText, options:FSharpProjectOptions, textSnapshotInfo, userOpName) =
2690+
member bc.ParseAndCheckFileInProject (filename:string, fileVersion, sourceText: ISourceText, options:FSharpProjectOptions, textSnapshotInfo, userOpName) =
26902691
let execWithReactorAsync action = reactor.EnqueueAndAwaitOpAsync(userOpName, "ParseAndCheckFileInProject", filename, action)
26912692
async {
26922693
try
@@ -2773,7 +2774,7 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC
27732774
match sourceText with
27742775
| Some sourceText ->
27752776
parseCacheLock.AcquireLock (fun ltok ->
2776-
match checkFileInProjectCache.TryGet(ltok,(filename,sourceText,options)) with
2777+
match checkFileInProjectCache.TryGet(ltok,(filename,sourceText.GetHashCode(),options)) with
27772778
| Some (a,b,c,_) -> Some (a,b,c)
27782779
| None -> parseCacheLock.AcquireLock (fun ltok -> checkFileInProjectCachePossiblyStale.TryGet(ltok,(filename,options))))
27792780
| None -> parseCacheLock.AcquireLock (fun ltok -> checkFileInProjectCachePossiblyStale.TryGet(ltok,(filename,options)))
@@ -3010,14 +3011,15 @@ type FSharpChecker(legacyReferenceResolver, projectCacheSize, keepAssemblyConten
30103011

30113012
member ic.ReferenceResolver = legacyReferenceResolver
30123013

3013-
member ic.MatchBraces(filename, sourceText, options: FSharpParsingOptions, ?userOpName: string) =
3014+
member ic.MatchBraces(filename, sourceText: ISourceText, options: FSharpParsingOptions, ?userOpName: string) =
30143015
let userOpName = defaultArg userOpName "Unknown"
3016+
let hash = sourceText.GetHashCode()
30153017
async {
3016-
match braceMatchCache.TryGet(AssumeAnyCallerThreadWithoutEvidence(), (filename, sourceText, options)) with
3018+
match braceMatchCache.TryGet(AssumeAnyCallerThreadWithoutEvidence(), (filename, hash, options)) with
30173019
| Some res -> return res
30183020
| None ->
30193021
let res = Parser.matchBraces(sourceText, filename, options, userOpName, suggestNamesForErrors)
3020-
braceMatchCache.Set(AssumeAnyCallerThreadWithoutEvidence(), (filename, sourceText, options), res)
3022+
braceMatchCache.Set(AssumeAnyCallerThreadWithoutEvidence(), (filename, hash, options), res)
30213023
return res
30223024
}
30233025

src/utils/CompilerLocationUtils.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ open System.Runtime.InteropServices
1212
module internal FSharpEnvironment =
1313

1414
/// The F# version reported in the banner
15-
let FSharpBannerVersion = "10.4.0 for F# 4.5"
15+
let FSharpBannerVersion = "10.4.0 for F# 4.6"
1616

1717
let versionOf<'t> =
1818
#if FX_RESHAPED_REFLECTION

src/utils/prim-lexing.fs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type ISourceText =
2525

2626
abstract ContentEquals : sourceText: ISourceText -> bool
2727

28-
abstract CopyTo : sourceIndex: int * destination: char [] * destinationIndex: int * count: int -> unit
28+
abstract CopyTo : sourceIndex: int * destination: char [] * destinationIndex: int * count: int -> unit
2929

3030
[<Sealed>]
3131
type StringText(str: string) =
@@ -50,6 +50,9 @@ type StringText(str: string) =
5050
lazy getLines str
5151

5252
member __.String = str
53+
54+
override __.GetHashCode() = str.GetHashCode()
55+
override __.Equals(obj: obj) = str.Equals(obj)
5356

5457
interface ISourceText with
5558

src/utils/prim-lexing.fsi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ type ISourceText =
2323

2424
abstract ContentEquals : sourceText: ISourceText -> bool
2525

26-
abstract CopyTo : sourceIndex: int * destination: char [] * destinationIndex: int * count: int -> unit
26+
abstract CopyTo : sourceIndex: int * destination: char [] * destinationIndex: int * count: int -> unit
2727

2828
module SourceText =
2929

tests/fsharp/tests.fs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,6 +1985,12 @@ module TypecheckTests =
19851985
fsc cfg "%s --target:exe -o:pos31.exe --warnaserror" cfg.fsc_flags ["pos31.fsi"; "pos31.fs"]
19861986
peverify cfg "pos31.exe"
19871987

1988+
[<Test>]
1989+
let ``sigs pos32`` () =
1990+
let cfg = testConfig "typecheck/sigs"
1991+
fsc cfg "%s --target:library -o:pos32.dll --warnaserror" cfg.fsc_flags ["pos32.fs"]
1992+
peverify cfg "pos32.dll"
1993+
19881994
[<Test>]
19891995
let ``sigs pos23`` () =
19901996
let cfg = testConfig "typecheck/sigs"
@@ -2470,6 +2476,9 @@ module TypecheckTests =
24702476
[<Test>]
24712477
let ``type check neg114`` () = singleNegTest (testConfig "typecheck/sigs") "neg114"
24722478

2479+
[<Test>]
2480+
let ``type check neg115`` () = singleNegTest (testConfig "typecheck/sigs") "neg115"
2481+
24732482
[<Test>]
24742483
let ``type check neg_anon_1`` () = singleNegTest (testConfig "typecheck/sigs") "neg_anon_1"
24752484

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
neg115.fs(8,30,8,34): typecheck error FS0001: Expecting a type supporting the operator 'get_Item1' but given a tuple type
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
module M
3+
4+
let inline test (arg: ^T when ^T : struct) =
5+
(^T : (member Item1: _) (arg))
6+
7+
let f () =
8+
let a = test struct (1, 2)
9+
()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module Pos32
2+
3+
let inline test (arg: ^T when ^T : struct) =
4+
()
5+
6+
let f () =
7+
let a = test struct (1, 2)
8+
()
9+

0 commit comments

Comments
 (0)