Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix :: Nullness in signature file is not considered by implementation and vice versa #18186

Draft
wants to merge 31 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c7295c2
type equivalence - add nullness support for signature conformance
T-Gro Dec 30, 2024
52bf00b
tests for nullness signature conformance
T-Gro Dec 30, 2024
0deae3d
softer whitespace handling for "withDiagnostics" check
T-Gro Dec 30, 2024
c0d4991
Merge branch 'main' into 18058-nullness-issue---nullness-in-signature…
T-Gro Dec 30, 2024
307eaef
fantomasd
T-Gro Dec 30, 2024
3e1b650
Merge branch '18058-nullness-issue---nullness-in-signature-file-is-no…
T-Gro Dec 30, 2024
5bd7b8b
Apply changes to codebase
T-Gro Dec 31, 2024
09d0232
adjust code to meet signature conformance
T-Gro Dec 31, 2024
05db836
see errors with ambivalence turned on
T-Gro Dec 31, 2024
c758e17
allow (WithoutNull === Ambivalent) in signature conformance
T-Gro Jan 3, 2025
dd55064
conform impl to signature
T-Gro Jan 3, 2025
6123665
fix
T-Gro Jan 6, 2025
f87f1fb
a few more
T-Gro Jan 6, 2025
79e0e52
format
T-Gro Jan 6, 2025
b58290b
Merge branch 'main' into 18058-nullness-issue---nullness-in-signature…
T-Gro Jan 6, 2025
582f9af
few more
T-Gro Jan 6, 2025
21f9e20
Can I get all errors at once if I replace them with warnings?
T-Gro Jan 6, 2025
c1ba534
some more
T-Gro Jan 6, 2025
3f2ae24
parsing
T-Gro Jan 6, 2025
9c300b2
one more
T-Gro Jan 7, 2025
703e821
try get more errors at once
T-Gro Jan 7, 2025
a0ef43e
That one should stay strict - this is checked per-phase (OK), not per…
T-Gro Jan 7, 2025
d30504c
Can I process more diags now?
T-Gro Jan 7, 2025
c67b453
Revisit this - this produced a "mismatch on accessibility" first
T-Gro Jan 7, 2025
8449fc4
another
T-Gro Jan 7, 2025
b1635c0
cannot see info warning in output
T-Gro Jan 8, 2025
d8fa0e6
i really want to see all warnings
T-Gro Jan 8, 2025
dc3e815
prettynaming conformant now
T-Gro Jan 8, 2025
9cc5227
ilreflect conformant
T-Gro Jan 8, 2025
f1454ea
format
T-Gro Jan 8, 2025
c1991ce
apply
T-Gro Jan 10, 2025
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
2 changes: 1 addition & 1 deletion src/Compiler/AbstractIL/ilreflect.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2548,7 +2548,7 @@ let EmitDynamicAssemblyFragment
ignore (typB.InvokeMemberAndLog(methodName, BindingFlags.InvokeMethod ||| BindingFlags.Public ||| BindingFlags.Static, [||]))
None
with :? TargetInvocationException as exn ->
Some exn.InnerException
Option.ofObj exn.InnerException

let emEnv, entryPts = envPopEntryPts emEnv
let execs = List.map execEntryPtFun entryPts
Expand Down
8 changes: 4 additions & 4 deletions src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4244,7 +4244,7 @@ module TcDeclarations =
// For historical reasons we only give a warning for incorrect type parameters on intrinsic extensions
if nReqTypars <> synTypars.Length then
errorR(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m))
if not (typarsAEquiv g TypeEquivEnv.Empty reqTypars declaredTypars) then
if not (typarsAEquiv g (TypeEquivEnv.EmptyWithNullChecks g) reqTypars declaredTypars) then
warning(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m))
// Note we return 'reqTypars' for intrinsic extensions since we may only have given warnings
IntrinsicExtensionBinding, reqTypars
Expand All @@ -4253,7 +4253,7 @@ module TcDeclarations =
errorR(Error(FSComp.SR.tcMembersThatExtendInterfaceMustBePlacedInSeparateModule(), tcref.Range))
if nReqTypars <> synTypars.Length then
error(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m))
if not (typarsAEquiv g TypeEquivEnv.Empty reqTypars declaredTypars) then
if not (typarsAEquiv g (TypeEquivEnv.EmptyWithNullChecks g) reqTypars declaredTypars) then
errorR(Error(FSComp.SR.tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars), m))
ExtrinsicExtensionBinding, declaredTypars

