@@ -241,6 +241,10 @@ desaturateAllTypeSynonyms = everywhere (mkT replace)
241241 replace (SaturatedTypeSynonym name args) = foldl TypeApp (TypeConstructor name) args
242242 replace t = t
243243
244+expandAllTypeSynonyms :: Type -> Subst Check Type
245+expandAllTypeSynonyms (SaturatedTypeSynonym name args) = expandTypeSynonym name args >>= expandAllTypeSynonyms
246+expandAllTypeSynonyms ty = return ty
247+
244248expandTypeSynonym :: Qualified ProperName -> [Type] -> Subst Check Type
245249expandTypeSynonym name args = do
246250 env <- lift getEnv
@@ -294,10 +298,15 @@ infer' m (Indexer index val) = do
294298 check m val (Array el)
295299 return el
296300infer' m (Accessor prop val) = do
297− field <- fresh
298− rest <- fresh
299− check m val (Object (RCons prop field rest))
300− return field
301+ obj <- infer m val
302+ propTy <- inferProperty obj prop
303+ case propTy of
304+ Nothing -> do
305+ field <- fresh
306+ rest <- fresh
307+ obj `subsumes` Object (RCons prop field rest)
308+ return field
309+ Just ty -> return ty
301310infer' m (Abs args ret) = do
302311 ts <- replicateM (length args) fresh
303312 let m' = m `M.union` M.fromList (zip args ts)
@@ -352,6 +361,18 @@ infer' m (TypedValue val ty) = do
352361 check m val ty'
353362 return ty'
354363
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
375+
355376inferUnary :: UnaryOperator -> Type -> Subst Check Type
356377inferUnary op val =
357378 case fromMaybe (error "Invalid operator") $ lookup op unaryOps of