diff --git a/src/Language/PureScript/TypeChecker/Roles.hs b/src/Language/PureScript/TypeChecker/Roles.hs index 5edbad4b80..bc0f0c7b5d 100644 --- a/src/Language/PureScript/TypeChecker/Roles.hs +++ b/src/Language/PureScript/TypeChecker/Roles.hs @@ -139,11 +139,11 @@ inferRoles env tyName -- the absence of a role signature, provides the safest default for a type whose -- constructors are opaque to us. rolesFromForeignTypeKind :: SourceType -> [Role] -rolesFromForeignTypeKind - = go [] - where - go acc = \case - TypeApp _ (TypeApp _ fn k1) _k2 | eqType fn tyFunction -> - go (Nominal : acc) k1 - _k -> - Nominal : acc +rolesFromForeignTypeKind k = replicate (kindArity k) Nominal + +kindArity :: SourceType -> Int +kindArity = go 0 where + go n (TypeApp _ (TypeApp _ fn _) k) + | fn == tyFunction = go (n + 1) k + go n (ForAll _ _ _ k _) = go n k + go n _ = n diff --git a/tests/purs/failing/CoercibleForeign2.out b/tests/purs/failing/CoercibleForeign2.out new file mode 100644 index 0000000000..083afcb7bf --- /dev/null +++ b/tests/purs/failing/CoercibleForeign2.out @@ -0,0 +1,28 @@ +Error found: +in module Main +at tests/purs/failing/CoercibleForeign2.purs:9:20 - 9:26 (line 9, column 20 - line 9, column 26) + + No type class instance was found for +   +  Prim.Coerce.Coercible (Foreign a0 b1 c2) +  (Foreign a0 b1 d3) +   + +while checking that type forall (a :: Type) (b :: Type). Coercible a b => a -> b + is at least as general as type Foreign a0 b1 c2 -> Foreign a0 b1 d3 +while checking that expression coerce + has type Foreign a0 b1 c2 -> Foreign a0 b1 d3 +in value declaration foreignToForeign + +where a0 is a rigid type variable + bound at (line 9, column 20 - line 9, column 26) + b1 is a rigid type variable + bound at (line 9, column 20 - line 9, column 26) + c2 is a rigid type variable + bound at (line 9, column 20 - line 9, column 26) + d3 is a rigid type variable + bound at (line 9, column 20 - line 9, column 26) + +See https://github.com/purescript/documentation/blob/master/errors/NoInstanceFound.md for more information, +or to contribute content related to this error. + diff --git a/tests/purs/failing/CoercibleForeign2.purs b/tests/purs/failing/CoercibleForeign2.purs new file mode 100644 index 0000000000..bc94a389d1 --- /dev/null +++ b/tests/purs/failing/CoercibleForeign2.purs @@ -0,0 +1,9 @@ +-- @shouldFailWith NoInstanceFound +module Main where + +import Safe.Coerce (coerce) + +foreign import data Foreign :: Type -> Type -> Type -> Type + +foreignToForeign :: forall a b c d. Foreign a b c -> Foreign a b d +foreignToForeign = coerce diff --git a/tests/purs/failing/CoercibleForeign3.out b/tests/purs/failing/CoercibleForeign3.out new file mode 100644 index 0000000000..9bf213691d --- /dev/null +++ b/tests/purs/failing/CoercibleForeign3.out @@ -0,0 +1,28 @@ +Error found: +in module Main +at tests/purs/failing/CoercibleForeign3.purs:9:20 - 9:26 (line 9, column 20 - line 9, column 26) + + No type class instance was found for +   +  Prim.Coerce.Coercible (Foreign @k0 a1 b2) +  (Foreign @k0 a1 c3) +   + +while checking that type forall (a :: Type) (b :: Type). Coercible a b => a -> b + is at least as general as type Foreign @k0 a1 b2 -> Foreign @k0 a1 c3 +while checking that expression coerce + has type Foreign @k0 a1 b2 -> Foreign @k0 a1 c3 +in value declaration foreignToForeign + +where k0 is a rigid type variable + bound at (line 9, column 20 - line 9, column 26) + a1 is a rigid type variable + bound at (line 9, column 20 - line 9, column 26) + b2 is a rigid type variable + bound at (line 9, column 20 - line 9, column 26) + c3 is a rigid type variable + bound at (line 9, column 20 - line 9, column 26) + +See https://github.com/purescript/documentation/blob/master/errors/NoInstanceFound.md for more information, +or to contribute content related to this error. + diff --git a/tests/purs/failing/CoercibleForeign3.purs b/tests/purs/failing/CoercibleForeign3.purs new file mode 100644 index 0000000000..2abd379b12 --- /dev/null +++ b/tests/purs/failing/CoercibleForeign3.purs @@ -0,0 +1,9 @@ +-- @shouldFailWith NoInstanceFound +module Main where + +import Safe.Coerce (coerce) + +foreign import data Foreign :: ∀ k. k -> k -> Type + +foreignToForeign :: ∀ k (a :: k) (b :: k) (c :: k). Foreign a b -> Foreign a c +foreignToForeign = coerce