Skip to content

Commit ccdd09c

Browse files
authored
Merge pull request #16465 from dotnet/merges/main-to-release/dev17.9
Merge main to release/dev17.9
2 parents 0c48954 + 2440528 commit ccdd09c

File tree

119 files changed

+1675
-841
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+1675
-841
lines changed
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
### Fixed
22

3-
* Miscellaneous fixes to parentheses analysis. ([PR #16262](https://github.com/dotnet/fsharp/pull/16262), [PR #16391](https://github.com/dotnet/fsharp/pull/16391), [PR #16370](https://github.com/dotnet/fsharp/pull/16370), [PR #16395](https://github.com/dotnet/fsharp/pull/16395))
3+
* Miscellaneous fixes to parentheses analysis. ([PR #16262](https://github.com/dotnet/fsharp/pull/16262), [PR #16391](https://github.com/dotnet/fsharp/pull/16391), [PR #16370](https://github.com/dotnet/fsharp/pull/16370), [PR #16395](https://github.com/dotnet/fsharp/pull/16395), [PR #16372](https://github.com/dotnet/fsharp/pull/16372))
44
* Correctly handle assembly imports with public key token of 0 length. ([Issue #16359](https://github.com/dotnet/fsharp/issues/16359), [PR #16363](https://github.com/dotnet/fsharp/pull/16363))
5+
* Range of [SynField](../reference/fsharp-compiler-syntax-synfield.html) ([PR #16357](https://github.com/dotnet/fsharp/pull/16357))
6+
* Limit a type to 65K methods, introduce a compile-time error if any class has over approx 64K methods in generated IL. ([Issue #16398](https://github.com/dotnet/fsharp/issues/16398), [#PR 16427](https://github.com/dotnet/fsharp/pull/16427))
57

68
### Added
79
* Raise a new error when interfaces with auto properties are implemented on constructor-less types. ([PR #16352](https://github.com/dotnet/fsharp/pull/16352))
810
* Allow usage of `[<TailCall>]` with older `FSharp.Core` package versions. ([PR #16373](https://github.com/dotnet/fsharp/pull/16373))
11+
* Parser recovers on unfinished `as` patterns. ([PR #16404](https://github.com/dotnet/fsharp/pull/16404))
12+
* Allow type-checking of unfinished object expressions. ([PR #16413](https://github.com/dotnet/fsharp/pull/16413))
13+
* Parser recovers on unfinished enum case declarations. ([PR #16401](https://github.com/dotnet/fsharp/pull/16401))
14+
* Parser recovers on unfinished record declarations. ([PR #16357](https://github.com/dotnet/fsharp/pull/16357))
15+
* `MutableKeyword` to [SynFieldTrivia](../reference/fsharp-compiler-syntaxtrivia-synfieldtrivia.html) ([PR #16357](https://github.com/dotnet/fsharp/pull/16357))
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
### Added
22

33
* Better generic unmanaged structs handling. ([Language suggestion #692](https://github.com/fsharp/fslang-suggestions/issues/692), [PR #12154](https://github.com/dotnet/fsharp/pull/12154))
4-
* Bidirectional F#/C# interop for 'unmanaged' constraint. ([PR #12154](https://github.com/dotnet/fsharp/pull/12154))
4+
* Bidirectional F#/C# interop for 'unmanaged' constraint. ([PR #12154](https://github.com/dotnet/fsharp/pull/12154))
5+
* Make `.Is*` discriminated union properties visible. ([Language suggestion #222](https://github.com/fsharp/fslang-suggestions/issues/222), [PR #16341](https://github.com/dotnet/fsharp/pull/16341))
6+
7+
### Fixed
8+
9+
* Allow extension methods without type attribute work for types from imported assemblies. ([PR #16368](https://github.com/dotnet/fsharp/pull/16368))

docs/release-notes/.aux/Common.fsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
#r "nuget: Markdig, 0.33.0"
1+
#i "nuget: https://api.nuget.org/v3/index.json"
2+
#r "nuget: Markdig, 0.33.0"
23
#r "nuget: FsHttp, 12.1.0"
34

45
open System.IO
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
title: Running the documentation locally
3+
category: Compiler Internals
4+
categoryindex: 200
5+
index: 999
6+
---
7+
# Running the documentation locally
8+
9+
The source of this documentation website is hosted on https://github.com/fsharp/fsharp-compiler-docs.
10+
You can follow this guide to see the results of your document changes rendered in the browser.
11+
12+
## Setup
13+
14+
`fsharp/fsharp-compiler-docs` will clone the `dotnet/fsharp` repository first to generate the documentation.
15+
You can however, easily run the documentation locally and modify the `docs` from `dotnet/fsharp`.
16+
17+
* Clone `fsharp/fsharp-compiler-docs` at the same level as your local `dotnet/fsharp` repository:
18+
19+
20+
git clone https://github.com/fsharp/fsharp-compiler-docs.git
21+
22+
23+
* Restore the `FSharp.Compiler.Service` project in `fsharp-compiler-docs`:
24+
25+
26+
cd fsharp-compiler-docs/FSharp.Compiler.Service
27+
dotnet restore
28+
29+
30+
* Restore the local tools in `fsharp-compiler-docs`:
31+
32+
33+
cd ..
34+
dotnet tool restore
35+
36+
37+
* Run the documentation tool using your `dotnet/fsharp` fork as input.
38+
39+
40+
dotnet fsdocs watch --eval --sourcefolder ../fsharp/ --input ../fsharp/docs/
41+
42+
43+
## Release notes caveat
44+
45+
The release notes pages from `docs/release-notes` are composed from the MarkDown files in subfolders.
46+
Changing any of these files, won't regenerate the served webpage. Only the changes to the `.fsx` will trigger the tool. This is a known limitation.

src/Compiler/AbstractIL/ilwrite.fs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ let emitBytesViaBuffer f = use bb = ByteBuffer.Create EmitBytesViaBufferCapacity
5050
/// Alignment and padding
5151
let align alignment n = ((n + alignment - 1) / alignment) * alignment
5252

53+
54+
/// Maximum number of methods in a dotnet type
55+
/// This differs from the spec and file formats slightly which suggests 0xfffe is the maximum
56+
/// this value was identified empirically.
57+
[<Literal>]
58+
let maximumMethodsPerDotNetType = 0xfff0
59+
5360
//---------------------------------------------------------------------
5461
// Concrete token representations etc. used in PE files
5562
//---------------------------------------------------------------------
@@ -672,8 +679,14 @@ let GetTypeNameAsElemPair cenv n =
672679
//=====================================================================
673680

674681
let rec GenTypeDefPass1 enc cenv (tdef: ILTypeDef) =
675-
ignore (cenv.typeDefs.AddUniqueEntry "type index" (fun (TdKey (_, n)) -> n) (TdKey (enc, tdef.Name)))
676-
GenTypeDefsPass1 (enc@[tdef.Name]) cenv (tdef.NestedTypes.AsList())
682+
ignore (cenv.typeDefs.AddUniqueEntry "type index" (fun (TdKey (_, n)) -> n) (TdKey (enc, tdef.Name)))
683+
684+
// Verify that the typedef contains fewer than maximumMethodsPerDotNetType
685+
let count = tdef.Methods.AsArray().Length
686+
if count > maximumMethodsPerDotNetType then
687+
errorR(Error(FSComp.SR.tooManyMethodsInDotNetTypeWritingAssembly (tdef.Name, count, maximumMethodsPerDotNetType), rangeStartup))
688+
689+
GenTypeDefsPass1 (enc@[tdef.Name]) cenv (tdef.NestedTypes.AsList())
677690

678691
and GenTypeDefsPass1 enc cenv tdefs = List.iter (GenTypeDefPass1 enc cenv) tdefs
679692

@@ -682,7 +695,8 @@ and GenTypeDefsPass1 enc cenv tdefs = List.iter (GenTypeDefPass1 enc cenv) tdefs
682695
//=====================================================================
683696

684697
let rec GetIdxForTypeDef cenv key =
685-
try cenv.typeDefs.GetTableEntry key
698+
try
699+
cenv.typeDefs.GetTableEntry key
686700
with
687701
:? KeyNotFoundException ->
688702
let (TdKey (enc, n) ) = key

src/Compiler/Checking/CheckDeclarations.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5577,7 +5577,7 @@ let CheckValueRestriction denvAtEnd infoReader rootSigOpt implFileTypePriorToSig
55775577
// for example FSharp 1.0 3661.
55785578
(match v.ValReprInfo with None -> true | Some tvi -> tvi.HasNoArgs)) then
55795579
match ftyvs with
5580-
| tp :: _ -> errorR (ValueRestriction(denvAtEnd, infoReader, false, v, tp, v.Range))
5580+
| tp :: _ -> errorR (ValueRestriction(denvAtEnd, infoReader, v, tp, v.Range))
55815581
| _ -> ()
55825582
mty.ModuleAndNamespaceDefinitions |> List.iter (fun v -> check v.ModuleOrNamespaceType)
55835583
try check implFileTypePriorToSig with RecoverableException e -> errorRecovery e m

src/Compiler/Checking/CheckExpressions.fs

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ exception UnionPatternsBindDifferentNames of range
9494

9595
exception VarBoundTwice of Ident
9696

97-
exception ValueRestriction of DisplayEnv * InfoReader * bool * Val * Typar * range
97+
exception ValueRestriction of DisplayEnv * InfoReader * Val * Typar * range
9898

9999
exception ValNotMutable of DisplayEnv * ValRef * range
100100

@@ -4076,7 +4076,8 @@ and TcConstraintWhereTyparSupportsMember cenv env newOk tpenv synSupportTys synM
40764076
let g = cenv.g
40774077
let traitInfo, tpenv = TcPseudoMemberSpec cenv newOk env synSupportTys tpenv synMemberSig m
40784078
match traitInfo with
4079-
| TTrait(objTys, ".ctor", memberFlags, argTys, returnTy, _) when memberFlags.MemberKind = SynMemberKind.Constructor ->
4079+
| TTrait(tys=objTys; memberName=".ctor"; memberFlags=memberFlags; objAndArgTys=argTys; returnTyOpt=returnTy)
4080+
when memberFlags.MemberKind = SynMemberKind.Constructor ->
40804081
match objTys, argTys with
40814082
| [ty], [] when typeEquiv g ty (GetFSharpViewOfReturnType g returnTy) ->
40824083
AddCxTypeMustSupportDefaultCtor env.DisplayEnv cenv.css m NoTrace ty
@@ -4125,7 +4126,7 @@ and TcPseudoMemberSpec cenv newOk env synTypes tpenv synMemberSig m =
41254126
let item = Item.OtherName (Some id, memberConstraintTy, None, None, id.idRange)
41264127
CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.AccessRights)
41274128

4128-
TTrait(tys, logicalCompiledName, memberFlags, argTys, returnTy, ref None), tpenv
4129+
TTrait(tys, logicalCompiledName, memberFlags, argTys, returnTy, ref None, ref None), tpenv
41294130

41304131
| _ -> error(Error(FSComp.SR.tcInvalidConstraint(), m))
41314132

@@ -7011,31 +7012,34 @@ and TcObjectExpr (cenv: cenv) env tpenv (objTy, realObjTy, argopt, binds, extraI
70117012

70127013
TcRecordConstruction cenv objTy true env tpenv None objTy fldsList mWholeExpr
70137014
else
7014-
let item = ForceRaise (ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mObjTy ad objTy)
7015+
let ctorCall, baseIdOpt, tpenv =
7016+
if isInterfaceTy g objTy then
7017+
match argopt with
7018+
| None ->
7019+
BuildObjCtorCall g mWholeExpr, None, tpenv
7020+
| Some _ ->
7021+
error(Error(FSComp.SR.tcConstructorForInterfacesDoNotTakeArguments(), mNewExpr))
7022+
else
7023+
let item = ForceRaise (ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mObjTy ad objTy)
70157024

7016-
if isFSharpObjModelTy g objTy && GetCtorShapeCounter env = 1 then
7017-
error(Error(FSComp.SR.tcObjectsMustBeInitializedWithObjectExpression(), mNewExpr))
7025+
if isFSharpObjModelTy g objTy && GetCtorShapeCounter env = 1 then
7026+
error(Error(FSComp.SR.tcObjectsMustBeInitializedWithObjectExpression(), mNewExpr))
70187027

7019-
let ctorCall, baseIdOpt, tpenv =
7020-
match item, argopt with
7021-
| Item.CtorGroup(methodName, minfos), Some (arg, baseIdOpt) ->
7022-
let meths = minfos |> List.map (fun minfo -> minfo, None)
7023-
let afterResolution = ForNewConstructors cenv.tcSink env mObjTy methodName minfos
7024-
let ad = env.AccessRights
7025-
7026-
let expr, tpenv = TcMethodApplicationThen cenv env (MustEqual objTy) None tpenv None [] mWholeExpr mObjTy methodName ad PossiblyMutates false meths afterResolution CtorValUsedAsSuperInit [arg] ExprAtomicFlag.Atomic None []
7027-
// The 'base' value is always bound
7028-
let baseIdOpt = (match baseIdOpt with None -> Some(ident("base", mObjTy)) | Some id -> Some id)
7029-
expr, baseIdOpt, tpenv
7030-
| Item.FakeInterfaceCtor intfTy, None ->
7031-
UnifyTypes cenv env mWholeExpr objTy intfTy
7032-
let expr = BuildObjCtorCall g mWholeExpr
7033-
expr, None, tpenv
7034-
| Item.FakeInterfaceCtor _, Some _ ->
7035-
error(Error(FSComp.SR.tcConstructorForInterfacesDoNotTakeArguments(), mNewExpr))
7036-
| Item.CtorGroup _, None ->
7037-
error(Error(FSComp.SR.tcConstructorRequiresArguments(), mNewExpr))
7038-
| _ -> error(Error(FSComp.SR.tcNewRequiresObjectConstructor(), mNewExpr))
7028+
match item, argopt with
7029+
| Item.CtorGroup(methodName, minfos), Some (arg, baseIdOpt) ->
7030+
let meths = minfos |> List.map (fun minfo -> minfo, None)
7031+
let afterResolution = ForNewConstructors cenv.tcSink env mObjTy methodName minfos
7032+
let ad = env.AccessRights
7033+
7034+
let expr, tpenv = TcMethodApplicationThen cenv env (MustEqual objTy) None tpenv None [] mWholeExpr mObjTy methodName ad PossiblyMutates false meths afterResolution CtorValUsedAsSuperInit [arg] ExprAtomicFlag.Atomic None []
7035+
// The 'base' value is always bound
7036+
let baseIdOpt = (match baseIdOpt with None -> Some(ident("base", mObjTy)) | Some id -> Some id)
7037+
expr, baseIdOpt, tpenv
7038+
7039+
| Item.CtorGroup _, None ->
7040+
error(Error(FSComp.SR.tcConstructorRequiresArguments(), mNewExpr))
7041+
7042+
| _ -> error(Error(FSComp.SR.tcNewRequiresObjectConstructor(), mNewExpr))
70397043

70407044
let baseValOpt = MakeAndPublishBaseVal cenv env baseIdOpt objTy
70417045
let env = Option.foldBack (AddLocalVal g cenv.tcSink mNewExpr) baseValOpt env
@@ -8141,8 +8145,11 @@ and TcNameOfExpr (cenv: cenv) env tpenv (synArg: SynExpr) =
81418145
when
81428146
(match item with
81438147
| Item.DelegateCtor _
8144-
| Item.CtorGroup _
8145-
| Item.FakeInterfaceCtor _ -> false
8148+
| Item.CtorGroup _ -> false
8149+
| Item.Types _ when delayed.IsEmpty ->
8150+
match delayed with
8151+
| [] | [DelayedTypeApp _] -> false
8152+
| _ -> true
81468153
| _ -> true) ->
81478154
let overallTy = match overallTyOpt with None -> MustEqual (NewInferenceType g) | Some t -> t
81488155
let _, _ = TcItemThen cenv overallTy env tpenv res None delayed
@@ -8374,9 +8381,6 @@ and TcItemThen (cenv: cenv) (overallTy: OverallTy) env tpenv (tinstEnclosing, it
83748381
| Item.CtorGroup(nm, minfos) ->
83758382
TcCtorItemThen cenv overallTy env item nm minfos tinstEnclosing tpenv mItem afterResolution delayed
83768383

8377-
| Item.FakeInterfaceCtor _ ->
8378-
error(Error(FSComp.SR.tcInvalidUseOfInterfaceType(), mItem))
8379-
83808384
| Item.ImplicitOp(id, sln) ->
83818385
TcImplicitOpItemThen cenv overallTy env id sln tpenv mItem delayed
83828386

@@ -8614,7 +8618,10 @@ and TcTypeItemThen (cenv: cenv) overallTy env nm ty tpenv mItem tinstEnclosing d
86148618
// In this case the type is not generic, and indeed we should never have returned Item.Types.
86158619
// That's because ResolveTypeNamesToCtors should have been set at the original
86168620
// call to ResolveLongIdentAsExprAndComputeRange
8617-
error(Error(FSComp.SR.tcInvalidUseOfTypeName(), mItem))
8621+
if isInterfaceTy g ty then
8622+
error(Error(FSComp.SR.tcInvalidUseOfInterfaceType(), mItem))
8623+
else
8624+
error(Error(FSComp.SR.tcInvalidUseOfTypeName(), mItem))
86188625

86198626
and TcMethodItemThen (cenv: cenv) overallTy env item methodName minfos tpenv mItem afterResolution staticTyOpt delayed =
86208627
let ad = env.eAccessRights
@@ -8807,7 +8814,7 @@ and TcImplicitOpItemThen (cenv: cenv) overallTy env id sln tpenv mItem delayed =
88078814

88088815
let memberFlags = StaticMemberFlags SynMemberKind.Member
88098816
let logicalCompiledName = ComputeLogicalName id memberFlags
8810-
let traitInfo = TTrait(argTys, logicalCompiledName, memberFlags, argTys, Some retTy, sln)
8817+
let traitInfo = TTrait(argTys, logicalCompiledName, memberFlags, argTys, Some retTy, ref None, sln)
88118818

88128819
let expr = Expr.Op (TOp.TraitCall traitInfo, [], ves, mItem)
88138820
let expr = mkLambdas g mItem [] vs (expr, retTy)
@@ -9305,7 +9312,7 @@ and TcLookupItemThen cenv overallTy env tpenv mObjExpr objExpr objExprTy delayed
93059312
| Item.Trait traitInfo ->
93069313
TcTraitItemThen cenv overallTy env (Some objExpr) traitInfo tpenv mItem delayed
93079314

9308-
| Item.FakeInterfaceCtor _ | Item.DelegateCtor _ -> error (Error (FSComp.SR.tcConstructorsCannotBeFirstClassValues(), mItem))
9315+
| Item.DelegateCtor _ -> error (Error (FSComp.SR.tcConstructorsCannotBeFirstClassValues(), mItem))
93099316

93109317
// These items are not expected here - they can't be the result of a instance member dot-lookup "expr.Ident"
93119318
| Item.ActivePatternResult _

src/Compiler/Checking/CheckExpressions.fsi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ exception UnionPatternsBindDifferentNames of range
7575

7676
exception VarBoundTwice of Ident
7777

78-
exception ValueRestriction of DisplayEnv * InfoReader * bool * Val * Typar * range
78+
exception ValueRestriction of DisplayEnv * InfoReader * Val * Typar * range
7979

8080
exception ValNotMutable of DisplayEnv * ValRef * range
8181

src/Compiler/Checking/CheckFormatStrings.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ let escapeDotnetFormatString str =
5959

6060
[<return: Struct>]
6161
let (|PrefixedBy|_|) (prefix: string) (str: string) =
62-
if str.StartsWith prefix then
62+
if str.StartsWithOrdinal(prefix) then
6363
ValueSome prefix.Length
6464
else
6565
ValueNone
@@ -371,7 +371,7 @@ let parseFormatStringInternal
371371
// type checker. They should always have '(...)' after for format string.
372372
let requireAndSkipInterpolationHoleFormat i =
373373
if i < len && fmt[i] = '(' then
374-
let i2 = fmt.IndexOf(")", i+1)
374+
let i2 = fmt.IndexOfOrdinal(")", i+1)
375375
if i2 = -1 then
376376
failwith (FSComp.SR.forFormatInvalidForInterpolated3())
377377
else

0 commit comments

Comments
 (0)