Adopt east const in generated code to avoid ambiguities
diff --git a/gen/src/builtin.rs b/gen/src/builtin.rs
index eb892d3..277c64f 100644
--- a/gen/src/builtin.rs
+++ b/gen/src/builtin.rs
@@ -264,8 +264,8 @@
             out,
             "  Fail(::rust::repr::PtrLen &throw$) noexcept : throw$(throw$) {{}}",
         );
-        writeln!(out, "  void operator()(const char *) noexcept;");
-        writeln!(out, "  void operator()(const std::string &) noexcept;");
+        writeln!(out, "  void operator()(char const *) noexcept;");
+        writeln!(out, "  void operator()(std::string const &) noexcept;");
         writeln!(out, "}};");
     }
 
@@ -352,7 +352,7 @@
         writeln!(out, "public:");
         writeln!(out, "  static Error error(repr::PtrLen repr) noexcept {{");
         writeln!(out, "    Error error;");
-        writeln!(out, "    error.msg = static_cast<const char *>(repr.ptr);");
+        writeln!(out, "    error.msg = static_cast<char const *>(repr.ptr);");
         writeln!(out, "    error.len = repr.len;");
         writeln!(out, "    return error;");
         writeln!(out, "  }}");
@@ -412,7 +412,7 @@
         writeln!(out, "                 missing>::value>::type");
         writeln!(out, "trycatch(Try &&func, Fail &&fail) noexcept try {{");
         writeln!(out, "  func();");
-        writeln!(out, "}} catch (const ::std::exception &e) {{");
+        writeln!(out, "}} catch (::std::exception const &e) {{");
         writeln!(out, "  fail(e.what());");
         writeln!(out, "}}");
         out.end_block(Block::Namespace("behavior"));
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 22a0d4b..6f535cc 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -177,7 +177,7 @@
                 writeln!(out, "template <> struct hash<{}> {{", qualified);
                 writeln!(
                     out,
-                    "  ::std::size_t operator()(const {} &self) const noexcept {{",
+                    "  ::std::size_t operator()({} const &self) const noexcept {{",
                     qualified,
                 );
                 let link_name = mangle::operator(&strct.name, "hash");
@@ -285,12 +285,12 @@
     if operator_eq {
         writeln!(
             out,
-            "  bool operator==(const {} &) const noexcept;",
+            "  bool operator==({} const &) const noexcept;",
             strct.name.cxx,
         );
         writeln!(
             out,
-            "  bool operator!=(const {} &) const noexcept;",
+            "  bool operator!=({} const &) const noexcept;",
             strct.name.cxx,
         );
     }
@@ -298,22 +298,22 @@
     if operator_ord {
         writeln!(
             out,
-            "  bool operator<(const {} &) const noexcept;",
+            "  bool operator<({} const &) const noexcept;",
             strct.name.cxx,
         );
         writeln!(
             out,
-            "  bool operator<=(const {} &) const noexcept;",
+            "  bool operator<=({} const &) const noexcept;",
             strct.name.cxx,
         );
         writeln!(
             out,
-            "  bool operator>(const {} &) const noexcept;",
+            "  bool operator>({} const &) const noexcept;",
             strct.name.cxx,
         );
         writeln!(
             out,
-            "  bool operator>=(const {} &) const noexcept;",
+            "  bool operator>=({} const &) const noexcept;",
             strct.name.cxx,
         );
     }
@@ -510,7 +510,7 @@
         let link_name = mangle::operator(&strct.name, "eq");
         writeln!(
             out,
-            "bool {}(const {1} &, const {1} &) noexcept;",
+            "bool {}({1} const &, {1} const &) noexcept;",
             link_name, strct.name.cxx,
         );
 
@@ -518,7 +518,7 @@
             let link_name = mangle::operator(&strct.name, "ne");
             writeln!(
                 out,
-                "bool {}(const {1} &, const {1} &) noexcept;",
+                "bool {}({1} const &, {1} const &) noexcept;",
                 link_name, strct.name.cxx,
             );
         }
@@ -528,14 +528,14 @@
         let link_name = mangle::operator(&strct.name, "lt");
         writeln!(
             out,
-            "bool {}(const {1} &, const {1} &) noexcept;",
+            "bool {}({1} const &, {1} const &) noexcept;",
             link_name, strct.name.cxx,
         );
 
         let link_name = mangle::operator(&strct.name, "le");
         writeln!(
             out,
-            "bool {}(const {1} &, const {1} &) noexcept;",
+            "bool {}({1} const &, {1} const &) noexcept;",
             link_name, strct.name.cxx,
         );
 
