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
3 changes: 3 additions & 0 deletions docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* Add missing byte chars notations, enforce limits in decimal notation in byte char & string (Issues [#15867](https://github.com/dotnet/fsharp/issues/15867), [#15868](https://github.com/dotnet/fsharp/issues/15868), [#15869](https://github.com/dotnet/fsharp/issues/15869), [PR #15898](https://github.com/dotnet/fsharp/pull/15898))
* Parentheses analysis: keep extra parentheses around unit & tuples in method definitions. ([PR #17618](https://github.com/dotnet/fsharp/pull/17618))
* Fix IsUnionCaseTester throwing for non-methods/properties [#17301](https://github.com/dotnet/fsharp/pull/17634)
* Fix xmlc doc tooltip display for nullable types [#17741](https://github.com/dotnet/fsharp/pull/17741)
* Consider `open type` used when the type is an enum and any of the enum cases is used unqualified. ([PR #17628](https://github.com/dotnet/fsharp/pull/17628))
* Guard for possible StackOverflowException when typechecking non recursive modules and namespaces ([PR #17654](https://github.com/dotnet/fsharp/pull/17654))
* Nullable - fix for processing System.Nullable types with nesting ([PR #17736](https://github.com/dotnet/fsharp/pull/17736))
Expand All @@ -36,6 +37,8 @@
* Enable LanguageFeature.EnforceAttributeTargets in F# 9.0. ([Issue #17514](https://github.com/dotnet/fsharp/issues/17558), [PR #17516](https://github.com/dotnet/fsharp/pull/17558))
* Parser: better recovery for unfinished patterns ([PR #17231](https://github.com/dotnet/fsharp/pull/17231), [PR #17232](https://github.com/dotnet/fsharp/pull/17232)))
* Enable consuming generic arguments defined as `allows ref struct` in C# ([Issue #17597](https://github.com/dotnet/fsharp/issues/17597)
* Trivia for SynTypeConstraint.WhereTyparNotSupportsNull. ([Issue #17721](https://github.com/dotnet/fsharp/issues/17721), [PR #17745](https://github.com/dotnet/fsharp/pull/17745))
* Trivia for SynType.WithNull. ([Issue #17720](https://github.com/dotnet/fsharp/issues/17720), [PR #17745](https://github.com/dotnet/fsharp/pull/17745))

### Changed

Expand Down
28 changes: 14 additions & 14 deletions src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ module TcRecdUnionAndEnumDeclarations =
let TcFieldDecl (cenv: cenv) env parent isIncrClass tpenv (isStatic, synAttrs, id: Ident, nameGenerated, ty, isMutable, xmldoc, vis) =
let g = cenv.g
let m = id.idRange
let attrs, _ = TcAttributesWithPossibleTargets false cenv env AttributeTargets.FieldDecl synAttrs
let attrs, _ = TcAttributesWithPossibleTargets TcCanFail.ReportAllErrors cenv env AttributeTargets.FieldDecl synAttrs

let attrsForProperty, attrsForField = attrs |> List.partition (fun (attrTargets, _) -> (attrTargets &&& AttributeTargets.Property) <> enum 0)
let attrsForProperty = (List.map snd attrsForProperty)
Expand All @@ -455,7 +455,7 @@ module TcRecdUnionAndEnumDeclarations =
match parent with
| Parent tcref when useGenuineField tcref.Deref rfspec ->
// Recheck the attributes for errors if the definition only generates a field
TcAttributesWithPossibleTargets false cenv env AttributeTargets.FieldDeclRestricted synAttrs |> ignore
TcAttributesWithPossibleTargets TcCanFail.ReportAllErrors cenv env AttributeTargets.FieldDeclRestricted synAttrs |> ignore
| _ -> ()
rfspec

Expand Down Expand Up @@ -2909,9 +2909,9 @@ module EstablishTypeDefinitionCores =

if reportAttributeTargetsErrors then
if hasStructAttr then
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Struct synAttrs |> ignore
TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Struct synAttrs |> ignore
else
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Class synAttrs |> ignore
TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Class synAttrs |> ignore

// Note: the table of union cases is initially empty
Construct.MakeUnionRepr []
Expand All @@ -2934,9 +2934,9 @@ module EstablishTypeDefinitionCores =

if reportAttributeTargetsErrors then
if hasStructAttr then
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Struct synAttrs |> ignore
TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Struct synAttrs |> ignore
else
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Class synAttrs |> ignore
TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Class synAttrs |> ignore

// Note: the table of record fields is initially empty
TFSharpTyconRepr (Construct.NewEmptyFSharpTyconData TFSharpRecord)
Expand All @@ -2952,19 +2952,19 @@ module EstablishTypeDefinitionCores =
match kind with
| SynTypeDefnKind.Class ->
if reportAttributeTargetsErrors then
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Class synAttrs |> ignore
TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Class synAttrs |> ignore
TFSharpClass
| SynTypeDefnKind.Interface ->
if reportAttributeTargetsErrors then
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Interface synAttrs |> ignore
TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Interface synAttrs |> ignore
TFSharpInterface
| SynTypeDefnKind.Delegate _ ->
if reportAttributeTargetsErrors then
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Delegate synAttrs |> ignore
TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Delegate synAttrs |> ignore
TFSharpDelegate (MakeSlotSig("Invoke", g.unit_ty, [], [], [], None))
| SynTypeDefnKind.Struct ->
if reportAttributeTargetsErrors then
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Struct synAttrs |> ignore
TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Struct synAttrs |> ignore
TFSharpStruct
| _ -> error(InternalError("should have inferred tycon kind", m))

Expand All @@ -2973,7 +2973,7 @@ module EstablishTypeDefinitionCores =
| SynTypeDefnSimpleRepr.Enum _ ->
noCLIMutableAttributeCheck()
if reportAttributeTargetsErrors then
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Enum synAttrs |> ignore
TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Enum synAttrs |> ignore
TFSharpTyconRepr (Construct.NewEmptyFSharpTyconData TFSharpEnum)

// OK, now fill in the (partially computed) type representation
Expand Down Expand Up @@ -4035,7 +4035,7 @@ module EstablishTypeDefinitionCores =
// Phase 1B. Establish the kind of each type constructor
// Here we run InferTyconKind and record partial information about the kind of the type constructor.
// This means FSharpTyconKind is set, which means isSealedTy, isInterfaceTy etc. give accurate results.
let withAttrs =
let withAttrs =
(envMutRecPrelim, withEnvs) ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls (origInfo, tyconOpt) ->
let res =
match origInfo, tyconOpt with
Expand Down Expand Up @@ -5202,7 +5202,7 @@ let TcModuleOrNamespaceElementsMutRec (cenv: cenv) parent typeNames m envInitial
let mutRecDefnsChecked, envAfter = TcDeclarations.TcMutRecDefinitions cenv envInitial parent typeNames tpenv m scopem mutRecNSInfo mutRecDefns true

// Check the assembly attributes
let attrs, _ = TcAttributesWithPossibleTargets false cenv envAfter AttributeTargets.Top synAttrs
let attrs, _ = TcAttributesWithPossibleTargets TcCanFail.ReportAllErrors cenv envAfter AttributeTargets.Top synAttrs

// Check the non-escaping condition as we build the list of module expressions on the way back up
let moduleContents = TcMutRecDefsFinish cenv mutRecDefnsChecked m
Expand Down Expand Up @@ -5279,7 +5279,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem
return! failwith "unreachable"

| SynModuleDecl.Attributes (Attributes synAttrs, _) ->
let attrs, _ = TcAttributesWithPossibleTargets false cenv env AttributeTargets.Top synAttrs
let attrs, _ = TcAttributesWithPossibleTargets TcCanFail.ReportAllErrors cenv env AttributeTargets.Top synAttrs
return ([], [], attrs), env, env

| SynModuleDecl.HashDirective _ ->
Expand Down
21 changes: 14 additions & 7 deletions src/Compiler/Checking/Expressions/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,13 @@ let TranslatePartialValReprInfo tps (PrelimValReprInfo (argsData, retData)) =
// Members
//-------------------------------------------------------------------------


[<RequireQualifiedAccess>]
type TcCanFail =
| IgnoreMemberResoutionError
| IgnoreAllErrors
| ReportAllErrors

let TcAddNullnessToType (warn: bool) (cenv: cenv) (env: TcEnv) nullness innerTyC m =
let g = cenv.g
if g.langFeatureNullness then
Expand Down Expand Up @@ -4028,7 +4035,7 @@ let rec TcTyparConstraint ridx (cenv: cenv) newOk checkConstraints occ (env: TcE
| SynTypeConstraint.WhereTyparSupportsNull(tp, m) ->
TcSimpleTyparConstraint cenv env newOk tpenv tp m AddCxTypeUseSupportsNull

| SynTypeConstraint.WhereTyparNotSupportsNull(tp, m) ->
| SynTypeConstraint.WhereTyparNotSupportsNull(tp, m, _) ->
if g.langFeatureNullness then
TcSimpleTyparConstraint cenv env newOk tpenv tp m AddCxTypeDefnNotSupportsNull
else
Expand Down Expand Up @@ -4472,7 +4479,7 @@ and TcTypeOrMeasure kindOpt (cenv: cenv) newOk checkConstraints occ (iwsam: Warn
errorR(Error(FSComp.SR.parsInvalidLiteralInType(), m))
NewErrorType (), tpenv

| SynType.WithNull(innerTy, ambivalent, m) ->
| SynType.WithNull(innerTy, ambivalent, m, _) ->
let innerTyC, tpenv = TcTypeAndRecover cenv newOk checkConstraints occ WarnOnIWSAM.Yes env tpenv innerTy
let nullness = if ambivalent then KnownAmbivalentToNull else KnownWithNull
let tyWithNull = TcAddNullnessToType false cenv env nullness innerTyC m
Expand Down Expand Up @@ -10869,7 +10876,7 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
// For all but attributes positioned at the return value, disallow implicitly
// targeting the return value.
let tgtEx = if isRet then enum 0 else AttributeTargets.ReturnValue
let attrs, _ = TcAttributesMaybeFailEx false cenv envinner tgt tgtEx attrs
let attrs, _ = TcAttributesMaybeFailEx TcCanFail.ReportAllErrors cenv envinner tgt tgtEx attrs
let attrs: Attrib list = attrs
if attrTgt = enum 0 && not (isNil attrs) then
for attr in attrs do
Expand Down Expand Up @@ -11131,7 +11138,7 @@ and TcAttributeTargetsOnLetBindings (cenv: cenv) env attrs overallPatTy overallE
else
AttributeTargets.ReturnValue ||| AttributeTargets.Field ||| AttributeTargets.Property

TcAttributesWithPossibleTargets false cenv env attrTgt attrs |> ignore
TcAttributesWithPossibleTargets TcCanFail.ReportAllErrors cenv env attrTgt attrs |> ignore

and TcLiteral (cenv: cenv) overallTy env tpenv (attrs, synLiteralValExpr) =

Expand Down Expand Up @@ -11291,7 +11298,7 @@ and TcAttributeEx canFail (cenv: cenv) (env: TcEnv) attrTgt attrEx (synAttr: Syn
error(Error(FSComp.SR.tcAttributeIsNotValidForLanguageElement(), mAttr))

match ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mAttr ad ty with
| Exception _ when canFail -> [ ], true
| Exception _ when canFail = TcCanFail.IgnoreAllErrors || canFail = TcCanFail.IgnoreMemberResoutionError -> [ ], true
| res ->

let item = ForceRaise res
Expand Down Expand Up @@ -11396,11 +11403,11 @@ and TcAttributesMaybeFail canFail cenv env attrTgt synAttribs =
TcAttributesMaybeFailEx canFail cenv env attrTgt (enum 0) synAttribs

and TcAttributesCanFail cenv env attrTgt synAttribs =
let attrs, didFail = TcAttributesMaybeFail true cenv env attrTgt synAttribs
let attrs, didFail = TcAttributesMaybeFail TcCanFail.IgnoreAllErrors cenv env attrTgt synAttribs
attrs, (fun () -> if didFail then TcAttributes cenv env attrTgt synAttribs else attrs)

and TcAttributes cenv env attrTgt synAttribs =
TcAttributesMaybeFail false cenv env attrTgt synAttribs |> fst
TcAttributesMaybeFail TcCanFail.ReportAllErrors cenv env attrTgt synAttribs |> fst

//-------------------------------------------------------------------------
// TcLetBinding
Expand Down
8 changes: 7 additions & 1 deletion src/Compiler/Checking/Expressions/CheckExpressions.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,12 @@ type PostSpecialValsRecursiveBinding =
{ ValScheme: ValScheme
Binding: Binding }

[<RequireQualifiedAccess>]
type TcCanFail =
| IgnoreMemberResoutionError
| IgnoreAllErrors
| ReportAllErrors

/// Represents a recursive binding after it has been both checked and generalized, but
/// before initialization recursion has been rewritten
type PreInitializationGraphEliminationBinding =
Expand Down Expand Up @@ -598,7 +604,7 @@ val TcAttributesCanFail:

/// Check a set of attributes which can only target specific elements
val TcAttributesWithPossibleTargets:
canFail: bool ->
canFail: TcCanFail ->
cenv: TcFileState ->
env: TcEnv ->
attrTgt: AttributeTargets ->
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Service/ServiceParseTreeWalk.fs
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,7 @@ module SyntaxTraversal =
| SynType.Fun(argType = ty1; returnType = ty2) -> [ ty1; ty2 ] |> List.tryPick (traverseSynType path)
| SynType.MeasurePower(ty, _, _)
| SynType.HashConstraint(ty, _)
| SynType.WithNull(ty, _, _)
| SynType.WithNull(innerType = ty)
| SynType.WithGlobalConstraints(ty, _, _)
| SynType.Array(_, ty, _) -> traverseSynType path ty
| SynType.StaticConstantNamed(ty1, ty2, _)
Expand Down
8 changes: 4 additions & 4 deletions src/Compiler/Service/ServiceParsedInputOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ module ParsedInput =
| SynTypeConstraint.WhereTyparIsReferenceType(t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparIsUnmanaged(t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparSupportsNull(t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparNotSupportsNull(t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparNotSupportsNull(genericName = t) -> walkTypar t
| SynTypeConstraint.WhereTyparIsComparable(t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparIsEquatable(t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparSubtypeOfType(t, ty, _) -> walkTypar t |> Option.orElseWith (fun () -> walkType ty)
Expand Down Expand Up @@ -711,7 +711,7 @@ module ParsedInput =
| SynType.Array(_, t, _) -> walkType t
| SynType.Fun(argType = t1; returnType = t2) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2)
| SynType.WithGlobalConstraints(t, _, _) -> walkType t
| SynType.WithNull(t, _, _)
| SynType.WithNull(innerType = t)
| SynType.HashConstraint(t, _) -> walkType t
| SynType.Or(t1, t2, _, _) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2)
| SynType.MeasurePower(t, _, _) -> walkType t
Expand Down Expand Up @@ -1914,7 +1914,7 @@ module ParsedInput =
| SynTypeConstraint.WhereTyparIsReferenceType(t, _)
| SynTypeConstraint.WhereTyparIsUnmanaged(t, _)
| SynTypeConstraint.WhereTyparSupportsNull(t, _)
| SynTypeConstraint.WhereTyparNotSupportsNull(t, _)
| SynTypeConstraint.WhereTyparNotSupportsNull(genericName = t)
| SynTypeConstraint.WhereTyparIsComparable(t, _)
| SynTypeConstraint.WhereTyparIsEquatable(t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparDefaultsToType(t, ty, _)
Expand Down Expand Up @@ -1976,7 +1976,7 @@ module ParsedInput =
| SynType.Array(_, t, _)
| SynType.HashConstraint(t, _)
| SynType.MeasurePower(t, _, _)
| SynType.WithNull(t, _, _)
| SynType.WithNull(innerType = t)
| SynType.Paren(t, _)
| SynType.SignatureParameter(usedType = t) -> walkType t
| SynType.Fun(argType = t1; returnType = t2)
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/SyntaxTree/SyntaxTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ type SynTypeConstraint =

| WhereTyparSupportsNull of typar: SynTypar * range: range

| WhereTyparNotSupportsNull of genericName: SynTypar * range: range
| WhereTyparNotSupportsNull of genericName: SynTypar * range: range * trivia: SynTypeConstraintWhereTyparNotSupportsNullTrivia

| WhereTyparIsComparable of typar: SynTypar * range: range

Expand Down Expand Up @@ -465,7 +465,7 @@ type SynType =

| StaticConstantNamed of ident: SynType * value: SynType * range: range

| WithNull of innerType: SynType * ambivalent: bool * range: range
| WithNull of innerType: SynType * ambivalent: bool * range: range * trivia: SynTypeWithNullTrivia

| Paren of innerType: SynType * range: range

Expand Down
7 changes: 5 additions & 2 deletions src/Compiler/SyntaxTree/SyntaxTree.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,10 @@ type SynTypeConstraint =
| WhereTyparSupportsNull of typar: SynTypar * range: range

/// F# syntax is 'typar : null
| WhereTyparNotSupportsNull of genericName: SynTypar * range: range
| WhereTyparNotSupportsNull of
genericName: SynTypar *
range: range *
trivia: SynTypeConstraintWhereTyparNotSupportsNullTrivia

/// F# syntax is 'typar: comparison
| WhereTyparIsComparable of typar: SynTypar * range: range
Expand Down Expand Up @@ -527,7 +530,7 @@ type SynType =
/// F# syntax: ident=1 etc., used in static parameters to type providers
| StaticConstantNamed of ident: SynType * value: SynType * range: range

| WithNull of innerType: SynType * ambivalent: bool * range: range
| WithNull of innerType: SynType * ambivalent: bool * range: range * trivia: SynTypeWithNullTrivia

| Paren of innerType: SynType * range: range

Expand Down
6 changes: 6 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,9 @@ type SynFieldTrivia =
[<NoEquality; NoComparison>]
type SynTypeOrTrivia = { OrKeyword: range }

[<NoEquality; NoComparison>]
type SynTypeWithNullTrivia = { BarRange: range }

[<NoEquality; NoComparison>]
type SynBindingReturnInfoTrivia = { ColonRange: range option }

Expand All @@ -429,3 +432,6 @@ type SynMeasureConstantTrivia =
LessRange: range
GreaterRange: range
}

[<NoEquality; NoComparison>]
type SynTypeConstraintWhereTyparNotSupportsNullTrivia = { ColonRange: range; NotRange: range }
19 changes: 19 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,14 @@ type SynTypeOrTrivia =
OrKeyword: range
}

/// Represents additional information for SynType.WithNull
[<NoEquality; NoComparison>]
type SynTypeWithNullTrivia =
{
/// The syntax range of the `|` token
BarRange: range
}

/// Represents additional information for SynBindingReturnInfo
[<NoEquality; NoComparison>]
type SynBindingReturnInfoTrivia =
Expand Down Expand Up @@ -545,3 +553,14 @@ type SynTyparDeclTrivia =
type SynMeasureConstantTrivia =
{ LessRange: range
GreaterRange: range }

/// Represents additional information for SynTypeConstraint.WhereTyparNotSupportsNull
[<NoEquality; NoComparison>]
type SynTypeConstraintWhereTyparNotSupportsNullTrivia =
{
/// The syntax range of `:`
ColonRange: range

/// The syntax range of `not`
NotRange: range
}
Loading