Remove io_reader.take
diff --git a/internal/cgen/base/io-private.h b/internal/cgen/base/io-private.h
index 02ed2c7..8f3ae53 100644
--- a/internal/cgen/base/io-private.h
+++ b/internal/cgen/base/io-private.h
@@ -113,25 +113,6 @@
   return b;
 }
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-qual"
-// TODO: can we avoid the const_cast (by deleting this function)? This might
-// involve converting the call sites to take an io_reader instead of a slice u8
-// (the result of io_reader.take).
-static inline wuffs_base__slice_u8  //
-wuffs_base__io_reader__take(const uint8_t** ptr_iop_r,
-                            const uint8_t* io2_r,
-                            uint64_t n) {
-  if (n <= ((size_t)(io2_r - *ptr_iop_r))) {
-    const uint8_t* p = *ptr_iop_r;
-    *ptr_iop_r += n;
-    // The arg is what C calls C++'s "const_cast<uint8_t*>(p)".
-    return wuffs_base__make_slice_u8((uint8_t*)(p), n);
-  }
-  return wuffs_base__make_slice_u8(NULL, 0);
-}
-#pragma GCC diagnostic pop
-
 // --------
 
 static inline uint64_t  //
diff --git a/internal/cgen/builtin.go b/internal/cgen/builtin.go
index 65dcd5e..5a2e1a0 100644
--- a/internal/cgen/builtin.go
+++ b/internal/cgen/builtin.go
@@ -236,10 +236,6 @@
 		}
 		b.writes(", wuffs_base__make_empty_struct())")
 		return nil