@@ -543,14 +543,14 @@
             let link_name = mangle::operator(&strct.name, "gt");
             writeln!(
                 out,
-                "bool {}(const {1} &, const {1} &) noexcept;",
+                "bool {}({1} const &, {1} const &) noexcept;",
                 link_name, strct.name.cxx,
             );
 
             let link_name = mangle::operator(&strct.name, "ge");
             writeln!(
                 out,
-                "bool {}(const {1} &, const {1} &) noexcept;",
+                "bool {}({1} const &, {1} const &) noexcept;",
                 link_name, strct.name.cxx,
             );
         }
@@ -561,7 +561,7 @@
         let link_name = mangle::operator(&strct.name, "hash");
         writeln!(
             out,
-            "::std::size_t {}(const {} &) noexcept;",
+            "::std::size_t {}({} const &) noexcept;",
             link_name, strct.name.cxx,
         );
     }
@@ -580,7 +580,7 @@
         out.next_section();
         writeln!(
             out,
-            "bool {0}::operator==(const {0} &rhs) const noexcept {{",
+            "bool {0}::operator==({0} const &rhs) const noexcept {{",
             strct.name.cxx,
         );
         let link_name = mangle::operator(&strct.name, "eq");
@@ -590,7 +590,7 @@
         out.next_section();
         writeln!(
             out,
-            "bool {0}::operator!=(const {0} &rhs) const noexcept {{",
+            "bool {0}::operator!=({0} const &rhs) const noexcept {{",
             strct.name.cxx,
         );
         if derive::contains(&strct.derives, Trait::Eq) {
@@ -606,7 +606,7 @@
         out.next_section();
         writeln!(
             out,
-            "bool {0}::operator<(const {0} &rhs) const noexcept {{",
+            "bool {0}::operator<({0} const &rhs) const noexcept {{",
             strct.name.cxx,
         );
         let link_name = mangle::operator(&strct.name, "lt");
@@ -616,7 +616,7 @@
         out.next_section();
         writeln!(
             out,
-            "bool {0}::operator<=(const {0} &rhs) const noexcept {{",
+            "bool {0}::operator<=({0} const &rhs) const noexcept {{",
             strct.name.cxx,
         );
         let link_name = mangle::operator(&strct.name, "le");
@@ -626,7 +626,7 @@
         out.next_section();
         writeln!(
             out,
-            "bool {0}::operator>(const {0} &rhs) const noexcept {{",
+            "bool {0}::operator>({0} const &rhs) const noexcept {{",
             strct.name.cxx,
         );
         if derive::contains(&strct.derives, Trait::Ord) {
@@ -640,7 +640,7 @@
         out.next_section();
         writeln!(
             out,
-            "bool {0}::operator>=(const {0} &rhs) const noexcept {{",
+            "bool {0}::operator>=({0} const &rhs) const noexcept {{",
             strct.name.cxx,
         );
         if derive::contains(&strct.derives, Trait::Ord) {
@@ -714,25 +714,29 @@
     let mangled = mangle::extern_fn(efn, out.types);
     write!(out, "{}(", mangled);
     if let Some(receiver) = &efn.receiver {
-        if !receiver.mutable {
-            write!(out, "const ");
-        }
         write!(
             out,
-            "{} &self",
+            "{}",
             out.types.resolve(&receiver.ty).name.to_fully_qualified(),
         );
+        if !receiver.mutable {
+            write!(out, " const");
+        }
+        write!(out, " &self");
     }
     for (i, arg) in efn.args.iter().enumerate() {
         if i > 0 || efn.receiver.is_some() {
             write!(out, ", ");
         }
         if arg.ty == RustString {
-            write!(out, "const ");
+            write_type_space(out, &arg.ty);
+            write!(out, "const *{}", arg.name.cxx);
         } else if let Type::RustVec(_) = arg.ty {
-            write!(out, "const ");
+            write_type_space(out, &arg.ty);
+            write!(out, "const *{}", arg.name.cxx);
+        } else {
+            write_extern_arg(out, arg);
         }
-        write_extern_arg(out, arg);
     }
     let indirect_return = indirect_return(efn, out.types);
     if indirect_return {
@@ -903,14 +907,15 @@
     write!(out, "{}(", link_name);
     let mut needs_comma = false;
     if let Some(receiver) = &sig.receiver {
-        if !receiver.mutable {
-            write!(out, "const ");
-        }
         write!(
             out,
-            "{} &self",
+            "{}",
             out.types.resolve(&receiver.ty).name.to_fully_qualified(),
         );
+        if !receiver.mutable {
+            write!(out, " const");
+        }
+        write!(out, " &self");
         needs_comma = true;
     }
     for arg in &sig.args {
@@ -926,8 +931,11 @@
         }
         match sig.ret.as_ref().unwrap() {
             Type::Ref(ret) => {
-                write_pointee_type(out, &ret.inner, ret.mutable);
-                write!(out, " *");
+                write_type_space(out, &ret.inner);
+                if !ret.mutable {
+                    write!(out, "const ");
+                }
+                write!(out, "*");
             }
             ret => write_type_space(out, ret),
         }
@@ -1030,8 +1038,11 @@
         write!(out, "::rust::MaybeUninit<");
         match sig.ret.as_ref().unwrap() {
             Type::Ref(ret) => {
-                write_pointee_type(out, &ret.inner, ret.mutable);
-                write!(out, " *");
+                write_type_space(out, &ret.inner);
+                if !ret.mutable {
+                    write!(out, "const ");
+                }
+                write!(out, "*");
             }
             ret => write_type(out, ret),
         }
@@ -1150,11 +1161,11 @@
             write!(out, "*");
         }
         Type::Ref(ty) => {
+            write_type_space(out, &ty.inner);
             if !ty.mutable {
                 write!(out, "const ");
             }
-            write_type(out, &ty.inner);
-            write!(out, " *");
+            write!(out, "*");
         }
         _ => write_type(out, ty),
     }
@@ -1176,11 +1187,11 @@
             write!(out, "*");
         }
         Some(Type::Ref(ty)) => {
+            write_type_space(out, &ty.inner);
             if !ty.mutable {
                 write!(out, "const ");
             }
-            write_type(out, &ty.inner);
-            write!(out, " *");
+            write!(out, "*");
         }
         Some(Type::Str(_)) | Some(Type::SliceRef(_)) => {
             out.builtin.repr_fat = true;
@@ -1246,22 +1257,28 @@
             write!(out, ">");
         }
         Type::Ref(r) => {
-            write_pointee_type(out, &r.inner, r.mutable);
-            write!(out, " &");
+            write_type_space(out, &r.inner);
+            if !r.mutable {
+                write!(out, "const ");
+            }
+            write!(out, "&");
         }
         Type::Ptr(p) => {
-            write_pointee_type(out, &p.inner, p.mutable);
-            write!(out, " *");
+            write_type_space(out, &p.inner);
+            if !p.mutable {
+                write!(out, "const ");
+            }
+            write!(out, "*");
         }
         Type::Str(_) => {
             write!(out, "::rust::Str");
         }
         Type::SliceRef(slice) => {
             write!(out, "::rust::Slice<");
+            write_type_space(out, &slice.inner);
             if slice.mutability.is_none() {
-                write!(out, "const ");
+                write!(out, "const");
             }
-            write_type(out, &slice.inner);
             write!(out, ">");
         }
         Type::Fn(f) => {
@@ -1288,21 +1305,6 @@
     }
 }
 
