Skip to content

Commit

Permalink
Fix PR suggestions and Add more testing
Browse files Browse the repository at this point in the history
  • Loading branch information
Edgar Gonzalez committed Jul 5, 2022
1 parent ffb11a4 commit 811eac2
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 13 deletions.
23 changes: 10 additions & 13 deletions src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -452,15 +452,15 @@ module TcRecdUnionAndEnumDeclarations =
// Bind other elements of type definitions (constructors etc.)
//-------------------------------------------------------------------------

let CheckUnionCaseName (cenv: cenv) (id: Ident) =
let CheckUnionCaseName (cenv: cenv) (id: Ident) hasRQAAttribute =
let g = cenv.g
let name = id.idText
if name = "Tags" then
errorR(Error(FSComp.SR.tcUnionCaseNameConflictsWithGeneratedType(name, "Tags"), id.idRange))

CheckNamespaceModuleOrTypeName g id

if not (String.isLeadingIdentifierCharacterUpperCase name) && name <> opNameCons && name <> opNameNil then
if not (String.isLeadingIdentifierCharacterUpperCase name) && not hasRQAAttribute && name <> opNameCons && name <> opNameNil then
errorR(NotUpperCaseConstructor(id.idRange))

let ValidateFieldNames (synFields: SynField list, tastFields: RecdField list) =
Expand All @@ -478,16 +478,13 @@ module TcRecdUnionAndEnumDeclarations =
| _ ->
seen.Add(f.LogicalName, sf))

let TcUnionCaseDecl (cenv: cenv) env parent thisTy thisTyInst tpenv (tycon: Tycon) (SynUnionCase(Attributes synAttrs, SynIdent(id, _), args, xmldoc, vis, m, _)) =
let TcUnionCaseDecl (cenv: cenv) env parent thisTy thisTyInst tpenv hasRQAAttribute (SynUnionCase(Attributes synAttrs, SynIdent(id, _), args, xmldoc, vis, m, _)) =
let g = cenv.g
let attrs = TcAttributes cenv env AttributeTargets.UnionCaseDecl synAttrs // the attributes of a union case decl get attached to the generated "static factory" method
let vis, _ = ComputeAccessAndCompPath env None m vis None parent
let vis = CombineReprAccess parent vis

let hasRequireQualifiedAccessAttribute = HasFSharpAttribute cenv.g cenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs

if not hasRequireQualifiedAccessAttribute then
CheckUnionCaseName cenv id
CheckUnionCaseName cenv id hasRQAAttribute

let rfields, recordTy =
match args with
Expand Down Expand Up @@ -528,8 +525,8 @@ module TcRecdUnionAndEnumDeclarations =
let xmlDoc = xmldoc.ToXmlDoc(true, Some names)
Construct.NewUnionCase id rfields recordTy attrs xmlDoc vis

let TcUnionCaseDecls (cenv: cenv) env (parent: ParentRef) (thisTy: TType) (thisTyInst: TypeInst) (tycon: Tycon) tpenv unionCases =
let unionCasesR = unionCases |> List.map (TcUnionCaseDecl cenv env parent thisTy thisTyInst tpenv tycon)
let TcUnionCaseDecls (cenv: cenv) env (parent: ParentRef) (thisTy: TType) (thisTyInst: TypeInst) hasRQAAttribute tpenv unionCases =
let unionCasesR = unionCases |> List.map (TcUnionCaseDecl cenv env parent thisTy thisTyInst tpenv hasRQAAttribute)
unionCasesR |> CheckDuplicates (fun uc -> uc.Id) "union case"

let TcEnumDecl cenv env parent thisTy fieldTy (SynEnumCase(attributes=Attributes synAttrs; ident= SynIdent(id,_); value=v; xmlDoc=xmldoc; range=m)) =
Expand Down Expand Up @@ -4056,9 +4053,8 @@ module EstablishTypeDefinitionCores =
structLayoutAttributeCheck false
noAllowNullLiteralAttributeCheck()