-
-	case t.IDTake:
-		b.printf("wuffs_base__io_reader__take(&%s%s, %s%s,", iopPrefix, name, io2Prefix, name)
-		return g.writeArgs(b, args, depth)
 	}
 
 	if method >= peekMethodsBase {
diff --git a/internal/cgen/data.go b/internal/cgen/data.go
index ccb1442..de7915f 100644
--- a/internal/cgen/data.go
+++ b/internal/cgen/data.go
@@ -333,8 +333,7 @@
 	"" +
 	"// --------\n\nstatic inline uint32_t  //\nwuffs_base__io_reader__limited_copy_u32_to_slice(const uint8_t** ptr_iop_r,\n                                                 const uint8_t* io2_r,\n                                                 uint32_t length,\n                                                 wuffs_base__slice_u8 dst) {\n  const uint8_t* iop_r = *ptr_iop_r;\n  size_t n = dst.len;\n  if (n > length) {\n    n = length;\n  }\n  if (n > ((size_t)(io2_r - iop_r))) {\n    n = (size_t)(io2_r - iop_r);\n  }\n  if (n > 0) {\n    memmove(dst.ptr, iop_r, n);\n    *ptr_iop_r += n;\n  }\n  return (uint32_t)(n);\n}\n\n// wuffs_base__io_reader__match7 returns whether the io_reader's upcoming bytes\n// start with the given prefix (up to 7 bytes long). It is peek-like, not\n// read-like, in that there are no side-effects.\n//\n// The low 3 bits of a hold the prefix length, n.\n//\n// The high 56 bits of a hold the prefix itself, in little-endian order. The\n// first prefix byte is in bits 8..=15, the second prefix byte is in bits\n// 16..=23" +
 	", etc. The high (8 * (7 - n)) bits are ignored.\n//\n// There are three possible return values:\n//  - 0 means success.\n//  - 1 means inconclusive, equivalent to \"$short read\".\n//  - 2 means failure.\nstatic inline uint32_t  //\nwuffs_base__io_reader__match7(const uint8_t* iop_r,\n                              const uint8_t* io2_r,\n                              wuffs_base__io_buffer* r,\n                              uint64_t a) {\n  uint32_t n = a & 7;\n  a >>= 8;\n  if ((io2_r - iop_r) >= 8) {\n    uint64_t x = wuffs_base__load_u64le__no_bounds_check(iop_r);\n    uint32_t shift = 8 * (8 - n);\n    return ((a << shift) == (x << shift)) ? 0 : 2;\n  }\n  for (; n > 0; n--) {\n    if (iop_r >= io2_r) {\n      return (r && r->meta.closed) ? 2 : 1;\n    } else if (*iop_r != ((uint8_t)(a))) {\n      return 2;\n    }\n    iop_r++;\n    a >>= 8;\n  }\n  return 0;\n}\n\nstatic inline wuffs_base__io_buffer*  //\nwuffs_base__io_reader__set(wuffs_base__io_buffer* b,\n                           const uint8_t** ptr_iop_r,\n                           c" +
-	"onst uint8_t** ptr_io0_r,\n                           const uint8_t** ptr_io1_r,\n                           const uint8_t** ptr_io2_r,\n                           wuffs_base__slice_u8 data) {\n  b->data = data;\n  b->meta.wi = data.len;\n  b->meta.ri = 0;\n  b->meta.pos = 0;\n  b->meta.closed = false;\n\n  *ptr_iop_r = data.ptr;\n  *ptr_io0_r = data.ptr;\n  *ptr_io1_r = data.ptr;\n  *ptr_io2_r = data.ptr + data.len;\n\n  return b;\n}\n\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wcast-qual\"\n// TODO: can we avoid the const_cast (by deleting this function)? This might\n// involve converting the call sites to take an io_reader instead of a slice u8\n// (the result of io_reader.take).\nstatic inline wuffs_base__slice_u8  //\nwuffs_base__io_reader__take(const uint8_t** ptr_iop_r,\n                            const uint8_t* io2_r,\n                            uint64_t n) {\n  if (n <= ((size_t)(io2_r - *ptr_iop_r))) {\n    const uint8_t* p = *ptr_iop_r;\n    *ptr_iop_r += n;\n    // The arg is what C calls C++'s \"const_cast" +
-	"<uint8_t*>(p)\".\n    return wuffs_base__make_slice_u8((uint8_t*)(p), n);\n  }\n  return wuffs_base__make_slice_u8(NULL, 0);\n}\n#pragma GCC diagnostic pop\n\n" +
+	"onst uint8_t** ptr_io0_r,\n                           const uint8_t** ptr_io1_r,\n                           const uint8_t** ptr_io2_r,\n                           wuffs_base__slice_u8 data) {\n  b->data = data;\n  b->meta.wi = data.len;\n  b->meta.ri = 0;\n  b->meta.pos = 0;\n  b->meta.closed = false;\n\n  *ptr_iop_r = data.ptr;\n  *ptr_io0_r = data.ptr;\n  *ptr_io1_r = data.ptr;\n  *ptr_io2_r = data.ptr + data.len;\n\n  return b;\n}\n\n" +
 	"" +
 	"// --------\n\nstatic inline uint64_t  //\nwuffs_base__io_writer__copy_from_slice(uint8_t** ptr_iop_w,\n                                       uint8_t* io2_w,\n                                       wuffs_base__slice_u8 src) {\n  uint8_t* iop_w = *ptr_iop_w;\n  size_t n = src.len;\n  if (n > ((size_t)(io2_w - iop_w))) {\n    n = (size_t)(io2_w - iop_w);\n  }\n  if (n > 0) {\n    memmove(iop_w, src.ptr, n);\n    *ptr_iop_w += n;\n  }\n  return (uint64_t)(n);\n}\n\nstatic inline uint32_t  //\nwuffs_base__io_writer__limited_copy_u32_from_history(uint8_t** ptr_iop_w,\n                                                     uint8_t* io1_w,\n                                                     uint8_t* io2_w,\n                                                     uint32_t length,\n                                                     uint32_t distance) {\n  if (!distance) {\n    return 0;\n  }\n  uint8_t* p = *ptr_iop_w;\n  if ((size_t)(p - io1_w) < (size_t)(distance)) {\n    return 0;\n  }\n  uint8_t* q = p - distance;\n  size_t n = (size_t)(io2_w - " +
 	"p);\n  if ((size_t)(length) > n) {\n    length = (uint32_t)(n);\n  } else {\n    n = (size_t)(length);\n  }\n  // TODO: unrolling by 3 seems best for the std/deflate benchmarks, but that\n  // is mostly because 3 is the minimum length for the deflate format. This\n  // function implementation shouldn't overfit to that one format. Perhaps the\n  // limited_copy_u32_from_history Wuffs method should also take an unroll hint\n  // argument, and the cgen can look if that argument is the constant\n  // expression '3'.\n  //\n  // See also wuffs_base__io_writer__limited_copy_u32_from_history_fast below.\n  //\n  // Alternatively or additionally, have a sloppy_limited_copy_u32_from_history\n  // method that copies 8 bytes at a time, which can more than length bytes?\n  for (; n >= 3; n -= 3) {\n    *p++ = *q++;\n    *p++ = *q++;\n    *p++ = *q++;\n  }\n  for (; n; n--) {\n    *p++ = *q++;\n  }\n  *ptr_iop_w = p;\n  return length;\n}\n\n// wuffs_base__io_writer__limited_copy_u32_from_history_fast is like the\n// wuffs_base__io_writer__limited_copy" +
diff --git a/lang/builtin/builtin.go b/lang/builtin/builtin.go
index af50b03..f065f52 100644
--- a/lang/builtin/builtin.go
+++ b/lang/builtin/builtin.go
@@ -273,7 +273,6 @@
 	"io_reader.match7(a: u64) u32[..= 2]",
 	"io_reader.position() u64",
 	"io_reader.since(mark: u64) slice u8",
-	"io_reader.take!(n: u64) slice u8",
 
 	"io_reader.limited_copy_u32_to_slice!(up_to: u32, s: slice u8) u32",
 
diff --git a/lang/token/list.go b/lang/token/list.go
index 6e23c66..705b970 100644
--- a/lang/token/list.go
+++ b/lang/token/list.go
@@ -515,7 +515,6 @@
 	IDSkip             = ID(0x16A)
 	IDSkipU32          = ID(0x16B)
 	IDSkipU32Fast      = ID(0x16C)
-	IDTake             = ID(0x16D)
 
 	IDCopyFromSlice                 = ID(0x170)
 	IDLimitedCopyU32FromHistory     = ID(0x171)
@@ -879,7 +878,6 @@
 	IDSkip:             "skip",
 	IDSkipU32:          "skip_u32",
 	IDSkipU32Fast:      "skip_u32_fast",
-	IDTake:             "take",
 
 	IDCopyFromSlice:                 "copy_from_slice",
 	IDLimitedCopyU32FromHistory:     "limited_copy_u32_from_history",
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index ee41931..899c0e3 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -7719,25 +7719,6 @@
   return b;
 }
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-qual"
-// TODO: can we avoid the const_cast (by deleting this function)? This might
-// involve converting the call sites to take an io_reader instead of a slice u8
-// (the result of io_reader.take).
-static inline wuffs_base__slice_u8  //
-wuffs_base__io_reader__take(const uint8_t** ptr_iop_r,
-                            const uint8_t* io2_r,
-                            uint64_t n) {
-  if (n <= ((size_t)(io2_r - *ptr_iop_r))) {
-    const uint8_t* p = *ptr_iop_r;
-    *ptr_iop_r += n;
-    // The arg is what C calls C++'s "const_cast<uint8_t*>(p)".
-    return wuffs_base__make_slice_u8((uint8_t*)(p), n);
-  }
-  return wuffs_base__make_slice_u8(NULL, 0);
-}
-#pragma GCC diagnostic pop
-
 // --------
 
 static inline uint64_t  //