diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java
index 7afbe27d40577b1c9665fb2ad129a876f53815b4..dbef3184430bd0dcab9fb401b0e1c81702becf48 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java
@@ -22,19 +22,20 @@
  */
 package com.oracle.truffle.r.nodes.builtin.base;
 
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.RootCallTarget;
 import com.oracle.truffle.api.Truffle;
-import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.FrameDescriptor;
 import com.oracle.truffle.r.nodes.access.AccessArgumentNode;
 import com.oracle.truffle.r.nodes.access.ConstantNode;
 import com.oracle.truffle.r.nodes.access.WriteVariableNode;
 import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.function.FormalArguments;
 import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode;
@@ -50,11 +51,11 @@ import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExpression;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RLanguage;
-import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RSymbol;
+import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
@@ -64,9 +65,16 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
 @RBuiltin(name = "as.function.default", kind = INTERNAL, parameterNames = {"x", "envir"}, behavior = PURE)
 public abstract class AsFunction extends RBuiltinNode {
+
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").mustBe(instanceOf(RAbstractListVector.class).or(instanceOf(RExpression.class)), RError.SHOW_CALLER2, RError.Message.TYPE_EXPECTED, RType.List.getName());
+        casts.arg("envir").mustBe(instanceOf(REnvironment.class), RError.Message.INVALID_ENVIRONMENT);
+    }
+
     @Specialization
     @TruffleBoundary
