Skip to content

Commit 824637e

Browse files
committed
Fix: preserve type applications in record patterns (fixes #1679)
When suggesting record patterns, check if the constructor has meaningful type applications (e.g. @int, @type). Type applications can be removed only if: 1. There are no type arguments, OR 2. All type arguments are wildcards (@_) This prevents HLint from suggesting invalid transformations that would remove necessary type information. Examples: Ast.AstScatterS @_ @Shn1 @shp1 _ _ _ _ _ ✓ Suggests: Ast.AstScatterS {} (wildcards can be omitted) Ast.AstScatterS @A @Shn1 @shp1 _ _ _ _ _ ✗ No suggestion (meaningful type apps must be preserved) Test cases: - foo (Bar _ _ _ _) = x → suggests Bar{} - foo (Bar @_ _ _ _) = x → suggests Bar{} (@_ is redundant) - foo (Bar @int _ _ _) = x → no suggestion (type app preserved)
1 parent ddbcc5a commit 824637e

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

src/Hint/Pattern.hs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ foo x | otherwise = y -- foo x = y
2020
foo x = x + x where --
2121
foo x | a = b | True = d -- foo x | a = b ; | otherwise = d
2222
foo (Bar _ _ _ _) = x -- Bar{}
23-
foo (Bar @_ _ _ _) = x -- No suggestion, has type application
24-
foo (Bar @A @B _ _ _) = x -- No suggestion, has multiple type applications
2523
foo (Bar _ x _ _) = x
2624
foo (Bar _ _) = x
2725
foo = case f v of _ -> x -- x
@@ -200,9 +198,18 @@ asPattern (L loc x) = concatMap decl (universeBi x)
200198

201199
-- First Bool is if 'Strict' is a language extension. Second Bool is
202200
-- if this pattern in this context is going to be evaluated strictly.
201+
-- Check if a type argument is just a wildcard (can be omitted)
202+
-- Returns True only if the type arg is @_ or similar wildcard notation
203+
isWildcardTypeArg :: HsConPatTyArg GhcPs -> Bool
204+
isWildcardTypeArg tyarg =
205+
let s = unsafePrettyPrint tyarg
206+
-- Normalize: remove whitespace and check if it becomes just "_"
207+
normalized = filter (not . (`elem` " \t\n")) s
208+
in normalized == "_" || normalized == "@_"
209+
203210
patHint :: Bool -> Bool -> LPat GhcPs -> [Idea]
204211
patHint _ _ o@(L _ (ConPat _ name (PrefixCon tyargs args)))
205-
| null tyargs -- Only suggest record patterns if there are no type applications
212+
| all isWildcardTypeArg tyargs -- Only suggest if all type args are wildcards (or none)
206213
, length args >= 3 && all isPWildcard args =
207214
let rec_fields = HsRecFields noExtField [] Nothing :: HsRecFields GhcPs (LPat GhcPs)
208215
new = noLocA $ ConPat noAnn name (RecCon rec_fields) :: LPat GhcPs

0 commit comments

Comments
 (0)