git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Don't expand synonyms until after kind checking (#2546)
0b9265fPhil Freeman
examples/failing/2542.pursnew file+9
@@ -0,0 +1,9 @@
1+-- @shouldFailWith UndefinedTypeVariable
2+module Main where
3+
4+type T = forall a. Array a
5+
6+foo :: T
7+foo = bar where
8+ bar :: Array a
9+ bar = []
examples/warning/2542.pursnew file+16
@@ -0,0 +1,16 @@
1+-- @shouldWarnWith MissingTypeDeclaration
2+module Main where
3+
4+import Control.Monad.Eff.Console
5+
6+type T = forall a. Array a
7+
8+-- | Note: This should not raise a `ShadowedTypeVar` warning as the
9+-- | type `a` introduced in `T` should not be in scope
10+-- | in the definition of `bar`.
11+foo :: T
12+foo = bar where
13+ bar :: forall a. Array a
14+ bar = []
15+
16+main = log "Done"
src/Language/PureScript/TypeChecker/Types.hs+8−5
@@ -187,7 +187,7 @@ data SplitBindingGroup = SplitBindingGroup
187-- This function also generates fresh unification variables for the types of
187-- This function also generates fresh unification variables for the types of
188-- declarations without type annotations, returned in the 'UntypedData' structure.
188-- declarations without type annotations, returned in the 'UntypedData' structure.
189typeDictionaryForBindingGroup
189typeDictionaryForBindingGroup
190− :: (MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
190+ :: (MonadState CheckState m, MonadWriter MultipleErrors m)
191 => Maybe ModuleName
191 => Maybe ModuleName
192 -> [(Ident, Expr)]
192 -> [(Ident, Expr)]
193 -> m SplitBindingGroup
193 -> m SplitBindingGroup
@@ -197,7 +197,7 @@ typeDictionaryForBindingGroup moduleName vals = do
197 -- fully expanded types.
197 -- fully expanded types.
198 let (untyped, typed) = partitionEithers (map splitTypeAnnotation vals)
198 let (untyped, typed) = partitionEithers (map splitTypeAnnotation vals)
199 (typedDict, typed') <- fmap unzip . for typed $ \(ident, (expr, ty, checkType)) -> do
199 (typedDict, typed') <- fmap unzip . for typed $ \(ident, (expr, ty, checkType)) -> do
200− ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
200+ ty' <- replaceTypeWildcards ty
201 return ((ident, ty'), (ident, (expr, ty', checkType)))
201 return ((ident, ty'), (ident, (expr, ty', checkType)))
202 -- Create fresh unification variables for the types of untyped declarations
202 -- Create fresh unification variables for the types of untyped declarations
203 (untypedDict, untyped') <- fmap unzip . for untyped $ \(ident, expr) -> do
203 (untypedDict, untyped') <- fmap unzip . for untyped $ \(ident, expr) -> do
@@ -233,11 +233,14 @@ checkTypedBindingGroupElement mn (ident, (val, ty, checkType)) dict = do
233 -- Kind check
233 -- Kind check
234 (kind, args) <- kindOfWithScopedVars ty
234 (kind, args) <- kindOfWithScopedVars ty
235 checkTypeKind ty kind
235 checkTypeKind ty kind
236+ -- We replace type synonyms _after_ kind-checking, since we don't want type
237+ -- synonym expansion to bring type variables into scope. See #2542.
238+ ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty
236 -- Check the type with the new names in scope
239 -- Check the type with the new names in scope
237 val' <- if checkType
240 val' <- if checkType
238− then withScopedTypeVars mn args $ bindNames dict $ TypedValue True <$> check val ty <*> pure ty
241+ then withScopedTypeVars mn args $ bindNames dict $ TypedValue True <$> check val ty' <*> pure ty'
239− else return (TypedValue False val ty)
242+ else return (TypedValue False val ty')
240− return (ident, (val', ty))
243+ return (ident, (val', ty'))
241
244
242-- | Infer a type for a value in a binding group which lacks an annotation.
245-- | Infer a type for a value in a binding group which lacks an annotation.
243typeForBindingGroupElement
246typeForBindingGroupElement