Bug 1403506 - Remove nsTFixedString<T>. r=erahm.
authorNicholas Nethercote <nnethercote@mozilla.com>
Wed, 27 Sep 2017 20:19:33 +1000
changeset 384370 15306340c1beda0eea937fa85b7e11a3d1110d9d
parent 384369 c3540bcc158b323422c291c86efe58b130762c07
child 384371 5ca16bd7a8d3316e32a92a2f1558551fb3ebcd7d
push id32628
push userkwierso@gmail.com
push dateWed, 04 Oct 2017 21:58:16 +0000
treeherdermozilla-central@c3b7759671de [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerserahm
bugs1403506
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1403506 - Remove nsTFixedString<T>. r=erahm. (patch is actually r=erahm,mystor) nsTFixedString<T> is only used as a base class for nsTAutoStringN<T, N>, so this patch merges the former into the latter, cutting some code and simplifying the string class hierarchy. Because the "Fixed" name is now gone, the patch also renames StringDataFlags::FIXED as INLINE and ClassDataFlags::FIXED as INLINE. The patch also removes nsFixed[C]String and ns_auto_[c]string! from Rust code because nsAutoString can't be implemented directly in Rust due to its move semantics. There were only two uses of ns_auto_string! outside of tests so this seems like a minor loss. MozReview-Commit-ID: 8ntximghiut
js/src/devtools/rootAnalysis/analyzeHeapWrites.js
xpcom/rust/nsstring/gtest/Test.cpp
xpcom/rust/nsstring/gtest/test.rs
xpcom/rust/nsstring/src/lib.rs
xpcom/string/nsStringFlags.h
xpcom/string/nsStringFwd.h
xpcom/string/nsTString.h
xpcom/string/nsTSubstring.cpp
xpcom/string/precompiled_templates.cpp
xpcom/tests/gtest/TestStrings.cpp
--- a/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
+++ b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js
@@ -501,17 +501,16 @@ function ignoreContents(entry)
             /(nsTSubstring<T>|nsAC?String)::Assign/,
             /(nsTSubstring<T>|nsAC?String)::Append/,
             /(nsTSubstring<T>|nsAC?String)::Replace/,
             /(nsTSubstring<T>|nsAC?String)::Trim/,
             /(nsTSubstring<T>|nsAC?String)::Truncate/,
             /(nsTSubstring<T>|nsAC?String)::StripTaggedASCII/,
             /(nsTSubstring<T>|nsAC?String)::operator=/,
             /nsTAutoStringN<T, N>::nsTAutoStringN/,
-            /nsTFixedString<T>::nsTFixedString/,
 
             // Similar for some other data structures
             /nsCOMArray_base::SetCapacity/,
             /nsCOMArray_base::Clear/,
             /nsCOMArray_base::AppendElement/,
 
             // UniquePtr is similar.
             /mozilla::UniquePtr/,
--- a/xpcom/rust/nsstring/gtest/Test.cpp
+++ b/xpcom/rust/nsstring/gtest/Test.cpp
@@ -16,80 +16,74 @@ extern "C" {
     size_t size, align;                                                 \
     Rust_Test_ReprSizeAlign_##Clazz(&size, &align);                     \
     EXPECT_EQ(size, sizeof(Clazz));                                     \
     EXPECT_EQ(align, alignof(Clazz));                                   \
   }
 
 SIZE_ALIGN_CHECK(nsString)
 SIZE_ALIGN_CHECK(nsCString)
-SIZE_ALIGN_CHECK(nsFixedString)
-SIZE_ALIGN_CHECK(nsFixedCString)
 
 #define MEMBER_CHECK(Clazz, Member)                                     \
   extern "C" void Rust_Test_Member_##Clazz##_##Member(size_t* size,     \
                                                       size_t* align,    \
                                                       size_t* offset);  \
   TEST(RustNsString, ReprMember_##Clazz##_##Member) {                   \
     class Hack : public Clazz {                                         \
     public:                                                             \
       static void RunTest() {                                           \
         size_t size, align, offset;                                     \
         Rust_Test_Member_##Clazz##_##Member(&size, &align, &offset);    \
         EXPECT_EQ(size, sizeof(mozilla::DeclVal<Hack>().Member));       \
-        EXPECT_EQ(size, alignof(decltype(mozilla::DeclVal<Hack>().Member))); \
+        EXPECT_EQ(align, alignof(decltype(mozilla::DeclVal<Hack>().Member))); \
         EXPECT_EQ(offset, offsetof(Hack, Member));                      \
       }                                                                 \
     };                                                                  \
     static_assert(sizeof(Clazz) == sizeof(Hack), "Hack matches class"); \
     Hack::RunTest();                                                    \
   }
 
 MEMBER_CHECK(nsString, mData)
 MEMBER_CHECK(nsString, mLength)
 MEMBER_CHECK(nsString, mDataFlags)
 MEMBER_CHECK(nsString, mClassFlags)
 MEMBER_CHECK(nsCString, mData)
 MEMBER_CHECK(nsCString, mLength)
 MEMBER_CHECK(nsCString, mDataFlags)
 MEMBER_CHECK(nsCString, mClassFlags)
-MEMBER_CHECK(nsFixedString, mFixedCapacity)
-MEMBER_CHECK(nsFixedString, mFixedBuf)
-MEMBER_CHECK(nsFixedCString, mFixedCapacity)
-MEMBER_CHECK(nsFixedCString, mFixedBuf)
 
 extern "C" void Rust_Test_NsStringFlags(uint16_t* f_terminated,
                                         uint16_t* f_voided,
                                         uint16_t* f_shared,
                                         uint16_t* f_owned,
-                                        uint16_t* f_fixed,
+                                        uint16_t* f_inline,
                                         uint16_t* f_literal,
-                                        uint16_t* f_class_fixed,
+                                        uint16_t* f_class_inline,
                                         uint16_t* f_class_null_terminated);
 TEST(RustNsString, NsStringFlags) {
-  uint16_t f_terminated, f_voided, f_shared, f_owned, f_fixed, f_literal,
-           f_class_fixed, f_class_null_terminated;
+  uint16_t f_terminated, f_voided, f_shared, f_owned, f_inline, f_literal,
+           f_class_inline, f_class_null_terminated;
   Rust_Test_NsStringFlags(&f_terminated,
                           &f_voided, &f_shared,
-                          &f_owned, &f_fixed,
-                          &f_literal, &f_class_fixed, &f_class_null_terminated);
+                          &f_owned, &f_inline,
+                          &f_literal, &f_class_inline, &f_class_null_terminated);
   EXPECT_EQ(f_terminated, uint16_t(nsAString::DataFlags::TERMINATED));
   EXPECT_EQ(f_terminated, uint16_t(nsACString::DataFlags::TERMINATED));
   EXPECT_EQ(f_voided, uint16_t(nsAString::DataFlags::VOIDED));
   EXPECT_EQ(f_voided, uint16_t(nsACString::DataFlags::VOIDED));
   EXPECT_EQ(f_shared, uint16_t(nsAString::DataFlags::SHARED));
   EXPECT_EQ(f_shared, uint16_t(nsACString::DataFlags::SHARED));
   EXPECT_EQ(f_owned, uint16_t(nsAString::DataFlags::OWNED));
   EXPECT_EQ(f_owned, uint16_t(nsACString::DataFlags::OWNED));
