diff --git a/compiler/GHC/Rename/Module.hs b/compiler/GHC/Rename/Module.hs index d83e03e89a6002ec4509599913246d50a6667013..5a7bc7ce827e45a74db0aba495bf7df358595c12 100644 --- a/compiler/GHC/Rename/Module.hs +++ b/compiler/GHC/Rename/Module.hs @@ -1128,12 +1128,10 @@ rnSrcDerivDecl (DerivDecl (inst_warn_ps, ann) ty mds overlap) ; addNoNestedForallsContextsErr ctxt NFC_StandaloneDerivedInstanceHead (getLHsInstDeclHead $ dropWildCards ty') - ; warnNoDerivStrat mds' loc ; inst_warn_rn <- mapM rnLWarningTxt inst_warn_ps ; return (DerivDecl (inst_warn_rn, ann) ty' mds' overlap, fvs) } where ctxt = DerivDeclCtx - loc = getLocA nowc_ty nowc_ty = dropWildCards ty {- @@ -2108,18 +2106,6 @@ The main parts of the implementation are: -} -warnNoDerivStrat :: Maybe (LDerivStrategy GhcRn) - -> SrcSpan - -> RnM () -warnNoDerivStrat mds loc - = do { dyn_flags <- getDynFlags - ; case mds of - Nothing -> - addDiagnosticAt loc $ TcRnNoDerivStratSpecified - (xopt LangExt.DerivingStrategies dyn_flags) - _ -> pure () - } - rnLHsDerivingClause :: HsDocContext -> LHsDerivingClause GhcPs -> RnM (LHsDerivingClause GhcRn, FreeVars) rnLHsDerivingClause doc @@ -2129,7 +2115,6 @@ rnLHsDerivingClause doc , deriv_clause_tys = dct })) = do { (dcs', dct', fvs) <- rnLDerivStrategy doc dcs $ rn_deriv_clause_tys dct - ; warnNoDerivStrat dcs' (locA loc) ; pure ( L loc (HsDerivingClause { deriv_clause_ext = noExtField , deriv_clause_strategy = dcs' , deriv_clause_tys = dct' }) diff --git a/compiler/GHC/Tc/Deriv.hs b/compiler/GHC/Tc/Deriv.hs index e431a4f2a686b248bb5484912188ddf9ebba4226..98a379d2078d0920d5d355bd6af57deceb1814ad 100644 --- a/compiler/GHC/Tc/Deriv.hs +++ b/compiler/GHC/Tc/Deriv.hs @@ -48,6 +48,7 @@ import GHC.Core.Type import GHC.Utils.Error import GHC.Core.DataCon import GHC.Data.Maybe +import GHC.Types.Hint (AssumedDerivingStrategy(..)) import GHC.Types.Name.Reader import GHC.Types.Name import GHC.Types.Name.Set as NameSet @@ -71,6 +72,8 @@ import Control.Monad import Control.Monad.Trans.Class import Control.Monad.Trans.Reader import Data.List (partition, find) +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map {- ************************************************************************ @@ -415,6 +418,76 @@ in derived code. @makeDerivSpecs@ fishes around to find the info about needed derived instances. -} +mechanismToAssumedStrategy :: DerivSpecMechanism -> Maybe AssumedDerivingStrategy +mechanismToAssumedStrategy = \case + DerivSpecStock{} -> Just AssumedStockStrategy + DerivSpecAnyClass{} -> Just AssumedAnyclassStrategy + DerivSpecNewtype{} -> Just AssumedNewtypeStrategy + DerivSpecVia{} -> Nothing -- `via` is never assumed, it is always explicit + +warnNoDerivingClauseStrategy + :: Maybe (LDerivStrategy GhcTc) + -- ^ The given deriving strategy, if any. + -> [(LHsSigType GhcRn, EarlyDerivSpec)] + -- ^ The given deriving predicates of a deriving clause (for example 'Show' & + -- 'Eq' in @deriving (Show, Eq)@) along with the 'EarlyDerivSpec' which we + -- use to find out what deriving strategy was actually used. + -- See comments of 'TcRnNoDerivingClauseStrategySpecified'. + -> TcM () +warnNoDerivingClauseStrategy Just{} _early_deriv_specs = pure () +warnNoDerivingClauseStrategy Nothing early_deriv_specs = do + let all_assumed_strategies :: Map AssumedDerivingStrategy [LHsSigType GhcRn] + all_assumed_strategies = + Map.unionsWith (++) (map early_deriv_spec_to_assumed_strategies early_deriv_specs) + + dyn_flags <- getDynFlags + addDiagnosticTc $ + TcRnNoDerivStratSpecified (xopt LangExt.DerivingStrategies dyn_flags) $ + TcRnNoDerivingClauseStrategySpecified all_assumed_strategies + + where + deriv_spec_to_assumed_strategy :: LHsSigType GhcRn + -> DerivSpec theta + -> Map AssumedDerivingStrategy [LHsSigType GhcRn] + deriv_spec_to_assumed_strategy deriv_head deriv_spec = + Map.fromList + [ (strat, [deriv_head]) + | strat <- maybeToList $ mechanismToAssumedStrategy (ds_mechanism deriv_spec) + ] + + early_deriv_spec_to_assumed_strategies :: (LHsSigType GhcRn, EarlyDerivSpec) + -> Map AssumedDerivingStrategy [LHsSigType GhcRn] + early_deriv_spec_to_assumed_strategies (deriv_head, InferTheta deriv_spec) = + deriv_spec_to_assumed_strategy deriv_head deriv_spec + early_deriv_spec_to_assumed_strategies (deriv_head, GivenTheta deriv_spec) = + deriv_spec_to_assumed_strategy deriv_head deriv_spec + +warnNoStandaloneDerivingStrategy + :: Maybe (LDerivStrategy GhcTc) + -- ^ The given deriving strategy, if any. + -> LHsSigWcType GhcRn + -- ^ The standalone deriving declaration's signature for example, the: + -- C a => C (T a) + -- part of the standalone deriving instance: + -- deriving instance C a => C (T a) + -> EarlyDerivSpec + -- ^ We extract the assumed deriving strategy from this. + -> TcM () +warnNoStandaloneDerivingStrategy Just{} _deriv_ty _early_deriv_spec = pure () +warnNoStandaloneDerivingStrategy Nothing deriv_ty early_deriv_spec = + case mechanismToAssumedStrategy $ early_deriv_spec_mechanism early_deriv_spec of + Nothing -> pure () + Just assumed_strategy -> do + dyn_flags <- getDynFlags + addDiagnosticTc $ + TcRnNoDerivStratSpecified (xopt LangExt.DerivingStrategies dyn_flags) $ + TcRnNoStandaloneDerivingStrategySpecified assumed_strategy deriv_ty + + where + early_deriv_spec_mechanism :: EarlyDerivSpec -> DerivSpecMechanism + early_deriv_spec_mechanism (InferTheta deriv_spec) = ds_mechanism deriv_spec + early_deriv_spec_mechanism (GivenTheta deriv_spec) = ds_mechanism deriv_spec + makeDerivSpecs :: [DerivInfo] -> [LDerivDecl GhcRn] -> TcM [EarlyDerivSpec] @@ -433,10 +506,10 @@ makeDerivSpecs deriv_infos deriv_decls ; eqns2 <- mapM (recoverM (pure Nothing) . deriveStandalone) deriv_decls ; return $ concat eqns1 ++ catMaybes eqns2 } where - deriv_clause_preds :: LDerivClauseTys GhcRn -> [LHsSigType GhcRn] - deriv_clause_preds (L _ dct) = case dct of - DctSingle _ ty -> [ty] - DctMulti _ tys -> tys + deriv_clause_preds :: LDerivClauseTys GhcRn -> LocatedC [LHsSigType GhcRn] + deriv_clause_preds (L loc dct) = case dct of + DctSingle _ ty -> L loc [ty] + DctMulti _ tys -> L loc tys ------------------------------------------------------------------ -- | Process the derived classes in a single @deriving@ clause. @@ -444,10 +517,13 @@ deriveClause :: TyCon -> [(Name, TcTyVar)] -- Scoped type variables taken from tcTyConScopedTyVars -- See Note [Scoped tyvars in a TcTyCon] in "GHC.Core.TyCon" -> Maybe (LDerivStrategy GhcRn) - -> [LHsSigType GhcRn] -> SDoc + -> LocatedC [LHsSigType GhcRn] + -- ^ The location refers to the @(Show, Eq)@ part of @deriving (Show, Eq)@. + -> SDoc -> TcM [EarlyDerivSpec] -deriveClause rep_tc scoped_tvs mb_lderiv_strat deriv_preds err_ctxt - = addErrCtxt err_ctxt $ do +deriveClause rep_tc scoped_tvs mb_lderiv_strat (L loc deriv_preds) err_ctxt + = setSrcSpanA loc $ + addErrCtxt err_ctxt $ do traceTc "deriveClause" $ vcat [ text "tvs" <+> ppr tvs , text "scoped_tvs" <+> ppr scoped_tvs @@ -456,15 +532,21 @@ deriveClause rep_tc scoped_tvs mb_lderiv_strat deriv_preds err_ctxt , text "mb_lderiv_strat" <+> ppr mb_lderiv_strat ] tcExtendNameTyVarEnv scoped_tvs $ do (mb_lderiv_strat', via_tvs) <- tcDerivStrategy mb_lderiv_strat - tcExtendTyVarEnv via_tvs $ + earlyDerivSpecs <- tcExtendTyVarEnv via_tvs $ -- Moreover, when using DerivingVia one can bind type variables in -- the `via` type as well, so these type variables must also be -- brought into scope. - mapMaybeM (derivePred tc tys mb_lderiv_strat' via_tvs) deriv_preds + mapMaybeM + (\deriv_pred -> + do maybe_early_deriv_spec <- derivePred tc tys mb_lderiv_strat' via_tvs deriv_pred + pure $ fmap (deriv_pred,) maybe_early_deriv_spec) + deriv_preds -- After typechecking the `via` type once, we then typecheck all -- of the classes associated with that `via` type in the -- `deriving` clause. -- See also Note [Don't typecheck too much in DerivingVia]. + warnNoDerivingClauseStrategy mb_lderiv_strat' earlyDerivSpecs + return (snd <$> earlyDerivSpecs) where tvs = tyConTyVars rep_tc (tc, tys) = case tyConFamInstSig_maybe rep_tc of @@ -678,10 +760,16 @@ deriveStandalone (L loc (DerivDecl (warn, _) deriv_ty mb_lderiv_strat overlap_mo ; if className cls == typeableClassName then do warnUselessTypeable return Nothing - else Just <$> mkEqnHelp (fmap unLoc overlap_mode) - tvs' cls inst_tys' - deriv_ctxt' mb_deriv_strat' - (fmap unLoc warn) } + else do early_deriv_spec <- + mkEqnHelp (fmap unLoc overlap_mode) + tvs' cls inst_tys' + deriv_ctxt' mb_deriv_strat' + (fmap unLoc warn) + warnNoStandaloneDerivingStrategy + mb_lderiv_strat + deriv_ty + early_deriv_spec + pure (Just early_deriv_spec) } -- Typecheck the type in a standalone deriving declaration. -- diff --git a/compiler/GHC/Tc/Errors/Ppr.hs b/compiler/GHC/Tc/Errors/Ppr.hs index 74647f6fd277f6aa5d5ab96ae6a315dd09be7b7e..6588b07c4785dbf1eca1a5e187faf93fa04fcb6b 100644 --- a/compiler/GHC/Tc/Errors/Ppr.hs +++ b/compiler/GHC/Tc/Errors/Ppr.hs @@ -3038,9 +3038,13 @@ instance Diagnostic TcRnMessage where _ -> [suggestExtension LangExt.DerivingStrategies] TcRnIllegalMultipleDerivClauses{} -> [suggestExtension LangExt.DerivingStrategies] - TcRnNoDerivStratSpecified isDSEnabled -> if isDSEnabled - then noHints - else [suggestExtension LangExt.DerivingStrategies] + TcRnNoDerivStratSpecified is_ds_enabled info -> do + let explicit_strategy_hint = case info of + TcRnNoDerivingClauseStrategySpecified assumed_derivings -> + SuggestExplicitDerivingClauseStrategies assumed_derivings + TcRnNoStandaloneDerivingStrategySpecified assumed_strategy deriv_sig -> + SuggestExplicitStandaloneDerivingStrategy assumed_strategy deriv_sig + explicit_strategy_hint : [suggestExtension LangExt.DerivingStrategies | not is_ds_enabled] TcRnStupidThetaInGadt{} -> noHints TcRnShadowedTyVarNameInFamResult{} diff --git a/compiler/GHC/Tc/Errors/Types.hs b/compiler/GHC/Tc/Errors/Types.hs index de1c809213bbd5232a095489eb1b2461cf44ab02..16d8cee25d3ee4d357ce515db8394c82e52702e2 100644 --- a/compiler/GHC/Tc/Errors/Types.hs +++ b/compiler/GHC/Tc/Errors/Types.hs @@ -53,6 +53,7 @@ module GHC.Tc.Errors.Types ( , Exported(..) , HsDocContext(..) , FixedRuntimeRepErrorInfo(..) + , TcRnNoDerivStratSpecifiedInfo(..) , ErrorItem(..), errorItemOrigin, errorItemEqRel, errorItemPred, errorItemCtLoc @@ -180,7 +181,7 @@ import GHC.Tc.Utils.TcType (TcType, TcSigmaType, TcPredType, import GHC.Types.Basic import GHC.Types.Error import GHC.Types.Avail -import GHC.Types.Hint (UntickedPromotedThing(..)) +import GHC.Types.Hint (UntickedPromotedThing(..), AssumedDerivingStrategy(..)) import GHC.Types.ForeignCall (CLabelString) import GHC.Types.Id.Info ( RecSelParent(..) ) import GHC.Types.Name (NamedThing(..), Name, OccName, getSrcLoc, getSrcSpan) @@ -219,6 +220,7 @@ import qualified Data.List.NonEmpty as NE import Data.Typeable (Typeable) import GHC.Unit.Module.Warnings (WarningCategory, WarningTxt) import qualified GHC.Internal.TH.Syntax as TH +import Data.Map.Strict (Map) import GHC.Generics ( Generic ) import GHC.Types.Name.Env (NameEnv) @@ -3265,20 +3267,22 @@ data TcRnMessage where -} TcRnIllegalMultipleDerivClauses :: TcRnMessage - {-| TcRnNoDerivStratSpecified is a warning implied by -Wmissing-deriving-strategies - and triggered by deriving clause without specified deriving strategy. + {-| TcRnNoDerivStratSpecified is a warning implied by + -Wmissing-deriving-strategies and triggered by deriving without + mentioning a strategy. - Example: + See 'TcRnNoDerivStratSpecifiedInfo' cases for examples. - data T = T - deriving Eq - - Test cases: rename/should_compile/T15798a - rename/should_compile/T15798b - rename/should_compile/T15798c + Test cases: deriving/should_compile/T15798a + deriving/should_compile/T15798b + deriving/should_compile/T15798c + deriving/should_compile/T24955a + deriving/should_compile/T24955b + deriving/should_compile/T24955c -} TcRnNoDerivStratSpecified - :: Bool -- True if DerivingStrategies is enabled + :: Bool -- ^ True if DerivingStrategies is enabled + -> TcRnNoDerivStratSpecifiedInfo -> TcRnMessage {-| TcRnStupidThetaInGadt is an error triggered by data contexts in GADT-style @@ -6740,3 +6744,48 @@ data TypeCannotBeMarshaledReason | NotSimpleUnliftedType | NotBoxedKindAny deriving Generic + +data TcRnNoDerivStratSpecifiedInfo where + {-| 'TcRnNoDerivStratSpecified TcRnNoDerivingClauseStrategySpecified' is + a warning implied by -Wmissing-deriving-strategies and triggered by a + deriving clause without a specified deriving strategy. + + Example: + + newtype T = T Int + deriving (Eq, Ord, Show) + + Here we would suggest fixing the deriving clause to: + + deriving stock (Show) + deriving newtype (Eq, Ord) + + Test cases: deriving/should_compile/T15798a + deriving/should_compile/T15798c + deriving/should_compile/T24955a + deriving/should_compile/T24955b + -} + TcRnNoDerivingClauseStrategySpecified + :: Map AssumedDerivingStrategy [LHsSigType GhcRn] + -> TcRnNoDerivStratSpecifiedInfo + + {-| 'TcRnNoDerivStratSpecified TcRnNoStandaloneDerivingStrategySpecified' is + a warning implied by -Wmissing-deriving-strategies and triggered by a + standalone deriving declaration without a specified deriving strategy. + + Example: + + data T a = T a + deriving instance Show a => Show (T a) + + Here we would suggest fixing the instance to: + + deriving stock instance Show a => Show (T a) + + Test cases: deriving/should_compile/T15798b + deriving/should_compile/T24955c + -} + TcRnNoStandaloneDerivingStrategySpecified + :: AssumedDerivingStrategy + -> LHsSigWcType GhcRn -- ^ The instance signature (e.g @Show a => Show (T a)@) + -> TcRnNoDerivStratSpecifiedInfo diff --git a/compiler/GHC/Types/Hint.hs b/compiler/GHC/Types/Hint.hs index e7c5d29ba97774d0bab90d32e47b0cc81bb20f95..44c1e97b9c0360315c56bf497b0e11e364815e1f 100644 --- a/compiler/GHC/Types/Hint.hs +++ b/compiler/GHC/Types/Hint.hs @@ -10,6 +10,7 @@ module GHC.Types.Hint ( , SimilarName(..) , StarIsType(..) , UntickedPromotedThing(..) + , AssumedDerivingStrategy(..) , pprUntickedConstructor, isBareSymbol , suggestExtension , suggestExtensionWithInfo @@ -22,7 +23,7 @@ module GHC.Types.Hint ( ) where import Language.Haskell.Syntax.Expr (LHsExpr) -import Language.Haskell.Syntax (LPat, LIdP) +import Language.Haskell.Syntax (LPat, LIdP, LHsSigType, LHsSigWcType) import GHC.Prelude @@ -46,6 +47,7 @@ import GHC.Utils.Outputable import GHC.Data.FastString (fsLit, FastString) import Data.Typeable ( Typeable ) +import Data.Map.Strict (Map) -- | The bindings we have available in scope when -- suggesting an explicit type signature. @@ -477,6 +479,40 @@ data GhcHint {-| Suggest binding explicitly; e.g data T @k (a :: F k) = .... -} | SuggestBindTyVarExplicitly Name + {-| Suggest using explicit deriving strategies for a deriving clause. + + Triggered by: 'GHC.Tc.Errors.Types.TcRnNoDerivingClauseStrategySpecified'. + + See comment of 'TcRnNoDerivingClauseStrategySpecified' for context. + -} + | SuggestExplicitDerivingClauseStrategies + (Map AssumedDerivingStrategy [LHsSigType GhcRn]) + -- ^ Those deriving clauses that we assumed a particular strategy for. + + {-| Suggest using an explicit deriving strategy for a standalone deriving instance. + + Triggered by: 'GHC.Tc.Errors.Types.TcRnNoStandaloneDerivingStrategySpecified'. + + See comment of 'TcRnNoStandaloneDerivingStrategySpecified' for context. + -} + | SuggestExplicitStandaloneDerivingStrategy + AssumedDerivingStrategy -- ^ The deriving strategy we assumed + (LHsSigWcType GhcRn) -- ^ The instance signature (e.g 'Show a => Show (T a)') + +-- | The deriving strategy that was assumed when not explicitly listed in the +-- source. This is used solely by the missing-deriving-strategies warning. +-- There's no `Via` case because we never assume that. +data AssumedDerivingStrategy + = AssumedStockStrategy + | AssumedAnyclassStrategy + | AssumedNewtypeStrategy + deriving (Eq, Ord) + +instance Outputable AssumedDerivingStrategy where + ppr AssumedStockStrategy = text "stock" + ppr AssumedAnyclassStrategy = text "anyclass" + ppr AssumedNewtypeStrategy = text "newtype" + -- | An 'InstantiationSuggestion' for a '.hsig' file. This is generated -- by GHC in case of a 'DriverUnexpectedSignature' and suggests a way -- to instantiate a particular signature, where the first argument is diff --git a/compiler/GHC/Types/Hint/Ppr.hs b/compiler/GHC/Types/Hint/Ppr.hs index 50e956ed260693ea8af2d6768d6b9de4dde56a4e..14e228faa6a64de6c9c77a218db81d2e1799859f 100644 --- a/compiler/GHC/Types/Hint/Ppr.hs +++ b/compiler/GHC/Types/Hint/Ppr.hs @@ -1,7 +1,7 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} -{-# OPTIONS_GHC -Wno-orphans #-} -- instance Outputable GhcHint +{-# OPTIONS_GHC -Wno-orphans #-} {- instance Outputable GhcHint -} module GHC.Types.Hint.Ppr ( perhapsAsPat @@ -28,10 +28,10 @@ import GHC.Utils.Outputable import GHC.Driver.Flags import qualified Data.List.NonEmpty as NE +import qualified Data.Map.Strict as Map import qualified GHC.LanguageExtensions as LangExt - instance Outputable GhcHint where ppr = \case UnknownHint m @@ -270,6 +270,19 @@ instance Outputable GhcHint where SuggestBindTyVarExplicitly tv -> text "bind" <+> quotes (ppr tv) <+> text "explicitly with" <+> quotes (char '@' <> ppr tv) + SuggestExplicitDerivingClauseStrategies assumed_derivings -> + hang + (text "Use explicit deriving strategies:") + 2 + (vcat $ map pp_derivings (Map.toList assumed_derivings)) + where + pp_derivings (strat, preds) = + hsep [text "deriving", ppr strat, parens (pprWithCommas ppr preds)] + SuggestExplicitStandaloneDerivingStrategy strat deriv_sig -> + hang + (text "Use an explicit deriving strategy:") + 2 + (hsep [text "deriving", ppr strat, text "instance", ppr deriv_sig]) perhapsAsPat :: SDoc perhapsAsPat = text "Perhaps you meant an as-pattern, which must not be surrounded by whitespace" diff --git a/docs/users_guide/using-warnings.rst b/docs/users_guide/using-warnings.rst index 5d32eab2b970e396726cfd8b5f0f5283ceb28810..2ad0044fa9bee6216e13739af9b232b25f723665 100644 --- a/docs/users_guide/using-warnings.rst +++ b/docs/users_guide/using-warnings.rst @@ -1109,7 +1109,7 @@ of ``-W(no-)*``. d a = x a -- would not warn .. ghc-flag:: -Wmissing-deriving-strategies - :shortdesc: warn when a deriving clause is missing a deriving strategy + :shortdesc: warn when deriving without mentioning a deriving strategy :type: dynamic :reverse: -Wno-missing-deriving-strategies :category: @@ -1125,8 +1125,11 @@ of ``-W(no-)*``. deriving (Eq) The compiler will warn here that the deriving clause doesn't specify a - strategy. If the warning is enabled, but :extension:`DerivingStrategies` is - not enabled, the compiler will suggest turning on the + strategy. The suggested fix will show which deriving strategies were + assumed. + + If the warning is enabled, but :extension:`DerivingStrategies` is not + enabled, the compiler will suggest turning on the :extension:`DerivingStrategies` extension. .. ghc-flag:: -Wmissing-fields diff --git a/testsuite/tests/rename/should_compile/T15798a.hs b/testsuite/tests/deriving/should_compile/T15798a.hs similarity index 100% rename from testsuite/tests/rename/should_compile/T15798a.hs rename to testsuite/tests/deriving/should_compile/T15798a.hs diff --git a/testsuite/tests/deriving/should_compile/T15798a.stderr b/testsuite/tests/deriving/should_compile/T15798a.stderr new file mode 100644 index 0000000000000000000000000000000000000000..997aee475d16b051e11fe188ea17e9f106614428 --- /dev/null +++ b/testsuite/tests/deriving/should_compile/T15798a.stderr @@ -0,0 +1,6 @@ +T15798a.hs:11:12: warning: [GHC-55631] [-Wmissing-deriving-strategies] + • No deriving strategy specified. Did you want stock, newtype, or anyclass? + • In the data declaration for ‘Bar’ + Suggested fix: + Use explicit deriving strategies: deriving stock (Eq, Show) + diff --git a/testsuite/tests/rename/should_compile/T15798b.hs b/testsuite/tests/deriving/should_compile/T15798b.hs similarity index 100% rename from testsuite/tests/rename/should_compile/T15798b.hs rename to testsuite/tests/deriving/should_compile/T15798b.hs diff --git a/testsuite/tests/deriving/should_compile/T15798b.stderr b/testsuite/tests/deriving/should_compile/T15798b.stderr new file mode 100644 index 0000000000000000000000000000000000000000..20129cdcafa10032f5efe3c84c81ee1012c474f1 --- /dev/null +++ b/testsuite/tests/deriving/should_compile/T15798b.stderr @@ -0,0 +1,8 @@ +T15798b.hs:9:1: warning: [GHC-55631] [-Wmissing-deriving-strategies] + • No deriving strategy specified. Did you want stock, newtype, or anyclass? + • In the stand-alone deriving instance for ‘Eq a => Eq (Foo a)’ + Suggested fixes: + • Use an explicit deriving strategy: + deriving stock instance Eq a => Eq (Foo a) + • Perhaps you intended to use the ‘DerivingStrategies’ extension (implied by ‘DerivingVia’) + diff --git a/testsuite/tests/rename/should_compile/T15798c.hs b/testsuite/tests/deriving/should_compile/T15798c.hs similarity index 100% rename from testsuite/tests/rename/should_compile/T15798c.hs rename to testsuite/tests/deriving/should_compile/T15798c.hs diff --git a/testsuite/tests/deriving/should_compile/T15798c.stderr b/testsuite/tests/deriving/should_compile/T15798c.stderr new file mode 100644 index 0000000000000000000000000000000000000000..cb9e89015c436870d4a5e7c517d36a7e29201577 --- /dev/null +++ b/testsuite/tests/deriving/should_compile/T15798c.stderr @@ -0,0 +1,7 @@ +T15798c.hs:6:12: warning: [GHC-55631] [-Wmissing-deriving-strategies] + • No deriving strategy specified. Did you want stock, newtype, or anyclass? + • In the data declaration for ‘Foo’ + Suggested fixes: + • Use explicit deriving strategies: deriving stock (Eq) + • Perhaps you intended to use the ‘DerivingStrategies’ extension (implied by ‘DerivingVia’) + diff --git a/testsuite/tests/deriving/should_compile/T24955a.hs b/testsuite/tests/deriving/should_compile/T24955a.hs new file mode 100644 index 0000000000000000000000000000000000000000..beb72ee05e2706704997983710e07c0182f659c2 --- /dev/null +++ b/testsuite/tests/deriving/should_compile/T24955a.hs @@ -0,0 +1,10 @@ +{-# OPTIONS_GHC -Wmissing-deriving-strategies #-} + +module T24955a () where + +-- Listing multiple classes which use different assumed strategies. +-- The suggested fixes should list: +-- deriving stock (Show, Read) +-- deriving newtype (Eq, Ord) +newtype N = N Int + deriving (Show, Eq, Read, Ord) diff --git a/testsuite/tests/deriving/should_compile/T24955a.stderr b/testsuite/tests/deriving/should_compile/T24955a.stderr new file mode 100644 index 0000000000000000000000000000000000000000..5426475050c329e25b415b09c2208c370507c972 --- /dev/null +++ b/testsuite/tests/deriving/should_compile/T24955a.stderr @@ -0,0 +1,9 @@ +T24955a.hs:10:12: warning: [GHC-55631] [-Wmissing-deriving-strategies] + • No deriving strategy specified. Did you want stock, newtype, or anyclass? + • In the newtype declaration for ‘N’ + Suggested fixes: + • Use explicit deriving strategies: + deriving stock (Show, Read) + deriving newtype (Eq, Ord) + • Perhaps you intended to use the ‘DerivingStrategies’ extension (implied by ‘DerivingVia’) + diff --git a/testsuite/tests/deriving/should_compile/T24955b.hs b/testsuite/tests/deriving/should_compile/T24955b.hs new file mode 100644 index 0000000000000000000000000000000000000000..67cb795bc9fdac1e349b669a8cb2a386f9cd51c5 --- /dev/null +++ b/testsuite/tests/deriving/should_compile/T24955b.hs @@ -0,0 +1,11 @@ +{-# OPTIONS_GHC -Wmissing-deriving-strategies #-} +{-# LANGUAGE FunctionalDependencies #-} + +module T24955b () where + +class C a b | b -> a + +instance C Int Int + +newtype N = N Int + deriving (C Int) diff --git a/testsuite/tests/deriving/should_compile/T24955b.stderr b/testsuite/tests/deriving/should_compile/T24955b.stderr new file mode 100644 index 0000000000000000000000000000000000000000..c1c2fe44e8fccc2cc14100347822ae995968d193 --- /dev/null +++ b/testsuite/tests/deriving/should_compile/T24955b.stderr @@ -0,0 +1,7 @@ +T24955b.hs:11:12: warning: [GHC-55631] [-Wmissing-deriving-strategies] + • No deriving strategy specified. Did you want stock, newtype, or anyclass? + • In the newtype declaration for ‘N’ + Suggested fixes: + • Use explicit deriving strategies: deriving newtype (C Int) + • Perhaps you intended to use the ‘DerivingStrategies’ extension (implied by ‘DerivingVia’) + diff --git a/testsuite/tests/deriving/should_compile/T24955c.hs b/testsuite/tests/deriving/should_compile/T24955c.hs new file mode 100644 index 0000000000000000000000000000000000000000..534e6b4d49277fd743b2d814cc8da5e49a87e4b4 --- /dev/null +++ b/testsuite/tests/deriving/should_compile/T24955c.hs @@ -0,0 +1,9 @@ +{-# LANGUAGE StandaloneDeriving #-} + +{-# OPTIONS_GHC -Wmissing-deriving-strategies #-} + +module T24955c () where + +data Foo a = Foo a + +deriving instance Eq a => Eq (Foo a) diff --git a/testsuite/tests/deriving/should_compile/T24955c.stderr b/testsuite/tests/deriving/should_compile/T24955c.stderr new file mode 100644 index 0000000000000000000000000000000000000000..116ae809c7452d7466ebdc274877cebeeada6608 --- /dev/null +++ b/testsuite/tests/deriving/should_compile/T24955c.stderr @@ -0,0 +1,8 @@ +T24955c.hs:9:1: warning: [GHC-55631] [-Wmissing-deriving-strategies] + • No deriving strategy specified. Did you want stock, newtype, or anyclass? + • In the stand-alone deriving instance for ‘Eq a => Eq (Foo a)’ + Suggested fixes: + • Use an explicit deriving strategy: + deriving stock instance Eq a => Eq (Foo a) + • Perhaps you intended to use the ‘DerivingStrategies’ extension (implied by ‘DerivingVia’) + diff --git a/testsuite/tests/deriving/should_compile/all.T b/testsuite/tests/deriving/should_compile/all.T index 79046f8ed70245e2aec7bf5749b3869d3934bd74..0e703d6ab15477ef3a8480fc65ba39275b8f8870 100644 --- a/testsuite/tests/deriving/should_compile/all.T +++ b/testsuite/tests/deriving/should_compile/all.T @@ -144,3 +144,9 @@ test('T22696a', normal, compile, ['']) test('T22696c', normal, compile, ['']) test('T23329', normal, multimod_compile, ['T23329', '-v0']) test('T17328', [extra_files(['T17328a.hs'])], multimod_compile, ['T17328', '-v0']) +test('T15798a', normal, compile, ['']) +test('T15798b', normal, compile, ['']) +test('T15798c', normal, compile, ['']) +test('T24955a', normal, compile, ['']) +test('T24955b', normal, compile, ['']) +test('T24955c', normal, compile, ['']) diff --git a/testsuite/tests/rename/should_compile/T15798a.stderr b/testsuite/tests/rename/should_compile/T15798a.stderr deleted file mode 100644 index 90615e8302ee15517a07cad4d8a0cacb3306c6ba..0000000000000000000000000000000000000000 --- a/testsuite/tests/rename/should_compile/T15798a.stderr +++ /dev/null @@ -1,3 +0,0 @@ - -T15798a.hs:11:3: warning: [GHC-55631] [-Wmissing-deriving-strategies] - No deriving strategy specified. Did you want stock, newtype, or anyclass? diff --git a/testsuite/tests/rename/should_compile/T15798b.stderr b/testsuite/tests/rename/should_compile/T15798b.stderr deleted file mode 100644 index 1629425eb46c83834349e20312da3e43573ea5c0..0000000000000000000000000000000000000000 --- a/testsuite/tests/rename/should_compile/T15798b.stderr +++ /dev/null @@ -1,5 +0,0 @@ - -T15798b.hs:9:19: warning: [GHC-55631] [-Wmissing-deriving-strategies] - No deriving strategy specified. Did you want stock, newtype, or anyclass? - Suggested fix: - Perhaps you intended to use the ‘DerivingStrategies’ extension (implied by ‘DerivingVia’) diff --git a/testsuite/tests/rename/should_compile/T15798c.stderr b/testsuite/tests/rename/should_compile/T15798c.stderr deleted file mode 100644 index 0ec0129f033814f779adc215635fd3f8e99ce11b..0000000000000000000000000000000000000000 --- a/testsuite/tests/rename/should_compile/T15798c.stderr +++ /dev/null @@ -1,5 +0,0 @@ - -T15798c.hs:6:3: warning: [GHC-55631] [-Wmissing-deriving-strategies] - No deriving strategy specified. Did you want stock, newtype, or anyclass? - Suggested fix: - Perhaps you intended to use the ‘DerivingStrategies’ extension (implied by ‘DerivingVia’) diff --git a/testsuite/tests/rename/should_compile/all.T b/testsuite/tests/rename/should_compile/all.T index 86fedd8aedf4803d1e65ed1985f1159de5e266d8..c4f1e3c5d9fbc36dd9520ae4cee4422605ec87fd 100644 --- a/testsuite/tests/rename/should_compile/all.T +++ b/testsuite/tests/rename/should_compile/all.T @@ -164,9 +164,6 @@ test('T15149', [], multimod_compile, ['T15149', '-v0']) test('T15214', normal, compile, ['']) test('T13064', normal, compile, ['']) test('T15994', [], makefile_test, ['T15994']) -test('T15798a', normal, compile, ['']) -test('T15798b', normal, compile, ['']) -test('T15798c', normal, compile, ['']) test('T16116a', normal, compile, ['']) test('T15957', normal, compile, ['-Werror -Wredundant-record-wildcards -Wunused-record-wildcards']) test('T17244A', normal, compile, ['-Wno-error=compat-unqualified-imports'])