+ go (Var f) n_args args = idAppIsNonUpd f n_args args
+
+ go (App f a) n_args args
+ | isTypeArg a = go f n_args args
+ | otherwise = go f (n_args + 1) (a:args)
+
+ go (Note (SCC _) f) n_args args = False
+ go (Note _ f) n_args args = go f n_args args
+
+ go other n_args args = False
+
+idAppIsNonUpd :: Id -> Int -> [CoreExpr] -> Bool
+idAppIsNonUpd id n_val_args args
+ = case idFlavour id of
+ DataConId con | not (isDynConApp con args) -> True
+ other -> n_val_args < idArity id
+
+isDynConApp con args = isDllName (dataConName con) || any isDynArg args
+
+ -- Does this argument refer to something in a different DLL,
+ -- or is a LitLit? Constructor arguments which are in another
+ -- DLL or are LitLits aren't compiled into static constructors
+ -- (see CoreToStg), so we have to take that into account here.
+isDynArg :: CoreExpr -> Bool
+isDynArg (Var v) = isDllName (idName v)
+isDynArg (Note _ e) = isDynArg e
+isDynArg (Lit lit) = isLitLitLit lit
+isDynArg (App e _) = isDynArg e -- must be a type app
+isDynArg (Lam _ e) = isDynArg e -- must be a type lam
+
+-- We consider partial applications to be non-updatable. NOTE: this
+-- must match how CoreToStg marks the closure.