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
9 changes: 8 additions & 1 deletion docs/release-notes/.FSharp.Compiler.Service/8.0.200.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
### Fixed

* 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))
* 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))
* 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))
* Range of [SynField](../reference/fsharp-compiler-syntax-synfield.html) ([PR #16357](https://github.com/dotnet/fsharp/pull/16357))
* 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))

### Added
* Raise a new error when interfaces with auto properties are implemented on constructor-less types. ([PR #16352](https://github.com/dotnet/fsharp/pull/16352))
* Allow usage of `[<TailCall>]` with older `FSharp.Core` package versions. ([PR #16373](https://github.com/dotnet/fsharp/pull/16373))
* Parser recovers on unfinished `as` patterns. ([PR #16404](https://github.com/dotnet/fsharp/pull/16404))
* Allow type-checking of unfinished object expressions. ([PR #16413](https://github.com/dotnet/fsharp/pull/16413))
* Parser recovers on unfinished enum case declarations. ([PR #16401](https://github.com/dotnet/fsharp/pull/16401))
* Parser recovers on unfinished record declarations. ([PR #16357](https://github.com/dotnet/fsharp/pull/16357))
* `MutableKeyword` to [SynFieldTrivia](../reference/fsharp-compiler-syntaxtrivia-synfieldtrivia.html) ([PR #16357](https://github.com/dotnet/fsharp/pull/16357))
7 changes: 6 additions & 1 deletion docs/release-notes/.Language/preview.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
### Added

* 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))
* Bidirectional F#/C# interop for 'unmanaged' constraint. ([PR #12154](https://github.com/dotnet/fsharp/pull/12154))
* Bidirectional F#/C# interop for 'unmanaged' constraint. ([PR #12154](https://github.com/dotnet/fsharp/pull/12154))
* 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))

### Fixed

* Allow extension methods without type attribute work for types from imported assemblies. ([PR #16368](https://github.com/dotnet/fsharp/pull/16368))
3 changes: 2 additions & 1 deletion docs/release-notes/.aux/Common.fsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#r "nuget: Markdig, 0.33.0"
#i "nuget: https://api.nuget.org/v3/index.json"
#r "nuget: Markdig, 0.33.0"
#r "nuget: FsHttp, 12.1.0"

open System.IO
Expand Down
46 changes: 46 additions & 0 deletions docs/running-documentation-locally.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
title: Running the documentation locally
category: Compiler Internals
categoryindex: 200
index: 999
---
# Running the documentation locally

The source of this documentation website is hosted on https://github.com/fsharp/fsharp-compiler-docs.
You can follow this guide to see the results of your document changes rendered in the browser.

## Setup

`fsharp/fsharp-compiler-docs` will clone the `dotnet/fsharp` repository first to generate the documentation.
You can however, easily run the documentation locally and modify the `docs` from `dotnet/fsharp`.

* Clone `fsharp/fsharp-compiler-docs` at the same level as your local `dotnet/fsharp` repository:


git clone https://github.com/fsharp/fsharp-compiler-docs.git


* Restore the `FSharp.Compiler.Service` project in `fsharp-compiler-docs`:


cd fsharp-compiler-docs/FSharp.Compiler.Service
dotnet restore


* Restore the local tools in `fsharp-compiler-docs`:


cd ..
dotnet tool restore


* Run the documentation tool using your `dotnet/fsharp` fork as input.


dotnet fsdocs watch --eval --sourcefolder ../fsharp/ --input ../fsharp/docs/


## Release notes caveat

The release notes pages from `docs/release-notes` are composed from the MarkDown files in subfolders.
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.
20 changes: 17 additions & 3 deletions src/Compiler/AbstractIL/ilwrite.fs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ let emitBytesViaBuffer f = use bb = ByteBuffer.Create EmitBytesViaBufferCapacity
/// Alignment and padding
let align alignment n = ((n + alignment - 1) / alignment) * alignment


/// Maximum number of methods in a dotnet type
/// This differs from the spec and file formats slightly which suggests 0xfffe is the maximum
/// this value was identified empirically.
[<Literal>]
let maximumMethodsPerDotNetType = 0xfff0

//---------------------------------------------------------------------
// Concrete token representations etc. used in PE files
//---------------------------------------------------------------------
Expand Down Expand Up @@ -672,8 +679,14 @@ let GetTypeNameAsElemPair cenv n =
//=====================================================================

let rec GenTypeDefPass1 enc cenv (tdef: ILTypeDef) =
ignore (cenv.typeDefs.AddUniqueEntry "type index" (fun (TdKey (_, n)) -> n) (TdKey (enc, tdef.Name)))
GenTypeDefsPass1 (enc@[tdef.Name]) cenv (tdef.NestedTypes.AsList())
ignore (cenv.typeDefs.AddUniqueEntry "type index" (fun (TdKey (_, n)) -> n) (TdKey (enc, tdef.Name)))

// Verify that the typedef contains fewer than maximumMethodsPerDotNetType
let count = tdef.Methods.AsArray().Length
if count > maximumMethodsPerDotNetType then
errorR(Error(FSComp.SR.tooManyMethodsInDotNetTypeWritingAssembly (tdef.Name, count, maximumMethodsPerDotNetType), rangeStartup))

GenTypeDefsPass1 (enc@[tdef.Name]) cenv (tdef.NestedTypes.AsList())

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

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

let rec GetIdxForTypeDef cenv key =
try cenv.typeDefs.GetTableEntry key
try
cenv.typeDefs.GetTableEntry key
with
:? KeyNotFoundException ->
let (TdKey (enc, n) ) = key
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5577,7 +5577,7 @@ let CheckValueRestriction denvAtEnd infoReader rootSigOpt implFileTypePriorToSig
// for example FSharp 1.0 3661.
(match v.ValReprInfo with None -> true | Some tvi -> tvi.HasNoArgs)) then
match ftyvs with
| tp :: _ -> errorR (ValueRestriction(denvAtEnd, infoReader, false, v, tp, v.Range))
| tp :: _ -> errorR (ValueRestriction(denvAtEnd, infoReader, v, tp, v.Range))
| _ -> ()
mty.ModuleAndNamespaceDefinitions |> List.iter (fun v -> check v.ModuleOrNamespaceType)
try check implFileTypePriorToSig with RecoverableException e -> errorRecovery e m
Expand Down
75 changes: 41 additions & 34 deletions src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ exception UnionPatternsBindDifferentNames of range

exception VarBoundTwice of Ident

exception ValueRestriction of DisplayEnv * InfoReader * bool * Val * Typar * range
exception ValueRestriction of DisplayEnv * InfoReader * Val * Typar * range

exception ValNotMutable of DisplayEnv * ValRef * range

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

TTrait(tys, logicalCompiledName, memberFlags, argTys, returnTy, ref None), tpenv
TTrait(tys, logicalCompiledName, memberFlags, argTys, returnTy, ref None, ref None), tpenv

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

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

TcRecordConstruction cenv objTy true env tpenv None objTy fldsList mWholeExpr
else
let item = ForceRaise (ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mObjTy ad objTy)
let ctorCall, baseIdOpt, tpenv =
if isInterfaceTy g objTy then
match argopt with
| None ->
BuildObjCtorCall g mWholeExpr, None, tpenv
| Some _ ->
error(Error(FSComp.SR.tcConstructorForInterfacesDoNotTakeArguments(), mNewExpr))
else
let item = ForceRaise (ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mObjTy ad objTy)

if isFSharpObjModelTy g objTy && GetCtorShapeCounter env = 1 then
error(Error(FSComp.SR.tcObjectsMustBeInitializedWithObjectExpression(), mNewExpr))
if isFSharpObjModelTy g objTy && GetCtorShapeCounter env = 1 then
error(Error(FSComp.SR.tcObjectsMustBeInitializedWithObjectExpression(), mNewExpr))

let ctorCall, baseIdOpt, tpenv =
match item, argopt with
| Item.CtorGroup(methodName, minfos), Some (arg, baseIdOpt) ->
let meths = minfos |> List.map (fun minfo -> minfo, None)
let afterResolution = ForNewConstructors cenv.tcSink env mObjTy methodName minfos
let ad = env.AccessRights

let expr, tpenv = TcMethodApplicationThen cenv env (MustEqual objTy) None tpenv None [] mWholeExpr mObjTy methodName ad PossiblyMutates false meths afterResolution CtorValUsedAsSuperInit [arg] ExprAtomicFlag.Atomic None []
// The 'base' value is always bound
let baseIdOpt = (match baseIdOpt with None -> Some(ident("base", mObjTy)) | Some id -> Some id)
expr, baseIdOpt, tpenv
| Item.FakeInterfaceCtor intfTy, None ->
UnifyTypes cenv env mWholeExpr objTy intfTy
let expr = BuildObjCtorCall g mWholeExpr
expr, None, tpenv
| Item.FakeInterfaceCtor _, Some _ ->
error(Error(FSComp.SR.tcConstructorForInterfacesDoNotTakeArguments(), mNewExpr))
| Item.CtorGroup _, None ->
error(Error(FSComp.SR.tcConstructorRequiresArguments(), mNewExpr))
| _ -> error(Error(FSComp.SR.tcNewRequiresObjectConstructor(), mNewExpr))
match item, argopt with
| Item.CtorGroup(methodName, minfos), Some (arg, baseIdOpt) ->
let meths = minfos |> List.map (fun minfo -> minfo, None)
let afterResolution = ForNewConstructors cenv.tcSink env mObjTy methodName minfos
let ad = env.AccessRights

let expr, tpenv = TcMethodApplicationThen cenv env (MustEqual objTy) None tpenv None [] mWholeExpr mObjTy methodName ad PossiblyMutates false meths afterResolution CtorValUsedAsSuperInit [arg] ExprAtomicFlag.Atomic None []
// The 'base' value is always bound
let baseIdOpt = (match baseIdOpt with None -> Some(ident("base", mObjTy)) | Some id -> Some id)
expr, baseIdOpt, tpenv

| Item.CtorGroup _, None ->
error(Error(FSComp.SR.tcConstructorRequiresArguments(), mNewExpr))

| _ -> error(Error(FSComp.SR.tcNewRequiresObjectConstructor(), mNewExpr))

let baseValOpt = MakeAndPublishBaseVal cenv env baseIdOpt objTy
let env = Option.foldBack (AddLocalVal g cenv.tcSink mNewExpr) baseValOpt env
Expand Down Expand Up @@ -8141,8 +8145,11 @@ and TcNameOfExpr (cenv: cenv) env tpenv (synArg: SynExpr) =
when
(match item with
| Item.DelegateCtor _
| Item.CtorGroup _
| Item.FakeInterfaceCtor _ -> false
| Item.CtorGroup _ -> false
| Item.Types _ when delayed.IsEmpty ->
match delayed with
| [] | [DelayedTypeApp _] -> false
| _ -> true
| _ -> true) ->
let overallTy = match overallTyOpt with None -> MustEqual (NewInferenceType g) | Some t -> t
let _, _ = TcItemThen cenv overallTy env tpenv res None delayed
Expand Down Expand Up @@ -8374,9 +8381,6 @@ and TcItemThen (cenv: cenv) (overallTy: OverallTy) env tpenv (tinstEnclosing, it
| Item.CtorGroup(nm, minfos) ->
TcCtorItemThen cenv overallTy env item nm minfos tinstEnclosing tpenv mItem afterResolution delayed

| Item.FakeInterfaceCtor _ ->
error(Error(FSComp.SR.tcInvalidUseOfInterfaceType(), mItem))

| Item.ImplicitOp(id, sln) ->
TcImplicitOpItemThen cenv overallTy env id sln tpenv mItem delayed

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

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

let memberFlags = StaticMemberFlags SynMemberKind.Member
let logicalCompiledName = ComputeLogicalName id memberFlags
let traitInfo = TTrait(argTys, logicalCompiledName, memberFlags, argTys, Some retTy, sln)
let traitInfo = TTrait(argTys, logicalCompiledName, memberFlags, argTys, Some retTy, ref None, sln)

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

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

// These items are not expected here - they can't be the result of a instance member dot-lookup "expr.Ident"
| Item.ActivePatternResult _
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/CheckExpressions.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ exception UnionPatternsBindDifferentNames of range

exception VarBoundTwice of Ident

exception ValueRestriction of DisplayEnv * InfoReader * bool * Val * Typar * range
exception ValueRestriction of DisplayEnv * InfoReader * Val * Typar * range

exception ValNotMutable of DisplayEnv * ValRef * range

Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Checking/CheckFormatStrings.fs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ let escapeDotnetFormatString str =

[<return: Struct>]
let (|PrefixedBy|_|) (prefix: string) (str: string) =
if str.StartsWith prefix then
if str.StartsWithOrdinal(prefix) then
ValueSome prefix.Length
else
ValueNone
Expand Down Expand Up @@ -371,7 +371,7 @@ let parseFormatStringInternal
// type checker. They should always have '(...)' after for format string.
let requireAndSkipInterpolationHoleFormat i =
if i < len && fmt[i] = '(' then
let i2 = fmt.IndexOf(")", i+1)
let i2 = fmt.IndexOfOrdinal(")", i+1)
if i2 = -1 then
failwith (FSComp.SR.forFormatInvalidForInterpolated3())
else
Expand Down
Loading