From 346a59f93edb3aee3133e2a34ec10925e654c40b Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 16 Oct 2024 13:39:58 +0100 Subject: [PATCH] Better error range for `struct` and restricted super types `inherit` (#17886) * Better error range for struct inherit * CheckSuperType * release notes * E_RestrictedSuperTypes * neg6.bsl * neg4.bsl --- .../.FSharp.Compiler.Service/9.0.200.md | 1 + src/Compiler/Checking/CheckDeclarations.fs | 19 +++++++++++------- .../Checking/Expressions/CheckExpressions.fs | 2 +- .../Types/StructTypes/E_Inheritance.fs | 7 +++++++ .../Types/StructTypes/StructTypes.fs | 12 +++++++++++ .../ErrorMessages/ClassesTests.fs | 19 ++++++++++++++++++ tests/fsharp/typeProviders/negTests/neg4.bsl | 8 ++++---- tests/fsharp/typeProviders/negTests/neg6.bsl | 12 +++++------ .../ClassTypes/Misc/E_RestrictedSuperTypes.fs | 20 +++++++++---------- .../TypeKindInference/infer_interface002e.fs | 4 ++-- 10 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/Types/StructTypes/E_Inheritance.fs diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md index 185fa3a015..a7d549b23b 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md @@ -21,5 +21,6 @@ * Better ranges for CE `match!`. ([PR #17789](https://github.com/dotnet/fsharp/pull/17789)) * Better ranges for CE `use` error reporting. ([PR #17811](https://github.com/dotnet/fsharp/pull/17811)) * Better ranges for `inherit` error reporting. ([PR #17879](https://github.com/dotnet/fsharp/pull/17879)) +* Better ranges for `inherit` `struct` error reporting. ([PR #17886](https://github.com/dotnet/fsharp/pull/17886)) ### Breaking Changes diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 814374417d..31ce9be573 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3322,7 +3322,7 @@ module EstablishTypeDefinitionCores = | SynTypeDefnSimpleRepr.Record _ -> if tycon.IsStructRecordOrUnionTycon then Some(g.system_Value_ty) else None - | SynTypeDefnSimpleRepr.General (kind, _, slotsigs, fields, isConcrete, _, _, _) -> + | SynTypeDefnSimpleRepr.General (kind, inherits, slotsigs, fields, isConcrete, _, _, _) -> let kind = InferTyconKind g (kind, attrs, slotsigs, fields, inSig, isConcrete, m) match inheritedTys with @@ -3333,15 +3333,20 @@ module EstablishTypeDefinitionCores = | SynTypeDefnKind.Opaque | SynTypeDefnKind.Class | SynTypeDefnKind.Interface -> None | _ -> error(InternalError("should have inferred tycon kind", m)) - | [(ty, m)] -> - if not firstPass && not (match kind with SynTypeDefnKind.Class -> true | _ -> false) then - errorR (Error(FSComp.SR.tcStructsInterfacesEnumsDelegatesMayNotInheritFromOtherTypes(), m)) - CheckSuperType cenv ty m + | [(ty, m)] -> + let inheritRange = + match inherits with + | [] -> m + | (synType, _, _) :: _ -> synType.Range + if not firstPass && not (match kind with SynTypeDefnKind.Class -> true | _ -> false) then + errorR (Error(FSComp.SR.tcStructsInterfacesEnumsDelegatesMayNotInheritFromOtherTypes(), inheritRange)) + CheckSuperType cenv ty inheritRange if isTyparTy g ty then if firstPass then - errorR(Error(FSComp.SR.tcCannotInheritFromVariableType(), m)) + errorR(Error(FSComp.SR.tcCannotInheritFromVariableType(), inheritRange)) Some g.obj_ty_noNulls // a "super" that is a variable type causes grief later - else + else + Some ty | _ -> error(Error(FSComp.SR.tcTypesCannotInheritFromMultipleConcreteTypes(), m)) diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index 4325d50320..30375d047f 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -7140,7 +7140,7 @@ and CheckSuperType (cenv: cenv) ty m = typeEquiv g ty g.system_Array_ty || typeEquiv g ty g.system_MulticastDelegate_ty || typeEquiv g ty g.system_Delegate_ty then - error(Error(FSComp.SR.tcPredefinedTypeCannotBeUsedAsSuperType(), m)) + errorR(Error(FSComp.SR.tcPredefinedTypeCannotBeUsedAsSuperType(), m)) if isErasedType g ty then errorR(Error(FSComp.SR.tcCannotInheritFromErasedType(), m)) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/StructTypes/E_Inheritance.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/StructTypes/E_Inheritance.fs new file mode 100644 index 0000000000..4407d0dafe --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/StructTypes/E_Inheritance.fs @@ -0,0 +1,7 @@ +type TK_I_005 = + abstract M : unit -> unit + +[] +type TK_I_006b = + inherit TK_I_005 + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/StructTypes/StructTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/StructTypes/StructTypes.fs index 95f228de96..95e1cb2e4a 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/StructTypes/StructTypes.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/StructTypes/StructTypes.fs @@ -38,3 +38,15 @@ module StructTypes = |> shouldSucceed |> ignore + [] + let ``StructTypes - E_Inheritance.fs`` compilation = + compilation + |> asFsx + |> withOptions ["--warnaserror+"; "--nowarn:988"] + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 931, Line 6, Col 12, Line 6, Col 20, "Structs, interfaces, enums and delegates cannot inherit from other types"); + (Error 946, Line 6, Col 12, Line 6, Col 20, "Cannot inherit from interface type. Use interface ... with instead.") + ] + diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs index 44e8e202a9..f902fa1436 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ClassesTests.fs @@ -830,4 +830,23 @@ type Class() = |> withDiagnostics [ (Error 961, Line 5, Col 5, Line 5, Col 12, "This 'inherit' declaration specifies the inherited type but no arguments. Consider supplying arguments, e.g. 'inherit BaseType(args)'.") (Error 946, Line 5, Col 13, Line 5, Col 15, "Cannot inherit from interface type. Use interface ... with instead.") + ] + + [] + let ``The types System.ValueType, System.Enum, System.Delegate, System.MulticastDelegate and System.Array cannot be used as super types in an object expression or class.`` () = + Fsx """ +type C1 = class inherit System.ValueType override x.ToString() = "" end +type C2 = class inherit System.Array override x.ToString() = "" end +type C3 = class inherit System.Enum override x.ToString() = "" end +type C4 = class inherit System.Delegate override x.ToString() = "" end +type C5 = class inherit System.MulticastDelegate override x.ToString() = "" end + """ + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 771, Line 2, Col 25, Line 2, Col 41, "The types System.ValueType, System.Enum, System.Delegate, System.MulticastDelegate and System.Array cannot be used as super types in an object expression or class"); + (Error 771, Line 3, Col 25, Line 3, Col 37, "The types System.ValueType, System.Enum, System.Delegate, System.MulticastDelegate and System.Array cannot be used as super types in an object expression or class"); + (Error 771, Line 4, Col 25, Line 4, Col 36, "The types System.ValueType, System.Enum, System.Delegate, System.MulticastDelegate and System.Array cannot be used as super types in an object expression or class") + (Error 771, Line 5, Col 25, Line 5, Col 40, "The types System.ValueType, System.Enum, System.Delegate, System.MulticastDelegate and System.Array cannot be used as super types in an object expression or class"); + (Error 771, Line 6, Col 25, Line 6, Col 49, "The types System.ValueType, System.Enum, System.Delegate, System.MulticastDelegate and System.Array cannot be used as super types in an object expression or class") ] \ No newline at end of file diff --git a/tests/fsharp/typeProviders/negTests/neg4.bsl b/tests/fsharp/typeProviders/negTests/neg4.bsl index 7f2259377c..a1ed652c2c 100644 --- a/tests/fsharp/typeProviders/negTests/neg4.bsl +++ b/tests/fsharp/typeProviders/negTests/neg4.bsl @@ -17,12 +17,12 @@ neg4.fsx(30,5,30,22): typecheck error FS3062: This type test with a provided typ neg4.fsx(36,5,36,28): typecheck error FS3060: This type test or downcast will erase the provided type 'HelloWorldType' to the type 'System.Object' -neg4.fsx(42,8,42,33): typecheck error FS3063: Cannot inherit from erased provided type +neg4.fsx(42,16,42,33): typecheck error FS3063: Cannot inherit from erased provided type -neg4.fsx(42,8,42,33): typecheck error FS3063: Cannot inherit from erased provided type +neg4.fsx(42,16,42,33): typecheck error FS3063: Cannot inherit from erased provided type -neg4.fsx(47,8,47,35): typecheck error FS3063: Cannot inherit from erased provided type +neg4.fsx(47,16,47,33): typecheck error FS3063: Cannot inherit from erased provided type -neg4.fsx(47,8,47,35): typecheck error FS3063: Cannot inherit from erased provided type +neg4.fsx(47,16,47,33): typecheck error FS3063: Cannot inherit from erased provided type neg4.fsx(52,25,52,42): typecheck error FS3063: Cannot inherit from erased provided type diff --git a/tests/fsharp/typeProviders/negTests/neg6.bsl b/tests/fsharp/typeProviders/negTests/neg6.bsl index 985dd48321..08c6c3166f 100644 --- a/tests/fsharp/typeProviders/negTests/neg6.bsl +++ b/tests/fsharp/typeProviders/negTests/neg6.bsl @@ -1,12 +1,12 @@ -neg6.fsx(8,3,8,27): typecheck error FS3063: Cannot inherit from erased provided type +neg6.fsx(8,11,8,25): typecheck error FS3063: Cannot inherit from erased provided type -neg6.fsx(8,3,8,27): typecheck error FS3063: Cannot inherit from erased provided type +neg6.fsx(8,11,8,25): typecheck error FS3063: Cannot inherit from erased provided type -neg6.fsx(11,3,11,30): typecheck error FS3063: Cannot inherit from erased provided type +neg6.fsx(11,11,11,28): typecheck error FS3063: Cannot inherit from erased provided type -neg6.fsx(11,3,11,30): typecheck error FS3063: Cannot inherit from erased provided type +neg6.fsx(11,11,11,28): typecheck error FS3063: Cannot inherit from erased provided type -neg6.fsx(14,3,14,35): typecheck error FS3063: Cannot inherit from erased provided type +neg6.fsx(14,11,14,33): typecheck error FS3063: Cannot inherit from erased provided type -neg6.fsx(14,3,14,35): typecheck error FS3063: Cannot inherit from erased provided type +neg6.fsx(14,11,14,33): typecheck error FS3063: Cannot inherit from erased provided type diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/Misc/E_RestrictedSuperTypes.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/Misc/E_RestrictedSuperTypes.fs index 4019069641..c973c28241 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/Misc/E_RestrictedSuperTypes.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/ClassTypes/Misc/E_RestrictedSuperTypes.fs @@ -5,16 +5,16 @@ //The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class //The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class //The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class -//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class -//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class -//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class -//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class -//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class -//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class -//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class -//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class -//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class -//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class +//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class +//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class +//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class +//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class +//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class +//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class +//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class +//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class +//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class +//The types System\.ValueType, System\.Enum, System\.Delegate, System\.MulticastDelegate and System\.Array cannot be used as super types in an object expression or class #light let o1 = { new System.ValueType with member x.ToString() = "" } diff --git a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeKindInference/infer_interface002e.fs b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeKindInference/infer_interface002e.fs index e5998a72c5..05074e12de 100644 --- a/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeKindInference/infer_interface002e.fs +++ b/tests/fsharpqa/Source/Conformance/ObjectOrientedTypeDefinitions/TypeKindInference/infer_interface002e.fs @@ -1,10 +1,10 @@ // #Regression #Conformance #ObjectOrientedTypes #TypeInference // attribute must match inferred type //The kind of the type specified by its attributes does not match the kind implied by its definition -//Structs, interfaces, enums and delegates cannot inherit from other types +//Structs, interfaces, enums and delegates cannot inherit from other types //Cannot inherit from interface type\. Use interface \.\.\. with instead //The kind of the type specified by its attributes does not match the kind implied by its definition -//Structs, interfaces, enums and delegates cannot inherit from other types +//Structs, interfaces, enums and delegates cannot inherit from other types //Cannot inherit from interface type\. Use interface \.\.\. with instead // An interface