-// Write just the T type behind a &T or &mut T or *const T or *mut T.
-fn write_pointee_type(out: &mut OutFile, inner: &Type, mutable: bool) {
-    if let Type::Ptr(_) = inner {
-        write_type_space(out, inner);
-        if !mutable {
-            write!(out, "const");
-        }
-    } else {
-        if !mutable {
-            write!(out, "const ");
-        }
-        write_type(out, inner);
-    }
-}
-
 fn write_atom(out: &mut OutFile, atom: Atom) {
     match atom {
         Bool => write!(out, "bool"),
@@ -1460,7 +1462,7 @@
 
     writeln!(
         out,
-        "void cxxbridge1$rust_vec${}$new(const ::rust::Vec<{}> *ptr) noexcept;",
+        "void cxxbridge1$rust_vec${}$new(::rust::Vec<{}> const *ptr) noexcept;",
         instance, inner,
     );
     writeln!(
@@ -1470,17 +1472,17 @@
     );
     writeln!(
         out,
-        "::std::size_t cxxbridge1$rust_vec${}$len(const ::rust::Vec<{}> *ptr) noexcept;",
+        "::std::size_t cxxbridge1$rust_vec${}$len(::rust::Vec<{}> const *ptr) noexcept;",
         instance, inner,
     );
     writeln!(
         out,
-        "::std::size_t cxxbridge1$rust_vec${}$capacity(const ::rust::Vec<{}> *ptr) noexcept;",
+        "::std::size_t cxxbridge1$rust_vec${}$capacity(::rust::Vec<{}> const *ptr) noexcept;",
         instance, inner,
     );
     writeln!(
         out,
-        "const {} *cxxbridge1$rust_vec${}$data(const ::rust::Vec<{0}> *ptr) noexcept;",
+        "{} const *cxxbridge1$rust_vec${}$data(::rust::Vec<{0}> const *ptr) noexcept;",
         inner, instance,
     );
     writeln!(
@@ -1577,7 +1579,7 @@
 
     writeln!(out, "template <>");
     begin_function_definition(out);
-    writeln!(out, "const {} *Vec<{0}>::data() const noexcept {{", inner);
+    writeln!(out, "{} const *Vec<{0}>::data() const noexcept {{", inner);
     writeln!(out, "  return cxxbridge1$rust_vec${}$data(this);", instance);
     writeln!(out, "}}");
 
@@ -1706,7 +1708,7 @@
     begin_function_definition(out);
     writeln!(
         out,
-        "const {} *cxxbridge1$unique_ptr${}$get(const ::std::unique_ptr<{}> &ptr) noexcept {{",
+        "{} const *cxxbridge1$unique_ptr${}$get(::std::unique_ptr<{}> const &ptr) noexcept {{",
         inner, instance, inner,
     );
     writeln!(out, "  return ptr.get();");
@@ -1791,7 +1793,7 @@
     begin_function_definition(out);
     writeln!(
         out,
-        "void cxxbridge1$shared_ptr${}$clone(const ::std::shared_ptr<{}> &self, ::std::shared_ptr<{}> *ptr) noexcept {{",
+        "void cxxbridge1$shared_ptr${}$clone(::std::shared_ptr<{}> const &self, ::std::shared_ptr<{}> *ptr) noexcept {{",
         instance, inner, inner,
     );
     writeln!(out, "  ::new (ptr) ::std::shared_ptr<{}>(self);", inner);
@@ -1799,7 +1801,7 @@
     begin_function_definition(out);
     writeln!(
         out,
-        "const {} *cxxbridge1$shared_ptr${}$get(const ::std::shared_ptr<{}> &self) noexcept {{",
+        "{} const *cxxbridge1$shared_ptr${}$get(::std::shared_ptr<{}> const &self) noexcept {{",
         inner, instance, inner,
     );
     writeln!(out, "  return self.get();");
@@ -1842,7 +1844,7 @@
     begin_function_definition(out);
     writeln!(
         out,
-        "void cxxbridge1$weak_ptr${}$clone(const ::std::weak_ptr<{}> &self, ::std::weak_ptr<{}> *ptr) noexcept {{",
+        "void cxxbridge1$weak_ptr${}$clone(::std::weak_ptr<{}> const &self, ::std::weak_ptr<{}> *ptr) noexcept {{",
         instance, inner, inner,
     );
     writeln!(out, "  ::new (ptr) ::std::weak_ptr<{}>(self);", inner);
@@ -1850,7 +1852,7 @@
     begin_function_definition(out);
     writeln!(
         out,
-        "void cxxbridge1$weak_ptr${}$downgrade(const ::std::shared_ptr<{}> &shared, ::std::weak_ptr<{}> *weak) noexcept {{",
+        "void cxxbridge1$weak_ptr${}$downgrade(::std::shared_ptr<{}> const &shared, ::std::weak_ptr<{}> *weak) noexcept {{",
         instance, inner, inner,
     );
     writeln!(out, "  ::new (weak) ::std::weak_ptr<{}>(shared);", inner);
@@ -1858,7 +1860,7 @@
     begin_function_definition(out);
     writeln!(
         out,
-        "void cxxbridge1$weak_ptr${}$upgrade(const ::std::weak_ptr<{}> &weak, ::std::shared_ptr<{}> *shared) noexcept {{",
+        "void cxxbridge1$weak_ptr${}$upgrade(::std::weak_ptr<{}> const &weak, ::std::shared_ptr<{}> *shared) noexcept {{",
         instance, inner, inner,
     );
     writeln!(
@@ -1888,7 +1890,7 @@
 
     writeln!(
         out,
-        "::std::size_t cxxbridge1$std$vector${}$size(const ::std::vector<{}> &s) noexcept {{",
+        "::std::size_t cxxbridge1$std$vector${}$size(::std::vector<{}> const &s) noexcept {{",
         instance, inner,
     );
     writeln!(out, "  return s.size();");