Expand Down Expand Up @@ -5695,7 +5695,7 @@ let CheckModuleSignature g (cenv: cenv) m denvAtEnd rootSigOpt implFileTypePrior
|]

// We want to show imperative type variables in any types in error messages at this late point
let denv = { denvAtEnd with showInferenceTyparAnnotations=true }
let denv = { denvAtEnd with showInferenceTyparAnnotations=true;showNullnessAnnotations=Some g.checkNullness }
try

// As typechecked the signature and implementation use different tycons etc.
Expand All @@ -5707,7 +5707,7 @@ let CheckModuleSignature g (cenv: cenv) m denvAtEnd rootSigOpt implFileTypePrior
// Compute the remapping from implementation to signature
let remapInfo, _ = ComputeRemappingFromInferredSignatureToExplicitSignature g implFileTypePriorToSig sigFileType

let aenv = { TypeEquivEnv.Empty with EquivTycons = TyconRefMap.OfList remapInfo.RepackagedEntities }
let aenv = { TypeEquivEnv.EmptyWithNullChecks g with EquivTycons = TyconRefMap.OfList remapInfo.RepackagedEntities }

if not (SignatureConformance.Checker(g, cenv.amap, denv, remapInfo, true).CheckSignature aenv cenv.infoReader (mkLocalModuleRef implFileSpecPriorToSig) sigFileType) then
// We can just raise 'ReportedError' since CheckModuleOrNamespace raises its own error
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/ConstraintSolver.fs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ let MakeConstraintSolverEnv contextInfo css m denv =
eContextInfo = contextInfo
MatchingOnly = false
ErrorOnFailedMemberConstraintResolution = false
EquivEnv = TypeEquivEnv.Empty
EquivEnv = TypeEquivEnv.EmptyIgnoreNulls
DisplayEnv = denv
IsSpeculativeForMethodOverloading = false
IsSupportsNullFlex = false
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/Expressions/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12670,7 +12670,7 @@ and FixupLetrecBind (cenv: cenv) denv generalizedTyparsForRecursiveBlock (bind:
| Some _ ->
match PartitionValTyparsForApparentEnclosingType g vspec with
| Some(parentTypars, memberParentTypars, _, _, _) ->
ignore(SignatureConformance.Checker(g, cenv.amap, denv, SignatureRepackageInfo.Empty, false).CheckTypars vspec.Range TypeEquivEnv.Empty memberParentTypars parentTypars)
ignore(SignatureConformance.Checker(g, cenv.amap, denv, SignatureRepackageInfo.Empty, false).CheckTypars vspec.Range TypeEquivEnv.EmptyIgnoreNulls memberParentTypars parentTypars)
| None ->
errorR(Error(FSComp.SR.tcMemberIsNotSufficientlyGeneric(), vspec.Range))
| _ -> ()
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Checking/MethodOverrides.fs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ module DispatchSlotChecking =
// Compare the types. CompiledSigOfMeth, GetObjectExprOverrideInfo and GetTypeMemberOverrideInfo have already
// applied all relevant substitutions except the renamings from fvtmps <-> methTypars

let aenv = TypeEquivEnv.FromEquivTypars fvmethTypars methTypars
let aenv = (TypeEquivEnv.EmptyIgnoreNulls).FromEquivTypars fvmethTypars methTypars

List.forall2 (List.lengthsEqAndForall2 (typeAEquiv g aenv)) vargTys argTys &&
returnTypesAEquiv g aenv vrty retTy &&
Expand Down Expand Up @@ -305,7 +305,7 @@ module DispatchSlotChecking =
ComposeTyparInsts ttpinst (ReverseTyparRenaming g memberToParentInst)

// Compare under the composed substitutions
let aenv = TypeEquivEnv.FromTyparInst ttpinst
let aenv = (TypeEquivEnv.EmptyIgnoreNulls).FromTyparInst ttpinst

typarsAEquiv g aenv fvmethTypars methTypars

Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/NicePrint.fs
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ module PrintTypes =
|> ListSet.setify (fun (_, cx1) (_, cx2) ->
match cx1, cx2 with
| TyparConstraint.MayResolveMember(traitInfo1, _),
TyparConstraint.MayResolveMember(traitInfo2, _) -> traitsAEquiv denv.g TypeEquivEnv.Empty traitInfo1 traitInfo2
TyparConstraint.MayResolveMember(traitInfo2, _) -> traitsAEquiv denv.g (TypeEquivEnv.EmptyWithNullChecks denv.g) traitInfo1 traitInfo2
| _ -> false)

let cxsL = List.collect (layoutConstraintWithInfo denv env) cxs
Expand Down
42 changes: 32 additions & 10 deletions src/Compiler/Checking/SignatureConformance.fs
Original file line number Diff line number Diff line change
Expand Up @@ -352,14 +352,22 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) =
else
let implTypars, implValTy = implVal.GeneralizedType
let sigTypars, sigValTy = sigVal.GeneralizedType
if implTypars.Length <> sigTypars.Length then (err {denv with showTyparBinding=true} FSComp.SR.ValueNotContainedMutabilityParameterCountsDiffer) else
let aenv = aenv.BindEquivTypars implTypars sigTypars
checkTypars m aenv implTypars sigTypars &&
if not (typeAEquiv g aenv implValTy sigValTy) then err denv FSComp.SR.ValueNotContainedMutabilityTypesDiffer
elif not (checkValInfo aenv (err denv) implVal sigVal) then false
elif implVal.IsExtensionMember <> sigVal.IsExtensionMember then err denv FSComp.SR.ValueNotContainedMutabilityExtensionsDiffer
elif not (checkMemberDatasConform (err denv) (implVal.Attribs, implVal, implVal.MemberInfo) (sigVal.Attribs, sigVal, sigVal.MemberInfo)) then false
else checkAttribs aenv implVal.Attribs sigVal.Attribs (fun attribs -> implVal.SetAttribs attribs)
if implTypars.Length <> sigTypars.Length then (err {denv with showTyparBinding=true} FSComp.SR.ValueNotContainedMutabilityParameterCountsDiffer)
else
let aenv = aenv.BindEquivTypars implTypars sigTypars
checkTypars m aenv implTypars sigTypars &&
let strictTyEquals = typeAEquiv g aenv implValTy sigValTy
let onlyDiffersInNullness = not(strictTyEquals) && g.checkNullness && typeAEquiv g {aenv with NullnessMustEqual = false} implValTy sigValTy