-  EXPECT_EQ(f_fixed, uint16_t(nsAString::DataFlags::FIXED));
-  EXPECT_EQ(f_fixed, uint16_t(nsACString::DataFlags::FIXED));
+  EXPECT_EQ(f_inline, uint16_t(nsAString::DataFlags::INLINE));
+  EXPECT_EQ(f_inline, uint16_t(nsACString::DataFlags::INLINE));
   EXPECT_EQ(f_literal, uint16_t(nsAString::DataFlags::LITERAL));
   EXPECT_EQ(f_literal, uint16_t(nsACString::DataFlags::LITERAL));
-  EXPECT_EQ(f_class_fixed, uint16_t(nsAString::ClassFlags::FIXED));
-  EXPECT_EQ(f_class_fixed, uint16_t(nsACString::ClassFlags::FIXED));
+  EXPECT_EQ(f_class_inline, uint16_t(nsAString::ClassFlags::INLINE));
+  EXPECT_EQ(f_class_inline, uint16_t(nsACString::ClassFlags::INLINE));
   EXPECT_EQ(f_class_null_terminated, uint16_t(nsAString::ClassFlags::NULL_TERMINATED));
   EXPECT_EQ(f_class_null_terminated, uint16_t(nsACString::ClassFlags::NULL_TERMINATED));
 }
 
 extern "C" void Rust_StringFromCpp(const nsACString* aCStr, const nsAString* aStr);
 TEST(RustNsString, StringFromCpp) {
   nsAutoCString foo;
   foo.AssignASCII("Hello, World!");
@@ -114,24 +108,16 @@ extern "C" {
     aCStr->AssignASCII("Hello, World!");
     aStr->AssignASCII("Hello, World!");
   }
 }
 extern "C" void Rust_AssignFromCpp();
 TEST(RustNsString, AssignFromCpp) {
   Rust_AssignFromCpp();
 }