-    protected RFunction asFunction(RList x, REnvironment envir) {
+    protected RFunction asFunction(RAbstractListVector x, REnvironment envir) {
         if (x.getLength() == 0) {
             throw RError.error(this, RError.Message.GENERIC, "argument must have length at least 1");
         }
@@ -147,11 +155,4 @@ public abstract class AsFunction extends RBuiltinNode {
     protected RFunction asFunction(RExpression x, REnvironment envir) {
         return asFunction(x.getList(), envir);
     }
-
-    @SuppressWarnings("unused")
-    @Fallback
-    @TruffleBoundary
-    protected RFunction asFunction(Object x, Object envir) {
-        throw RError.error(this, RError.Message.TYPE_EXPECTED, RType.List.getName());
-    }
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java
index eed6487e7d200d01f870fc30c9c3217d6c11d3d1..3622943accf8632b7ddd6e475f491e09b7a0d148 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java
@@ -36,6 +36,7 @@ import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
 import com.oracle.truffle.r.nodes.RASTUtils;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode;
 import com.oracle.truffle.r.nodes.function.UseMethodInternalNode;
@@ -90,7 +91,7 @@ public abstract class Bind extends RBaseNode {
     protected static final int LIST_PRECEDENCE = PrecedenceNode.LIST_PRECEDENCE;
     protected static final int EXPRESSION_PRECEDENCE = PrecedenceNode.EXPRESSION_PRECEDENCE;
 
-    public abstract Object execute(VirtualFrame frame, Object deparseLevelObj, Object[] args, RArgsValuesAndNames promiseArgs, int precedence);
+    public abstract Object execute(VirtualFrame frame, int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, int precedence);
 
     @Child private CastToVectorNode castVector;
     @Child private UseMethodInternalNode dcn;
@@ -139,7 +140,7 @@ public abstract class Bind extends RBaseNode {
 
     @SuppressWarnings("unused")
     @Specialization(guards = "precedence == NO_PRECEDENCE")
-    protected RNull allNull(VirtualFrame frame, Object deparseLevelObj, Object[] args, RArgsValuesAndNames promiseArgs, int precedence) {
+    protected RNull allNull(VirtualFrame frame, int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, int precedence) {
         return RNull.instance;
     }
 
@@ -148,7 +149,7 @@ public abstract class Bind extends RBaseNode {
     private static final RStringVector DATA_FRAME_CLASS = RDataFactory.createStringVectorFromScalar("data.frame");
 
     @Specialization(guards = {"args.length > 1", "isDataFrame(args)"})
-    protected Object allDataFrame(VirtualFrame frame, Object deparseLevel, @SuppressWarnings("unused") Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence) {
+    protected Object allDataFrame(VirtualFrame frame, int deparseLevel, @SuppressWarnings("unused") Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence) {
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             dcn = insert(new UseMethodInternalNode(type.toString(), SIGNATURE, false));
@@ -160,7 +161,7 @@ public abstract class Bind extends RBaseNode {
         }
     }
 
-    private Object bindInternal(Object deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, CastNode castNode, boolean needsVectorCast) {
+    private Object bindInternal(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, CastNode castNode, boolean needsVectorCast) {
         ArgumentsSignature signature = promiseArgs.getSignature();
         String[] vecNames = nullNamesProfile.profile(signature.getNonNullCount() == 0) ? null : new String[signature.getLength()];
         RAbstractVector[] vectors = new RAbstractVector[args.length];
@@ -203,31 +204,31 @@ public abstract class Bind extends RBaseNode {
     }
 
     @Specialization(guards = {"precedence == INT_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"})
-    protected Object allInt(Object deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, //
+    protected Object allInt(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, //
                     @Cached("create()") CastIntegerNode cast) {
         return bindInternal(deparseLevel, args, promiseArgs, cast, true);
     }
 
     @Specialization(guards = {"precedence == DOUBLE_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"})
-    protected Object allDouble(Object deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, //
+    protected Object allDouble(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, //
                     @Cached("create()") CastDoubleNode cast) {
         return bindInternal(deparseLevel, args, promiseArgs, cast, true);
     }
 
     @Specialization(guards = {"precedence == STRING_PRECEDENCE", "args.length> 1", "!isDataFrame(args)"})
-    protected Object allString(Object deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, //
+    protected Object allString(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, //
                     @Cached("create()") CastStringNode cast) {
         return bindInternal(deparseLevel, args, promiseArgs, cast, true);
     }
 
     @Specialization(guards = {"precedence == COMPLEX_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"})
-    protected Object allComplex(Object deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, //
+    protected Object allComplex(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, //
                     @Cached("create()") CastComplexNode cast) {
         return bindInternal(deparseLevel, args, promiseArgs, cast, true);
     }
 
     @Specialization(guards = {"precedence == LIST_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"})
-    protected Object allList(Object deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, //
+    protected Object allList(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, //
                     @Cached("create()") CastListNode cast) {
         return bindInternal(deparseLevel, args, promiseArgs, cast, false);
     }
@@ -267,7 +268,7 @@ public abstract class Bind extends RBaseNode {
      * Compute dimnames for columns (cbind) or rows (rbind) from names of vectors being combined or
      * by deparsing.
      */
-    protected int getDimResultNamesFromVectors(RArgsValuesAndNames promiseArgs, RAbstractVector vec, String[] argNames, int resDim, int oldInd, int vecInd, Object deparseLevelObj,
+    protected int getDimResultNamesFromVectors(RArgsValuesAndNames promiseArgs, RAbstractVector vec, String[] argNames, int resDim, int oldInd, int vecInd, int deparseLevel,
                     String[] dimNamesArray,
                     int dimNamesInd) {
         int ind = oldInd;
@@ -294,7 +295,6 @@ public abstract class Bind extends RBaseNode {
             return -ind;
         } else if (!vec.isArray() || vec.getDimensions().length == 1) {
             if (argNames == null) {
-                int deparseLevel = deparseLevel(deparseLevelObj);
                 if (deparseLevel == 0) {
                     dimNamesArray[ind++] = RRuntime.NAMES_ATTR_EMPTY_VALUE;
                     return -ind;
@@ -350,15 +350,6 @@ public abstract class Bind extends RBaseNode {
         return notEqualDims;
     }
 
-    protected int deparseLevel(Object deparseLevelObj) {
-        RAbstractLogicalVector v = (RAbstractLogicalVector) castLogical(castVector(deparseLevelObj), true);
-        if (v.getLength() == 0 || v.getDataAt(0) == 0) {
-            return 0;
-        } else {
-            return v.getDataAt(0);
-        }
-    }
-
     protected int[] getDimensions(RAbstractVector vector) {
         int[] dimensions = vector.getDimensions();
         if (dimensions == null || dimensions.length != 2) {
@@ -404,6 +395,11 @@ public abstract class Bind extends RBaseNode {
         @Child private Bind bind = BindNodeGen.create(BindType.cbind);
         @Child private PrecedenceNode precedenceNode = PrecedenceNodeGen.create();
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("deparse.level").asIntegerVector().findFirst();
+        }
+
         private int precedence(Object[] args) {
             int precedence = -1;
             for (int i = 0; i < args.length; i++) {
@@ -413,8 +409,8 @@ public abstract class Bind extends RBaseNode {
         }
 
         @Specialization
-        protected Object bind(VirtualFrame frame, Object deparseLevelObj, RArgsValuesAndNames args) {
-            return bind.execute(frame, deparseLevelObj, args.getArguments(), (RArgsValuesAndNames) RArguments.getArgument(frame, 0), precedence(args.getArguments()));
+        protected Object bind(VirtualFrame frame, int deparseLevel, RArgsValuesAndNames args) {
+            return bind.execute(frame, deparseLevel, args.getArguments(), (RArgsValuesAndNames) RArguments.getArgument(frame, 0), precedence(args.getArguments()));
         }
     }
 
@@ -422,7 +418,7 @@ public abstract class Bind extends RBaseNode {
     private final BranchProfile everSeenNotEqualColumns = BranchProfile.create();
 
     @Specialization(guards = {"precedence != NO_PRECEDENCE", "args.length == 1"})
-    protected Object allOneElem(Object deparseLevelObj, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence) {
+    protected Object allOneElem(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence) {
         RAbstractVector vec = castVector(args[0]);
         if (vec.isMatrix()) {
             return vec;
@@ -435,7 +431,6 @@ public abstract class Bind extends RBaseNode {
 
         ArgumentsSignature signature = promiseArgs.getSignature();
         if (signature.getNonNullCount() == 0) {
-            int deparseLevel = deparseLevel(deparseLevelObj);
             if (deparseLevel == 0) {
                 dimNamesB = RNull.instance;
             } else {
@@ -457,7 +452,7 @@ public abstract class Bind extends RBaseNode {
         return res;
     }
 
-    public RVector genericCBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, Object deparseLevel) {
+    public RVector genericCBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel) {
 
         int[] resultDimensions = new int[2];
         int[] secondDims = new int[vectors.length];
@@ -518,6 +513,11 @@ public abstract class Bind extends RBaseNode {
         @Child private Bind bind = BindNodeGen.create(BindType.rbind);
         @Child private PrecedenceNode precedenceNode = PrecedenceNodeGen.create();
 
+        @Override
+        protected void createCasts(CastBuilder casts) {
+            casts.arg("deparse.level").asIntegerVector().findFirst();
+        }
+
         private int precedence(Object[] args) {
             int precedence = -1;
             for (int i = 0; i < args.length; i++) {
@@ -527,12 +527,12 @@ public abstract class Bind extends RBaseNode {
         }
 
         @Specialization
-        protected Object bind(VirtualFrame frame, Object deparseLevelObj, RArgsValuesAndNames args) {
-            return bind.execute(frame, deparseLevelObj, args.getArguments(), (RArgsValuesAndNames) RArguments.getArgument(frame, 0), precedence(args.getArguments()));
+        protected Object bind(VirtualFrame frame, int deparseLevel, RArgsValuesAndNames args) {
+            return bind.execute(frame, deparseLevel, args.getArguments(), (RArgsValuesAndNames) RArguments.getArgument(frame, 0), precedence(args.getArguments()));
         }
     }
 
-    public RVector genericRBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, Object deparseLevel) {
+    public RVector genericRBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel) {
 
         int[] resultDimensions = new int[2];
         int[] firstDims = new int[vectors.length];
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
index b1e8b8809410ffaade8698147faf38c847b2b085..a2527d8e6e5a10fc63638a4654c25af041d201b2 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
@@ -368,7 +368,7 @@ public final class RError extends RuntimeException {
         // below: not exactly GNU-R message
         PROMISE_CYCLE("promise already under evaluation: recursive default argument reference or earlier problems?"),
         MISSING_ARGUMENTS("'missing' can only be used for arguments"),
-        INVALID_ENVIRONMENT("invalid environment specified"),
+        INVALID_ENVIRONMENT("invalid environment"),
         ENVIR_NOT_LENGTH_ONE("numeric 'envir' arg not of length one"),
         FMT_NOT_CHARACTER("'fmt' is not a character vector"),
         UNSUPPORTED_TYPE("unsupported type"),
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index 747b14fce59ab65bc0324e28d1ca11432e604e52..f1dc824c72aaca9c94b7fa3e2124a04d6450d925 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -6001,6 +6001,15 @@ a + foo(c) * b
 #foo <- function(x) x*2; f <- function() a+foo(c)*b; as.function(c(alist(a=1+14, b=foo(x),c=), body(f)))(c=3,b=1)
 [1] 21
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asfunction.testasfunction
+#{ .Internal(as.function.default(alist(a+b), "foo")) }
+Error in as.function.default(alist(a + b), "foo") : invalid environment
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_asfunction.testasfunction
+#{ .Internal(as.function.default(function() 42, parent.frame())) }
+Error in as.function.default(function() 42, parent.frame()) :
+  list argument expected
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_asfunction.testasfunction
 #{ as.function(alist("foo"))() }
 [1] "foo"
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asfunction.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asfunction.java
index fd5ab3b839035c4da732444ea11a2285d5ed31f5..b0432a40b7d1b1a86be53c5f91686a31760b0bb6 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asfunction.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asfunction.java
@@ -40,5 +40,7 @@ public class TestBuiltin_asfunction extends TestBase {
         assertEval("{ as.function(alist(\"foo\"))() }");
         assertEval("{ as.function(alist(7+42i))() }");
         assertEval("{ as.function(alist(as.raw(7)))() }");
+        assertEval(Output.IgnoreErrorContext, "{ .Internal(as.function.default(alist(a+b), \"foo\")) }");
+        assertEval(Output.IgnoreErrorContext, "{ .Internal(as.function.default(function() 42, parent.frame())) }");
     }
 }