let hasRequireQualifiedAccessAttribute = HasFSharpAttribute cenv.g cenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs
if not hasRequireQualifiedAccessAttribute then
TcRecdUnionAndEnumDeclarations.CheckUnionCaseName cenv unionCaseName
let hasRQAAttribute = HasFSharpAttribute cenv.g cenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs
TcRecdUnionAndEnumDeclarations.CheckUnionCaseName cenv unionCaseName hasRQAAttribute
let unionCase = Construct.NewUnionCase unionCaseName [] thisTy [] XmlDoc.Empty tycon.Accessibility
writeFakeUnionCtorsToSink [ unionCase ]
Construct.MakeUnionRepr [ unionCase ], None, NoSafeInitInfo
Expand Down Expand Up @@ -4090,7 +4086,8 @@ module EstablishTypeDefinitionCores =
noAllowNullLiteralAttributeCheck()
structLayoutAttributeCheck false

let unionCases = TcRecdUnionAndEnumDeclarations.TcUnionCaseDecls cenv envinner innerParent thisTy thisTyInst tycon tpenv unionCases
let hasRQAAttribute = HasFSharpAttribute cenv.g cenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs
let unionCases = TcRecdUnionAndEnumDeclarations.TcUnionCaseDecls cenv envinner innerParent thisTy thisTyInst hasRQAAttribute tpenv unionCases
if tycon.IsStructRecordOrUnionTycon && unionCases.Length > 1 then
let fieldNames = [ for uc in unionCases do for ft in uc.FieldTable.TrueInstanceFieldsAsList do yield ft.LogicalName ]
if fieldNames |> List.distinct |> List.length <> fieldNames.Length then
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// #Conformance #TypesAndModules #Unions
// This testcase verifies that lower-case discriminated union are not allowed
//<Expects status="error"></Expects>
#light

type DU1 = | ``not.allowed``

type DU2 = ``not.allowed``

[<RequireQualifiedAccess>]
type DU3 = | ``not.allowed``

[<RequireQualifiedAccess>]
type DU4 = ``not.allowed``

type DU5 = | a

type DU6 = a

type du1 = du1 of string

type du2 = | du2 of string
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,25 @@ module UnionTypes =
|> verifyCompileAndRun
|> shouldSucceed

//SOURCE=E_LowercaseWhenRequireQualifiedAccess.fsx # E_LowercaseWhenRequireQualifiedAccess.fsx
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"E_LowercaseWhenRequireQualifiedAccess.fsx"|])>]
let ``E_LowercaseWhenRequireQualifiedAccess_fs`` compilation =
compilation
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 883, Line 6, Col 14, Line 6, Col 29, "Invalid namespace, module, type or union case name");
(Error 53, Line 6, Col 14, Line 6, Col 29, "Discriminated union cases and exception labels must be uppercase identifiers");
(Error 883, Line 8, Col 12, Line 8, Col 27, "Invalid namespace, module, type or union case name");
(Error 53, Line 8, Col 12, Line 8, Col 27, "Discriminated union cases and exception labels must be uppercase identifiers");
(Error 883, Line 11, Col 14, Line 11, Col 29, "Invalid namespace, module, type or union case name");
(Error 883, Line 14, Col 12, Line 14, Col 27, "Invalid namespace, module, type or union case name");
(Error 53, Line 16, Col 14, Line 16, Col 15, "Discriminated union cases and exception labels must be uppercase identifiers");
(Error 53, Line 18, Col 12, Line 18, Col 13, "Discriminated union cases and exception labels must be uppercase identifiers");
(Error 53, Line 20, Col 12, Line 20, Col 15, "Discriminated union cases and exception labels must be uppercase identifiers");
(Error 53, Line 22, Col 14, Line 22, Col 17, "Discriminated union cases and exception labels must be uppercase identifiers")
]

//SOURCE=W_GenericFunctionValuedStaticProp02.fs SCFLAGS="--test:ErrorRanges --warnaserror-" # W_GenericFunctionValuedStaticProp02.fs
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"W_GenericFunctionValuedStaticProp02.fs"|])>]
let ``W_GenericFunctionValuedStaticProp02_fs`` compilation =
Expand Down

0 comments on commit 811eac2

Please sign in to comment.