-extern "C" void Rust_FixedAssignFromCpp();
-TEST(RustNsString, FixedAssignFromCpp) {
-  Rust_FixedAssignFromCpp();
-}
-extern "C" void Rust_AutoAssignFromCpp();
-TEST(RustNsString, AutoAssignFromCpp) {
-  Rust_AutoAssignFromCpp();
-}
 
 extern "C" void Rust_StringWrite();
 TEST(RustNsString, StringWrite) {
   Rust_StringWrite();
 }
 
 extern "C" void Rust_FromEmptyRustString();
 TEST(RustNsString, FromEmptyRustString) {
--- a/xpcom/rust/nsstring/gtest/test.rs
+++ b/xpcom/rust/nsstring/gtest/test.rs
@@ -1,11 +1,10 @@
 #![allow(non_snake_case)]
 
-#[macro_use]
 extern crate nsstring;
 
 use std::fmt::Write;
 use std::ffi::CString;
 use std::os::raw::c_char;
 use nsstring::*;
 
 fn nonfatal_fail(msg: String) {
@@ -59,47 +58,19 @@ pub extern fn Rust_AssignFromCpp() {
     unsafe {
         Cpp_AssignFromCpp(&mut *cs, &mut *s);
     }
     expect_eq!(cs, "Hello, World!");
     expect_eq!(s, "Hello, World!");
 }
 
 #[no_mangle]
-pub extern fn Rust_FixedAssignFromCpp() {
-    let mut cs_buf: [u8; 64] = [0; 64];
-    let cs_buf_ptr = &cs_buf as *const _ as usize;
-    let mut s_buf: [u16; 64] = [0; 64];
-    let s_buf_ptr = &s_buf as *const _ as usize;
-    let mut cs = nsFixedCString::new(&mut cs_buf);
-    let mut s = nsFixedString::new(&mut s_buf);
-    unsafe {
-        Cpp_AssignFromCpp(&mut *cs, &mut *s);
-    }
-    expect_eq!(cs, "Hello, World!");
-    expect_eq!(s, "Hello, World!");
-    expect_eq!(cs.as_ptr() as usize, cs_buf_ptr);
-    expect_eq!(s.as_ptr() as usize, s_buf_ptr);
-}
-
-#[no_mangle]
-pub extern fn Rust_AutoAssignFromCpp() {
-    ns_auto_cstring!(cs);
-    ns_auto_string!(s);
-    unsafe {
-        Cpp_AssignFromCpp(&mut *cs, &mut *s);
-    }
-    expect_eq!(cs, "Hello, World!");
-    expect_eq!(s, "Hello, World!");
-}
-
-#[no_mangle]
 pub extern fn Rust_StringWrite() {
-    ns_auto_cstring!(cs);
-    ns_auto_string!(s);
+    let mut cs = nsCString::new();
+    let mut s = nsString::new();
 
     write!(s, "a").unwrap();
     write!(cs, "a").unwrap();
     expect_eq!(s, "a");
     expect_eq!(cs, "a");
     write!(s, "bc").unwrap();
     write!(cs, "bc").unwrap();
     expect_eq!(s, "abc");
--- a/xpcom/rust/nsstring/src/lib.rs
+++ b/xpcom/rust/nsstring/src/lib.rs
@@ -13,22 +13,26 @@
 //!
 //! Use `ns[C]Str` (`nsDependent[C]String` in C++) as an intermediate between
 //! borrowed rust data structures (such as `&str` and `&[u16]`) and `&{mut,}
 //! nsA[C]String` (using `ns[C]Str::from(value)`). These conversions should not
 //! perform any allocations. This type is not safe to share with `C++` as a
 //! struct field, but passing the borrowed `&{mut,} nsA[C]String` over FFI is
 //! safe.
 //!
-//! Use `nsFixed[C]String` or `ns_auto_[c]string!` for dynamic stack allocated
-//! strings which are expected to hold short string values.
-//!
 //! Use `*{const,mut} nsA[C]String` (`{const,} nsA[C]String*` in C++) for
 //! function arguments passed across the rust/C++ language boundary.
 //!
+//! There is currently no Rust equivalent to nsAuto[C]String. Implementing a
+//! type that contains a pointer to an inline buffer is difficult in Rust due
+//! to its move semantics, which require that it be safe to move a value by
+//! copying its bits. If such a type is genuinely needed at some point,
+//! https://bugzilla.mozilla.org/show_bug.cgi?id=1403506#c6 has a sketch of how
+//! to emulate it via macros.
+//!
 //! # String Types
 //!
 //! ## `nsA[C]String`
 //!
 //! The core types in this module are `nsAString` and `nsACString`. These types
 //! are zero-sized as far as rust is concerned, and are safe to pass around
 //! behind both references (in rust code), and pointers (in C++ code). They
 //! represent a handle to a XPCOM string which holds either `u16` or `u8`
@@ -89,46 +93,16 @@
 //! When passing this type by reference, prefer passing a `&nsA[C]String` or
 //! `&mut nsA[C]String`. to passing this type.
 //!
 //! When passing this type across the language boundary, pass it as `*const
 //! nsA[C]String` for an immutable reference, or `*mut nsA[C]String` for a
 //! mutable reference. This struct may also be included in `#[repr(C)]` structs
 //! shared with C++.
 //!
-//! ## `nsFixed[C]String<'a>`
-//!
-//! This type is a string type with fixed backing storage. It is created with
-//! `nsFixed[C]String::new(buffer)`, passing a mutable reference to a buffer as
-//! the argument. This buffer will be used as backing storage whenever the
-//! resulting string will fit within it, falling back to heap allocations only
-//! when the string size exceeds that of the backing buffer.
-//!
-//! Like `ns[C]String`, this type dereferences to `nsA[C]String` which provides
-//! the methods for manipulating the type, and is not `#[repr(C)]`.
-//!
-//! When passing this type by reference, prefer passing a `&nsA[C]String` or
-//! `&mut nsA[C]String`. to passing this type.
-//!
-//! When passing this type across the language boundary, pass it as `*const
-//! nsA[C]String` for an immutable reference, or `*mut nsA[C]String` for a
-//! mutable reference. This struct may also be included in `#[repr(C)]`
-//! structs shared with C++, although `nsFixed[C]String` objects are uncommon
-//! as struct members.
-//!
-//! ## `ns_auto_[c]string!($name)`
-//!
-//! This is a helper macro which defines a fixed size, (currently 64 character),
-//! backing array on the stack, and defines a local variable with name `$name`
-//! which is a `nsFixed[C]String` using this buffer as its backing storage.
-//!
-//! Usage of this macro is similar to the C++ type `nsAuto[C]String`, but could
-//! not be implemented as a basic type due to the differences between rust and
-//! C++'s move semantics.
-//!
 //! ## `ns[C]StringRepr`
 //!
 //! This crate also provides the type `ns[C]StringRepr` which acts conceptually
 //! similar to an `ns[C]String`, however, it does not have a `Drop`
 //! implementation.
 //!
 //! If this type is dropped in rust, it will not free its backing storage. This
 //! can be useful when implementing FFI types which contain `ns[C]String` members
@@ -146,43 +120,43 @@ use std::borrow;
 use std::slice;
 use std::mem;
 use std::fmt;
 use std::cmp;
 use std::str;
 use std::u32;
 use std::os::raw::c_void;
 
-//////////////////////////////////
-// Internal Implemenation Flags //
-//////////////////////////////////
+///////////////////////////////////
+// Internal Implementation Flags //
+///////////////////////////////////
 
 mod data_flags {
     bitflags! {
         // While this has the same layout as u16, it cannot be passed
         // over FFI safely as a u16.
         #[repr(C)]
         pub flags DataFlags : u16 {
             const TERMINATED = 1 << 0, // IsTerminated returns true
             const VOIDED = 1 << 1, // IsVoid returns true
             const SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer
             const OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer
-            const FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer
+            const INLINE = 1 << 4, // mData points to a writable, inline buffer
             const LITERAL = 1 << 5, // mData points to a string literal; TERMINATED will also be set
         }
     }
 }
 
 mod class_flags {
     bitflags! {
         // While this has the same layout as u16, it cannot be passed
         // over FFI safely as a u16.
         #[repr(C)]
         pub flags ClassFlags : u16 {
-            const FIXED = 1 << 0, // |this| is of type nsTFixedString
+            const INLINE = 1 << 0, // |this|'s buffer is inline
             const NULL_TERMINATED = 1 << 1, // |this| requires its buffer is null-terminated
         }
     }
 }
 
 use data_flags::DataFlags;
 use class_flags::ClassFlags;
 
@@ -192,17 +166,16 @@ use class_flags::ClassFlags;
 
 macro_rules! define_string_types {
     {
         char_t = $char_t: ty;
 
         AString = $AString: ident;
         String = $String: ident;
         Str = $Str: ident;
-        FixedString = $FixedString: ident;
 
         StringLike = $StringLike: ident;
         StringAdapter = $StringAdapter: ident;
 
         StringRepr = $StringRepr: ident;
 
         drop = $drop: ident;
         assign = $assign: ident, $fallible_assign: ident;
@@ -426,22 +399,16 @@ macro_rules! define_string_types {
         }
 
         impl<'a> cmp::PartialEq<$Str<'a>> for $AString {
             fn eq(&self, other: &$Str<'a>) -> bool {
                 self.eq(&**other)
             }
         }
 
-        impl<'a> cmp::PartialEq<$FixedString<'a>> for $AString {
-            fn eq(&self, other: &$FixedString<'a>) -> bool {
-                self.eq(&**other)
-            }
-        }
-
         #[repr(C)]
         pub struct $Str<'a> {
             hdr: $StringRepr,
             _marker: PhantomData<&'a [$char_t]>,
         }
 
         impl $Str<'static> {
             pub fn new() -> $Str<'static> {
@@ -697,110 +664,16 @@ macro_rules! define_string_types {
         }
 
         impl<'a> cmp::PartialEq<&'a str> for $String {
             fn eq(&self, other: &&'a str) -> bool {
                 $AString::eq(self, *other)
             }
         }
 
-        /// A nsFixed[C]String is a string which uses a fixed size mutable
-        /// backing buffer for storing strings which will fit within that
-        /// buffer, rather than using heap allocations.
-        #[repr(C)]
-        pub struct $FixedString<'a> {
-            base: $String,
-            capacity: u32,
-            buffer: *mut $char_t,
-            _marker: PhantomData<&'a mut [$char_t]>,
-        }
-
-        impl<'a> $FixedString<'a> {
-            pub fn new(buf: &'a mut [$char_t]) -> $FixedString<'a> {
-                let len = buf.len();
-                assert!(len < (u32::MAX as usize));
-                let buf_ptr = buf.as_mut_ptr();
-                $FixedString {
-                    base: $String {
-                        hdr: $StringRepr::new(class_flags::FIXED | class_flags::NULL_TERMINATED),
-                    },
-                    capacity: len as u32,
-                    buffer: buf_ptr,
-                    _marker: PhantomData,
-                }
-            }
-        }
-
-        impl<'a> Deref for $FixedString<'a> {
-            type Target = $AString;
-            fn deref(&self) -> &$AString {
-                &self.base
-            }
-        }
-
-        impl<'a> DerefMut for $FixedString<'a> {
-            fn deref_mut(&mut self) -> &mut $AString {
-                &mut self.base
-            }
-        }
-
-        impl<'a> AsRef<[$char_t]> for $FixedString<'a> {
-            fn as_ref(&self) -> &[$char_t] {
-                &self
-            }
-        }
-
-        impl<'a> fmt::Write for $FixedString<'a> {
-            fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
-                $AString::write_str(self, s)
-            }
-        }
-
-        impl<'a> fmt::Display for $FixedString<'a> {
-            fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-                <$AString as fmt::Display>::fmt(self, f)
-            }
-        }
-
-        impl<'a> fmt::Debug for $FixedString<'a> {
-            fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-                <$AString as fmt::Debug>::fmt(self, f)
-            }
-        }
-
-        impl<'a> cmp::PartialEq for $FixedString<'a> {
-            fn eq(&self, other: &$FixedString<'a>) -> bool {
-                $AString::eq(self, other)
-            }
-        }
-
-        impl<'a> cmp::PartialEq<[$char_t]> for $FixedString<'a> {
-            fn eq(&self, other: &[$char_t]) -> bool {
-                $AString::eq(self, other)
-            }
-        }
-
-        impl<'a, 'b> cmp::PartialEq<&'b [$char_t]> for $FixedString<'a> {
-            fn eq(&self, other: &&'b [$char_t]) -> bool {
-                $AString::eq(self, *other)
-            }
-        }
-
-        impl<'a> cmp::PartialEq<str> for $FixedString<'a> {
-            fn eq(&self, other: &str) -> bool {
-                $AString::eq(self, other)
-            }
-        }
-
-        impl<'a, 'b> cmp::PartialEq<&'b str> for $FixedString<'a> {
-            fn eq(&self, other: &&'b str) -> bool {
-                $AString::eq(self, *other)
-            }
-        }
-
         /// An adapter type to allow for passing both types which coerce to
         /// &[$char_type], and &$AString to a function, while still performing
         /// optimized operations when passed the $AString.
         pub enum $StringAdapter<'a> {
             Borrowed($Str<'a>),
             Abstract(&'a $AString),
         }
 
@@ -860,22 +733,16 @@ macro_rules! define_string_types {
         }
 
         impl $StringLike for $String {
             fn adapt(&self) -> $StringAdapter {
                 $StringAdapter::Abstract(self)
             }
         }
 
-        impl<'a> $StringLike for $FixedString<'a> {
-            fn adapt(&self) -> $StringAdapter {
-                $StringAdapter::Abstract(self)
-            }
-        }
-
         impl $StringLike for [$char_t] {
             fn adapt(&self) -> $StringAdapter {
                 $StringAdapter::Borrowed($Str::from(self))
             }
         }
 
         impl $StringLike for Vec<$char_t> {
             fn adapt(&self) -> $StringAdapter {
@@ -896,17 +763,16 @@ macro_rules! define_string_types {
 ///////////////////////////////////////////
 
 define_string_types! {
     char_t = u8;
 
     AString = nsACString;
     String = nsCString;
     Str = nsCStr;
-    FixedString = nsFixedCString;
 
     StringLike = nsCStringLike;
     StringAdapter = nsCStringAdapter;
 
     StringRepr = nsCStringRepr;
 
     drop = Gecko_FinalizeCString;
     assign = Gecko_AssignCString, Gecko_FallibleAssignCString;
@@ -1020,35 +886,26 @@ impl nsCStringLike for String {
 }
 
 impl nsCStringLike for Box<str> {
     fn adapt(&self) -> nsCStringAdapter {
         nsCStringAdapter::Borrowed(nsCStr::from(&self[..]))
     }
 }
 
-#[macro_export]
-macro_rules! ns_auto_cstring {
-    ($name:ident) => {
-        let mut buf: [u8; 64] = [0; 64];
-        let mut $name = $crate::nsFixedCString::new(&mut buf);
-    }
-}
-
 ///////////////////////////////////////////
 // Bindings for nsString (u16 char type) //
 ///////////////////////////////////////////
 
 define_string_types! {
     char_t = u16;
 
     AString = nsAString;
     String = nsString;
     Str = nsStr;
-    FixedString = nsFixedString;
 
     StringLike = nsStringLike;
     StringAdapter = nsStringAdapter;
 
     StringRepr = nsStringRepr;
 
     drop = Gecko_FinalizeString;
     assign = Gecko_AssignString, Gecko_FallibleAssignString;
@@ -1120,24 +977,16 @@ impl fmt::Debug for nsAString {
 }
 
 impl cmp::PartialEq<str> for nsAString {
     fn eq(&self, other: &str) -> bool {
         other.encode_utf16().eq(self.iter().cloned())
     }
 }
 
-#[macro_export]
-macro_rules! ns_auto_string {
-    ($name:ident) => {
-        let mut buf: [u16; 64] = [0; 64];
-        let mut $name = $crate::nsFixedString::new(&mut buf);
-    }
-}
-
 #[cfg(not(debug_assertions))]
 #[allow(non_snake_case)]
 unsafe fn Gecko_IncrementStringAdoptCount(_: *mut c_void) {}
 
 extern "C" {
     #[cfg(debug_assertions)]
     fn Gecko_IncrementStringAdoptCount(data: *mut c_void);
 
@@ -1178,18 +1027,16 @@ extern "C" {
 pub mod test_helpers {
     //! This module only exists to help with ensuring that the layout of the
     //! structs inside of rust and C++ are identical.
     //!
     //! It is public to ensure that these testing functions are avaliable to
     //! gtest code.
 
     use super::{
-        nsFixedCString,
-        nsFixedString,
         nsCString,
         nsString,
         nsCStr,
         nsStr,
         nsCStringRepr,
         nsStringRepr,
         data_flags,
         class_flags,
@@ -1225,18 +1072,16 @@ pub mod test_helpers {
             }
         }
     }
 
     size_align_check!(nsStringRepr, nsString, nsStr<'static>,
                       Rust_Test_ReprSizeAlign_nsString);
     size_align_check!(nsCStringRepr, nsCString, nsCStr<'static>,
                       Rust_Test_ReprSizeAlign_nsCString);
-    size_align_check!(nsFixedString<'static>, Rust_Test_ReprSizeAlign_nsFixedString);
-    size_align_check!(nsFixedCString<'static>, Rust_Test_ReprSizeAlign_nsFixedCString);
 
     /// Generates a $[no_mangle] extern "C" function which returns the size,
     /// alignment and offset in the parent struct of a given member, with the
     /// given name.
     ///
     /// This method can trigger Undefined Behavior if the accessing the member
     /// $member on a given type would use that type's `Deref` implementation.
     macro_rules! member_check {
@@ -1307,35 +1152,31 @@ pub mod test_helpers {
     member_check!(nsCStringRepr, nsCString, nsCStr<'static>,
                   data, Rust_Test_Member_nsCString_mData);
     member_check!(nsCStringRepr, nsCString, nsCStr<'static>,
                   length, Rust_Test_Member_nsCString_mLength);
     member_check!(nsCStringRepr, nsCString, nsCStr<'static>,
                   dataflags, Rust_Test_Member_nsCString_mDataFlags);
     member_check!(nsCStringRepr, nsCString, nsCStr<'static>,
                   classflags, Rust_Test_Member_nsCString_mClassFlags);
-    member_check!(nsFixedString<'static>, capacity, Rust_Test_Member_nsFixedString_mFixedCapacity);
-    member_check!(nsFixedString<'static>, buffer, Rust_Test_Member_nsFixedString_mFixedBuf);
-    member_check!(nsFixedCString<'static>, capacity, Rust_Test_Member_nsFixedCString_mFixedCapacity);
-    member_check!(nsFixedCString<'static>, buffer, Rust_Test_Member_nsFixedCString_mFixedBuf);
 
     #[no_mangle]
     #[allow(non_snake_case)]
     pub extern fn Rust_Test_NsStringFlags(f_terminated: *mut u16,
                                           f_voided: *mut u16,
                                           f_shared: *mut u16,
                                           f_owned: *mut u16,
-                                          f_fixed: *mut u16,
+                                          f_inline: *mut u16,
                                           f_literal: *mut u16,
-                                          f_class_fixed: *mut u16,
+                                          f_class_inline: *mut u16,
                                           f_class_null_terminated: *mut u16) {
         unsafe {
             *f_terminated = data_flags::TERMINATED.bits();
             *f_voided = data_flags::VOIDED.bits();
             *f_shared = data_flags::SHARED.bits();
             *f_owned = data_flags::OWNED.bits();
-            *f_fixed = data_flags::FIXED.bits();
+            *f_inline = data_flags::INLINE.bits();
             *f_literal = data_flags::LITERAL.bits();
-            *f_class_fixed = class_flags::FIXED.bits();
+            *f_class_inline = class_flags::INLINE.bits();
             *f_class_null_terminated = class_flags::NULL_TERMINATED.bits();
         }
     }
 }
--- a/xpcom/string/nsStringFlags.h
+++ b/xpcom/string/nsStringFlags.h
@@ -35,40 +35,40 @@ enum class StringDataFlags : uint16_t
   //                         buffer length.  See nsStringHeader.
   //
   //   "adopted buffer"      An adopted buffer is a raw string buffer
   //                         allocated on the heap (using moz_xmalloc)
   //                         of which the string class subsumes ownership.
   //
   // Some comments about the string data flags:
   //
-  //   SHARED, OWNED, and FIXED are all mutually exlusive.  They
+  //   SHARED, OWNED, and INLINE are all mutually exlusive.  They
   //   indicate the allocation type of mData.  If none of these flags
   //   are set, then the string buffer is dependent.
   //
-  //   SHARED, OWNED, or FIXED imply TERMINATED.  This is because
+  //   SHARED, OWNED, or INLINE imply TERMINATED.  This is because
   //   the string classes always allocate null-terminated buffers, and
   //   non-terminated substrings are always dependent.
   //
   //   VOIDED implies TERMINATED, and moreover it implies that mData
   //   points to char_traits::sEmptyBuffer.  Therefore, VOIDED is
-  //   mutually exclusive with SHARED, OWNED, and FIXED.
+  //   mutually exclusive with SHARED, OWNED, and INLINE.
 
   TERMINATED   = 1 << 0,  // IsTerminated returns true
   VOIDED       = 1 << 1,  // IsVoid returns true
   SHARED       = 1 << 2,  // mData points to a heap-allocated, shared buffer
   OWNED        = 1 << 3,  // mData points to a heap-allocated, raw buffer
-  FIXED        = 1 << 4,  // mData points to a fixed-size writable, dependent buffer
+  INLINE       = 1 << 4,  // mData points to a writable, inline buffer
   LITERAL      = 1 << 5   // mData points to a string literal; DataFlags::TERMINATED will also be set
 };
 
 // bits for mClassFlags
 enum class StringClassFlags : uint16_t
 {
-  FIXED           = 1 << 0, // |this| is of type nsTFixedString
+  INLINE          = 1 << 0, // |this|'s buffer is inline
   NULL_TERMINATED = 1 << 1  // |this| requires its buffer is null-terminated
 };
 
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StringDataFlags)
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StringClassFlags)
 
 } // namespace detail
 } // namespace mozilla
--- a/xpcom/string/nsStringFwd.h
+++ b/xpcom/string/nsStringFwd.h
@@ -29,17 +29,16 @@ template <typename T> class nsTSubstring
 template <typename T> class nsTString;
 template <typename T, size_t N> class nsTAutoStringN;
 template <typename T> class nsTDependentString;
 template <typename T> class nsTDependentSubstring;
 template <typename T> class nsTPromiseFlatString;
 template <typename T> class nsTStringComparator;
 template <typename T> class nsTDefaultStringComparator;
 template <typename T> class nsTLiteralString;
-template <typename T> class nsTFixedString;
 
 // We define this version without a size param instead of providing a
 // default value for N so that so there is a default typename that doesn't
 // require angle brackets.
 template <typename T> using nsTAutoString = nsTAutoStringN<T, AutoStringDefaultStorageSize>;
 
 
 // Double-byte (char16_t) string types.
@@ -50,26 +49,24 @@ using nsString = nsTString<char16_t>;
 using nsAutoString = nsTAutoString<char16_t>;
 template <size_t N> using nsAutoStringN = nsTAutoStringN<char16_t, N>;
 using nsDependentString = nsTDependentString<char16_t>;
 using nsDependentSubstring = nsTDependentSubstring<char16_t>;
 using nsPromiseFlatString = nsTPromiseFlatString<char16_t>;
 using nsStringComparator = nsTStringComparator<char16_t>;
 using nsDefaultStringComparator = nsTDefaultStringComparator<char16_t>;
 using nsLiteralString = nsTLiteralString<char16_t>;
-using nsFixedString = nsTFixedString<char16_t>;
 
 // Single-byte (char) string types.
 
 using nsACString = nsTSubstring<char>;
 using nsCSubstringTuple = nsTSubstringTuple<char>;
 using nsCString = nsTString<char>;
 using nsAutoCString = nsTAutoString<char>;
 template <size_t N> using nsAutoCStringN = nsTAutoStringN<char, N>;
 using nsDependentCString = nsTDependentString<char>;
 using nsDependentCSubstring = nsTDependentSubstring<char>;
 using nsPromiseFlatCString = nsTPromiseFlatString<char>;
 using nsCStringComparator = nsTStringComparator<char>;
 using nsDefaultCStringComparator = nsTDefaultStringComparator<char>;
 using nsLiteralCString = nsTLiteralString<char>;
-using nsFixedCString = nsTFixedString<char>;
 
 #endif /* !defined(nsStringFwd_h) */
--- a/xpcom/string/nsTString.h
+++ b/xpcom/string/nsTString.h
@@ -520,23 +520,34 @@ protected:
   };
 };
 
 // TODO(erahm): Do something with ToDouble so that we can extern the
 // nsTString templates.
 //extern template class nsTString<char>;
 //extern template class nsTString<char16_t>;
 
-template <typename T>
-class nsTFixedString : public nsTString<T>
+/**
+ * nsTAutoStringN
+ *
+ * Subclass of nsTString that adds support for stack-based string
+ * allocation.  It is normally not a good idea to use this class on the
+ * heap, because it will allocate space which may be wasted if the string
+ * it contains is significantly smaller or any larger than 64 characters.
+ *
+ * NAMES:
+ *   nsAutoStringN / nsTAutoString for wide characters
+ *   nsAutoCStringN / nsTAutoCString for narrow characters
+ */
+template<typename T, size_t N>
+class MOZ_NON_MEMMOVABLE nsTAutoStringN : public nsTString<T>
 {
 public:
 
-  typedef nsTFixedString<T> self_type;
-  typedef nsTFixedString<T> fixed_string_type;
+  typedef nsTAutoStringN<T, N> self_type;
 
   typedef nsTString<T> base_string_type;
   typedef typename base_string_type::string_type string_type;
   typedef typename base_string_type::char_type char_type;
   typedef typename base_string_type::char_traits char_traits;
   typedef typename base_string_type::substring_type substring_type;
   typedef typename base_string_type::size_type size_type;
   typedef typename base_string_type::substring_tuple_type substring_tuple_type;
@@ -546,164 +557,66 @@ public:
   typedef typename base_string_type::ClassFlags ClassFlags;
 
   using typename base_string_type::IsChar;
   using typename base_string_type::IsChar16;
 
 public:
 
   /**
-   * @param aData
-   *        fixed-size buffer to be used by the string (the contents of
-   *        this buffer may be modified by the string)
-   * @param aStorageSize
-   *        the size of the fixed buffer
-   * @param aLength (optional)
-   *        the length of the string already contained in the buffer
-   */
-
-  nsTFixedString(char_type* aData, size_type aStorageSize)
-    : string_type(aData, uint32_t(char_traits::length(aData)),
-                  DataFlags::TERMINATED | DataFlags::FIXED,
-                  ClassFlags::FIXED)
-    , mFixedCapacity(aStorageSize - 1)
-    , mFixedBuf(aData)
-  {
-  }
-
-  nsTFixedString(char_type* aData, size_type aStorageSize,
-                 size_type aLength)
-    : string_type(aData, aLength, DataFlags::TERMINATED | DataFlags::FIXED,
-                  ClassFlags::FIXED)
-    , mFixedCapacity(aStorageSize - 1)
-    , mFixedBuf(aData)
-  {
-    // null-terminate
-    mFixedBuf[aLength] = char_type(0);
-  }
-
-  // |operator=| does not inherit, so we must define our own
-  self_type& operator=(char_type aChar)
-  {
-    this->Assign(aChar);
-    return *this;
-  }
-  self_type& operator=(const char_type* aData)
-  {
-    this->Assign(aData);
-    return *this;
-  }
-  self_type& operator=(const substring_type& aStr)
-  {
-    this->Assign(aStr);
-    return *this;
-  }
-  self_type& operator=(const substring_tuple_type& aTuple)
-  {
-    this->Assign(aTuple);
-    return *this;
-  }
-
-protected:
-
-  friend class nsTSubstring<T>;
-
-  size_type  mFixedCapacity;
-  char_type* mFixedBuf;
-};
-
-extern template class nsTFixedString<char>;
-extern template class nsTFixedString<char>;
-
-/**
- * nsTAutoStringN
- *
- * Subclass of nsTString that adds support for stack-based string
- * allocation.  It is normally not a good idea to use this class on the
- * heap, because it will allocate space which may be wasted if the string
- * it contains is significantly smaller or any larger than 64 characters.
- *
- * NAMES:
- *   nsAutoStringN / nsTAutoString for wide characters
- *   nsAutoCStringN / nsTAutoCString for narrow characters
- */
-template<typename T, size_t N>
-class MOZ_NON_MEMMOVABLE nsTAutoStringN : public nsTFixedString<T>
-{
-public:
-
-  typedef nsTAutoStringN<T, N> self_type;
-
-#ifdef __clang__
-  // bindgen w/ clang 3.9 at least chokes on a typedef, but using is okay.
-  using typename nsTFixedString<T>::fixed_string_type;
-#else
-  // On the other hand msvc chokes on the using statement. It seems others
-  // don't care either way so we lump them in here.
-  typedef typename nsTFixedString<T>::fixed_string_type fixed_string_type;
-#endif
-
-  typedef typename fixed_string_type::char_type char_type;
-  typedef typename fixed_string_type::char_traits char_traits;
-  typedef typename fixed_string_type::substring_type substring_type;
-  typedef typename fixed_string_type::size_type size_type;
-  typedef typename fixed_string_type::substring_tuple_type substring_tuple_type;
-
-  using typename fixed_string_type::IsChar;
-  using typename fixed_string_type::IsChar16;
-
-public:
-
-  /**
    * constructors
    */
 
   nsTAutoStringN()
-    : fixed_string_type(mStorage, N, 0)
+    : string_type(mStorage, 0, DataFlags::TERMINATED | DataFlags::INLINE,
+                  ClassFlags::INLINE)
+    , mInlineCapacity(N - 1)
   {
+    // null-terminate
+    mStorage[0] = char_type(0);
   }
 
   explicit
   nsTAutoStringN(char_type aChar)
-    : fixed_string_type(mStorage, N, 0)
+    : self_type()
   {
     this->Assign(aChar);
   }
 
   explicit
   nsTAutoStringN(const char_type* aData, size_type aLength = size_type(-1))
-    : fixed_string_type(mStorage, N, 0)
+    : self_type()
   {
     this->Assign(aData, aLength);
   }
 
 #if defined(MOZ_USE_CHAR16_WRAPPER)
   template <typename EnableIfChar16 = IsChar16>
   explicit
   nsTAutoStringN(char16ptr_t aData, size_type aLength = size_type(-1))
-    : nsTAutoStringN(static_cast<const char16_t*>(aData), aLength)
+    : self_type(static_cast<const char16_t*>(aData), aLength)
   {
   }
 #endif
 
   nsTAutoStringN(const self_type& aStr)
-    : fixed_string_type(mStorage, N, 0)
+    : self_type()
   {
     this->Assign(aStr);
   }
 
   explicit
   nsTAutoStringN(const substring_type& aStr)
-    : fixed_string_type(mStorage, N, 0)
+    : self_type()
   {
     this->Assign(aStr);
   }
 
   MOZ_IMPLICIT nsTAutoStringN(const substring_tuple_type& aTuple)
-    : fixed_string_type(mStorage, N, 0)
+    : self_type()
   {
     this->Assign(aTuple);
   }
 
   // |operator=| does not inherit, so we must define our own
   self_type& operator=(char_type aChar)
   {
     this->Assign(aChar);
@@ -735,18 +648,22 @@ public:
   self_type& operator=(const substring_tuple_type& aTuple)
   {
     this->Assign(aTuple);
     return *this;
   }
 
   static const size_t kStorageSize = N;
 
+protected:
+  friend class nsTSubstring<T>;
+
+  size_type mInlineCapacity;
+
 private:
-
   char_type mStorage[N];
 };
 
 // Externs for the most common nsTAutoStringN variations.
 extern template class nsTAutoStringN<char, 64>;
 extern template class nsTAutoStringN<char16_t, 64>;
 
 //
--- a/xpcom/string/nsTSubstring.cpp
+++ b/xpcom/string/nsTSubstring.cpp
@@ -32,23 +32,23 @@ nsTSubstring<T>::nsTSubstring(char_type*
   if (aDataFlags & DataFlags::OWNED) {
     STRING_STAT_INCREMENT(Adopt);
     MOZ_LOG_CTOR(this->mData, "StringAdopt", 1);
   }
 }
 #endif /* XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE */
 
 /**
- * helper function for down-casting a nsTSubstring to a nsTFixedString.
+ * helper function for down-casting a nsTSubstring to an nsTAutoString.
  */
 template <typename T>
-inline const nsTFixedString<T>*
-AsFixedString(const nsTSubstring<T>* aStr)
+inline const nsTAutoString<T>*
+AsAutoString(const nsTSubstring<T>* aStr)
 {
-  return static_cast<const nsTFixedString<T>*>(aStr);
+  return static_cast<const nsTAutoString<T>*>(aStr);
 }
 
 /**
  * this function is called to prepare mData for writing.  the given capacity
  * indicates the required minimum storage size for mData, in sizeof(char_type)
  * increments.  this function returns true if the operation succeeds.  it also
  * returns the old data and old flags members if mData is newly allocated.
  * the old data must be released by the caller.
@@ -117,17 +117,17 @@ nsTSubstring<T>::MutatePrep(size_type aC
     aCapacity = XPCOM_MIN(temp, kMaxCapacity);
   }
 
   //
   // several cases:
   //
   //  (1) we have a shared buffer (this->mDataFlags & DataFlags::SHARED)
   //  (2) we have an owned buffer (this->mDataFlags & DataFlags::OWNED)
-  //  (3) we have a fixed buffer (this->mDataFlags & DataFlags::FIXED)
+  //  (3) we have an inline buffer (this->mDataFlags & DataFlags::INLINE)
   //  (4) we have a readonly buffer
   //
   // requiring that we in some cases preserve the data before creating
   // a new buffer complicates things just a bit ;-)
   //
 
   size_type storageSize = (aCapacity + 1) * sizeof(char_type);
 
@@ -145,26 +145,26 @@ nsTSubstring<T>::MutatePrep(size_type aC
       this->mDataFlags &= ~DataFlags::VOIDED;  // mutation clears voided flag
       return true;
     }
   }
 
   char_type* newData;
   DataFlags newDataFlags;
 
-  // if we have a fixed buffer of sufficient size, then use it.  this helps
-  // avoid heap allocations.
-  if ((this->mClassFlags & ClassFlags::FIXED) &&
-      (aCapacity < AsFixedString(this)->mFixedCapacity)) {
-    newData = AsFixedString(this)->mFixedBuf;
-    newDataFlags = DataFlags::TERMINATED | DataFlags::FIXED;
+  // If this is an nsTAutoStringN whose inline buffer is sufficiently large,
+  // then use it. This helps avoid heap allocations.
+  if ((this->mClassFlags & ClassFlags::INLINE) &&
+      (aCapacity < AsAutoString(this)->mInlineCapacity)) {
+    newData = (char_type*)AsAutoString(this)->mStorage;
+    newDataFlags = DataFlags::TERMINATED | DataFlags::INLINE;
   } else {
     // if we reach here then, we must allocate a new buffer.  we cannot
-    // make use of our DataFlags::OWNED or DataFlags::FIXED buffers because they are not
-    // large enough.
+    // make use of our DataFlags::OWNED or DataFlags::INLINE buffers because
+    // they are not large enough.
 
     nsStringBuffer* newHdr =
       nsStringBuffer::Alloc(storageSize).take();
     if (!newHdr) {
       return false;  // we are still in a consistent state
     }
 
     newData = (char_type*)newHdr->Data();
@@ -278,18 +278,18 @@ nsTSubstring<T>::Capacity() const
   if (this->mDataFlags & DataFlags::SHARED) {
     // if the string is readonly, then we pretend that it has no capacity.
     nsStringBuffer* hdr = nsStringBuffer::FromData(this->mData);
     if (hdr->IsReadonly()) {
       capacity = 0;
     } else {
       capacity = (hdr->StorageSize() / sizeof(char_type)) - 1;
     }
-  } else if (this->mDataFlags & DataFlags::FIXED) {
-    capacity = AsFixedString(this)->mFixedCapacity;
+  } else if (this->mDataFlags & DataFlags::INLINE) {
+    capacity = AsAutoString(this)->mInlineCapacity;
   } else if (this->mDataFlags & DataFlags::OWNED) {
     // we don't store the capacity of an adopted buffer because that would
     // require an additional member field.  the best we can do is base the
     // capacity on our length.  remains to be seen if this is the right
     // trade-off.
     capacity = this->mLength;
   } else {
     capacity = 0;
@@ -298,17 +298,17 @@ nsTSubstring<T>::Capacity() const
   return capacity;
 }
 
 template <typename T>
 bool
 nsTSubstring<T>::EnsureMutable(size_type aNewLen)
 {
   if (aNewLen == size_type(-1) || aNewLen == this->mLength) {
-    if (this->mDataFlags & (DataFlags::FIXED | DataFlags::OWNED)) {
+    if (this->mDataFlags & (DataFlags::INLINE | DataFlags::OWNED)) {
       return true;
     }
     if ((this->mDataFlags & DataFlags::SHARED) &&
         !nsStringBuffer::FromData(this->mData)->IsReadonly()) {
       return true;
     }
 
     aNewLen = this->mLength;
@@ -1172,20 +1172,20 @@ nsTSubstring<T>::SizeOfExcludingThisIfUn
       SizeOfIncludingThisIfUnshared(aMallocSizeOf);
   }
   if (this->mDataFlags & DataFlags::OWNED) {
     return aMallocSizeOf(this->mData);
   }
 
   // If we reach here, exactly one of the following must be true:
   // - DataFlags::VOIDED is set, and this->mData points to sEmptyBuffer;
-  // - DataFlags::FIXED is set, and this->mData points to a buffer within a string
-  //   object (e.g. nsAutoString);
-  // - None of DataFlags::SHARED, DataFlags::OWNED, DataFlags::FIXED is set, and this->mData points to a buffer
-  //   owned by something else.
+  // - DataFlags::INLINE is set, and this->mData points to a buffer within a
+  //   string object (e.g. nsAutoString);
+  // - None of DataFlags::SHARED, DataFlags::OWNED, DataFlags::INLINE is set,
+  //   and this->mData points to a buffer owned by something else.
   //
   // In all three cases, we don't measure it.
   return 0;
 }
 
 template <typename T>
 size_t
 nsTSubstring<T>::SizeOfExcludingThisEvenIfShared(
--- a/xpcom/string/precompiled_templates.cpp
+++ b/xpcom/string/precompiled_templates.cpp
@@ -22,18 +22,16 @@ template class nsTSubstring<char>;
 template class nsTSubstring<char16_t>;
 
 template class nsTDependentSubstring<char>;
 template class nsTDependentSubstring<char16_t>;
 
 // Note: nsTString is skipped as it's implicitly instantiated by derived
 // classes.
 
-template class nsTFixedString<char>;
-template class nsTFixedString<char16_t>;
 template class nsTAutoStringN<char, 64>;
 template class nsTAutoStringN<char16_t, 64>;
 
 template class nsTDependentString<char>;
 template class nsTDependentString<char16_t>;
 
 template class nsTPromiseFlatString<char>;
 template class nsTPromiseFlatString<char16_t>;
--- a/xpcom/tests/gtest/TestStrings.cpp
+++ b/xpcom/tests/gtest/TestStrings.cpp
@@ -421,30 +421,16 @@ TEST(Strings, strip_ws)
 }
 
 TEST(Strings, equals_ic)
 {
   nsCString s;
   EXPECT_FALSE(s.LowerCaseEqualsLiteral("view-source"));
 }
 
-TEST(Strings, fixed_string)
-{
-  char buf[256] = "hello world";
-
-  nsFixedCString s(buf, sizeof(buf));
-
-  EXPECT_EQ(s.Length(), strlen(buf));
-
-  EXPECT_STREQ(s.get(), buf);
-
-  s.Assign("foopy doopy doo");
-  EXPECT_EQ(s.get(), buf);
-}
-
 TEST(Strings, concat)
 {
   nsCString bar("bar");
   const nsACString& barRef = bar;
 
   const nsPromiseFlatCString& result =
       PromiseFlatCString(NS_LITERAL_CSTRING("foo") +
                          NS_LITERAL_CSTRING(",") +