// The types would be equal if we did not have nullness checks => lets just generate a warning, not an error
if onlyDiffersInNullness then
warning(mk_err denv FSComp.SR.ValueNotContainedMutabilityTypesDiffer)

if not strictTyEquals && not onlyDiffersInNullness then err denv FSComp.SR.ValueNotContainedMutabilityTypesDiffer
elif not (checkValInfo aenv (err denv) implVal sigVal) then false
elif implVal.IsExtensionMember <> sigVal.IsExtensionMember then err denv FSComp.SR.ValueNotContainedMutabilityExtensionsDiffer
elif not (checkMemberDatasConform (err denv) (implVal.Attribs, implVal, implVal.MemberInfo) (sigVal.Attribs, sigVal, sigVal.MemberInfo)) then false
else checkAttribs aenv implVal.Attribs sigVal.Attribs (fun attribs -> implVal.SetAttribs attribs)


and checkExnInfo err aenv (infoReader: InfoReader) (enclosingImplTycon: Tycon) (enclosingSigTycon: Tycon) implTypeRepr sigTypeRepr =
Expand Down Expand Up @@ -394,15 +402,29 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) =
and checkField aenv infoReader (enclosingImplTycon: Tycon) (enclosingSigTycon: Tycon) implField sigField =
implField.SetOtherXmlDoc(sigField.XmlDoc)

