Add -Wderiving-defaults (#15839)
authorKari Pahula <kaol@iki.fi>
Tue, 24 Sep 2019 13:33:15 +0000 (16:33 +0300)
committerMarge Bot <ben+marge-bot@smart-cactus.org>
Wed, 25 Sep 2019 17:52:48 +0000 (13:52 -0400)
Enabling both DeriveAnyClass and GeneralizedNewtypeDeriving can cause
a warning when no explicit deriving strategy is in use. This change adds
an enable/suppress flag for it.

compiler/main/DynFlags.hs
compiler/typecheck/TcDeriv.hs
docs/users_guide/8.10.1-notes.rst
docs/users_guide/using-warnings.rst
testsuite/tests/deriving/should_compile/T16179.stderr
testsuite/tests/typecheck/should_compile/T15839a.hs [new file with mode: 0644]
testsuite/tests/typecheck/should_compile/T15839a.stderr [new file with mode: 0644]
testsuite/tests/typecheck/should_compile/T15839b.hs [new file with mode: 0644]
testsuite/tests/typecheck/should_compile/all.T

index 5bd8cb8..45a465b 100644 (file)
@@ -920,6 +920,7 @@ data WarningFlag =
    | Opt_WarnUnusedPackages               -- Since 8.10
    | Opt_WarnInferredSafeImports          -- Since 8.10
    | Opt_WarnMissingSafeHaskellMode       -- Since 8.10
+   | Opt_WarnDerivingDefaults
    deriving (Eq, Show, Enum)
 
 data Language = Haskell98 | Haskell2010
@@ -4026,6 +4027,7 @@ wWarningFlagsDeps = [
                                          Opt_WarnDeferredOutOfScopeVariables,
   flagSpec "deprecations"                Opt_WarnWarningsDeprecations,
   flagSpec "deprecated-flags"            Opt_WarnDeprecatedFlags,
+  flagSpec "deriving-defaults"           Opt_WarnDerivingDefaults,
   flagSpec "deriving-typeable"           Opt_WarnDerivingTypeable,
   flagSpec "dodgy-exports"               Opt_WarnDodgyExports,
   flagSpec "dodgy-foreign-imports"       Opt_WarnDodgyForeignImports,
@@ -4824,6 +4826,7 @@ standardWarnings -- see Note [Documenting warning flags]
         Opt_WarnPartialTypeSignatures,
         Opt_WarnUnrecognisedPragmas,
         Opt_WarnDuplicateExports,
+        Opt_WarnDerivingDefaults,
         Opt_WarnOverflowedLiterals,
         Opt_WarnEmptyEnumerations,
         Opt_WarnMissingFields,
index 0b78b8e..d2b32e7 100644 (file)
@@ -1756,7 +1756,8 @@ mkNewTypeEqn
                  -- DeriveAnyClass, but emitting a warning about the choice.
                  -- See Note [Deriving strategies]
                  when (newtype_deriving && deriveAnyClass) $
-                   lift $ addWarnTc NoReason $ sep
+                   lift $ whenWOptM Opt_WarnDerivingDefaults $
+                     addWarnTc (Reason Opt_WarnDerivingDefaults) $ sep
                      [ text "Both DeriveAnyClass and"
                        <+> text "GeneralizedNewtypeDeriving are enabled"
                      , text "Defaulting to the DeriveAnyClass strategy"
index 2ca9ce5..e8316d7 100644 (file)
@@ -90,6 +90,16 @@ Language
   for a ``newtype``. This was proposed in
   `GHC proposal #13 <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0013-unlifted-newtypes.rst>`__.
 
+- New flag :ghc-flag:`-Wderiving-defaults` that controls a warning
+  message when both :extension:`DeriveAnyClass` and
+  :extension:`GeneralizedNewtypeDeriving` are enabled and no explicit
+  deriving strategy is in use. The warning is enabled by default and
+  has been present in earlier GHC versions but without the option of
+  disabling it.  For example, this code would trigger the warning: ::
+
+    class C a
+    newtype T a = MkT a deriving C
+
 Compiler
 ~~~~~~~~
 
index dda7bb6..31060d7 100644 (file)
@@ -26,6 +26,7 @@ generally likely to indicate bugs in your program. These are:
     * :ghc-flag:`-Wdeprecated-flags`
     * :ghc-flag:`-Wunrecognised-pragmas`
     * :ghc-flag:`-Wduplicate-exports`
+    * :ghc-flag:`-Wderiving-defaults`
     * :ghc-flag:`-Woverflowed-literals`
     * :ghc-flag:`-Wempty-enumerations`
     * :ghc-flag:`-Wmissing-fields`
@@ -640,6 +641,23 @@ of ``-W(no-)*``.
     Causes a warning to be emitted if an enumeration is empty, e.g.
     ``[5 .. 3]``.
 
+.. ghc-flag:: -Wderiving-defaults
+    :shortdesc: warn about default deriving when using both
+        DeriveAnyClass and GeneralizedNewtypeDeriving
+    :type: dynamic
+    :reverse: -Wno-deriving-defaults
+    :category:
+
+    :since: 8.10
+
+    Causes a warning when both :ref:`DeriveAnyClass` and
+    :ref:`GeneralizedNewtypeDeriving` are enabled and no explicit
+    deriving strategy is in use.  For example, this would result a
+    warning: ::
+
+        class C a
+        newtype T a = MkT a deriving C
+
 .. ghc-flag:: -Wduplicate-constraints
     :shortdesc: warn when a constraint appears duplicated in a type signature
     :type: dynamic
index c3815d1..ae40e85 100644 (file)
@@ -1,5 +1,6 @@
-T16179.hs:7:30: warning:
-     Both DeriveAnyClass and GeneralizedNewtypeDeriving are enabled
+
+T16179.hs:7:30: warning: [-Wderiving-defaults (in -Wdefault)]
+    • Both DeriveAnyClass and GeneralizedNewtypeDeriving are enabled
       Defaulting to the DeriveAnyClass strategy for instantiating C
       Use DerivingStrategies to pick a different strategy
-     In the newtype declaration for ‘T’
+     In the newtype declaration for ‘T’
diff --git a/testsuite/tests/typecheck/should_compile/T15839a.hs b/testsuite/tests/typecheck/should_compile/T15839a.hs
new file mode 100644 (file)
index 0000000..28763aa
--- /dev/null
@@ -0,0 +1,6 @@
+{-# LANGUAGE DeriveAnyClass, GeneralizedNewtypeDeriving #-}
+
+module T15839a () where
+
+class C a
+newtype T a = MkT a deriving C
diff --git a/testsuite/tests/typecheck/should_compile/T15839a.stderr b/testsuite/tests/typecheck/should_compile/T15839a.stderr
new file mode 100644 (file)
index 0000000..b4aef83
--- /dev/null
@@ -0,0 +1,6 @@
+
+T15839a.hs:6:30: warning: [-Wderiving-defaults (in -Wdefault)]
+    • Both DeriveAnyClass and GeneralizedNewtypeDeriving are enabled
+      Defaulting to the DeriveAnyClass strategy for instantiating C
+      Use DerivingStrategies to pick a different strategy
+    • In the newtype declaration for ‘T’
diff --git a/testsuite/tests/typecheck/should_compile/T15839b.hs b/testsuite/tests/typecheck/should_compile/T15839b.hs
new file mode 100644 (file)
index 0000000..02b9bfb
--- /dev/null
@@ -0,0 +1,8 @@
+{-# LANGUAGE DeriveAnyClass, GeneralizedNewtypeDeriving #-}
+
+{-# OPTIONS_GHC -Wno-deriving-defaults #-}
+
+module T15839a () where
+
+class C a
+newtype T a = MkT a deriving C
index e359f8d..30a6451 100644 (file)
@@ -689,3 +689,5 @@ test('T16946', normal, compile, [''])
 test('T17007', normal, compile, [''])
 test('T17067', normal, compile, [''])
 test('T17202', expect_broken(17202), compile, [''])
+test('T15839a', normal, compile, [''])
+test('T15839b', normal, compile, [''])