GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2021-11-17T21:20:04Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/17563Validity check quantified constraints2021-11-17T21:20:04ZRichard Eisenbergrae@richarde.devValidity check quantified constraintsThis module is accepted:
```hs
{-# LANGUAGE QuantifiedConstraints #-}
module Bug2 where
blah :: (forall a. a b ~ a c) => b -> c
blah = undefined
```
But it shouldn't be: it uses `~` with neither `GADTs` nor `TypeFamilies` enabled.This module is accepted:
```hs
{-# LANGUAGE QuantifiedConstraints #-}
module Bug2 where
blah :: (forall a. a b ~ a c) => b -> c
blah = undefined
```
But it shouldn't be: it uses `~` with neither `GADTs` nor `TypeFamilies` enabled.8.10.2https://gitlab.haskell.org/ghc/ghc/-/issues/20864TransformListComp accepts invalid unboxed let bindings2022-08-02T12:56:23ZDavid FeuerTransformListComp accepts invalid unboxed let bindings## Summary
`let` bindings with unboxed types in transformed list comprehensions desugar to invalid Core.
## Steps to reproduce
```haskell
{-# language MagicHash, TransformListComp #-}
module TLC where
import GHC.Exts
glum :: [Int] ->...## Summary
`let` bindings with unboxed types in transformed list comprehensions desugar to invalid Core.
## Steps to reproduce
```haskell
{-# language MagicHash, TransformListComp #-}
module TLC where
import GHC.Exts
glum :: [Int] -> [Int]
glum xs = [I# p | I# x <- xs, let p = x +# 3#, then take 3]
```
This fails Core Lint. With optimizations enabled, it desugars like the following, but it's desugared just as invalidly when optimizations are disabled.
```haskell
glum :: [Int] -> [Int]
[LclIdX]
glum
= \ (xs_aw5 :: [Int]) ->
build
@Int
(\ (@a_dye) (c_dyf :: Int -> a_dye -> a_dye) (n_dyg :: a_dye) ->
GHC.Base.foldr
@Int#
@a_dye
(\ (ds_dyv :: Int#) (ds_dyu :: a_dye) ->
let {
p_axE :: Int#
[LclId]
p_axE = ds_dyv } in
c_dyf ((\ (ds_dyw :: Int#) -> GHC.Types.I# ds_dyw) p_axE) ds_dyu)
n_dyg
((\ (@a_axU) -> take @a_axU (GHC.Types.I# 3#))
@Int#
(build
@Int#
(\ (@a_dyh) (c_dyi :: Int# -> a_dyh -> a_dyh) (n_dyj :: a_dyh) ->
GHC.Base.foldr
@Int
@a_dyh
(\ (ds_dyl :: Int) (ds_dyk :: a_dyh) ->
case ds_dyl of wild_00 { I# x_axD ->
let {
p_axR :: Int#
[LclId]
p_axR = +# x_axD 3# } in
let {
p_axE :: Int#
[LclId]
p_axE = p_axR } in
c_dyi p_axE ds_dyk
})
n_dyj
xs_aw5))))
end Rec }
```
Note that one application each of `foldr` and `build` are at type `Int#`, which has the wrong kind.
## Expected behavior
I expect this particular example to be rejected by the type checker. However, I would expect the following to continue to work:
```haskell
loom :: [Int] -> [Int]
loom xs = [z | I# x <- xs, let p = x +# 3#, z <- [1 .. I# p], then take 3]
```
Note: I've included a "runtime crash" tag even though I haven't written an example that crashes because my informal testing strongly indicates invalid memory accesses that don't happen to segfault.
## Environment
* GHC version used:
Optional:
* Operating System:
* System Architecture:9.4.1sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/24469Lexer is too permissive with numbers followed by an identifier (e.g. "1foo")2024-02-28T18:22:40ZVaibhav SagarLexer is too permissive with numbers followed by an identifier (e.g. "1foo")## Summary
GHC's lexer lexes numbers followed by an identifier as two separate tokens (number and then identifier) when I think it should reject this as invalid.
## Steps to reproduce
```
GHCi, version 9.8.1: https://www.haskell.org/g...## Summary
GHC's lexer lexes numbers followed by an identifier as two separate tokens (number and then identifier) when I think it should reject this as invalid.
## Steps to reproduce
```
GHCi, version 9.8.1: https://www.haskell.org/ghc/ :? for help
ghci> foo = 1
ghci> (+) 1foo
2
```
## Expected behavior
I would expect the lexer to throw an error.
## Environment
* GHC version used: 9.8.1
Optional:
* Operating System:
* System Architecture:https://gitlab.haskell.org/ghc/ghc/-/issues/23152DerivingError constraint failures are too lazy2023-03-28T13:45:39ZDavid FeuerDerivingError constraint failures are too lazy## Summary
Constraints on instances derived using `DerivingVia` aren't checked eagerly enough.
## Steps to reproduce
```haskell
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE DataKinds #-}
import GHC.Ty...## Summary
Constraints on instances derived using `DerivingVia` aren't checked eagerly enough.
## Steps to reproduce
```haskell
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE DataKinds #-}
import GHC.TypeLits
class Crumb a
newtype Fool a = Fool a
instance TypeError ('Text "You can't do that") => Crumb (Fool a)
deriving via Fool Int
instance Crumb Int
```
This compiles with no warnings or errors.
## Expected behavior
I expect the above program to be rejected, since it produces an instance for `Crumb Int` with no constraints when the ground instance it's based on has an unsatisfiable constraint. I don't *think* this is a soundness problem per se, but it does make me slightly nervous.
This example is a highly boring reduction of a more interesting one in `linear-generics`. I'd like to produce a custom type error when attempting to derive an instance of `Generics.Linear.Generic1` via `Generics.Linear.Unsafe.ViaGHCGenerics.GHCGenerically1`. This sort of works, but only because the derived *methods* fail to typecheck. Since there are two methods, we get two type errors. And since the errors are on the methods, they end up being considerably more confusing to read than they should be.
## Environment
* GHC version used: 9.6.1
Optional:
* Operating System:
* System Architecture:https://gitlab.haskell.org/ghc/ghc/-/issues/21376Type synonym with forall causes point-free code to not be equivalent2022-04-12T21:16:58ZpbrisbinType synonym with forall causes point-free code to not be equivalent## Summary
In GHC 9.0.2, it seems that using a point-free style doesn't
work when a certain kind of `type` is involved.
This fails to compile (full details below):
```hs
limitRetries :: Natural -> RetryPolicy
limitRetries = Retry.limi...## Summary
In GHC 9.0.2, it seems that using a point-free style doesn't
work when a certain kind of `type` is involved.
This fails to compile (full details below):
```hs
limitRetries :: Natural -> RetryPolicy
limitRetries = Retry.limitRetries . fromIntegral
-- Given,
-- Retry.limitRetries :: Int -> RetryPolicy
-- type RetryPolicy = forall m. RetryPolicyM m
```
While this works fine:
```hs
limitRetries :: Natural -> RetryPolicy
limitRetries x = Retry.limitRetries $ fromIntegral x
```
As a relatively compiler-naive Haskell user, I wouldn't expect code with
and without a point here to behave any differently, so I'm reporting this
as a bug.
Also, HLint will automatically eta-reduce away a point, so this is a new avenue by which
it can break your code.
## Steps to reproduce
This error first hit me when upgrading a project using the `retry` library,
so I've pared down my repro from there. I'm also using `stack` because it
makes it trivial to ensure someone can run this at all the exact versions
as I'm seeing.
**repro.hs**
```hs
{-# LANGUAGE RankNTypes #-}
module Control.Retry
( main
) where
import Prelude
import Numeric.Natural
newtype RetryPolicyM m = RetryPolicyM { getRetryPolicyM :: () -> m (Maybe Int) }
type RetryPolicy = forall m . Monad m => RetryPolicyM m
limitRetries :: Int -> RetryPolicy
limitRetries = undefined
limitRetries' :: Natural -> RetryPolicy
limitRetries' = limitRetries . fromIntegral
main :: IO ()
main = putStrLn "hi"
```
```console
% stack --resolver lts-19.3 runhaskell -- repro.hs
repro.hs:16:16: error:
• Couldn't match expected type ‘Int -> RetryPolicy’
with actual type ‘a0’
Cannot instantiate unification variable ‘a0’
with a type involving polytypes: Int -> RetryPolicy
• In the expression: undefined
In an equation for ‘limitRetries’: limitRetries = undefined
|
16 | limitRetries = undefined
| ^^^^^^^^^
repro.hs:19:17: error:
• Couldn't match type ‘c0’ with ‘RetryPolicy’
Expected: Int -> c0
Actual: Int -> RetryPolicy
Cannot instantiate unification variable ‘c0’
with a type involving polytypes: RetryPolicy
• In the first argument of ‘(.)’, namely ‘limitRetries’
In the expression: limitRetries . fromIntegral
In an equation for ‘limitRetries'’:
limitRetries' = limitRetries . fromIntegral
|
19 | limitRetries' = limitRetries . fromIntegral
```
## Expected behavior
The code should compile.
GHC 8.10 does not exhibit this behavior:
```console
% stack --resolver lts-18.28 runhaskell -- repro.hs
hi
```
With GHC 9, you have to add points to both of these:
```diff
- limitRetries = undefined
+ limitRetries x = undefined x
```
```diff
- limitRetries' = limitRetries . fromIntegral
+ limitRetries' x = limitRetries $ fromIntegral x
```
```console
% stack --resolver lts-19.3 runhaskell -- repro.hs
hi
```
## Environment
* GHC version used: 9.0.2 and 9.2.2
Optional:
* Operating System: Arch Linux
* System Architecture:
```console
% uname -a
Linux prince 5.16.14-arch1-1 #1 SMP PREEMPT Fri, 11 Mar 2022 17:40:36 +0000 x86_64 GNU/Linux
```https://gitlab.haskell.org/ghc/ghc/-/issues/20078Safe import should not be accepted2021-08-02T12:34:28ZKrzysztof GogolewskiSafe import should not be accepted```
{-# LANGUAGE Unsafe #-}
module Bug where
import safe Unsafe.Coerce
```
I think this should be rejected. It is rejected by 8.10 and 9.0, accepted by HEAD.
Results are the same if I use `Trustworthy` instead of `Unsafe`. If I use `Sa...```
{-# LANGUAGE Unsafe #-}
module Bug where
import safe Unsafe.Coerce
```
I think this should be rejected. It is rejected by 8.10 and 9.0, accepted by HEAD.
Results are the same if I use `Trustworthy` instead of `Unsafe`. If I use `Safe`, HEAD rejects.https://gitlab.haskell.org/ghc/ghc/-/issues/20071Overlapping instances mentioning constructor-bound type variables give no error2022-02-24T11:31:39Zaadaa-fgtaaOverlapping instances mentioning constructor-bound type variables give no error## Summary
Constraints mentioning type variable bound by data constructor are solved even when they trigger overlapping instances.
## Steps to reproduce
```haskell
{-# LANGUAGE FlexibleInstances, ExistentialQuantification #-}
module ...## Summary
Constraints mentioning type variable bound by data constructor are solved even when they trigger overlapping instances.
## Steps to reproduce
```haskell
{-# LANGUAGE FlexibleInstances, ExistentialQuantification #-}
module Bug where
import Data.Proxy
class Foo x where
x :: Proxy x -> String
instance Foo Int where
x _ = "Int"
instance Foo a where
x _ = "-"
data SomeProxy = forall x . SomeProxy (Proxy x)
foo :: SomeProxy -> String
foo (SomeProxy p) = x p
```
This code compiles without an error, although `Foo Int` and `Foo a` are obviously overlapping. Encoding existential type via universal quantification fails as expected
```haskell
bar :: ((forall x . Proxy x -> String) -> String) -> String
bar f = f x
```
```
• Overlapping instances for Foo x arising from a use of ‘x’
Matching instances:
instance Foo a -- Defined at Bug.hs:15:10
instance Foo Int -- Defined at Bug.hs:12:10
(The choice depends on the instantiation of ‘x’
To pick the first instance above, use IncoherentInstances
when compiling the other instance declarations)
```
## Expected behavior
Compiling `foo` gives the same error as `bar`.
## Environment
* GHC version used: 8.10.4, 9.0.1, 9.3.20210504
* Operating System: Linux (NixOS)
* System Architecture: x86-64https://gitlab.haskell.org/ghc/ghc/-/issues/19816SOURCE imported things shouldn't be allowed to be used in TH splices2021-05-11T03:27:18ZMatthew PickeringSOURCE imported things shouldn't be allowed to be used in TH splicesIn a module loop, if you use something which is source imported in a TH splice then you get an error during linking the expression.
It seems this is a bit late during compilation and the error should be raised earlier, because there's ...In a module loop, if you use something which is source imported in a TH splice then you get an error during linking the expression.
It seems this is a bit late during compilation and the error should be raised earlier, because there's never going to be an object file for the .hs-boot file.
https://gist.github.com/522acd04b479217e0e728ada01f309f3
```
[1 of 3] Compiling C[boot] ( C.hs-boot, C.o-boot, C.dyn_o )
[2 of 3] Compiling D ( D.hs, D.o, D.dyn_o )
[3 of 3] Compiling C ( C.hs, C.o, C.dyn_o )
module C cannot be linked; it is only available as a boot module
```https://gitlab.haskell.org/ghc/ghc/-/issues/19304Promotion quote syntax without -XDataKinds2021-12-20T19:28:41ZKrzysztof GogolewskiPromotion quote syntax without -XDataKindsThis compiles by default (Haskell2010). I'd expect the promotion quote syntax to work only when `-XDataKinds` is on.
```
import GHC.Types
type T = 'LiftedRep
```This compiles by default (Haskell2010). I'd expect the promotion quote syntax to work only when `-XDataKinds` is on.
```
import GHC.Types
type T = 'LiftedRep
```https://gitlab.haskell.org/ghc/ghc/-/issues/18762Validity checker should reject polytypes passed to type functions2022-07-27T16:19:21ZRichard Eisenbergrae@richarde.devValidity checker should reject polytypes passed to type functions@RyanGlScott points out in https://gitlab.haskell.org/ghc/ghc/-/issues/11715#note_303067 that we can now say
```hs
λ> :set -XTypeFamilies -XImpredicativeTypes -XFlexibleContexts
λ> type family F a where F (a -> b) = a -> b
λ> :kind! F (...@RyanGlScott points out in https://gitlab.haskell.org/ghc/ghc/-/issues/11715#note_303067 that we can now say
```hs
λ> :set -XTypeFamilies -XImpredicativeTypes -XFlexibleContexts
λ> type family F a where F (a -> b) = a -> b
λ> :kind! F (Eq Int => Int)
F (Eq Int => Int) :: *
= Eq Int -> Int
```
Ew. While indeed this does show a problem around confusing `Constraint` and `Type`, there is a simpler problem here: type families are designed to work only with plain old "tau" types. These types have no dependency or invisible arguments.
<details>
<summary>Why type families work over tau-types only</summary>
The restriction around tau-types is necessary to guide type inference. Suppose we have
```hs
type family Id a where
Id a = a
f :: Id (forall a. a -> a) -> Char
f x = x 'z'
```
When GHC checks the definition of `f`, it knows is that the type of `x` is `Id (forall a. a -> a)`. The type checker has not yet tried to reduce type families. (Even if it did, which is plausible, more complicated scenarios would still exist -- such as a type family being stuck on a variable that we learn only through a GADT pattern-match equals some concrete type -- that witness the fundamental problem.) The type checker sees `x` applied to an argument of type `Char` and returning a result of type `Char`, so it concludes that `Id (forall a. a -> a) ~ (Char -> Char)`. Later, GHC reduces `Id (forall a. a -> a)` to `forall a. a -> a`. Yet we're now stuck, because it is not the case that `(forall a. a -> a) ~ (Char -> Char)`. The former is a subtype of the latter, but that's different (and GHC does not yet track subtype relationships in its constraint-solving).
Bottom line: type families mustn't return something that isn't a tau-type, or strange things like this can ensue.
Note that there is *no* type safety issue here. It's all about type inference.
</details>
So we should stop this nonsense in the validity checker.
But, actually, that's probably not enough, because an innocent-looking `F a` could get instantiated to `F (forall b. b -> b)` at some call-site, due to Quick Look. Maybe any variable used in the argument to a type function should be excluded from Quick Look. @trupill @simonpj will want to think about that.https://gitlab.haskell.org/ghc/ghc/-/issues/18400Instances do not respect functional dependency, yet are accepted2020-11-13T13:39:12ZRichard Eisenbergrae@richarde.devInstances do not respect functional dependency, yet are acceptedTaken from #7875:
```hs
class Het a b | a -> b where
het :: m (f c) -> a -> m b
class GHet (a :: Type -> Type) (b :: Type -> Type) | a -> b
instance GHet (K a) (K [a])
instance Het a b => GHet (K a) (K b)
data K x a = K x...Taken from #7875:
```hs
class Het a b | a -> b where
het :: m (f c) -> a -> m b
class GHet (a :: Type -> Type) (b :: Type -> Type) | a -> b
instance GHet (K a) (K [a])
instance Het a b => GHet (K a) (K b)
data K x a = K x
```
Ticket #7875 is about a problem that arises later... but I'm flummoxed as to why these instances are accepted. The two instances of `GHet` seem quite assuredly to violate its fundep. Yet ticket #7875 seems unconcerned about this issue, so I'm reluctant to fix until someone agrees that these instances are indeed problematic. Help?https://gitlab.haskell.org/ghc/ghc/-/issues/17416Missing overlapping pattern warning for pattern with required constraint2022-05-27T18:07:45Zsheafsam.derbyshire@gmail.comMissing overlapping pattern warning for pattern with required constraintAdding a required constraint to a pattern affects overlap checking:
```haskell
{-# OPTIONS_GHC -Woverlapping-patterns -Wincomplete-patterns #-}
{-# LANGUAGE FlexibleContexts, PatternSynonyms #-}
class C a where
pattern P1 :: C Int =>...Adding a required constraint to a pattern affects overlap checking:
```haskell
{-# OPTIONS_GHC -Woverlapping-patterns -Wincomplete-patterns #-}
{-# LANGUAGE FlexibleContexts, PatternSynonyms #-}
class C a where
pattern P1 :: C Int => Int
pattern P1 = 1
test :: C Int => Int -> Int
test i = case i of
P1 -> 3
P1 -> 7
_ -> 11
```
This causes no warnings. Removing the required constraint to the pattern signature of `P1` reinstates the expected warning:
```
Pattern match is redundant
In a case alternative: P1 -> ...
```
Note that this is not limited to pattern synonyms, as can be seen by inlining the pattern signature.
Note also that completeness checking is not affected (as can be seen by removing the catch-all case).
I saw a few tickets concerning overlap checking in particular in the context of insoluble constraints (e.g. #13766), but in this case it seems a shame to lose overlap checking. Is there some option I could switch on to enforce overlap checks?https://gitlab.haskell.org/ghc/ghc/-/issues/17197Nested arrow do notation doesn't cause errors in GHCi2020-01-23T19:48:51ZAshesh AmbastaNested arrow do notation doesn't cause errors in GHCi## Summary
[See the gist of the issue here.](https://gist.github.com/asheshambasta/64496f5f2c55f9b78293ff2eba72f884)
The [offending line](https://gist.github.com/asheshambasta/64496f5f2c55f9b78293ff2eba72f884#file-arrowbug-hs-L3) is co...## Summary
[See the gist of the issue here.](https://gist.github.com/asheshambasta/64496f5f2c55f9b78293ff2eba72f884)
The [offending line](https://gist.github.com/asheshambasta/64496f5f2c55f9b78293ff2eba72f884#file-arrowbug-hs-L3) is considered an empty do block in the arrow command. This happens due to indentation: the do block is at the same level of indentation as the enclosing do block.
This is incorrect syntax which doesn't lead to complaints when loading this module with GHCi; but it does when building the module.
## Steps to reproduce
1. Create a module similar to the one in the gist
2. Load the module in GHCi (in my case, `stack ghci`)
3. Build the module (`stack build`)
## Expected behavior
The compilation errors listed in https://gist.github.com/asheshambasta/64496f5f2c55f9b78293ff2eba72f884#file-errors-txt must also be emitted when loading the module with ghci.
## Environment
* GHC version used: 8.4.4
Optional:
* Operating System: NixOS
* System Architecture: `Linux quasar-nixos-tp 5.1.21 #1-NixOS SMP Sun Jul 28 06:28:39 UTC 2019 x86_64 GNU/Linux`https://gitlab.haskell.org/ghc/ghc/-/issues/16581Trivial Functional Dependencies (and downright nonsense) accepted2019-07-07T18:00:07ZAnthony ClaydenTrivial Functional Dependencies (and downright nonsense) accepted# Summary
GHC accepts Functional Dependencies that are pointless and/or nonsensical.
(This ticket was originally posted as a possible 'feature'. But the allowed syntax is misleading: there's no useful behaviour. Commentary from SPJ & R...# Summary
GHC accepts Functional Dependencies that are pointless and/or nonsensical.
(This ticket was originally posted as a possible 'feature'. But the allowed syntax is misleading: there's no useful behaviour. Commentary from SPJ & RAE retained below for ref.)
# Steps to reproduce
These FunDeps are accepted
class C a | a -> a where -- not even MultiParam
cMeth :: a -> String
class D a b | a b -> b where
dMeth :: a -> b -> String
class D2 a b | a b a b -> b a b a
# Expected behavior
I expect these to be rejected, because they're pointless. The class behaves just as if there were no FunDep at all.
# Environment
* GHC version used: 8.6.4
Optional:
* Operating System: Windows
* For comparison, the validation on FunDeps in Hugs [static validation, search for "trivial"](https://github.com/FranklinChen/hugs98-plus-Sep2006/blob/master/src/static.c) is, for each FunDep in the class decl:
* the tyvars to the right of each `->` must be non-empty;
* no tyvar can appear both left and right of the same `->`;
* no tyvar repeated left of each `->`;
* no tyvar repeated right of each `->`.
* In general, in database theory for functional dependencies, these are known as 'trivial'. (Neither the Jones 2000 paper introducing FunDeps; nor the JFP 2006 Sulzmann et al 'via CHRs paper' explicitly give these rules.)
/label ~bug
-- as originally posted, for ref
# Motivation
This isn't so much a feature request as: does anybody know GHC can do this?/Is there some reasoning behind it?/I can think of a possible use.
There's a long-standing ticket #8634 which got dubbed 'Dysfunctional Dependencies'. It seems GHC already supports something like it.
# Proposal
Consider these FunDeps
class C a | a -> a where -- not even MultiParam
cMeth :: a -> String
class D a b | a b -> b where
dMeth :: a -> b -> String
This is accepted by GHC (8.6.4), and I can write and use instances for those classes. Those dependencies are what's called "trivial" -- that is, the FunDep target also appears on LHS of the `->`. FunDep theory (such as the 'via CHRs' paper) says they shouldn't be allowed, and indeed Hugs rejects those class decls.
But wait! Here's some useful instances
instance D Int Bool where
dMeth x p = show $ if p then x else -x
instance D Int Char where -- rejected if FunDep is bare a -> b
dMeth x y = y : show x -- because FunDep conflict between instances
instance (b1 ~ Int) => D Int (b1 -> b1) where
dMeth x f = show $ f x
fi = dMeth (5 :: Int) ((\x -> x + x) :: Num b2 => b2 -> b2)
instance {-# OVERLAPPABLE #-} (b ~ String) => D Int b where
dMeth x _ = "String" ++ show x
(That last instance and the `(b1 -> b1)` would need `UndecidableInstances` if just FunDep `a -> b`.)
OTOH I don't seem to be getting behaviour any different from just `D` without a FunDep at all. For example
f :: D a b => a -> a
f x = x
is rejected as ambiguous, as would be with no FunDep on `D`.
From what I recall of 'Dysfunctional Dependencies' (by now the ticket is long and turgid), a FunDep `a b -> b` does represent what's happening: for some instances you can get from `a` to `b` by the coverage conditions; for some you can get from `a` to `b` via Constraints (and `UndecidableInstances`); for some you need to also look at the combo of `a, b` -- in that case, the Wanted from the use site will give sufficient typing to select the instance and then fix `b`. Just trust me that when the FunDep says `... -> b` you'll be able to infer `b`.