let err f = errorR(FieldNotContained(denv, infoReader, enclosingImplTycon, enclosingSigTycon, implField, sigField, f)); false
let diag f = FieldNotContained(denv, infoReader, enclosingImplTycon, enclosingSigTycon, implField, sigField, f)
let err f = errorR(diag f); false

let areTypesDifferent() =
let strictTyEquals = typeAEquiv g aenv implField.FormalType sigField.FormalType
let onlyDiffersInNullness = not(strictTyEquals) && g.checkNullness && typeAEquiv g {aenv with NullnessMustEqual = false} implField.FormalType sigField.FormalType

// The types would be equal if we did not have nullness checks => lets just generate a warning, not an error
if onlyDiffersInNullness then
warning(diag FSComp.SR.FieldNotContainedTypesDiffer)
false
else
not strictTyEquals


sigField.rfield_other_range <- Some (implField.Range, true)
implField.rfield_other_range <- Some (sigField.Range, false)
if implField.rfield_id.idText <> sigField.rfield_id.idText then err FSComp.SR.FieldNotContainedNamesDiffer
elif isLessAccessible implField.Accessibility sigField.Accessibility then err FSComp.SR.FieldNotContainedAccessibilitiesDiffer
elif implField.IsStatic <> sigField.IsStatic then err FSComp.SR.FieldNotContainedStaticsDiffer
elif implField.IsMutable <> sigField.IsMutable then err FSComp.SR.FieldNotContainedMutablesDiffer
elif implField.LiteralValue <> sigField.LiteralValue then err FSComp.SR.FieldNotContainedLiteralsDiffer
elif not (typeAEquiv g aenv implField.FormalType sigField.FormalType) then err FSComp.SR.FieldNotContainedTypesDiffer
elif areTypesDifferent() then err FSComp.SR.FieldNotContainedTypesDiffer
else
checkAttribs aenv implField.FieldAttribs sigField.FieldAttribs (fun attribs -> implField.rfield_fattribs <- attribs) &&
checkAttribs aenv implField.PropertyAttribs sigField.PropertyAttribs (fun attribs -> implField.rfield_pattribs <- attribs)
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Checking/infos.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2503,7 +2503,7 @@ let MethInfosEquivByPartialSig erasureFlag ignoreFinal g amap m (minfo: MethInfo
let argTys = minfo.GetParamTypes(amap, m, fminst)
let argTys2 = minfo2.GetParamTypes(amap, m, fminst2)
(argTys, argTys2) ||> List.lengthsEqAndForall2 (List.lengthsEqAndForall2 (fun ty1 ty2 ->
typeAEquivAux erasureFlag g (TypeEquivEnv.FromEquivTypars formalMethTypars formalMethTypars2) (stripByrefTy g ty1) (stripByrefTy g ty2)))
typeAEquivAux erasureFlag g (TypeEquivEnv.EmptyIgnoreNulls.FromEquivTypars formalMethTypars formalMethTypars2) (stripByrefTy g ty1) (stripByrefTy g ty2)))

