@@ -241,6 +241,10 @@ desaturateAllTypeSynonyms = everywhere (mkT replace)
241 replace (SaturatedTypeSynonym name args) = foldl TypeApp (TypeConstructor name) args
241 replace (SaturatedTypeSynonym name args) = foldl TypeApp (TypeConstructor name) args
242 replace t = t
242 replace t = t
244+expandAllTypeSynonyms :: Type -> Subst Check Type
245+expandAllTypeSynonyms (SaturatedTypeSynonym name args) = expandTypeSynonym name args >>= expandAllTypeSynonyms
246+expandAllTypeSynonyms ty = return ty
244expandTypeSynonym :: Qualified ProperName -> [Type] -> Subst Check Type
248expandTypeSynonym :: Qualified ProperName -> [Type] -> Subst Check Type
245expandTypeSynonym name args = do
249expandTypeSynonym name args = do
246 env <- lift getEnv
250 env <- lift getEnv
@@ -294,10 +298,15 @@ infer' m (Indexer index val) = do
294 check m val (Array el)
298 check m val (Array el)
295 return el
299 return el
296infer' m (Accessor prop val) = do
300infer' m (Accessor prop val) = do
297− field <- fresh
301+ obj <- infer m val
298− rest <- fresh
302+ propTy <- inferProperty obj prop
299− check m val (Object (RCons prop field rest))
307+ obj `subsumes` Object (RCons prop field rest)
300− return field
308+ return field
309+ Just ty -> return ty
301infer' m (Abs args ret) = do
310infer' m (Abs args ret) = do
302 ts <- replicateM (length args) fresh
311 ts <- replicateM (length args) fresh
303 let m' = m `M.union` M.fromList (zip args ts)
312 let m' = m `M.union` M.fromList (zip args ts)
@@ -352,6 +361,18 @@ infer' m (TypedValue val ty) = do
352 check m val ty'
361 check m val ty'
353 return ty'
362 return ty'
364+inferProperty :: Type -> String -> Subst Check (Maybe Type)
365+inferProperty (Object row) prop = do
366+ let (props, _) = rowToList row
367+ return $ lookup prop props
368+inferProperty (SaturatedTypeSynonym name args) prop = do
369+ replaced <- expandTypeSynonym name args
370+ inferProperty replaced prop
371+inferProperty (ForAll ident ty) prop = do
372+ replaced <- replaceVarsWithUnknowns [ident] ty
373+ inferProperty replaced prop
374+inferProperty _ prop = return Nothing
355inferUnary :: UnaryOperator -> Type -> Subst Check Type
376inferUnary :: UnaryOperator -> Type -> Subst Check Type
356inferUnary op val =
377inferUnary op val =
357 case fromMaybe (error "Invalid operator") $ lookup op unaryOps of
378 case fromMaybe (error "Invalid operator") $ lookup op unaryOps of