on master help sign in
Fix problem with variable shadowing when instantiating aliased types
commit143547e766efe66c007f37e1c4b278edba4ebebc authorEvan Czaplicki <info@elm-lang.org> dateThu 8 Aug 2013, 15:45 (13 years ago) parentc70d59f
1 file changed+28−28
compiler/Type/Environment.hs+28−28
compiler/Type/Environment.hs+28−28
@@ -122,40 +122,40 @@ instantiator env sourceType = go sourceType
122122
123123 Src.Var x -> do
124124 (dict, aliases) <- State.get
125− case Map.lookup x dict of
126− Just var -> return (VarN var)
127− Nothing ->
128− case Map.lookup x aliases of
129− Just t -> return t
130− Nothing ->
131− do var <- State.liftIO $ namedVar flex x
132− State.put (Map.insert x var dict, aliases)
133− return (VarN var)
134− where
135− flex | "number" `isPrefixOf` x = Is Number
136− | "comparable" `isPrefixOf` x = Is Comparable
137− | "appendable" `isPrefixOf` x = Is Appendable
138− | otherwise = Flexible
125+ case (Map.lookup x dict, Map.lookup x aliases) of
126+ (_, Just t) -> return t
127+ (Just v, _) -> return (VarN v)
128+ _ ->
129+ do var <- State.liftIO $ namedVar flex x
130+ State.put (Map.insert x var dict, aliases)
131+ return (VarN var)
132+ where
133+ flex | "number" `isPrefixOf` x = Is Number
134+ | "comparable" `isPrefixOf` x = Is Comparable
135+ | "appendable" `isPrefixOf` x = Is Appendable
136+ | otherwise = Flexible
139137
140138 Src.Data "String" [] ->
141139 return (get env types "_List" <| get env types "Char")
142140
143141 Src.Data name ts -> do
144142 ts' <- mapM go ts
145− case Map.lookup name (types env) of
146− Just t -> return $ foldl (<|) t ts'
147− Nothing ->
148− case Map.lookup name (aliases env) of
149− Nothing -> error $ "\nCould not find type constructor '" ++ name ++ "' while checking types."
150− Just (tvars, t) ->
151− let tvarLen = length tvars
152− msg = "\nType alias '" ++ name ++ "' expects " ++ show tvarLen ++
153− " type argument" ++ (if tvarLen == 1 then "" else "s") ++
154− " but was given " ++ show (length ts')
155− in if length ts' /= length tvars then error msg else
156− do (dict, aliases) <- State.get
157− State.put (dict, Map.union aliases . Map.fromList $ zip tvars ts')
158− go t
143+ case (Map.lookup name (types env), Map.lookup name (aliases env)) of
144+ (Just t, _) -> return $ foldl (<|) t ts'
145+ (_, Just (tvars, t)) ->
146+ let tvarLen = length tvars
147+ msg = "\nType alias '" ++ name ++ "' expects " ++ show tvarLen ++
148+ " type argument" ++ (if tvarLen == 1 then "" else "s") ++
149+ " but was given " ++ show (length ts')
150+ in if length ts' /= length tvars then error msg else
151+ do (dict, aliases) <- State.get
152+ let aliases' = Map.union (Map.fromList $ zip tvars ts') aliases
153+ State.put (dict, aliases')
154+ t' <- go t
155+ State.put (dict, aliases)
156+ return t'
157+ _ -> error $ "\nCould not find type constructor '" ++
158+ name ++ "' while checking types."
159159
160160 Src.EmptyRecord -> return (TermN EmptyRecord1)
161161