Rename rust::Slice<T> to rust::Slice<const T>
diff --git a/README.md b/README.md
index 9c0289b..49b8d09 100644
--- a/README.md
+++ b/README.md
@@ -315,7 +315,7 @@
 <tr><th>name in Rust</th><th>name in C++</th><th>restrictions</th></tr>
 <tr><td>String</td><td>rust::String</td><td></td></tr>
 <tr><td>&amp;str</td><td>rust::Str</td><td></td></tr>
-<tr><td>&amp;[u8]</td><td>rust::Slice&lt;uint8_t&gt;</td><td><sup><i>arbitrary &amp;[T] not implemented yet</i></sup></td></tr>
+<tr><td>&amp;[u8]</td><td>rust::Slice&lt;const uint8_t&gt;</td><td><sup><i>arbitrary &amp;[T] not implemented yet</i></sup></td></tr>
 <tr><td><a href="https://docs.rs/cxx/0.5/cxx/struct.CxxString.html">CxxString</a></td><td>std::string</td><td><sup><i>cannot be passed by value</i></sup></td></tr>
 <tr><td>Box&lt;T&gt;</td><td>rust::Box&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
 <tr><td><a href="https://docs.rs/cxx/0.5/cxx/struct.UniquePtr.html">UniquePtr&lt;T&gt;</a></td><td>std::unique_ptr&lt;T&gt;</td><td><sup><i>cannot hold opaque Rust type</i></sup></td></tr>
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 5fe8ee3..5708b49 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -432,7 +432,7 @@
         }
         Some(Type::SliceRefU8(_)) if !indirect_return => {
             out.builtin.rust_slice_repr = true;
-            write!(out, "::rust::impl<::rust::Slice<uint8_t>>::repr(")
+            write!(out, "::rust::impl<::rust::Slice<const uint8_t>>::repr(")
         }
         _ => {}
     }
@@ -471,7 +471,7 @@
         } else if let Type::SliceRefU8(_) = arg.ty {
             write!(
                 out,
-                "::rust::Slice<uint8_t>(static_cast<const uint8_t *>({0}.ptr), {0}.len)",
+                "::rust::Slice<const uint8_t>(static_cast<const uint8_t *>({0}.ptr), {0}.len)",
                 arg.ident,
             );
         } else if out.types.needs_indirect_abi(&arg.ty) {
@@ -688,7 +688,7 @@
             }
             Type::SliceRefU8(_) => {
                 out.builtin.rust_slice_new = true;
-                write!(out, "::rust::impl<::rust::Slice<uint8_t>>::slice(");
+                write!(out, "::rust::impl<::rust::Slice<const uint8_t>>::slice(");
             }
             _ => {}
         }
@@ -714,7 +714,7 @@
             }
             Type::SliceRefU8(_) => {
                 out.builtin.rust_slice_repr = true;
-                write!(out, "::rust::impl<::rust::Slice<uint8_t>>::repr(");
+                write!(out, "::rust::impl<::rust::Slice<const uint8_t>>::repr(");
             }
             ty if out.types.needs_indirect_abi(ty) => write!(out, "&"),
             _ => {}
@@ -885,7 +885,7 @@
             write!(out, "::rust::Str");
         }
         Type::SliceRefU8(_) => {
-            write!(out, "::rust::Slice<uint8_t>");
+            write!(out, "::rust::Slice<const uint8_t>");
         }
         Type::Fn(f) => {
             write!(out, "::rust::{}<", if f.throws { "TryFn" } else { "Fn" });
diff --git a/include/cxx.h b/include/cxx.h
index 7dfbbca..83a0ccd 100644
--- a/include/cxx.h
+++ b/include/cxx.h
@@ -90,13 +90,16 @@
 #ifndef CXXBRIDGE05_RUST_SLICE
 template <typename T>
 class Slice final {
+  static_assert(std::is_const<T>::value,
+                "&[T] needs to be written as rust::Slice<const T> in C++");
+
 public:
   Slice() noexcept;
-  Slice(const T *, size_t count) noexcept;
+  Slice(T *, size_t count) noexcept;
 
   Slice &operator=(const Slice<T> &) noexcept = default;
 
-  const T *data() const noexcept;
+  T *data() const noexcept;
   size_t size() const noexcept;
   size_t length() const noexcept;
 
@@ -108,7 +111,7 @@
   friend impl<Slice>;
   // Not necessarily ABI compatible with &[T]. Codegen will translate to
   // cxx::rust_sliceu8::RustSliceU8 which matches this layout.
-  const T *ptr;
+  T *ptr;
   size_t len;
 };
 #endif // CXXBRIDGE05_RUST_SLICE
@@ -358,13 +361,13 @@
 #ifndef CXXBRIDGE05_RUST_SLICE
 #define CXXBRIDGE05_RUST_SLICE
 template <typename T>
-Slice<T>::Slice() noexcept : ptr(reinterpret_cast<const T *>(this)), len(0) {}
+Slice<T>::Slice() noexcept : ptr(reinterpret_cast<T *>(this)), len(0) {}
 
 template <typename T>
-Slice<T>::Slice(const T *s, size_t count) noexcept : ptr(s), len(count) {}
+Slice<T>::Slice(T *s, size_t count) noexcept : ptr(s), len(count) {}
 
 template <typename T>
-const T *Slice<T>::data() const noexcept {
+T *Slice<T>::data() const noexcept {
   return this->ptr;
 }
 
diff --git a/src/lib.rs b/src/lib.rs
index 17d7548..1b71536 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -324,7 +324,7 @@
 //! <tr><th>name in Rust</th><th>name in C++</th><th>restrictions</th></tr>
 //! <tr><td>String</td><td>rust::String</td><td></td></tr>
 //! <tr><td>&amp;str</td><td>rust::Str</td><td></td></tr>
-//! <tr><td>&amp;[u8]</td><td>rust::Slice&lt;uint8_t&gt;</td><td><sup><i>arbitrary &amp;[T] not implemented yet</i></sup></td></tr>
+//! <tr><td>&amp;[u8]</td><td>rust::Slice&lt;const uint8_t&gt;</td><td><sup><i>arbitrary &amp;[T] not implemented yet</i></sup></td></tr>
 //! <tr><td><a href="struct.CxxString.html">CxxString</a></td><td>std::string</td><td><sup><i>cannot be passed by value</i></sup></td></tr>
 //! <tr><td>Box&lt;T&gt;</td><td>rust::Box&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
 //! <tr><td><a href="struct.UniquePtr.html">UniquePtr&lt;T&gt;</a></td><td>std::unique_ptr&lt;T&gt;</td><td><sup><i>cannot hold opaque Rust type</i></sup></td></tr>
diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc
index 2305766..fdf7a14 100644
--- a/tests/ffi/tests.cc
+++ b/tests/ffi/tests.cc
@@ -76,10 +76,10 @@
   return "2020";
 }
 
-rust::Slice<uint8_t> c_return_sliceu8(const Shared &shared) {
+rust::Slice<const uint8_t> c_return_sliceu8(const Shared &shared) {
   (void)shared;
-  return rust::Slice<uint8_t>(reinterpret_cast<const uint8_t *>(SLICE_DATA),
-                              sizeof(SLICE_DATA));
+  return rust::Slice<const uint8_t>(
+      reinterpret_cast<const uint8_t *>(SLICE_DATA), sizeof(SLICE_DATA));
 }
 
 rust::String c_return_rust_string() { return "2020"; }
@@ -240,7 +240,7 @@
   }
 }
 
