@@ -16,8 +16,7 @@ module Type.State
16 , register
16 , register
17 , introduce
17 , introduce
19− , makeInstance
19+ , copy
@@ -130,6 +129,13 @@ getPool =
130 return ( sPool state, state )
129 return ( sPool state, state )
132+{-# INLINE getMaxRank #-}
133+getMaxRank :: Solver Int
135+ Solver $ \state@(SS _ _ (Pool maxRank _) _ _) ->
136+ return ( maxRank, state )
133{-# INLINE getEnv #-}
139{-# INLINE getEnv #-}
134getEnv :: Solver Env
140getEnv :: Solver Env
@@ -147,23 +153,15 @@ saveLocalEnv =
147{-# INLINE uniqueMark #-}
153{-# INLINE uniqueMark #-}
148uniqueMark :: Solver Int
154uniqueMark :: Solver Int
149uniqueMark =
155uniqueMark =
150− Solver $ \state ->
156+ Solver $ \(SS env savedEnv pool mark errors) ->
155− return ( mark, state { sMark = mark + 1 } )
157+ return ( mark, SS env savedEnv pool (mark + 1) errors )
158{-# INLINE nextRankPool #-}
160{-# INLINE nextRankPool #-}
159nextRankPool :: Solver Pool
161nextRankPool :: Solver Pool
160nextRankPool =
162nextRankPool =
161− Solver $ \state ->
163+ Solver $ \state@(SS _ _ (Pool maxRank _) _ _) ->
166− return ( Pool (maxRank + 1) [], state )
164+ return ( Pool (maxRank + 1) [], state )
@@ -186,13 +184,10 @@ register variable =
186introduce :: Variable -> Solver Variable
184introduce :: Variable -> Solver Variable
187introduce variable =
185introduce variable =
188 {-# SCC elm_compiler_type_introduce #-}
186 {-# SCC elm_compiler_type_introduce #-}
191− (Pool maxRank inhabitants) =
187+ Solver $ \(SS env savedEnv (Pool maxRank inhabitants) mark errors) ->
194− do UF.modifyDescriptor variable (\desc -> desc { _rank = maxRank })
188+ do UF.modifyDescriptor variable $ \(Descriptor c _ m cp) -> Descriptor c maxRank m cp
195− return ( variable, state { sPool = Pool maxRank (variable : inhabitants) } )
189+ let newPool = Pool maxRank (variable : inhabitants)
190+ return ( variable, SS env savedEnv newPool mark errors )
@@ -202,201 +197,140 @@ introduce variable =
202flatten :: Type -> Solver Variable
197flatten :: Type -> Solver Variable
203flatten term =
198flatten term =
204 {-# SCC elm_compiler_type_flatten #-}
199 {-# SCC elm_compiler_type_flatten #-}
200+ do maxRank <- getMaxRank
205− flattenHelp Map.empty term
201+ flattenHelp maxRank Map.empty term
208−flattenHelp :: Map.Map Text Variable -> Type -> Solver Variable
204+flattenHelp :: Int -> Map.Map Text Variable -> Type -> Solver Variable
209−flattenHelp aliasDict termN =
205+flattenHelp maxRank aliasDict termN =
210 case termN of
206 case termN of
211 PlaceHolder name ->
207 PlaceHolder name ->
212 return (aliasDict ! name)
208 return (aliasDict ! name)
214 AliasN name args realType ->
210 AliasN name args realType ->
215− do flatArgs <- mapM (traverse (flattenHelp aliasDict)) args
211+ do flatArgs <- mapM (traverse (flattenHelp maxRank aliasDict)) args
216− flatVar <- flattenHelp (Map.fromList flatArgs) realType
212+ flatVar <- flattenHelp maxRank (Map.fromList flatArgs) realType
217− makeFlatType (Alias name flatArgs flatVar)
213+ makeFlatType maxRank (Alias name flatArgs flatVar)
219 VarN v ->
215 VarN v ->
222 AppN name args ->
218 AppN name args ->
223− do flatArgs <- traverse (flattenHelp aliasDict) args
219+ do flatArgs <- traverse (flattenHelp maxRank aliasDict) args
224− makeFlatType (Structure (App1 name flatArgs))
220+ makeFlatType maxRank (Structure (App1 name flatArgs))
226 FunN a b ->
222 FunN a b ->
227− do flatA <- flattenHelp aliasDict a
223+ do flatA <- flattenHelp maxRank aliasDict a
228− flatB <- flattenHelp aliasDict b
224+ flatB <- flattenHelp maxRank aliasDict b
229− makeFlatType (Structure (Fun1 flatA flatB))
225+ makeFlatType maxRank (Structure (Fun1 flatA flatB))
231 EmptyRecordN ->
227 EmptyRecordN ->
232− makeFlatType (Structure EmptyRecord1)
228+ makeFlatType maxRank (Structure EmptyRecord1)
234 RecordN fields ext ->
230 RecordN fields ext ->
235− do flatFields <- traverse (flattenHelp aliasDict) fields
231+ do flatFields <- traverse (flattenHelp maxRank aliasDict) fields
236− flatExt <- flattenHelp aliasDict ext
232+ flatExt <- flattenHelp maxRank aliasDict ext
237− makeFlatType (Structure (Record1 flatFields flatExt))
233+ makeFlatType maxRank (Structure (Record1 flatFields flatExt))
240−makeFlatType :: Content -> Solver Variable
236+makeFlatType :: Int -> Content -> Solver Variable
241−makeFlatType content =
237+makeFlatType maxRank content =
242− do pool <- getPool
238+ register =<< liftIO (UF.fresh (Descriptor content maxRank noMark Nothing))
243− variable <- liftIO $ UF.fresh $
245− { _content = content
246− , _rank = _maxRank pool
254−-- MAKE INSTANCE
242+-- COPY
257−makeInstance :: Variable -> Solver Variable
245+copy :: Variable -> Solver Variable
258−makeInstance var =
246+copy var =
259− do alreadyCopiedMark <- uniqueMark
247+ {-# SCC elm_compiler_type_copy #-}
260− freshVar <- makeCopy alreadyCopiedMark var
248+ do maxRank <- getMaxRank
249+ copyVar <- copyHelp maxRank var
261− _ <- restore alreadyCopiedMark var
250+ _ <- restore var
262− return freshVar
251+ return copyVar
254+copyHelp :: Int -> Variable -> Solver Variable
255+copyHelp maxRank variable =
256+ do (Descriptor content rank _mark maybeCopy) <- liftIO $ UF.descriptor variable
258+ Just copiedVariable ->
259+ return copiedVariable
266−-- MAKE COPY
261+ Nothing ->
262+ if rank /= noRank then
266+ do let mkCopyDesc cont = Descriptor cont maxRank noMark Nothing
267+ newVar <- liftIO $ UF.fresh $ mkCopyDesc content
268+ _ <- register newVar
269−makeCopy :: Int -> Variable -> Solver Variable
270+ -- Link the original variable to the new variable. This lets us
270−makeCopy alreadyCopiedMark variable =
271+ -- avoid making multiple copies of the variable we are instantiating.
271− {-# SCC elm_compiler_type_copy #-}
272+ --
273+ -- Need to do this before recursively copying the content of
274+ -- the variable to avoid looping on cyclic terms.
272− do desc <- liftIO $ UF.descriptor variable
275+ liftIO $ UF.setDescriptor variable $
273− makeCopyHelp desc alreadyCopiedMark variable
276+ Descriptor content rank noMark (Just newVar)
278+ -- Now we recursively copy the content of the variable.
279+ -- We have already marked the variable as copied, so we
280+ -- will not repeat this work or crawl this variable again.
283+ do newTerm <- traverseFlatType (copyHelp maxRank) term
284+ liftIO $ UF.setDescriptor newVar $ mkCopyDesc (Structure newTerm)
276−makeCopyHelp :: Descriptor -> Int -> Variable -> Solver Variable
286+ Var Rigid maybeSuper maybeName ->
277−makeCopyHelp (Descriptor content rank mark copy) alreadyCopiedMark variable =
287+ liftIO $ UF.setDescriptor newVar $ mkCopyDesc $ Var Flex maybeSuper maybeName
278− if mark == alreadyCopiedMark then
280− Just copiedVariable ->
281− return copiedVariable
285− "Error copying type variable. This should be impossible.\
286− \ Please report this at <https://github.com/elm-lang/elm-compiler/issues>\
287− \ with a <http://sscce.org> and information on your OS, how you installed,\
288− \ and any other configuration information that might be helpful."
290− else if rank /= noRank || not (needsCopy content) then
296− liftIO $ UF.fresh $ Descriptor
297− { _content = content -- place holder!
298− , _rank = _maxRank pool
302− _ <- register newVar
304− -- Link the original variable to the new variable. This lets us
305− -- avoid making multiple copies of the variable we are instantiating.
307− -- Need to do this before recursively copying the content of
308− -- the variable to avoid looping on cyclic terms.
309− liftIO $ UF.modifyDescriptor variable $ \desc ->
310− desc { _mark = alreadyCopiedMark, _copy = Just newVar }
313− let setContent newContent =
314− liftIO $ UF.modifyDescriptor newVar $ \desc ->
315− desc { _content = newContent }
317− -- Now we recursively copy the content of the variable.
318− -- We have already marked the variable as copied, so we
319− -- will not repeat this work or crawl this variable again.
322− do newTerm <- traverseFlatType (makeCopy alreadyCopiedMark) term
323− setContent (Structure newTerm)
325− Var Rigid maybeSuper maybeName ->
326− setContent (Var Flex maybeSuper maybeName)
328− Var Flex _ _ ->
289+ Var Flex _ _ ->
331− Alias name args realType ->
334− <$> mapM (traverse (makeCopy alreadyCopiedMark)) args
335− <*> makeCopy alreadyCopiedMark realType
339− return ()
290+ return ()
344−needsCopy :: Content -> Bool
350− Var _ _ _ ->
292+ Alias name args realType ->
351− True
293+ do newArgs <- mapM (traverse (copyHelp maxRank)) args
294+ newRealType <- copyHelp maxRank realType
295+ liftIO $ UF.setDescriptor newVar $ mkCopyDesc (Alias name newArgs newRealType)
353− Alias _ _ _ ->
297+ Error _ ->
356− Error _ ->
300+ return newVar
361-- RESTORE
304-- RESTORE
364−restore :: Int -> Variable -> Solver Variable
307+restore :: Variable -> Solver Variable
365−restore alreadyCopiedMark variable =
308+restore variable =
366− do desc <- liftIO $ UF.descriptor variable
309+ do (Descriptor content _rank _mark maybeCopy) <- liftIO $ UF.descriptor variable
367− if _mark desc /= alreadyCopiedMark
310+ case maybeCopy of
369 return variable
312 return variable
372− do restoredContent <-
315+ do restoredContent <- restoreContent content
373− restoreContent alreadyCopiedMark (_content desc)
374− liftIO $ UF.setDescriptor variable $ Descriptor
316+ liftIO $ UF.setDescriptor variable $
375− { _content = restoredContent
317+ Descriptor restoredContent noRank noMark Nothing
380 return variable
318 return variable
384−restoreContent :: Int -> Content -> Solver Content
321+restoreContent :: Content -> Solver Content
385−restoreContent alreadyCopiedMark content =
322+restoreContent content =
387− go = restore alreadyCopiedMark
389 case content of
323 case content of
390 Structure term ->
324 Structure term ->
391− Structure <$> traverseFlatType go term
325+ Structure <$> traverseFlatType restore term
393 Var _ _ _ ->
327 Var _ _ _ ->
394 return content
328 return content
396 Alias name args var ->
330 Alias name args var ->
397 Alias name
331 Alias name
398− <$> mapM (traverse go) args
332+ <$> mapM (traverse restore) args
399− <*> go var
333+ <*> restore var
401 Error _ ->
335 Error _ ->
402 return content
336 return content