/// Used to hide/filter members from super classes based on signature
/// Inref and outref parameter types will be treated as a byref type for equivalency.
Expand All @@ -2525,7 +2525,7 @@ let MethInfosEquivByNameAndSig erasureFlag ignoreFinal g amap m minfo minfo2 =
let (CompiledSig(_, retTy2, formalMethTypars2, _)) = CompiledSigOfMeth g amap m minfo2
match retTy, retTy2 with
| None, None -> true
| Some retTy, Some retTy2 -> typeAEquivAux erasureFlag g (TypeEquivEnv.FromEquivTypars formalMethTypars formalMethTypars2) retTy retTy2
| Some retTy, Some retTy2 -> typeAEquivAux erasureFlag g (TypeEquivEnv.EmptyIgnoreNulls.FromEquivTypars formalMethTypars formalMethTypars2) retTy retTy2
| _ -> false

/// Used to hide/filter members from super classes based on signature
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/DependencyManager/AssemblyResolveHandler.fs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ type AssemblyResolveHandler internal (assemblyProbingPaths: AssemblyResolutionPr
else
new AssemblyResolveHandlerDeskTop(assemblyProbingPaths) :> IDisposable)

new(assemblyProbingPaths: AssemblyResolutionProbe MaybeNull) = new AssemblyResolveHandler(Option.ofObj assemblyProbingPaths)
new(assemblyProbingPaths: AssemblyResolutionProbe | null) = new AssemblyResolveHandler(Option.ofObj assemblyProbingPaths)

interface IDisposable with
member _.Dispose() =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type AssemblyResolutionProbe = delegate of Unit -> seq<string>
type AssemblyResolveHandler =

/// Construct a new DependencyProvider
new: assemblyProbingPaths: AssemblyResolutionProbe -> AssemblyResolveHandler
new: assemblyProbingPaths: AssemblyResolutionProbe|null -> AssemblyResolveHandler

/// Construct a new DependencyProvider
internal new: assemblyProbingPaths: AssemblyResolutionProbe option -> AssemblyResolveHandler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ type NativeDllResolveHandler(nativeProbingRoots: NativeResolutionProbe option) =
|> Option.filter (fun _ -> isRunningOnCoreClr)
|> Option.map (fun _ -> new NativeDllResolveHandlerCoreClr(nativeProbingRoots))

new(nativeProbingRoots: NativeResolutionProbe MaybeNull) = new NativeDllResolveHandler(Option.ofObj nativeProbingRoots)
new(nativeProbingRoots: NativeResolutionProbe | null) = new NativeDllResolveHandler(Option.ofObj nativeProbingRoots)

member internal _.RefreshPathsInEnvironment(roots: string seq) =
handler |> Option.iter (fun handler -> handler.RefreshPathsInEnvironment(roots))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type NativeResolutionProbe = delegate of Unit -> seq<string>
type NativeDllResolveHandler =

/// Construct a new NativeDllResolveHandler
new: nativeProbingRoots: NativeResolutionProbe -> NativeDllResolveHandler
new: nativeProbingRoots: NativeResolutionProbe|null -> NativeDllResolveHandler