-void c_take_sliceu8(rust::Slice<uint8_t> s) {
+void c_take_sliceu8(rust::Slice<const uint8_t> s) {
   if (std::string(reinterpret_cast<const char *>(s.data()), s.size()) ==
       "2020") {
     cxx_test_suite_set_correct();
@@ -436,7 +436,9 @@
 
 rust::Str c_try_return_str(rust::Str s) { return s; }
 
-rust::Slice<uint8_t> c_try_return_sliceu8(rust::Slice<uint8_t> s) { return s; }
+rust::Slice<const uint8_t> c_try_return_sliceu8(rust::Slice<const uint8_t> s) {
+  return s;
+}
 
 rust::String c_try_return_rust_string() { return c_return_rust_string(); }
 
@@ -608,7 +610,7 @@
   r_take_unique_ptr(std::unique_ptr<C>(new C{2020}));
   r_take_ref_c(C{2020});
   r_take_str(rust::Str("2020"));
-  r_take_sliceu8(rust::Slice<uint8_t>(
+  r_take_sliceu8(rust::Slice<const uint8_t>(
       reinterpret_cast<const uint8_t *>(SLICE_DATA), sizeof(SLICE_DATA)));
   r_take_rust_string(rust::String("2020"));
   r_take_unique_ptr_string(
diff --git a/tests/ffi/tests.h b/tests/ffi/tests.h
index 2217c36..d231939 100644
--- a/tests/ffi/tests.h
+++ b/tests/ffi/tests.h
@@ -84,7 +84,7 @@
 const size_t &c_return_nested_ns_ref(const ::A::B::ABShared &shared);
 size_t &c_return_mut(Shared &shared);
 rust::Str c_return_str(const Shared &shared);
-rust::Slice<uint8_t> c_return_sliceu8(const Shared &shared);
+rust::Slice<const uint8_t> c_return_sliceu8(const Shared &shared);
 rust::String c_return_rust_string();
 std::unique_ptr<std::string> c_return_unique_ptr_string();
 std::unique_ptr<std::vector<uint8_t>> c_return_unique_ptr_vector_u8();
@@ -114,7 +114,7 @@
 void c_take_ref_c(const C &c);
 void c_take_ref_ns_c(const ::H::H &h);
 void c_take_str(rust::Str s);
-void c_take_sliceu8(rust::Slice<uint8_t> s);
+void c_take_sliceu8(rust::Slice<const uint8_t> s);
 void c_take_rust_string(rust::String s);
 void c_take_unique_ptr_string(std::unique_ptr<std::string> s);
 void c_take_unique_ptr_vector_u8(std::unique_ptr<std::vector<uint8_t>> v);
@@ -148,7 +148,7 @@
 rust::Box<R> c_try_return_box();
 const rust::String &c_try_return_ref(const rust::String &);
 rust::Str c_try_return_str(rust::Str);
-rust::Slice<uint8_t> c_try_return_sliceu8(rust::Slice<uint8_t>);
+rust::Slice<const uint8_t> c_try_return_sliceu8(rust::Slice<const uint8_t>);
 rust::String c_try_return_rust_string();
 std::unique_ptr<std::string> c_try_return_unique_ptr_string();
 rust::Vec<uint8_t> c_try_return_rust_vec();