diff options
author | Alfredo Di Napoli <alfredo@well-typed.com> | 2021-06-28 15:42:57 +0200 |
---|---|---|
committer | Alfredo Di Napoli <alfredo@well-typed.com> | 2021-07-12 14:19:22 +0200 |
commit | a181313e9205fe289bedf6c8931eb2933490625c (patch) | |
tree | 19cb046c6fdba62f1987b49b5f6ec2821f438591 /compiler/GHC | |
parent | c38bce737f532cec1d863d3e15bed4a8addbffd1 (diff) | |
download | haskell-a181313e9205fe289bedf6c8931eb2933490625c.tar.gz |
Add proper GHCHints for most PsMessage constructorswip/adinapoli-issue-20055
This commit adds proper hints to most diagnostic types in the
`GHC.Parser.Errors.Types` module. By "proper" we mean that previous to
this commit the hints were bundled together with the diagnostic message,
whereas now we moved most of them as proper `[GhcHint]` in the
implementation of `diagnosticHints`.
More specifically, this is the list of constructors which now has
proper hints:
* PsErrIllegalBangPattern
* PsWarnOperatorWhitespaceExtConflict
* PsErrLambdaCase
* PsErrIllegalPatSynExport
* PsWarnOperatorWhitespace
* PsErrMultiWayIf
* PsErrIllegalQualifiedDo
* PsErrNumUnderscores
* PsErrLinearFunction
* PsErrIllegalTraditionalRecordSyntax
* PsErrIllegalExplicitNamespace
* PsErrOverloadedRecordUpdateNotEnabled
* PsErrIllegalDataTypeContext
* PsErrSemiColonsInCondExpr
* PsErrSemiColonsInCondCmd
* PsWarnStarIsType
* PsWarnImportPreQualified
* PsErrImportPostQualified
* PsErrEmptyDoubleQuotes
* PsErrIllegalRoleName
* PsWarnStarBinder
For some reason, this patch increases the peak_megabyte_allocated of
the T11545 test to 90 (from a baseline of 80) but that particular test
doesn't emit any parsing diagnostic or hint and the metric increase
happens only for the `aarch64-linux-deb10`.
Metric Increase:
T11545
Diffstat (limited to 'compiler/GHC')
-rw-r--r-- | compiler/GHC/Parser/Errors/Basic.hs | 22 | ||||
-rw-r--r-- | compiler/GHC/Parser/Errors/Ppr.hs | 160 | ||||
-rw-r--r-- | compiler/GHC/Parser/Errors/Types.hs | 13 | ||||
-rw-r--r-- | compiler/GHC/Parser/Lexer.x | 1 | ||||
-rw-r--r-- | compiler/GHC/Types/Hint.hs | 78 | ||||
-rw-r--r-- | compiler/GHC/Types/Hint/Ppr.hs | 29 |
6 files changed, 197 insertions, 106 deletions
diff --git a/compiler/GHC/Parser/Errors/Basic.hs b/compiler/GHC/Parser/Errors/Basic.hs new file mode 100644 index 0000000000..6cec1da8d6 --- /dev/null +++ b/compiler/GHC/Parser/Errors/Basic.hs @@ -0,0 +1,22 @@ +{-# LANGUAGE LambdaCase #-} +module GHC.Parser.Errors.Basic where + +import GHC.Utils.Outputable ( SDoc, text ) + +-- | The operator symbol in the 'PsOperatorWhitespaceExtConflictMessage' diagnostic. +data OperatorWhitespaceSymbol + = OperatorWhitespaceSymbol_PrefixPercent + | OperatorWhitespaceSymbol_PrefixDollar + | OperatorWhitespaceSymbol_PrefixDollarDollar + +pprOperatorWhitespaceSymbol :: OperatorWhitespaceSymbol -> SDoc +pprOperatorWhitespaceSymbol = \case + OperatorWhitespaceSymbol_PrefixPercent -> text "%" + OperatorWhitespaceSymbol_PrefixDollar -> text "$" + OperatorWhitespaceSymbol_PrefixDollarDollar -> text "$$" + +-- | The operator occurrence type in the 'PsOperatorWhitespaceMessage' diagnostic. +data OperatorWhitespaceOccurrence + = OperatorWhitespaceOccurrence_Prefix + | OperatorWhitespaceOccurrence_Suffix + | OperatorWhitespaceOccurrence_TightInfix diff --git a/compiler/GHC/Parser/Errors/Ppr.hs b/compiler/GHC/Parser/Errors/Ppr.hs index b349f310e2..048605a225 100644 --- a/compiler/GHC/Parser/Errors/Ppr.hs +++ b/compiler/GHC/Parser/Errors/Ppr.hs @@ -1,4 +1,5 @@ {-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE MultiWayIf #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE FlexibleContexts #-} @@ -9,6 +10,7 @@ module GHC.Parser.Errors.Ppr where import GHC.Prelude import GHC.Driver.Flags +import GHC.Parser.Errors.Basic import GHC.Parser.Errors.Types import GHC.Parser.Types import GHC.Types.Basic @@ -57,23 +59,20 @@ instance Diagnostic PsMessage where TransLayout_Pipe -> "`|' at the same depth as implicit layout block" ) PsWarnOperatorWhitespaceExtConflict sym - -> let mk_prefix_msg operator_symbol extension_name syntax_meaning = - text "The prefix use of a" <+> quotes (text operator_symbol) + -> let mk_prefix_msg extension_name syntax_meaning = + text "The prefix use of a" <+> quotes (pprOperatorWhitespaceSymbol sym) <+> text "would denote" <+> text syntax_meaning $$ nest 2 (text "were the" <+> text extension_name <+> text "extension enabled.") - $$ text "Suggested fix: add whitespace after the" - <+> quotes (text operator_symbol) <> char '.' in mkSimpleDecorated $ case sym of - OperatorWhitespaceSymbol_PrefixPercent -> mk_prefix_msg "%" "LinearTypes" "a multiplicity annotation" - OperatorWhitespaceSymbol_PrefixDollar -> mk_prefix_msg "$" "TemplateHaskell" "an untyped splice" - OperatorWhitespaceSymbol_PrefixDollarDollar -> mk_prefix_msg "$$" "TemplateHaskell" "a typed splice" + OperatorWhitespaceSymbol_PrefixPercent -> mk_prefix_msg "LinearTypes" "a multiplicity annotation" + OperatorWhitespaceSymbol_PrefixDollar -> mk_prefix_msg "TemplateHaskell" "an untyped splice" + OperatorWhitespaceSymbol_PrefixDollarDollar -> mk_prefix_msg "TemplateHaskell" "a typed splice" PsWarnOperatorWhitespace sym occ_type -> let mk_msg occ_type_str = text "The" <+> text occ_type_str <+> text "use of a" <+> quotes (ftext sym) <+> text "might be repurposed as special syntax" $$ nest 2 (text "by a future language extension.") - $$ text "Suggested fix: add whitespace around it." in mkSimpleDecorated $ case occ_type of OperatorWhitespaceOccurrence_Prefix -> mk_msg "prefix" @@ -83,9 +82,6 @@ instance Diagnostic PsMessage where -> mkSimpleDecorated $ text "Found binding occurrence of" <+> quotes (text "*") <+> text "yet StarIsType is enabled." - $$ text "NB. To use (or export) this operator in" - <+> text "modules with StarIsType," - $$ text " including the definition module, you must qualify it." PsWarnStarIsType -> mkSimpleDecorated $ text "Using" <+> quotes (text "*") @@ -93,17 +89,12 @@ instance Diagnostic PsMessage where <+> quotes (text "Data.Kind.Type") $$ text "relies on the StarIsType extension, which will become" $$ text "deprecated in the future." - $$ text "Suggested fix: use" <+> quotes (text "Type") - <+> text "from" <+> quotes (text "Data.Kind") <+> text "instead." PsWarnUnrecognisedPragma -> mkSimpleDecorated $ text "Unrecognised pragma" PsWarnImportPreQualified -> mkSimpleDecorated $ text "Found" <+> quotes (text "qualified") <+> text "in prepositive position" - $$ text "Suggested fix: place " <+> quotes (text "qualified") - <+> text "after the module name instead." - $$ text "To allow this, enable language extension 'ImportQualifiedPost'" PsErrLexer err kind -> mkSimpleDecorated $ hcat @@ -161,38 +152,34 @@ instance Diagnostic PsMessage where -> mkSimpleDecorated $ text "Expected a hyphen" PsErrSpaceInSCC -> mkSimpleDecorated $ text "Spaces are not allowed in SCCs" - PsErrEmptyDoubleQuotes th_on - -> mkSimpleDecorated $ if th_on then vcat (msg ++ th_msg) else vcat msg + PsErrEmptyDoubleQuotes _th_on + -> mkSimpleDecorated $ vcat msg where msg = [ text "Parser error on `''`" , text "Character literals may not be empty" ] - th_msg = [ text "Or perhaps you intended to use quotation syntax of TemplateHaskell," - , text "but the type variable or constructor is missing" - ] - PsErrLambdaCase - -> mkSimpleDecorated $ text "Illegal lambda-case (use LambdaCase)" + -> mkSimpleDecorated $ text "Illegal lambda-case" PsErrEmptyLambda -> mkSimpleDecorated $ text "A lambda requires at least one parameter" PsErrLinearFunction - -> mkSimpleDecorated $ text "Enable LinearTypes to allow linear functions" + -> mkSimpleDecorated $ text "Illegal use of linear functions" PsErrOverloadedRecordUpdateNotEnabled - -> mkSimpleDecorated $ text "OverloadedRecordUpdate needs to be enabled" + -> mkSimpleDecorated $ text "Illegal overloaded record update" PsErrMultiWayIf - -> mkSimpleDecorated $ text "Multi-way if-expressions need MultiWayIf turned on" + -> mkSimpleDecorated $ text "Illegal multi-way if-expression" PsErrNumUnderscores reason -> mkSimpleDecorated $ text $ case reason of - NumUnderscore_Integral -> "Use NumericUnderscores to allow underscores in integer literals" - NumUnderscore_Float -> "Use NumericUnderscores to allow underscores in floating literals" + NumUnderscore_Integral -> "Illegal underscores in integer literals" + NumUnderscore_Float -> "Illegal underscores in floating literals" PsErrIllegalBangPattern e - -> mkSimpleDecorated $ text "Illegal bang-pattern (use BangPatterns):" $$ ppr e + -> mkSimpleDecorated $ text "Illegal bang-pattern" $$ ppr e PsErrOverloadedRecordDotInvalid -> mkSimpleDecorated $ text "Use of OverloadedRecordDot '.' not valid ('.' isn't allowed when constructing records or in record patterns)" PsErrIllegalPatSynExport - -> mkSimpleDecorated $ text "Illegal export form (use PatternSynonyms to enable)" + -> mkSimpleDecorated $ text "Illegal export form" PsErrOverloadedRecordUpdateNoQualifiedFields -> mkSimpleDecorated $ text "Fields cannot be qualified when OverloadedRecordUpdate is enabled" PsErrExplicitForall is_unicode @@ -206,10 +193,8 @@ instance Diagnostic PsMessage where forallSym True = text "∀" forallSym False = text "forall" PsErrIllegalQualifiedDo qdoDoc - -> mkSimpleDecorated $ vcat - [ text "Illegal qualified" <+> quotes qdoDoc <+> text "block" - , text "Perhaps you intended to use QualifiedDo" - ] + -> mkSimpleDecorated $ + text "Illegal qualified" <+> quotes qdoDoc <+> text "block" PsErrQualifiedDoInCmd m -> mkSimpleDecorated $ hang (text "Parse error in command:") 2 $ @@ -245,7 +230,7 @@ instance Diagnostic PsMessage where ] PsErrIllegalExplicitNamespace -> mkSimpleDecorated $ - text "Illegal keyword 'type' (use ExplicitNamespaces to enable)" + text "Illegal keyword 'type'" PsErrUnallowedPragma prag -> mkSimpleDecorated $ @@ -255,7 +240,6 @@ instance Diagnostic PsMessage where -> mkSimpleDecorated $ text "Found" <+> quotes (text "qualified") <+> text "in postpositive position. " - $$ text "To allow this, enable language extension 'ImportQualifiedPost'" PsErrImportQualifiedTwice -> mkSimpleDecorated $ text "Multiple occurrences of 'qualified'" PsErrIllegalImportBundleForm @@ -382,7 +366,7 @@ instance Diagnostic PsMessage where ] PsErrIllegalDataTypeContext c -> mkSimpleDecorated $ - text "Illegal datatype context (use DatatypeContexts):" + text "Illegal datatype context:" <+> pprLHsContext (Just c) PsErrPrimStringInvalidChar -> mkSimpleDecorated $ text "primitive string literal must contain only characters <= \'\\xFF\'" @@ -395,7 +379,6 @@ instance Diagnostic PsMessage where -> mkSimpleDecorated $ text "Unexpected semi-colons in conditional:" $$ nest 4 expr - $$ text "Perhaps you meant to use DoAndIfThenElse?" where pprOptSemi True = semi pprOptSemi False = empty @@ -406,7 +389,6 @@ instance Diagnostic PsMessage where -> mkSimpleDecorated $ text "Unexpected semi-colons in conditional:" $$ nest 4 expr - $$ text "Perhaps you meant to use DoAndIfThenElse?" where pprOptSemi True = semi pprOptSemi False = empty @@ -439,7 +421,7 @@ instance Diagnostic PsMessage where -> mkSimpleDecorated $ text "Inferred type variables are not allowed here" PsErrIllegalTraditionalRecordSyntax s -> mkSimpleDecorated $ - text "Illegal record syntax (use TraditionalRecordSyntax):" <+> s + text "Illegal record syntax:" <+> s PsErrParseErrorInCmd s -> mkSimpleDecorated $ hang (text "Parse error in command:") 2 s PsErrInPat s details @@ -463,43 +445,14 @@ instance Diagnostic PsMessage where in mkSimpleDecorated $ msg <+> body PsErrParseRightOpSectionInPat infixOcc s -> mkSimpleDecorated $ parse_error_in_pat <+> pprInfixOcc infixOcc <> ppr s - PsErrIllegalRoleName role nearby + PsErrIllegalRoleName role _nearby -> mkSimpleDecorated $ text "Illegal role name" <+> quotes (ppr role) - $$ case nearby of - [] -> empty - [r] -> text "Perhaps you meant" <+> quotes (ppr r) - -- will this last case ever happen?? - _ -> hang (text "Perhaps you meant one of these:") - 2 (pprWithCommas (quotes . ppr) nearby) PsErrInvalidTypeSignature lhs -> mkSimpleDecorated $ text "Invalid type signature:" <+> ppr lhs <+> text ":: ..." - $$ text hint - where - hint | foreign_RDR `looks_like` lhs - = "Perhaps you meant to use ForeignFunctionInterface?" - | default_RDR `looks_like` lhs - = "Perhaps you meant to use DefaultSignatures?" - | pattern_RDR `looks_like` lhs - = "Perhaps you meant to use PatternSynonyms?" - | otherwise - = "Should be of form <variables> :: <type>" - - -- A common error is to forget the ForeignFunctionInterface flag - -- so check for that, and suggest. cf #3805 - -- Sadly 'foreign import' still barfs 'parse error' because - -- 'import' is a keyword - -- looks_like :: RdrName -> LHsExpr GhcPsErr -> Bool -- AZ - looks_like s (L _ (HsVar _ (L _ v))) = v == s - looks_like s (L _ (HsApp _ lhs _)) = looks_like s lhs - looks_like _ _ = False - - foreign_RDR = mkUnqual varName (fsLit "foreign") - default_RDR = mkUnqual varName (fsLit "default") - pattern_RDR = mkUnqual varName (fsLit "pattern") PsErrUnexpectedTypeInDecl t what tc tparms equals_or_where -> mkSimpleDecorated $ vcat [ text "Unexpected type" <+> quotes (ppr t) @@ -646,14 +599,15 @@ instance Diagnostic PsMessage where PsHeaderMessage m -> psHeaderMessageHints m PsWarnTab{} -> [SuggestUseSpaces] PsWarnTransitionalLayout{} -> noHints - PsWarnOperatorWhitespaceExtConflict{} -> noHints - PsWarnOperatorWhitespace{} -> noHints + PsWarnOperatorWhitespaceExtConflict sym -> [SuggestUseWhitespaceAfter sym] + PsWarnOperatorWhitespace sym occ -> [SuggestUseWhitespaceAround (unpackFS sym) occ] PsWarnHaddockInvalidPos -> noHints PsWarnHaddockIgnoreMulti -> noHints - PsWarnStarBinder -> noHints - PsWarnStarIsType -> noHints + PsWarnStarBinder -> [SuggestQualifyStarOperator] + PsWarnStarIsType -> [SuggestUseTypeFromDataKind] PsWarnUnrecognisedPragma -> noHints - PsWarnImportPreQualified -> noHints + PsWarnImportPreQualified -> [ SuggestQualifiedAfterModuleName + , SuggestExtension LangExt.ImportQualifiedPost] PsErrLexer{} -> noHints PsErrCmmLexer -> noHints PsErrCmmParser{} -> noHints @@ -672,19 +626,20 @@ instance Diagnostic PsMessage where PsErrInvalidInfixHole -> noHints PsErrExpectedHyphen -> noHints PsErrSpaceInSCC -> noHints - PsErrEmptyDoubleQuotes{} -> noHints - PsErrLambdaCase{} -> noHints + PsErrEmptyDoubleQuotes th_on | th_on -> [SuggestThQuotationSyntax] + | otherwise -> noHints + PsErrLambdaCase{} -> [SuggestExtension LangExt.LambdaCase] PsErrEmptyLambda{} -> noHints - PsErrLinearFunction{} -> noHints - PsErrMultiWayIf{} -> noHints - PsErrOverloadedRecordUpdateNotEnabled{} -> noHints - PsErrNumUnderscores{} -> noHints - PsErrIllegalBangPattern{} -> noHints + PsErrLinearFunction{} -> [SuggestExtension LangExt.LinearTypes] + PsErrMultiWayIf{} -> [SuggestExtension LangExt.MultiWayIf] + PsErrOverloadedRecordUpdateNotEnabled{} -> [SuggestExtension LangExt.OverloadedRecordUpdate] + PsErrNumUnderscores{} -> [SuggestExtension LangExt.NumericUnderscores] + PsErrIllegalBangPattern{} -> [SuggestExtension LangExt.BangPatterns] PsErrOverloadedRecordDotInvalid{} -> noHints - PsErrIllegalPatSynExport -> noHints + PsErrIllegalPatSynExport -> [SuggestExtension LangExt.PatternSynonyms] PsErrOverloadedRecordUpdateNoQualifiedFields -> noHints PsErrExplicitForall{} -> noHints - PsErrIllegalQualifiedDo{} -> noHints + PsErrIllegalQualifiedDo{} -> [SuggestExtension LangExt.QualifiedDo] PsErrQualifiedDoInCmd{} -> noHints PsErrRecordSyntaxInPatSynDecl{} -> noHints PsErrEmptyWhereInPatSynDecl{} -> noHints @@ -692,9 +647,9 @@ instance Diagnostic PsMessage where PsErrNoSingleWhereBindInPatSynDecl{} -> noHints PsErrDeclSpliceNotAtTopLevel{} -> noHints PsErrMultipleNamesInStandaloneKindSignature{} -> noHints - PsErrIllegalExplicitNamespace -> noHints + PsErrIllegalExplicitNamespace -> [SuggestExtension LangExt.ExplicitNamespaces] PsErrUnallowedPragma{} -> noHints - PsErrImportPostQualified -> noHints + PsErrImportPostQualified -> [SuggestExtension LangExt.ImportQualifiedPost] PsErrImportQualifiedTwice -> noHints PsErrIllegalImportBundleForm -> noHints PsErrInvalidRuleActivationMarker -> noHints @@ -738,19 +693,19 @@ instance Diagnostic PsMessage where PsErrProcInFunAppExpr{} -> suggestParensAndBlockArgs PsErrMalformedTyOrClDecl{} -> noHints PsErrIllegalWhereInDataDecl -> noHints - PsErrIllegalDataTypeContext{} -> noHints + PsErrIllegalDataTypeContext{} -> [SuggestExtension LangExt.DatatypeContexts] PsErrPrimStringInvalidChar -> noHints PsErrSuffixAT -> noHints PsErrPrecedenceOutOfRange{} -> noHints - PsErrSemiColonsInCondExpr{} -> noHints - PsErrSemiColonsInCondCmd{} -> noHints + PsErrSemiColonsInCondExpr{} -> [SuggestExtension LangExt.DoAndIfThenElse] + PsErrSemiColonsInCondCmd{} -> [SuggestExtension LangExt.DoAndIfThenElse] PsErrAtInPatPos -> noHints PsErrParseErrorOnInput{} -> noHints PsErrMalformedDecl{} -> noHints PsErrUnexpectedTypeAppInDecl{} -> noHints PsErrNotADataCon{} -> noHints PsErrInferredTypeVarNotAllowed -> noHints - PsErrIllegalTraditionalRecordSyntax{} -> noHints + PsErrIllegalTraditionalRecordSyntax{} -> [SuggestExtension LangExt.TraditionalRecordSyntax] PsErrParseErrorInCmd{} -> noHints PsErrInPat _ details -> case details of PEIP_RecPattern args YesPatIsRecursive ctx @@ -763,8 +718,29 @@ instance Diagnostic PsMessage where sug_missingdo (ParseContext _ YesIncompleteDoBlock) = Just SuggestMissingDo sug_missingdo _ = Nothing PsErrParseRightOpSectionInPat{} -> noHints - PsErrIllegalRoleName{} -> noHints - PsErrInvalidTypeSignature{} -> noHints + PsErrIllegalRoleName _ nearby -> [SuggestRoles nearby] + PsErrInvalidTypeSignature lhs -> + if | foreign_RDR `looks_like` lhs + -> [SuggestExtension LangExt.ForeignFunctionInterface] + | default_RDR `looks_like` lhs + -> [SuggestExtension LangExt.DefaultSignatures] + | pattern_RDR `looks_like` lhs + -> [SuggestExtension LangExt.PatternSynonyms] + | otherwise + -> [SuggestTypeSignatureForm] + where + -- A common error is to forget the ForeignFunctionInterface flag + -- so check for that, and suggest. cf #3805 + -- Sadly 'foreign import' still barfs 'parse error' because + -- 'import' is a keyword + -- looks_like :: RdrName -> LHsExpr GhcPsErr -> Bool -- AZ + looks_like s (L _ (HsVar _ (L _ v))) = v == s + looks_like s (L _ (HsApp _ lhs _)) = looks_like s lhs + looks_like _ _ = False + + foreign_RDR = mkUnqual varName (fsLit "foreign") + default_RDR = mkUnqual varName (fsLit "default") + pattern_RDR = mkUnqual varName (fsLit "pattern") PsErrUnexpectedTypeInDecl{} -> noHints PsErrInvalidPackageName{} -> noHints PsErrIllegalGadtRecordMultiplicity{} -> noHints diff --git a/compiler/GHC/Parser/Errors/Types.hs b/compiler/GHC/Parser/Errors/Types.hs index 95b1733c6e..a78685c11a 100644 --- a/compiler/GHC/Parser/Errors/Types.hs +++ b/compiler/GHC/Parser/Errors/Types.hs @@ -10,6 +10,7 @@ import GHC.Core.TyCon (Role) import GHC.Data.FastString import GHC.Hs import GHC.Parser.Types +import GHC.Parser.Errors.Basic import GHC.Types.Error import GHC.Types.Name.Occurrence (OccName) import GHC.Types.Name.Reader @@ -511,18 +512,6 @@ data CmmParserError | CmmUnrecognisedSafety !String -- ^ Unrecognised safety | CmmUnrecognisedHint !String -- ^ Unrecognised hint --- | The operator symbol in the 'PsOperatorWhitespaceExtConflictMessage' diagnostic. -data OperatorWhitespaceSymbol - = OperatorWhitespaceSymbol_PrefixPercent - | OperatorWhitespaceSymbol_PrefixDollar - | OperatorWhitespaceSymbol_PrefixDollarDollar - --- | The operator occurrence type in the 'PsOperatorWhitespaceMessage' diagnostic. -data OperatorWhitespaceOccurrence - = OperatorWhitespaceOccurrence_Prefix - | OperatorWhitespaceOccurrence_Suffix - | OperatorWhitespaceOccurrence_TightInfix - data TransLayoutReason = TransLayout_Where -- ^ "`where' clause at the same depth as implicit layout block" | TransLayout_Pipe -- ^ "`|' at the same depth as implicit layout block") diff --git a/compiler/GHC/Parser/Lexer.x b/compiler/GHC/Parser/Lexer.x index 6c7a12395a..95fc574cb2 100644 --- a/compiler/GHC/Parser/Lexer.x +++ b/compiler/GHC/Parser/Lexer.x @@ -124,6 +124,7 @@ import GHC.Parser.CharClass import GHC.Parser.Annotation import GHC.Driver.Flags +import GHC.Parser.Errors.Basic import GHC.Parser.Errors.Types import GHC.Parser.Errors.Ppr () } diff --git a/compiler/GHC/Types/Hint.hs b/compiler/GHC/Types/Hint.hs index 883bfa4af4..e1ed317753 100644 --- a/compiler/GHC/Types/Hint.hs +++ b/compiler/GHC/Types/Hint.hs @@ -5,13 +5,16 @@ module GHC.Types.Hint ( InstantiationSuggestion(..) ) where +import GHC.Prelude + import GHC.Utils.Outputable import qualified GHC.LanguageExtensions as LangExt import Data.Typeable import GHC.Unit.Module (ModuleName, Module) import GHC.Hs.Extension (GhcTc) -import GHC.Types.Var (Var) +import GHC.Core.Coercion import GHC.Types.Basic (Activation, RuleName) +import GHC.Parser.Errors.Basic import {-# SOURCE #-} Language.Haskell.Syntax.Expr -- This {-# SOURCE #-} import should be removable once -- 'Language.Haskell.Syntax.Bind' no longer depends on 'GHC.Tc.Types.Evidence'. @@ -83,6 +86,25 @@ data GhcHint Test Case(s): None -} | SuggestUseSpaces + {-| Suggests adding a whitespace after the given symbol. + + Examples: None + Test Case(s): parser/should_compile/T18834a.hs + -} + | SuggestUseWhitespaceAfter !OperatorWhitespaceSymbol + {-| Suggests adding a whitespace around the given operator symbol, + as it might be repurposed as special syntax by a future language extension. + The second parameter is how such operator occurred, if in a prefix, suffix + or tight infix position. + + Triggered by: 'GHC.Parser.Errors.Types.PsWarnOperatorWhitespace'. + + Example: + h a b = a+b -- not OK, no spaces around '+'. + + Test Case(s): parser/should_compile/T18834b.hs + -} + | SuggestUseWhitespaceAround !String !OperatorWhitespaceOccurrence {-| Suggests wrapping an expression in parentheses Examples: None @@ -115,11 +137,63 @@ data GhcHint | SuggestAddInlineOrNoInlinePragma !Var !Activation | SuggestAddPhaseToCompetingRule !RuleName - {-| Suggests increasing the limit for the number of iterations in the simplifier. -} | SuggestIncreaseSimplifierIterations + {-| Suggests to explicitly import 'Type' from the 'Data.Kind' module, because + using "*" to mean 'Data.Kind.Type' relies on the StarIsType extension, which + will become deprecated in the future. + + Triggered by: 'GHC.Parser.Errors.Types.PsWarnStarIsType' + Example: None + Test case(s): wcompat-warnings/WCompatWarningsOn.hs + + -} + | SuggestUseTypeFromDataKind + + {-| Suggests placing the 'qualified' keyword /after/ the module name. + + Triggered by: 'GHC.Parser.Errors.Types.PsWarnImportPreQualified' + Example: None + Test case(s): module/mod184.hs + + -} + | SuggestQualifiedAfterModuleName + + {-| Suggests using TemplateHaskell quotation syntax. + + Triggered by: 'GHC.Parser.Errors.Types.PsErrEmptyDoubleQuotes' only if TemplateHaskell + is enabled. + Example: None + Test case(s): parser/should_fail/T13450TH.hs + + -} + | SuggestThQuotationSyntax + + {-| Suggests alternative roles in case we found an illegal one. + + Triggered by: 'GHC.Parser.Errors.Types.PsErrIllegalRoleName' + Example: None + Test case(s): roles/should_fail/Roles7.hs + + -} + | SuggestRoles [Role] + + {-| Suggests qualifying the '*' operator in modules where StarIsType is enabled. + + Triggered by: 'GHC.Parser.Errors.Types.PsWarnStarBinder' + Test case(s): warnings/should_compile/StarBinder.hs + -} + | SuggestQualifyStarOperator + + {-| Suggests that a type signature should have form <variable> :: <type> + in order to be accepted by GHC. + + Triggered by: 'GHC.Parser.Errors.Types.PsErrInvalidTypeSignature' + Test case(s): parser/should_fail/T3811 + -} + | SuggestTypeSignatureForm -- | An 'InstantiationSuggestion' for a '.hsig' file. This is generated -- by GHC in case of a 'DriverUnexpectedSignature' and suggests a way diff --git a/compiler/GHC/Types/Hint/Ppr.hs b/compiler/GHC/Types/Hint/Ppr.hs index e6e1663fde..56d105dd53 100644 --- a/compiler/GHC/Types/Hint/Ppr.hs +++ b/compiler/GHC/Types/Hint/Ppr.hs @@ -9,6 +9,7 @@ module GHC.Types.Hint.Ppr ( import GHC.Prelude +import GHC.Parser.Errors.Basic import GHC.Types.Hint import GHC.Hs.Expr () -- instance Outputable @@ -50,6 +51,11 @@ instance Outputable GhcHint where text "replacing <" <> ppr pi_mod_name <> text "> as necessary." SuggestUseSpaces -> text "Please use spaces instead." + SuggestUseWhitespaceAfter sym + -> text "Add whitespace after the" + <+> quotes (pprOperatorWhitespaceSymbol sym) <> char '.' + SuggestUseWhitespaceAround sym _occurrence + -> text "Add whitespace around" <+> quotes (text sym) <> char '.' SuggestParentheses -> text "Use parentheses." SuggestIncreaseMaxPmCheckModels @@ -67,6 +73,29 @@ instance Outputable GhcHint where , whenPprDebug (ppr bad_rule) ] SuggestIncreaseSimplifierIterations -> text "Set limit with -fconstraint-solver-iterations=n; n=0 for no limit" + SuggestUseTypeFromDataKind + -> text "Use" <+> quotes (text "Type") + <+> text "from" <+> quotes (text "Data.Kind") <+> text "instead." + SuggestQualifiedAfterModuleName + -> text "Place" <+> quotes (text "qualified") + <+> text "after the module name." + SuggestThQuotationSyntax + -> vcat [ text "Perhaps you intended to use quotation syntax of TemplateHaskell," + , text "but the type variable or constructor is missing" + ] + SuggestRoles nearby + -> case nearby of + [] -> empty + [r] -> text "Perhaps you meant" <+> quotes (ppr r) + -- will this last case ever happen?? + _ -> hang (text "Perhaps you meant one of these:") + 2 (pprWithCommas (quotes . ppr) nearby) + SuggestQualifyStarOperator + -> text "To use (or export) this operator in" + <+> text "modules with StarIsType," + $$ text " including the definition module, you must qualify it." + SuggestTypeSignatureForm + -> text "A type signature should be of form <variables> :: <type>" perhapsAsPat :: SDoc perhapsAsPat = text "Perhaps you meant an as-pattern, which must not be surrounded by whitespace" |