/// Construct a new NativeDllResolveHandler
internal new: nativeProbingRoots: NativeResolutionProbe option -> NativeDllResolveHandler
Expand Down
7 changes: 5 additions & 2 deletions src/Compiler/Driver/ParseAndCheckInputs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1907,7 +1907,10 @@ let CheckMultipleInputsUsingGraphMode
let (Finisher(finisher = finisher)) =
cancellable {
use _ = UseDiagnosticsLogger logger
let checkForErrors2 () = priorErrors || (logger.ErrorCount > 0)

let checkForErrors2 () =
priorErrors || (logger.CheckForRealErrorsIgnoringWarnings)

let tcSink = TcResultsSink.NoSink

return!
Expand All @@ -1922,7 +1925,7 @@ let CheckMultipleInputsUsingGraphMode
(fun (state: State) ->
let tcState, priorErrors = state
let (partialResult: PartialResult, tcState) = finisher tcState
let hasErrors = logger.ErrorCount > 0
let hasErrors = logger.CheckForRealErrorsIgnoringWarnings
let priorOrCurrentErrors = priorErrors || hasErrors
let state: State = tcState, priorOrCurrentErrors
partialResult, state)
Expand Down
4 changes: 4 additions & 0 deletions src/Compiler/FSharp.Compiler.Service.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
<NoWarn>$(NoWarn);NU5125</NoWarn>
<NoWarn>$(NoWarn);64;1182;1204</NoWarn> <!--Temporary fix for sourcebuild -->
<OtherFlags>$(OtherFlags) --warnaserror-:1182</OtherFlags> <!--Temporary fix for sourcebuild -->
<OtherFlags>$(OtherFlags) --warnaserror-:34</OtherFlags>
<OtherFlags>$(OtherFlags) --warnaserror-:193</OtherFlags>
<!-- for the love of god I cannot see all errors at once -->

<AssemblyName>FSharp.Compiler.Service</AssemblyName>
<AllowCrossTargeting>true</AllowCrossTargeting>
<DefineConstants>$(DefineConstants);COMPILER</DefineConstants>
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/Facilities/CompilerLocation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module internal FSharpEnvironment =
let FSharpCoreLibRunningVersion =
try
match versionOf<Unit> with
| null -> None
| s when String.IsNullOrEmpty(s) -> None
| s -> Some(s)
with _ ->
Expand Down
3 changes: 1 addition & 2 deletions src/Compiler/Facilities/DiagnosticsLogger.fs
Original file line number Diff line number Diff line change
Expand Up @@ -795,8 +795,7 @@ let NewlineifyErrorString (message: string) =
/// fixes given string by replacing all control chars with spaces.
/// NOTE: newlines are recognized and replaced with stringThatIsAProxyForANewlineInFlatErrors (ASCII 29, the 'group separator'),
/// which is decoded by the IDE with 'NewlineifyErrorString' back into newlines, so that multi-line errors can be displayed in QuickInfo
let NormalizeErrorString (text: string MaybeNull) =
let text = nullArgCheck "text" text
let NormalizeErrorString (text: string) =
let text = text.Trim()

let buf = System.Text.StringBuilder()
Expand Down
5 changes: 3 additions & 2 deletions src/Compiler/Facilities/prim-parsing.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Internal.Utilities.Text.Parsing

open Internal.Utilities.Text.Lexing
open Internal.Utilities.Library

open System
open System.Buffers
Expand All @@ -28,7 +29,7 @@ type internal IParseState

member _.ResultEndPosition = lhsPos[1]

member _.GetInput index = ruleValues[index - 1]
member _.GetInput index = !!ruleValues[index - 1]

member _.ResultRange = (lhsPos[0], lhsPos[1])

Expand Down Expand Up @@ -572,7 +573,7 @@ module internal Implementation =
else if Flags.debug then
Console.WriteLine("ALARM!!! drop through case in parser")
// OK, we're done - read off the overall generated value
valueStack.Peep().value
!!valueStack.Peep().value

type internal Tables<'Token> with

Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/SyntaxTree/PrettyNaming.fs
Original file line number Diff line number Diff line change
Expand Up @@ -670,8 +670,8 @@ let IsLogicalPrefixOperator logicalName =
if String.IsNullOrEmpty logicalName then
false
else
let displayName = ConvertValLogicalNameToDisplayNameCore !!logicalName
displayName <> !!logicalName && IsValidPrefixOperatorDefinitionName displayName
let displayName = ConvertValLogicalNameToDisplayNameCore logicalName
displayName <> logicalName && IsValidPrefixOperatorDefinitionName displayName

let IsLogicalTernaryOperator logicalName =
let displayName = ConvertValLogicalNameToDisplayNameCore logicalName
Expand Down
Loading
Loading