Repository: servo/html5ever (language: python)

Issue:
Make criterion a regular dev-dependency
This avoids compilation failing for the benchmark targets.


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 4f2f1a6f..f2fa4305 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -70,3 +70,25 @@ jobs:
       - name: Mark the job as unsuccessful
         run: exit 1
         if: ${{ !success() }}
+
+  lint:
+    name: Lint
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+
+      - name: Install stable toolchain
+        run: |
+          rustup set profile minimal
+          rustup override set stable
+
+      - name: Install clippy
+        run: |
+          rustup component add clippy
+          rustup component add rustfmt
+
+      - name: Format
+        run: cargo fmt --all -- --check
+
+      - name: Run clippy
+        run: cargo clippy --all-features --all-targets -- -D warnings
diff --git a/html5ever/benches/html5ever.rs b/html5ever/benches/html5ever.rs
index ff20c4f7..f52cb574 100644
--- a/html5ever/benches/html5ever.rs
+++ b/html5ever/benches/html5ever.rs
@@ -27,12 +27,11 @@ fn run_bench(c: &mut Criterion, name: &str) {
     let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
     path.push("data/bench/");
     path.push(name);
-    let mut file = fs::File::open(&path).ok().expect("can't open file");
+    let mut file = fs::File::open(&path).expect("can't open file");
 
     // Read the file and treat it as an infinitely repeating sequence of characters.
     let mut file_input = ByteTendril::new();
     file.read_to_tendril(&mut file_input)
-        .ok()
         .expect("can't read file");
     let file_input: StrTendril = file_input.try_reinterpret().unwrap();
     let size = file_input.len();
@@ -55,7 +54,7 @@ fn run_bench(c: &mut Criterion, name: &str) {
     c.bench_function(&test_name, move |b| {
         b.iter(|| {
             let mut tok = Tokenizer::new(Sink, Default::default());
-            let mut buffer = BufferQueue::new();
+            let mut buffer = BufferQueue::default();
             // We are doing clone inside the bench function, this is not ideal, but possibly
             // necessary since our iterator consumes the underlying buffer.
             for buf in input.clone().into_iter() {
diff --git a/html5ever/examples/arena.rs b/html5ever/examples/arena.rs
index 1b59ae1b..d084e011 100644
--- a/html5ever/examples/arena.rs
+++ b/html5ever/examples/arena.rs
@@ -28,7 +28,7 @@ fn main() {
 
 fn html5ever_parse_slice_into_arena<'a>(bytes: &[u8], arena: Arena<'a>) -> Ref<'a> {
     let sink = Sink {
-        arena: arena,
+        arena,
         document: arena.alloc(Node::new(NodeData::Document)),
         quirks_mode: QuirksMode::NoQuirks,
     };
@@ -91,7 +91,7 @@ impl<'arena> Node<'arena> {
             next_sibling: Cell::new(None),
             first_child: Cell::new(None),
             last_child: Cell::new(None),
-            data: data,
+            data,
         }
     }
 
@@ -209,7 +209,7 @@ impl<'arena> TreeSink for Sink<'arena> {
 
     fn get_template_contents(&mut self, target: &Ref<'arena>) -> Ref<'arena> {
         if let NodeData::Element {
-            template_contents: Some(ref contents),
+            template_contents: Some(contents),
             ..
         } = target.data
         {
@@ -255,7 +255,7 @@ impl<'arena> TreeSink for Sink<'arena> {
 
     fn create_pi(&mut self, target: StrTendril, data: StrTendril) -> Ref<'arena> {
         self.new_node(NodeData::ProcessingInstruction {
-            target: target,
+            target,
             contents: data,
         })
     }
diff --git a/html5ever/examples/noop-tokenize.rs b/html5ever/examples/noop-tokenize.rs
index 4aa94497..68b1c8c9 100644
--- a/html5ever/examples/noop-tokenize.rs
+++ b/html5ever/examples/noop-tokenize.rs
@@ -32,7 +32,7 @@ impl TokenSink for Sink {
 fn main() {
     let mut chunk = ByteTendril::new();
     io::stdin().read_to_tendril(&mut chunk).unwrap();
-    let mut input = BufferQueue::new();
+    let mut input = BufferQueue::default();
     input.push_back(chunk.try_reinterpret().unwrap());
 
     let mut tok = Tokenizer::new(Sink(Vec::new()), Default::default());
diff --git a/html5ever/examples/noop-tree-builder.rs b/html5ever/examples/noop-tree-builder.rs
index 27f4fa3c..5e516df6 100644
--- a/html5ever/examples/noop-tree-builder.rs
+++ b/html5ever/examples/noop-tree-builder.rs
@@ -44,7 +44,7 @@ impl TreeSink for Sink {
     }
 
     fn get_template_contents(&mut self, target: &usize) -> usize {
-        if let Some(expanded_name!(html "template")) = self.names.get(&target).map(|n| n.expanded())
+        if let Some(expanded_name!(html "template")) = self.names.get(target).map(|n| n.expanded())
         {
             target + 1
         } else {
@@ -91,7 +91,7 @@ impl TreeSink for Sink {
 
     fn append_doctype_to_document(&mut self, _: StrTendril, _: StrTendril, _: StrTendril) {}
     fn add_attrs_if_missing(&mut self, target: &usize, _attrs: Vec<Attribute>) {
-        assert!(self.names.contains_key(&target), "not an element");
+        assert!(self.names.contains_key(target), "not an element");
     }
     fn remove_from_parent(&mut self, _target: &usize) {}
     fn reparent_children(&mut self, _node: &usize, _new_parent: &usize) {}
diff --git a/html5ever/examples/tokenize.rs b/html5ever/examples/tokenize.rs
index ae1f6203..8d4d9e7d 100644
--- a/html5ever/examples/tokenize.rs
+++ b/html5ever/examples/tokenize.rs
@@ -85,7 +85,7 @@ fn main() {
     let mut sink = TokenPrinter { in_char_run: false };
     let mut chunk = ByteTendril::new();
     io::stdin().read_to_tendril(&mut chunk).unwrap();
-    let mut input = BufferQueue::new();
+    let mut input = BufferQueue::default();
     input.push_back(chunk.try_reinterpret().unwrap());
 
     let mut tok = Tokenizer::new(
diff --git a/html5ever/macros/match_token.rs b/html5ever/macros/match_token.rs
index b4bff19f..4157ddf4 100644
--- a/html5ever/macros/match_token.rs
+++ b/html5ever/macros/match_token.rs
@@ -141,16 +141,16 @@ struct MatchToken {
 
 struct MatchTokenArm {
     binding: Option<syn::Ident>,
-    lhs: LHS,
-    rhs: RHS,
+    lhs: Lhs,
+    rhs: Rhs,
 }
 
-enum LHS {
+enum Lhs {
     Tags(Vec<Tag>),
     Pattern(syn::Pat),
 }
 
-enum RHS {
+enum Rhs {
     Expression(syn::Expr),
     Else,
 }
@@ -188,17 +188,17 @@ impl Parse for Tag {
     }
 }
 
-impl Parse for LHS {
+impl Parse for Lhs {
     fn parse(input: ParseStream) -> Result<Self> {
         if input.peek(Token![<]) {
             let mut tags = Vec::new();
             while !input.peek(Token![=>]) {
                 tags.push(input.parse()?);
             }
-            Ok(LHS::Tags(tags))
+            Ok(Lhs::Tags(tags))
         } else {
             let p = input.call(syn::Pat::parse_single)?;
-            Ok(LHS::Pattern(p))
+            Ok(Lhs::Pattern(p))
         }
     }
 }
@@ -212,7 +212,7 @@ impl Parse for MatchTokenArm {
         } else {
             None
         };
-        let lhs = input.parse::<LHS>()?;
+        let lhs = input.parse::<Lhs>()?;
         input.parse::<Token![=>]>()?;
         let rhs = if input.peek(syn::token::Brace) {
             let block = input.parse::<syn::Block>().unwrap();
@@ -222,15 +222,15 @@ impl Parse for MatchTokenArm {
                 block,
             };
             input.parse::<Option<Token![,]>>()?;
-            RHS::Expression(syn::Expr::Block(block))
+            Rhs::Expression(syn::Expr::Block(block))
         } else if input.peek(Token![else]) {
             input.parse::<Token![else]>()?;
             input.parse::<Token![,]>()?;
-            RHS::Else
+            Rhs::Else
         } else {
             let expr = input.parse::<syn::Expr>().unwrap();
             input.parse::<Option<Token![,]>>()?;
-            RHS::Expression(expr)
+            Rhs::Expression(expr)
         };
 
         Ok(MatchTokenArm { binding, lhs, rhs })
@@ -283,12 +283,12 @@ fn expand_match_token_macro(match_token: MatchToken) -> TokenStream {
         };
 
         match (lhs, rhs) {
-            (LHS::Pattern(_), RHS::Else) => {
+            (Lhs::Pattern(_), Rhs::Else) => {
                 panic!("'else' may not appear with an ordinary pattern")
             },
 
             // ordinary pattern => expression
-            (LHS::Pattern(pat), RHS::Expression(expr)) => {
+            (Lhs::Pattern(pat), Rhs::Expression(expr)) => {
                 if !wildcards_patterns.is_empty() {
                     panic!(
                         "ordinary patterns may not appear after wildcard tags {:?} {:?}",
@@ -299,7 +299,7 @@ fn expand_match_token_macro(match_token: MatchToken) -> TokenStream {
             },
 
             // <tag> <tag> ... => else
-            (LHS::Tags(tags), RHS::Else) => {
+            (Lhs::Tags(tags), Rhs::Else) => {
                 for tag in tags {
                     if !seen_tags.insert(tag.clone()) {
                         panic!("duplicate tag");
@@ -313,7 +313,7 @@ fn expand_match_token_macro(match_token: MatchToken) -> TokenStream {
 
             // <_> => expression
             // <tag> <tag> ... => expression
-            (LHS::Tags(tags), RHS::Expression(expr)) => {
+            (Lhs::Tags(tags), Rhs::Expression(expr)) => {
                 // Is this arm a tag wildcard?
                 // `None` if we haven't processed the first tag yet.
                 let mut wildcard = None;
@@ -388,9 +388,9 @@ fn expand_match_token_macro(match_token: MatchToken) -> TokenStream {
 
     let (last_pat, last_expr) = match (binding, lhs, rhs) {
         (Some(_), _, _) => panic!("the last arm cannot have an @-binding"),
-        (None, LHS::Tags(_), _) => panic!("the last arm cannot have tag patterns"),
-        (None, _, RHS::Else) => panic!("the last arm cannot use 'else'"),
-        (None, LHS::Pattern(p), RHS::Expression(e)) => (p, e),
+        (None, Lhs::Tags(_), _) => panic!("the last arm cannot have tag patterns"),
+        (None, _, Rhs::Else) => panic!("the last arm cannot use 'else'"),
+        (None, Lhs::Pattern(p), Rhs::Expression(e)) => (p, e),
     };
 
     quote! {
@@ -418,29 +418,23 @@ fn expand_match_token_macro(match_token: MatchToken) -> TokenStream {
 
 impl Fold for MatchTokenParser {
     fn fold_stmt(&mut self, stmt: syn::Stmt) -> syn::Stmt {
-        match stmt {
-            syn::Stmt::Item(syn::Item::Macro(syn::ItemMacro { ref mac, .. })) => {
-                if mac.path == parse_quote!(match_token) {
-                    return syn::fold::fold_stmt(
-                        self,
-                        syn::Stmt::Expr(expand_match_token(&mac.tokens), None),
-                    );
-                }
-            },
-            _ => {},
+        if let syn::Stmt::Item(syn::Item::Macro(syn::ItemMacro { ref mac, .. })) = stmt {
+            if mac.path == parse_quote!(match_token) {
+                return syn::fold::fold_stmt(
+                    self,
+                    syn::Stmt::Expr(expand_match_token(&mac.tokens), None),
+                );
+            }
         }
 
         syn::fold::fold_stmt(self, stmt)
     }
 
     fn fold_expr(&mut self, expr: syn::Expr) -> syn::Expr {
-        match expr {
-            syn::Expr::Macro(syn::ExprMacro { ref mac, .. }) => {
-                if mac.path == parse_quote!(match_token) {
-                    return syn::fold::fold_expr(self, expand_match_token(&mac.tokens));
-                }
-            },
-            _ => {},
+        if let syn::Expr::Macro(syn::ExprMacro { ref mac, .. }) = expr {
+            if mac.path == parse_quote!(match_token) {
+                return syn::fold::fold_expr(self, expand_match_token(&mac.tokens));
+            }
         }
 
         syn::fold::fold_expr(self, expr)
diff --git a/html5ever/src/driver.rs b/html5ever/src/driver.rs
index 26db9b8d..42426e7b 100644
--- a/html5ever/src/driver.rs
+++ b/html5ever/src/driver.rs
@@ -45,7 +45,7 @@ where
     let tok = Tokenizer::new(tb, opts.tokenizer);
     Parser {
         tokenizer: tok,
-        input_buffer: BufferQueue::new(),
+        input_buffer: BufferQueue::default(),
     }
 }
 
@@ -88,7 +88,7 @@ where
     let tok = Tokenizer::new(tb, tok_opts);
     Parser {
         tokenizer: tok,
-        input_buffer: BufferQueue::new(),
+        input_buffer: BufferQueue::default(),
     }
 }
 
diff --git a/html5ever/src/serialize/mod.rs b/html5ever/src/serialize/mod.rs
index d95cb452..2620c195 100644
--- a/html5ever/src/serialize/mod.rs
+++ b/html5ever/src/serialize/mod.rs
@@ -52,7 +52,7 @@ impl Default for SerializeOpts {
 #[derive(Default)]
 struct ElemInfo {
     html_name: Option<LocalName>,
-    ignore_children: bool
+    ignore_children: bool,
 }
 
 pub struct HtmlSerializer<Wr: Write> {
@@ -162,28 +162,28 @@ impl<Wr: Write> Serializer for HtmlSerializer<Wr> {
         }
         self.writer.write_all(b">")?;
 
-        let ignore_children = name.ns == ns!(html) &&
-            match name.local {
-                local_name!("area") |
-                local_name!("base") |
-                local_name!("basefont") |
-                local_name!("bgsound") |
-                local_name!("br") |
-                local_name!("col") |
-                local_name!("embed") |
-                local_name!("frame") |
-                local_name!("hr") |
-                local_name!("img") |
-                local_name!("input") |
-                local_name!("keygen") |
-                local_name!("link") |
-                local_name!("meta") |
-                local_name!("param") |
-                local_name!("source") |
-                local_name!("track") |
-                local_name!("wbr") => true,
-                _ => false,
-            };
+        let ignore_children = name.ns == ns!(html)
+            && matches!(
+                name.local,
+                local_name!("area")
+                    | local_name!("base")
+                    | local_name!("basefont")
+                    | local_name!("bgsound")
+                    | local_name!("br")
+                    | local_name!("col")
+                    | local_name!("embed")
+                    | local_name!("frame")
+                    | local_name!("hr")
+                    | local_name!("img")
+                    | local_name!("input")
+                    | local_name!("keygen")
+                    | local_name!("link")
+                    | local_name!("meta")
+                    | local_name!("param")
+                    | local_name!("source")
+                    | local_name!("track")
+                    | local_name!("wbr")
+            );
 
         self.stack.push(ElemInfo {
             html_name,
@@ -213,13 +213,13 @@ impl<Wr: Write> Serializer for HtmlSerializer<Wr> {
 
     fn write_text(&mut self, text: &str) -> io::Result<()> {
         let escape = match self.parent().html_name {
-            Some(local_name!("style")) |
-            Some(local_name!("script")) |
-            Some(local_name!("xmp")) |
-            Some(local_name!("iframe")) |
-            Some(local_name!("noembed")) |
-            Some(local_name!("noframes")) |
-            Some(local_name!("plaintext")) => false,
+            Some(local_name!("style"))
+            | Some(local_name!("script"))
+            | Some(local_name!("xmp"))
+            | Some(local_name!("iframe"))
+            | Some(local_name!("noembed"))
+            | Some(local_name!("noframes"))
+            | Some(local_name!("plaintext")) => false,
 
             Some(local_name!("noscript")) => !self.opts.scripting_enabled,
 
diff --git a/html5ever/src/tokenizer/char_ref/mod.rs b/html5ever/src/tokenizer/char_ref/mod.rs
index 6c5b63b9..9dee0278 100644
--- a/html5ever/src/tokenizer/char_ref/mod.rs
+++ b/html5ever/src/tokenizer/char_ref/mod.rs
@@ -224,9 +224,8 @@ impl CharRefTokenizer {
         input: &mut BufferQueue,
     ) -> Status {
         let mut unconsume = StrTendril::from_char('#');
-        match self.hex_marker {
-            Some(c) => unconsume.push_char(c),
-            None => (),
+        if let Some(c) = self.hex_marker {
+            unconsume.push_char(c)
         }
 
         input.push_front(unconsume);
@@ -361,7 +360,8 @@ impl CharRefTokenizer {
                 // then, for historical reasons, flush code points consumed as a character
                 // reference and switch to the return state.
 
-                let unconsume_all = match (self.is_consumed_in_attribute, last_matched, next_after) {
+                let unconsume_all = match (self.is_consumed_in_attribute, last_matched, next_after)
+                {
                     (_, ';', _) => false,
                     (true, _, Some('=')) => true,
                     (true, _, Some(c)) if c.is_ascii_alphanumeric() => true,
diff --git a/html5ever/src/tokenizer/interface.rs b/html5ever/src/tokenizer/interface.rs
index 22d11be5..b3b8a1cf 100644
--- a/html5ever/src/tokenizer/interface.rs
+++ b/html5ever/src/tokenizer/interface.rs
@@ -19,7 +19,7 @@ pub use self::Token::{EOFToken, NullCharacterToken, ParseError};
 
 /// A `DOCTYPE` token.
 // FIXME: already exists in Servo DOM
-#[derive(PartialEq, Eq, Clone, Debug)]
+#[derive(PartialEq, Eq, Clone, Debug, Default)]
 pub struct Doctype {
     pub name: Option<StrTendril>,
     pub public_id: Option<StrTendril>,
@@ -27,17 +27,6 @@ pub struct Doctype {
     pub force_quirks: bool,
 }
 
-impl Doctype {
-    pub fn new() -> Doctype {
-        Doctype {
-            name: None,
-            public_id: None,
-            system_id: None,
-            force_quirks: false,
-        }
-    }
-}
-
 #[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
 pub enum TagKind {
     StartTag,
diff --git a/html5ever/src/tokenizer/mod.rs b/html5ever/src/tokenizer/mod.rs
index 54d11855..1bf62af2 100644
--- a/html5ever/src/tokenizer/mod.rs
+++ b/html5ever/src/tokenizer/mod.rs
@@ -28,7 +28,7 @@ use mac::format_if;
 use markup5ever::{namespace_url, ns, small_char_set};
 use std::borrow::Cow::{self, Borrowed};
 use std::collections::BTreeMap;
-use std::mem::replace;
+use std::mem;
 
 pub use crate::buffer_queue::{BufferQueue, FromSet, NotFromSet, SetResult};
 use crate::tendril::StrTendril;
@@ -196,7 +196,7 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
             current_attr_name: StrTendril::new(),
             current_attr_value: StrTendril::new(),
             current_comment: StrTendril::new(),
-            current_doctype: Doctype::new(),
+            current_doctype: Doctype::default(),
             last_start_tag_name: start_tag_name,
             temp_buf: StrTendril::new(),
             state_profile: BTreeMap::new(),
@@ -265,8 +265,8 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
             self.current_line += 1;
         }
 
-        if self.opts.exact_errors &&
-            match c as u32 {
+        if self.opts.exact_errors
+            && match c as u32 {
                 0x01..=0x08 | 0x0B | 0x0E..=0x1F | 0x7F..=0x9F | 0xFDD0..=0xFDEF => true,
                 n if (n & 0xFFFE) == 0xFFFE => true,
                 _ => false,
@@ -332,13 +332,11 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
             }
         }
 
-        input.push_front(replace(&mut self.temp_buf, StrTendril::new()));
+        input.push_front(mem::take(&mut self.temp_buf));
         match input.eat(pat, eq) {
             None if self.at_eof => Some(false),
             None => {
-                while let Some(c) = input.next() {
-                    self.temp_buf.push_char(c);
-                }
+                self.temp_buf.extend(input);
                 None
             },
             Some(matched) => Some(matched),
@@ -439,7 +437,7 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
             kind: self.current_tag_kind,
             name,
             self_closing: self.current_tag_self_closing,
-            attrs: replace(&mut self.current_tag_attrs, vec![]),
+            attrs: std::mem::take(&mut self.current_tag_attrs),
         });
 
         match self.process_token(token) {
@@ -461,7 +459,7 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
 
     fn emit_temp_buf(&mut self) {
         // FIXME: Make sure that clearing on emit is spec-compatible.
-        let buf = replace(&mut self.temp_buf, StrTendril::new());
+        let buf = mem::take(&mut self.temp_buf);
         self.emit_chars(buf);
     }
 
@@ -471,7 +469,7 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
     }
 
     fn emit_current_comment(&mut self) {
-        let comment = replace(&mut self.current_comment, StrTendril::new());
+        let comment = mem::take(&mut self.current_comment);
         self.process_token_and_continue(CommentToken(comment));
     }
 
@@ -525,13 +523,13 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
                 // The tree builder will adjust the namespace if necessary.
                 // This only happens in foreign elements.
                 name: QualName::new(None, ns!(), name),
-                value: replace(&mut self.current_attr_value, StrTendril::new()),
+                value: mem::take(&mut self.current_attr_value),
             });
         }
     }
 
     fn emit_current_doctype(&mut self) {
-        let doctype = replace(&mut self.current_doctype, Doctype::new());
+        let doctype = mem::take(&mut self.current_doctype);
         self.process_token_and_continue(DoctypeToken(doctype));
     }
 
@@ -551,9 +549,10 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
     }
 
     fn consume_char_ref(&mut self) {
-        self.char_ref_tokenizer = Some(
-            Box::new(CharRefTokenizer::new(matches!(self.state, states::AttributeValue(_))))
-        );
+        self.char_ref_tokenizer = Some(Box::new(CharRefTokenizer::new(matches!(
+            self.state,
+            states::AttributeValue(_)
+        ))));
     }
 
     fn emit_eof(&mut self) {
@@ -605,7 +604,7 @@ macro_rules! shorthand (
     ( $me:ident : append_comment $c:expr           ) => ( $me.current_comment.push_slice($c)                  );
     ( $me:ident : emit_comment                     ) => ( $me.emit_current_comment()                          );
     ( $me:ident : clear_comment                    ) => ( $me.current_comment.clear()                         );
-    ( $me:ident : create_doctype                   ) => ( $me.current_doctype = Doctype::new()                );
+    ( $me:ident : create_doctype                   ) => ( $me.current_doctype = Doctype::default()            );
     ( $me:ident : push_doctype_name $c:expr        ) => ( option_push(&mut $me.current_doctype.name, $c)      );
     ( $me:ident : push_doctype_id $k:ident $c:expr ) => ( option_push($me.doctype_id($k), $c)                 );
     ( $me:ident : clear_doctype_id $k:ident        ) => ( $me.clear_doctype_id($k)                            );
@@ -1348,10 +1347,9 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
                     if self
                         .sink
                         .adjusted_current_node_present_but_not_in_html_namespace()
+                        && eat_exact!(self, input, "[CDATA[")
                     {
-                        if eat_exact!(self, input, "[CDATA[") {
-                            go!(self: clear_temp; to CdataSection);
-                        }
+                        go!(self: clear_temp; to CdataSection);
                     }
                     go!(self: error; clear_comment; to BogusComment);
                 }
@@ -1434,7 +1432,7 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
     pub fn end(&mut self) {
         // Handle EOF in the char ref sub-tokenizer, if there is one.
         // Do this first because it might un-consume stuff.
-        let mut input = BufferQueue::new();
+        let mut input = BufferQueue::default();
         match self.char_ref_tokenizer.take() {
             None => (),
             Some(mut tok) => {
@@ -1486,22 +1484,22 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
     fn eof_step(&mut self) -> ProcessResult<Sink::Handle> {
         debug!("processing EOF in state {:?}", self.state);
         match self.state {
-            states::Data |
-            states::RawData(Rcdata) |
-            states::RawData(Rawtext) |
-            states::RawData(ScriptData) |
-            states::Plaintext => go!(self: eof),
-
-            states::TagName |
-            states::RawData(ScriptDataEscaped(_)) |
-            states::BeforeAttributeName |
-            states::AttributeName |
-            states::AfterAttributeName |
-            states::AttributeValue(_) |
-            states::AfterAttributeValueQuoted |
-            states::SelfClosingStartTag |
-            states::ScriptDataEscapedDash(_) |
-            states::ScriptDataEscapedDashDash(_) => go!(self: error_eof; to Data),
+            states::Data
+            | states::RawData(Rcdata)
+            | states::RawData(Rawtext)
+            | states::RawData(ScriptData)
+            | states::Plaintext => go!(self: eof),
+
+            states::TagName
+            | states::RawData(ScriptDataEscaped(_))
+            | states::BeforeAttributeName
+            | states::AttributeName
+            | states::AfterAttributeName
+            | states::AttributeValue(_)
+            | states::AfterAttributeValueQuoted
+            | states::SelfClosingStartTag
+            | states::ScriptDataEscapedDash(_)
+            | states::ScriptDataEscapedDashDash(_) => go!(self: error_eof; to Data),
 
             states::BeforeAttributeValue => go!(self: reconsume AttributeValue Unquoted),
 
@@ -1529,14 +1527,16 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
                 go!(self: to RawData ScriptDataEscaped DoubleEscaped)
             },
 
-            states::CommentStart |
-            states::CommentStartDash |
-            states::Comment |
-            states::CommentEndDash |
-            states::CommentEnd |
-            states::CommentEndBang => go!(self: error_eof; emit_comment; to Data),
+            states::CommentStart
+            | states::CommentStartDash
+            | states::Comment
+            | states::CommentEndDash
+            | states::CommentEnd
+            | states::CommentEndBang => go!(self: error_eof; emit_comment; to Data),
 
-            states::CommentLessThanSign | states::CommentLessThanSignBang => go!(self: reconsume Comment),
+            states::CommentLessThanSign | states::CommentLessThanSignBang => {
+                go!(self: reconsume Comment)
+            },
 
             states::CommentLessThanSignBangDash => go!(self: reconsume CommentEndDash),
 
@@ -1546,14 +1546,14 @@ impl<Sink: TokenSink> Tokenizer<Sink> {
                 go!(self: error_eof; create_doctype; force_quirks; emit_doctype; to Data)
             },
 
-            states::DoctypeName |
-            states::AfterDoctypeName |
-            states::AfterDoctypeKeyword(_) |
-            states::BeforeDoctypeIdentifier(_) |
-            states::DoctypeIdentifierDoubleQuoted(_) |
-            states::DoctypeIdentifierSingleQuoted(_) |
-            states::AfterDoctypeIdentifier(_) |
-            states::BetweenDoctypePublicAndSystemIdentifiers => {
+            states::DoctypeName
+            | states::AfterDoctypeName
+            | states::AfterDoctypeKeyword(_)
+            | states::BeforeDoctypeIdentifier(_)
+            | states::DoctypeIdentifierDoubleQuoted(_)
+            | states::DoctypeIdentifierSingleQuoted(_)
+            | states::AfterDoctypeIdentifier(_)
+            | states::BetweenDoctypePublicAndSystemIdentifiers => {
                 go!(self: error_eof; force_quirks; emit_doctype; to Data)
             },
 
@@ -1585,7 +1585,7 @@ mod test {
     use super::interface::{TagToken, Token};
 
     use markup5ever::buffer_queue::BufferQueue;
-    use std::mem::replace;
+    use std::mem;
 
     use crate::LocalName;
 
@@ -1614,7 +1614,7 @@ mod test {
 
         fn finish_str(&mut self) {
             if self.current_str.len() > 0 {
-                let s = replace(&mut self.current_str, StrTendril::new());
+                let s = mem::take(&mut self.current_str);
                 self.tokens.push(CharacterTokens(s));
             }
         }
@@ -1668,7 +1668,7 @@ mod test {
     fn tokenize(input: Vec<StrTendril>, opts: TokenizerOpts) -> Vec<(Token, u64)> {
         let sink = LinesMatch::new();
         let mut tok = Tokenizer::new(sink, opts);
-        let mut buffer = BufferQueue::new();
+        let mut buffer = BufferQueue::default();
         for chunk in input.into_iter() {
             buffer.push_back(chunk);
             let _ = tok.feed(&mut buffer);
@@ -1680,13 +1680,13 @@ mod test {
     // Create a tag token
     fn create_tag(token: StrTendril, tagkind: TagKind) -> Token {
         let name = LocalName::from(&*token);
-        let token = TagToken(Tag {
+
+        TagToken(Tag {
             kind: tagkind,
             name,
             self_closing: false,
             attrs: vec![],
-        });
-        token
+        })
     }
 
     #[test]
diff --git a/html5ever/src/tree_builder/data.rs b/html5ever/src/tree_builder/data.rs
index 9d51a710..2a81b5b7 100644
--- a/html5ever/src/tree_builder/data.rs
+++ b/html5ever/src/tree_builder/data.rs
@@ -109,26 +109,26 @@ pub fn doctype_error_and_quirks(doctype: &Doctype, iframe_srcdoc: bool) -> (bool
     let system = opt_tendril_as_slice(&doctype.system_id);
 
     let err = match (name, public, system) {
-        (Some("html"), None, None) |
-        (Some("html"), None, Some("about:legacy-compat")) |
-        (Some("html"), Some("-//W3C//DTD HTML 4.0//EN"), None) |
-        (
+        (Some("html"), None, None)
+        | (Some("html"), None, Some("about:legacy-compat"))
+        | (Some("html"), Some("-//W3C//DTD HTML 4.0//EN"), None)
+        | (
             Some("html"),
             Some("-//W3C//DTD HTML 4.0//EN"),
             Some("http://www.w3.org/TR/REC-html40/strict.dtd"),
-        ) |
-        (Some("html"), Some("-//W3C//DTD HTML 4.01//EN"), None) |
-        (
+        )
+        | (Some("html"), Some("-//W3C//DTD HTML 4.01//EN"), None)
+        | (
             Some("html"),
             Some("-//W3C//DTD HTML 4.01//EN"),
             Some("http://www.w3.org/TR/html4/strict.dtd"),
-        ) |
-        (
+        )
+        | (
             Some("html"),
             Some("-//W3C//DTD XHTML 1.0 Strict//EN"),
             Some("http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"),
-        ) |
-        (
+        )
+        | (
             Some("html"),
             Some("-//W3C//DTD XHTML 1.1//EN"),
             Some("http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"),
diff --git a/html5ever/src/tree_builder/mod.rs b/html5ever/src/tree_builder/mod.rs
index 6929bd68..20f6fb71 100644
--- a/html5ever/src/tree_builder/mod.rs
+++ b/html5ever/src/tree_builder/mod.rs
@@ -27,7 +27,7 @@ use crate::tokenizer::{Doctype, EndTag, StartTag, Tag, TokenSink, TokenSinkResul
 use std::borrow::Cow::Borrowed;
 use std::collections::VecDeque;
 use std::iter::{Enumerate, Rev};
-use std::mem::replace;
+use std::mem;
 use std::{fmt, slice};
 
 use crate::tokenizer::states::{RawData, RawKind};
@@ -236,11 +236,11 @@ where
         match *name {
             local_name!("title") | local_name!("textarea") => tok_state::RawData(tok_state::Rcdata),
 
-            local_name!("style") |
-            local_name!("xmp") |
-            local_name!("iframe") |
-            local_name!("noembed") |
-            local_name!("noframes") => tok_state::RawData(tok_state::Rawtext),
+            local_name!("style")
+            | local_name!("xmp")
+            | local_name!("iframe")
+            | local_name!("noembed")
+            | local_name!("noframes") => tok_state::RawData(tok_state::Rawtext),
 
             local_name!("script") => tok_state::RawData(tok_state::ScriptData),
 
@@ -455,7 +455,7 @@ where
         if line_number != self.current_line {
             self.sink.set_current_line(line_number);
         }
-        let ignore_lf = replace(&mut self.ignore_lf, false);
+        let ignore_lf = mem::take(&mut self.ignore_lf);
 
         // Handle `ParseError` and `DoctypeToken`; convert everything else to the local `Token` type.
         let token = match token {
@@ -529,8 +529,8 @@ where
     }
 
     fn adjusted_current_node_present_but_not_in_html_namespace(&self) -> bool {
-        !self.open_elems.is_empty() &&
-            self.sink.elem_name(self.adjusted_current_node()).ns != &ns!(html)
+        !self.open_elems.is_empty()
+            && self.sink.elem_name(self.adjusted_current_node()).ns != &ns!(html)
     }
 }
 
@@ -850,8 +850,8 @@ where
                 Bookmark::InsertAfter(previous) => {
                     let index = self
                         .position_in_active_formatting(&previous)
-                        .expect("bookmark not found in active formatting elements") +
-                        1;
+                        .expect("bookmark not found in active formatting elements")
+                        + 1;
                     self.active_formatting.insert(index, new_entry);
                     let old_index = self
                         .position_in_active_formatting(&fmt_elem)
@@ -1299,11 +1299,11 @@ where
         };
 
         // Step 12.
-        if form_associatable(qname.expanded()) &&
-            self.form_elem.is_some() &&
-            !self.in_html_elem_named(local_name!("template")) &&
-            !(listed(qname.expanded()) &&
-                attrs
+        if form_associatable(qname.expanded())
+            && self.form_elem.is_some()
+            && !self.in_html_elem_named(local_name!("template"))
+            && !(listed(qname.expanded())
+                && attrs
                     .iter()
                     .any(|a| a.name.expanded() == expanded_name!("", "form")))
         {
@@ -1661,9 +1661,7 @@ where
     fn unexpected_start_tag_in_foreign_content(&mut self, tag: Tag) -> ProcessResult<Handle> {
         self.unexpected(&tag);
         while !self.current_node_in(|n| {
-            *n.ns == ns!(html) ||
-                mathml_text_integration_point(n) ||
-                svg_html_integration_point(n)
+            *n.ns == ns!(html) || mathml_text_integration_point(n) || svg_html_integration_point(n)
         }) {
             self.pop();
         }
diff --git a/html5ever/src/tree_builder/rules.rs b/html5ever/src/tree_builder/rules.rs
index 521ce1cc..5e94bd57 100644
--- a/html5ever/src/tree_builder/rules.rs
+++ b/html5ever/src/tree_builder/rules.rs
@@ -859,7 +859,7 @@ where
                 }
 
                 token => {
-                    let pending = replace(&mut self.pending_table_text, vec!());
+                    let pending = ::std::mem::take(&mut self.pending_table_text);
                     let contains_nonspace = pending.iter().any(|&(split, ref text)| {
                         match split {
                             Whitespace => false,
diff --git a/html5ever/src/tree_builder/tag_sets.rs b/html5ever/src/tree_builder/tag_sets.rs
index 4b46eeb1..510d5ddd 100644
--- a/html5ever/src/tree_builder/tag_sets.rs
+++ b/html5ever/src/tree_builder/tag_sets.rs
@@ -59,9 +59,9 @@ declare_tag_set!(pub html_default_scope =
 
 #[inline(always)]
 pub fn default_scope(name: ExpandedName) -> bool {
-    html_default_scope(name) ||
-        mathml_text_integration_point(name) ||
-        svg_html_integration_point(name)
+    html_default_scope(name)
+        || mathml_text_integration_point(name)
+        || svg_html_integration_point(name)
 }
 
 declare_tag_set!(pub list_item_scope = [default_scope] + "ol" "ul");
@@ -95,11 +95,11 @@ declare_tag_set!(pub special_tag =
 pub fn mathml_text_integration_point(p: ExpandedName) -> bool {
     matches!(
         p,
-        expanded_name!(mathml "mi") |
-            expanded_name!(mathml "mo") |
-            expanded_name!(mathml "mn") |
-            expanded_name!(mathml "ms") |
-            expanded_name!(mathml "mtext")
+        expanded_name!(mathml "mi")
+            | expanded_name!(mathml "mo")
+            | expanded_name!(mathml "mn")
+            | expanded_name!(mathml "ms")
+            | expanded_name!(mathml "mtext")
     )
 }
 
@@ -108,8 +108,8 @@ pub fn svg_html_integration_point(p: ExpandedName) -> bool {
     // annotation-xml are handle in another place
     matches!(
         p,
-        expanded_name!(svg "foreignObject") |
-            expanded_name!(svg "desc") |
-            expanded_name!(svg "title")
+        expanded_name!(svg "foreignObject")
+            | expanded_name!(svg "desc")
+            | expanded_name!(svg "title")
     )
 }
diff --git a/markup5ever/build.rs b/markup5ever/build.rs
index c4bbd564..354c7ec5 100644
--- a/markup5ever/build.rs
+++ b/markup5ever/build.rs
@@ -31,14 +31,14 @@ static NAMESPACES: &[(&str, &str)] = &[
 
 fn main() {
     let generated = Path::new(&env::var("OUT_DIR").unwrap()).join("generated.rs");
-    let mut generated = BufWriter::new(File::create(&generated).unwrap());
+    let mut generated = BufWriter::new(File::create(generated).unwrap());
 
     named_entities_to_phf(&Path::new(&env::var("OUT_DIR").unwrap()).join("named_entities.rs"));
 
     // Create a string cache for local names
     let local_names = Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap()).join("local_names.txt");
     let mut local_names_atom = string_cache_codegen::AtomType::new("LocalName", "local_name!");
-    for line in BufReader::new(File::open(&local_names).unwrap()).lines() {
+    for line in BufReader::new(File::open(local_names).unwrap()).lines() {
         let local_name = line.unwrap();
         local_names_atom.atom(&local_name);
         local_names_atom.atom(&local_name.to_ascii_lowercase());
diff --git a/markup5ever/interface/mod.rs b/markup5ever/interface/mod.rs
index f498fdfb..7c4bea2e 100644
--- a/markup5ever/interface/mod.rs
+++ b/markup5ever/interface/mod.rs
@@ -303,11 +303,7 @@ impl QualName {
     ///
     #[inline]
     pub fn new(prefix: Option<Prefix>, ns: Namespace, local: LocalName) -> QualName {
-        QualName {
-            prefix,
-            ns,
-            local,
-        }
+        QualName { prefix, ns, local }
     }
 
     /// Take a reference of `self` as an `ExpandedName`, dropping the unresolved prefix.
diff --git a/markup5ever/interface/tree_builder.rs b/markup5ever/interface/tree_builder.rs
index 43361f36..4010a160 100644
--- a/markup5ever/interface/tree_builder.rs
+++ b/markup5ever/interface/tree_builder.rs
@@ -54,6 +54,7 @@ pub enum NextParserState {
 
 /// Special properties of an element, useful for tagging elements with this information.
 #[derive(Default)]
+#[non_exhaustive]
 pub struct ElementFlags {
     /// A document fragment should be created, associated with the element,
     /// and returned in TreeSink::get_template_contents.
@@ -70,9 +71,6 @@ pub struct ElementFlags {
     ///
     /// [whatwg integration-point]: https://html.spec.whatwg.org/multipage/#html-integration-point
     pub mathml_annotation_xml_integration_point: bool,
-
-    // Prevent construction from outside module
-    _private: (),
 }
 
 /// A constructor for an element.
@@ -89,9 +87,9 @@ where
         expanded_name!(html "template") => flags.template = true,
         expanded_name!(mathml "annotation-xml") => {
             flags.mathml_annotation_xml_integration_point = attrs.iter().any(|attr| {
-                attr.name.expanded() == expanded_name!("", "encoding") &&
-                    (attr.value.eq_ignore_ascii_case("text/html") ||
-                        attr.value.eq_ignore_ascii_case("application/xhtml+xml"))
+                attr.name.expanded() == expanded_name!("", "encoding")
+                    && (attr.value.eq_ignore_ascii_case("text/html")
+                        || attr.value.eq_ignore_ascii_case("application/xhtml+xml"))
             })
         },
         _ => {},
diff --git a/markup5ever/util/buffer_queue.rs b/markup5ever/util/buffer_queue.rs
index ab3f0389..d41b6135 100644
--- a/markup5ever/util/buffer_queue.rs
+++ b/markup5ever/util/buffer_queue.rs
@@ -49,15 +49,17 @@ pub struct BufferQueue {
     buffers: VecDeque<StrTendril>,
 }
 
-impl BufferQueue {
+impl Default for BufferQueue {
     /// Create an empty BufferQueue.
     #[inline]
-    pub fn new() -> BufferQueue {
-        BufferQueue {
+    fn default() -> Self {
+        Self {
             buffers: VecDeque::with_capacity(16),
         }
     }
+}
 
+impl BufferQueue {
     /// Returns whether the queue is empty.
     #[inline]
     pub fn is_empty(&self) -> bool {
@@ -93,31 +95,12 @@ impl BufferQueue {
     /// Look at the next available character without removing it, if the queue is not empty.
     pub fn peek(&self) -> Option<char> {
         debug_assert!(
-            self.buffers.iter().find(|el| el.len32() == 0).is_none(),
+            !self.buffers.iter().any(|el| el.len32() == 0),
             "invariant \"all buffers in the queue are non-empty\" failed"
         );
         self.buffers.front().map(|b| b.chars().next().unwrap())
     }
 
-    /// Get the next character if one is available, removing it from the queue.
-    ///
-    /// This function manages the buffers, removing them as they become empty.
-    pub fn next(&mut self) -> Option<char> {
-        let (result, now_empty) = match self.buffers.front_mut() {
-            None => (None, false),
-            Some(buf) => {
-                let c = buf.pop_front_char().expect("empty buffer in queue");
-                (Some(c), buf.is_empty())
-            },
-        };
-
-        if now_empty {
-            self.buffers.pop_front();
-        }
-
-        result
-    }
-
     /// Pops and returns either a single character from the given set, or
     /// a buffer of characters none of which are in the set.
     ///
@@ -129,7 +112,7 @@ impl BufferQueue {
     /// # fn main() {
     /// use markup5ever::buffer_queue::{BufferQueue, SetResult};
     ///
-    /// let mut queue = BufferQueue::new();
+    /// let mut queue = BufferQueue::default();
     /// queue.push_back(format_tendril!(r#"<some_tag attr="text">SomeText</some_tag>"#));
     /// let set = small_char_set!(b'<' b'>' b' ' b'=' b'"' b'/');
     /// let tag = format_tendril!("some_tag");
@@ -185,9 +168,9 @@ impl BufferQueue {
     /// # extern crate markup5ever;
     /// # #[macro_use] extern crate tendril;
     /// # fn main() {
-    /// use markup5ever::buffer_queue::{BufferQueue};
+    /// use markup5ever::buffer_queue::BufferQueue;
     ///
-    /// let mut queue = BufferQueue::new();
+    /// let mut queue = BufferQueue::default();
     /// queue.push_back(format_tendril!("testtext"));
     /// let test_str = "test";
     /// assert_eq!(queue.eat("test", |&a, &b| a == b), Some(true));
@@ -232,6 +215,29 @@ impl BufferQueue {
     }
 }
 
+impl Iterator for BufferQueue {
+    type Item = char;
+
+    /// Get the next character if one is available, removing it from the queue.
+    ///
+    /// This function manages the buffers, removing them as they become empty.
+    fn next(&mut self) -> Option<char> {
+        let (result, now_empty) = match self.buffers.front_mut() {
+            None => (None, false),
+            Some(buf) => {
+                let c = buf.pop_front_char().expect("empty buffer in queue");
+                (Some(c), buf.is_empty())
+            },
+        };
+
+        if now_empty {
+            self.buffers.pop_front();
+        }
+
+        result
+    }
+}
+
 #[cfg(test)]
 #[allow(non_snake_case)]
 mod test {
@@ -242,7 +248,7 @@ mod test {
 
     #[test]
     fn smoke_test() {
-        let mut bq = BufferQueue::new();
+        let mut bq = BufferQueue::default();
         assert_eq!(bq.peek(), None);
         assert_eq!(bq.next(), None);
 
@@ -260,7 +266,7 @@ mod test {
 
     #[test]
     fn can_unconsume() {
-        let mut bq = BufferQueue::new();
+        let mut bq = BufferQueue::default();
         bq.push_back("abc".to_tendril());
         assert_eq!(bq.next(), Some('a'));
 
@@ -274,7 +280,7 @@ mod test {
 
     #[test]
     fn can_pop_except_set() {
-        let mut bq = BufferQueue::new();
+        let mut bq = BufferQueue::default();
         bq.push_back("abc&def".to_tendril());
         let mut pop = || bq.pop_except_from(small_char_set!('&'));
         assert_eq!(pop(), Some(NotFromSet("abc".to_tendril())));
@@ -288,7 +294,7 @@ mod test {
         // This is not very comprehensive.  We rely on the tokenizer
         // integration tests for more thorough testing with many
         // different input buffer splits.
-        let mut bq = BufferQueue::new();
+        let mut bq = BufferQueue::default();
         bq.push_back("a".to_tendril());
         bq.push_back("bc".to_tendril());
         assert_eq!(bq.eat("abcd", u8::eq_ignore_ascii_case), None);
diff --git a/markup5ever/util/smallcharset.rs b/markup5ever/util/smallcharset.rs
index 957dad73..2c0c4504 100644
--- a/markup5ever/util/smallcharset.rs
+++ b/markup5ever/util/smallcharset.rs
@@ -70,16 +70,14 @@ impl SmallCharSet {
 
 #[cfg(test)]
 mod test {
-    use std::iter::repeat;
-
     #[test]
     fn nonmember_prefix() {
         for &c in ['&', '\0'].iter() {
             for x in 0..48u32 {
                 for y in 0..48u32 {
-                    let mut s = repeat("x").take(x as usize).collect::<String>();
+                    let mut s = "x".repeat(x as usize);
                     s.push(c);
-                    s.push_str(&repeat("x").take(y as usize).collect::<String>());
+                    s.push_str(&"x".repeat(y as usize));
                     let set = small_char_set!('&' '\0');
 
                     assert_eq!(x, set.nonmember_prefix_len(&s));
diff --git a/rcdom/examples/hello_xml.rs b/rcdom/examples/hello_xml.rs
index 396c199c..792e4d96 100644
--- a/rcdom/examples/hello_xml.rs
+++ b/rcdom/examples/hello_xml.rs
@@ -25,21 +25,13 @@ fn main() {
     let doc = &dom.document;
 
     let hello_node = &doc.children.borrow()[0];
-    let hello_tag = &*dom.elem_name(hello_node).local;
+    let hello_tag = dom.elem_name(hello_node).local;
     let text_node = &hello_node.children.borrow()[0];
 
-    let xml = {
-        let mut xml = String::new();
-
-        match &text_node.data {
-            &NodeData::Text { ref contents } => {
-                xml.push_str(&contents.borrow());
-            },
-            _ => {},
-        };
-
-        xml
-    };
+    let mut xml = String::new();
+    if let NodeData::Text { contents } = &text_node.data {
+        xml.push_str(&contents.borrow());
+    }
 
     println!("{:?} {:?}!", hello_tag, xml);
 }
diff --git a/rcdom/examples/html2html.rs b/rcdom/examples/html2html.rs
index 634b2dfa..316dd0b0 100644
--- a/rcdom/examples/html2html.rs
+++ b/rcdom/examples/html2html.rs
@@ -43,10 +43,7 @@ fn main() {
     // The validator.nu HTML2HTML always prints a doctype at the very beginning.
     io::stdout()
         .write_all(b"<!DOCTYPE html>\n")
-        .ok()
         .expect("writing DOCTYPE failed");
     let document: SerializableHandle = dom.document.clone().into();
-    serialize(&mut io::stdout(), &document, Default::default())
-        .ok()
-        .expect("serialization failed");
+    serialize(&mut io::stdout(), &document, Default::default()).expect("serialization failed");
 }
diff --git a/rcdom/examples/print-rcdom.rs b/rcdom/examples/print-rcdom.rs
index c55d2348..47ea9b1a 100644
--- a/rcdom/examples/print-rcdom.rs
+++ b/rcdom/examples/print-rcdom.rs
@@ -21,7 +21,9 @@ use rcdom::{Handle, NodeData, RcDom};
 
 fn walk(indent: usize, handle: &Handle) {
     let node = handle;
-    for _ in 0..indent { print!(" "); }
+    for _ in 0..indent {
+        print!(" ");
+    }
     match node.data {
         NodeData::Document => println!("#Document"),
 
diff --git a/rcdom/examples/xml_tree_printer.rs b/rcdom/examples/xml_tree_printer.rs
index e61e6ef2..b55289cf 100644
--- a/rcdom/examples/xml_tree_printer.rs
+++ b/rcdom/examples/xml_tree_printer.rs
@@ -44,10 +44,7 @@ fn walk(prefix: &str, handle: &Handle) {
         .children
         .borrow()
         .iter()
-        .filter(|child| match child.data {
-            NodeData::Text { .. } | NodeData::Element { .. } => true,
-            _ => false,
-        })
+        .filter(|child| matches!(child.data, NodeData::Text { .. } | NodeData::Element { .. }))
     {
         walk(&new_indent, child);
     }
diff --git a/rcdom/lib.rs b/rcdom/lib.rs
index c53869a7..0018c879 100644
--- a/rcdom/lib.rs
+++ b/rcdom/lib.rs
@@ -126,9 +126,9 @@ impl Node {
 
 impl Drop for Node {
     fn drop(&mut self) {
-        let mut nodes = mem::replace(&mut *self.children.borrow_mut(), vec![]);
+        let mut nodes = mem::take(&mut *self.children.borrow_mut());
         while let Some(node) = nodes.pop() {
-            let children = mem::replace(&mut *node.children.borrow_mut(), vec![]);
+            let children = mem::take(&mut *node.children.borrow_mut());
             nodes.extend(children.into_iter());
             if let NodeData::Element {
                 ref template_contents,
@@ -294,16 +294,12 @@ impl TreeSink for RcDom {
 
     fn append(&mut self, parent: &Handle, child: NodeOrText<Handle>) {
         // Append to an existing Text node if we have one.
-        match child {
-            NodeOrText::AppendText(ref text) => match parent.children.borrow().last() {
-                Some(h) => {
-                    if append_to_existing_text(h, text) {
-                        return;
-                    }
-                },
-                _ => (),
-            },
-            _ => (),
+        if let NodeOrText::AppendText(text) = &child {
+            if let Some(h) = parent.children.borrow().last() {
+                if append_to_existing_text(h, text) {
+                    return;
+                }
+            }
         }
 
         append(
@@ -417,7 +413,7 @@ impl TreeSink for RcDom {
                 &previous_parent.unwrap().upgrade().expect("dangling weak")
             ))
         }
-        new_children.extend(mem::replace(&mut *children, Vec::new()));
+        new_children.extend(mem::take(&mut *children));
     }
 
     fn is_mathml_annotation_xml_integration_point(&self, target: &Handle) -> bool {
diff --git a/rustfmt.toml b/rustfmt.toml
index de839bae..ecd1b146 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1,3 +1,2 @@
 match_block_trailing_comma = true
-binop_separator = "Back"
 reorder_imports = true
diff --git a/xml5ever/benches/xml5ever.rs b/xml5ever/benches/xml5ever.rs
index a2dc33b0..288613c3 100644
--- a/xml5ever/benches/xml5ever.rs
+++ b/xml5ever/benches/xml5ever.rs
@@ -26,12 +26,11 @@ fn run_bench(c: &mut Criterion, name: &str) {
     let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
     path.push("data/bench/");
     path.push(name);
-    let mut file = fs::File::open(&path).ok().expect("can't open file");
+    let mut file = fs::File::open(&path).expect("can't open file");
 
     // Read the file and treat it as an infinitely repeating sequence of characters.
     let mut file_input = ByteTendril::new();
     file.read_to_tendril(&mut file_input)
-        .ok()
         .expect("can't read file");
     let file_input: StrTendril = file_input.try_reinterpret().unwrap();
     let size = file_input.len();
@@ -54,14 +53,14 @@ fn run_bench(c: &mut Criterion, name: &str) {
     c.bench_function(&test_name, move |b| {
         b.iter(|| {
             let mut tok = XmlTokenizer::new(Sink, Default::default());
-            let mut buffer = BufferQueue::new();
+            let mut buffer = BufferQueue::default();
             // We are doing clone inside the bench function, this is not ideal, but possibly
             // necessary since our iterator consumes the underlying buffer.
             for buf in input.clone().into_iter() {
                 buffer.push_back(buf);
-                let _ = tok.feed(&mut buffer);
+                tok.feed(&mut buffer);
             }
-            let _ = tok.feed(&mut buffer);
+            tok.feed(&mut buffer);
             tok.end();
         })
     });
diff --git a/xml5ever/examples/simple_xml_tokenizer.rs b/xml5ever/examples/simple_xml_tokenizer.rs
index 35dc8a38..66651b68 100644
--- a/xml5ever/examples/simple_xml_tokenizer.rs
+++ b/xml5ever/examples/simple_xml_tokenizer.rs
@@ -40,10 +40,10 @@ impl TokenSink for SimpleTokenPrinter {
                 ref target,
                 ref data,
             }) => {
-                println!("PI : <?{} {}?>", &*target, &*data);
+                println!("PI : <?{} {}?>", target, data);
             },
             CommentToken(ref comment) => {
-                println!("<!--{:?}-->", &*comment);
+                println!("<!--{:?}-->", comment);
             },
             EOFToken => {
                 println!("EOF");
@@ -53,7 +53,7 @@ impl TokenSink for SimpleTokenPrinter {
                 ref public_id,
                 ..
             }) => {
-                println!("<!DOCTYPE {:?} {:?}>", &*name, &*public_id);
+                println!("<!DOCTYPE {:?} {:?}>", name, public_id);
             },
         }
     }
@@ -72,7 +72,7 @@ fn main() {
     // into StrTendril.
 
     // Load input into BufferQueue
-    let mut input_buffer = BufferQueue::new();
+    let mut input_buffer = BufferQueue::default();
     input_buffer.push_back(input.try_reinterpret().unwrap());
     // Here we create and run tokenizer
     let mut tok = XmlTokenizer::new(sink, Default::default());
diff --git a/xml5ever/examples/xml_tokenizer.rs b/xml5ever/examples/xml_tokenizer.rs
index 46d683e3..ff648597 100644
--- a/xml5ever/examples/xml_tokenizer.rs
+++ b/xml5ever/examples/xml_tokenizer.rs
@@ -91,7 +91,7 @@ fn main() {
     let mut sink = TokenPrinter { in_char_run: false };
     let mut input = ByteTendril::new();
     io::stdin().read_to_tendril(&mut input).unwrap();
-    let mut input_buffer = BufferQueue::new();
+    let mut input_buffer = BufferQueue::default();
     input_buffer.push_back(input.try_reinterpret().unwrap());
 
     let mut tok = XmlTokenizer::new(
diff --git a/xml5ever/src/driver.rs b/xml5ever/src/driver.rs
index df5b9ee4..fd853433 100644
--- a/xml5ever/src/driver.rs
+++ b/xml5ever/src/driver.rs
@@ -42,7 +42,7 @@ where
     let tok = XmlTokenizer::new(tb, opts.tokenizer);
     XmlParser {
         tokenizer: tok,
-        input_buffer: BufferQueue::new(),
+        input_buffer: BufferQueue::default(),
     }
 }
 
diff --git a/xml5ever/src/serialize/mod.rs b/xml5ever/src/serialize/mod.rs
index 95e16a0d..cbc4cbd2 100644
--- a/xml5ever/src/serialize/mod.rs
+++ b/xml5ever/src/serialize/mod.rs
@@ -91,11 +91,9 @@ fn write_qual_name<W: Write>(writer: &mut W, name: &QualName) -> io::Result<()>
     if let Some(ref prefix) = name.prefix {
         writer.write_all(prefix.as_bytes())?;
         writer.write_all(b":")?;
-        writer.write_all(&*name.local.as_bytes())?;
-    } else {
-        writer.write_all(&*name.local.as_bytes())?;
     }
 
+    writer.write_all(name.local.as_bytes())?;
     Ok(())
 }
 
@@ -123,7 +121,7 @@ impl<Wr: Write> XmlSerializer<Wr> {
     fn find_uri(&self, name: &QualName) -> bool {
         let mut found = false;
         for stack in self.namespace_stack.0.iter().rev() {
-            if let Some(&Some(ref el)) = stack.get(&name.prefix) {
+            if let Some(Some(el)) = stack.get(&name.prefix) {
                 found = *el == name.ns;
                 break;
             }
@@ -132,11 +130,9 @@ impl<Wr: Write> XmlSerializer<Wr> {
     }
 
     fn find_or_insert_ns(&mut self, name: &QualName) {
-        if name.prefix.is_some() || &*name.ns != "" {
-            if !self.find_uri(name) {
-                if let Some(last_ns) = self.namespace_stack.0.last_mut() {
-                    last_ns.insert(name);
-                }
+        if (name.prefix.is_some() || !name.ns.is_empty()) && !self.find_uri(name) {
+            if let Some(last_ns) = self.namespace_stack.0.last_mut() {
+                last_ns.insert(name);
             }
         }
     }
diff --git a/xml5ever/src/tokenizer/char_ref/mod.rs b/xml5ever/src/tokenizer/char_ref/mod.rs
index 6351087e..c9171908 100644
--- a/xml5ever/src/tokenizer/char_ref/mod.rs
+++ b/xml5ever/src/tokenizer/char_ref/mod.rs
@@ -227,9 +227,8 @@ impl CharRefTokenizer {
         input: &mut BufferQueue,
     ) -> Status {
         let mut unconsume = StrTendril::from_char('#');
-        match self.hex_marker {
-            Some(c) => unconsume.push_char(c),
-            None => (),
+        if let Some(c) = self.hex_marker {
+            unconsume.push_char(c);
         }
 
         tokenizer.unconsume(input, unconsume);
diff --git a/xml5ever/src/tokenizer/interface.rs b/xml5ever/src/tokenizer/interface.rs
index 3dbf07ea..c2dad9be 100644
--- a/xml5ever/src/tokenizer/interface.rs
+++ b/xml5ever/src/tokenizer/interface.rs
@@ -64,7 +64,7 @@ impl Tag {
 /// Doctype token in XML5 is rather limited for reasons, such as:
 /// security and simplicity. XML5 only supports declaring DTD with
 /// name, public identifier and system identifier
-#[derive(PartialEq, Eq, Clone, Debug)]
+#[derive(PartialEq, Eq, Clone, Debug, Default)]
 pub struct Doctype {
     /// Name of DOCTYPE declared
     pub name: Option<StrTendril>,
@@ -74,17 +74,6 @@ pub struct Doctype {
     pub system_id: Option<StrTendril>,
 }
 
-impl Doctype {
-    /// Constructs an empty DOCTYPE, with all fields set to None.
-    pub fn new() -> Doctype {
-        Doctype {
-            name: None,
-            public_id: None,
-            system_id: None,
-        }
-    }
-}
-
 /// A ProcessingInstruction token.
 #[derive(PartialEq, Eq, Clone, Debug)]
 pub struct Pi {
diff --git a/xml5ever/src/tokenizer/mod.rs b/xml5ever/src/tokenizer/mod.rs
index ee876101..4aad2207 100644
--- a/xml5ever/src/tokenizer/mod.rs
+++ b/xml5ever/src/tokenizer/mod.rs
@@ -26,7 +26,7 @@ use mac::{format_if, unwrap_or_return};
 use markup5ever::{local_name, namespace_prefix, namespace_url, ns, small_char_set};
 use std::borrow::Cow::{self, Borrowed};
 use std::collections::BTreeMap;
-use std::mem::replace;
+use std::mem::{self, replace};
 
 use self::buffer_queue::{BufferQueue, FromSet, NotFromSet, SetResult};
 use self::char_ref::{CharRef, CharRefTokenizer};
@@ -193,7 +193,7 @@ impl<Sink: TokenSink> XmlTokenizer<Sink> {
             current_comment: StrTendril::new(),
             current_pi_data: StrTendril::new(),
             current_pi_target: StrTendril::new(),
-            current_doctype: Doctype::new(),
+            current_doctype: Doctype::default(),
             state_profile: BTreeMap::new(),
             time_in_sink: 0,
         }
@@ -305,9 +305,7 @@ impl<Sink: TokenSink> XmlTokenizer<Sink> {
         match input.eat(pat, u8::eq_ignore_ascii_case) {
             None if self.at_eof => Some(false),
             None => {
-                while let Some(c) = input.next() {
-                    self.temp_buf.push_char(c);
-                }
+                self.temp_buf.extend(input);
                 None
             },
             Some(matched) => Some(matched),
@@ -434,7 +432,7 @@ impl<Sink: TokenSink> XmlTokenizer<Sink> {
         let token = TagToken(Tag {
             kind: self.current_tag_kind,
             name: qname,
-            attrs: replace(&mut self.current_tag_attrs, vec![]),
+            attrs: mem::take(&mut self.current_tag_attrs),
         });
         self.process_token(token);
 
@@ -473,12 +471,12 @@ impl<Sink: TokenSink> XmlTokenizer<Sink> {
     }
 
     fn emit_current_comment(&mut self) {
-        let comment = replace(&mut self.current_comment, StrTendril::new());
+        let comment = mem::take(&mut self.current_comment);
         self.process_token(CommentToken(comment));
     }
 
     fn emit_current_doctype(&mut self) {
-        let doctype = replace(&mut self.current_doctype, Doctype::new());
+        let doctype = mem::take(&mut self.current_doctype);
         self.process_token(DoctypeToken(doctype));
     }
 
@@ -533,7 +531,7 @@ macro_rules! shorthand (
     ( $me:ident : append_comment $c:expr           ) => ( $me.current_comment.push_slice($c)                  );
     ( $me:ident : emit_comment                     ) => ( $me.emit_current_comment()                          );
     ( $me:ident : clear_comment                    ) => ( $me.current_comment.clear()                         );
-    ( $me:ident : create_doctype                   ) => ( $me.current_doctype = Doctype::new()                );
+    ( $me:ident : create_doctype                   ) => ( $me.current_doctype = Doctype::default()            );
     ( $me:ident : push_doctype_name $c:expr        ) => ( option_push(&mut $me.current_doctype.name, $c)      );
     ( $me:ident : push_doctype_id $k:ident $c:expr ) => ( option_push($me.doctype_id($k), $c)                 );
     ( $me:ident : clear_doctype_id $k:ident        ) => ( $me.clear_doctype_id($k)                            );
@@ -1070,9 +1068,8 @@ impl<Sink: TokenSink> XmlTokenizer<Sink> {
             },
             //§ bogus_doctype_state
             XmlState::BogusDoctype => loop {
-                match get_char!(self, input) {
-                    '>' => go!(self: emit_doctype; to Data),
-                    _ => (),
+                if get_char!(self, input) == '>' {
+                    go!(self: emit_doctype; to Data);
                 }
             },
         }
@@ -1082,7 +1079,7 @@ impl<Sink: TokenSink> XmlTokenizer<Sink> {
     pub fn end(&mut self) {
         // Handle EOF in the char ref sub-tokenizer, if there is one.
         // Do this first because it might un-consume stuff.
-        let mut input = BufferQueue::new();
+        let mut input = BufferQueue::default();
         match self.char_ref_tokenizer.take() {
             None => (),
             Some(mut tok) => {
diff --git a/xml5ever/src/tree_builder/mod.rs b/xml5ever/src/tree_builder/mod.rs
index 4c10f8e2..c452c75a 100644
--- a/xml5ever/src/tree_builder/mod.rs
+++ b/xml5ever/src/tree_builder/mod.rs
@@ -40,11 +40,7 @@ struct NamespaceMapStack(Vec<NamespaceMap>);
 
 impl NamespaceMapStack {
     fn new() -> NamespaceMapStack {
-        NamespaceMapStack({
-            let mut vec = Vec::new();
-            vec.push(NamespaceMap::default());
-            vec
-        })
+        NamespaceMapStack(vec![NamespaceMap::default()])
     }
 
     fn push(&mut self, map: NamespaceMap) {
@@ -112,11 +108,7 @@ impl NamespaceMap {
 
     #[doc(hidden)]
     pub fn insert(&mut self, name: &QualName) {
-        let prefix = if let Some(ref p) = name.prefix {
-            Some(p.clone())
-        } else {
-            None
-        };
+        let prefix = name.prefix.as_ref().cloned();
         let namespace = Some(Namespace::from(&*name.ns));
         self.scope.insert(prefix, namespace);
     }
@@ -175,15 +167,9 @@ impl NamespaceMap {
 }
 
 /// Tree builder options, with an impl for Default.
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Default)]
 pub struct XmlTreeBuilderOpts {}
 
-impl Default for XmlTreeBuilderOpts {
-    fn default() -> XmlTreeBuilderOpts {
-        XmlTreeBuilderOpts {}
-    }
-}
-
 /// The XML tree builder.
 pub struct XmlTreeBuilder<Handle, Sink> {
     /// Configuration options for XmlTreeBuilder
@@ -236,7 +222,7 @@ where
             namespace_stack: NamespaceMapStack::new(),
             current_namespace: NamespaceMap::empty(),
             present_attrs: HashSet::new(),
-            phase: StartPhase,
+            phase: Start,
         }
     }
 
@@ -413,13 +399,13 @@ where
                 return;
             },
 
-            tokenizer::DoctypeToken(d) => DoctypeToken(d),
-            tokenizer::PIToken(x) => PIToken(x),
-            tokenizer::TagToken(x) => TagToken(x),
-            tokenizer::CommentToken(x) => CommentToken(x),
-            tokenizer::NullCharacterToken => NullCharacterToken,
-            tokenizer::EOFToken => EOFToken,
-            tokenizer::CharacterTokens(x) => CharacterTokens(x),
+            tokenizer::DoctypeToken(d) => Doctype(d),
+            tokenizer::PIToken(x) => Pi(x),
+            tokenizer::TagToken(x) => Tag(x),
+            tokenizer::CommentToken(x) => Comment(x),
+            tokenizer::NullCharacterToken => NullCharacter,
+            tokenizer::EOFToken => Eof,
+            tokenizer::CharacterTokens(x) => Characters(x),
         };
 
         self.process_to_completion(token);
@@ -541,7 +527,7 @@ where
         P: Fn(ExpandedName) -> bool,
     {
         loop {
-            if self.current_node_in(|x| pred(x)) {
+            if self.current_node_in(&pred) {
                 break;
             }
             self.pop();
@@ -617,8 +603,8 @@ where
         self.debug_step(mode, &token);
 
         match mode {
-            StartPhase => match token {
-                TagToken(Tag {
+            Start => match token {
+                Tag(Tag {
                     kind: StartTag,
                     name,
                     attrs,
@@ -632,11 +618,11 @@ where
                         self.process_namespaces(&mut tag);
                         tag
                     };
-                    self.phase = MainPhase;
+                    self.phase = Main;
                     let handle = self.append_tag_to_doc(tag);
                     self.add_to_open_elems(handle)
                 },
-                TagToken(Tag {
+                Tag(Tag {
                     kind: EmptyTag,
                     name,
                     attrs,
@@ -650,20 +636,20 @@ where
                         self.process_namespaces(&mut tag);
                         tag
                     };
-                    self.phase = EndPhase;
+                    self.phase = End;
                     let handle = self.append_tag_to_doc(tag);
                     self.sink.pop(&handle);
                     Done
                 },
-                CommentToken(comment) => self.append_comment_to_doc(comment),
-                PIToken(pi) => self.append_pi_to_doc(pi),
-                CharacterTokens(ref chars) if !any_not_whitespace(chars) => Done,
-                EOFToken => {
+                Comment(comment) => self.append_comment_to_doc(comment),
+                Pi(pi) => self.append_pi_to_doc(pi),
+                Characters(ref chars) if !any_not_whitespace(chars) => Done,
+                Eof => {
                     self.sink
                         .parse_error(Borrowed("Unexpected EOF in start phase"));
-                    Reprocess(EndPhase, EOFToken)
+                    Reprocess(End, Eof)
                 },
-                DoctypeToken(d) => {
+                Doctype(d) => {
                     self.append_doctype_to_doc(d);
                     Done
                 },
@@ -673,9 +659,9 @@ where
                     Done
                 },
             },
-            MainPhase => match token {
-                CharacterTokens(chs) => self.append_text(chs),
-                TagToken(Tag {
+            Main => match token {
+                Characters(chs) => self.append_text(chs),
+                Tag(Tag {
                     kind: StartTag,
                     name,
                     attrs,
@@ -691,7 +677,7 @@ where
                     };
                     self.insert_tag(tag)
                 },
-                TagToken(Tag {
+                Tag(Tag {
                     kind: EmptyTag,
                     name,
                     attrs,
@@ -713,7 +699,7 @@ where
                         self.append_tag(tag)
                     }
                 },
-                TagToken(Tag {
+                Tag(Tag {
                     kind: EndTag,
                     name,
                     attrs,
@@ -732,31 +718,31 @@ where
                     }
                     let retval = self.close_tag(tag);
                     if self.no_open_elems() {
-                        self.phase = EndPhase;
+                        self.phase = End;
                     }
                     retval
                 },
-                TagToken(Tag { kind: ShortTag, .. }) => {
+                Tag(Tag { kind: ShortTag, .. }) => {
                     self.pop();
                     if self.no_open_elems() {
-                        self.phase = EndPhase;
+                        self.phase = End;
                     }
                     Done
                 },
-                CommentToken(comment) => self.append_comment_to_tag(comment),
-                PIToken(pi) => self.append_pi_to_tag(pi),
-                EOFToken | NullCharacterToken => Reprocess(EndPhase, EOFToken),
-                DoctypeToken(_) => {
+                Comment(comment) => self.append_comment_to_tag(comment),
+                Pi(pi) => self.append_pi_to_tag(pi),
+                Eof | NullCharacter => Reprocess(End, Eof),
+                Doctype(_) => {
                     self.sink
                         .parse_error(Borrowed("Unexpected element in main phase"));
                     Done
                 },
             },
-            EndPhase => match token {
-                CommentToken(comment) => self.append_comment_to_doc(comment),
-                PIToken(pi) => self.append_pi_to_doc(pi),
-                CharacterTokens(ref chars) if !any_not_whitespace(chars) => Done,
-                EOFToken => self.stop_parsing(),
+            End => match token {
+                Comment(comment) => self.append_comment_to_doc(comment),
+                Pi(pi) => self.append_pi_to_doc(pi),
+                Characters(ref chars) if !any_not_whitespace(chars) => Done,
+                Eof => self.stop_parsing(),
                 _ => {
                     self.sink
                         .parse_error(Borrowed("Unexpected element in end phase"));
diff --git a/xml5ever/src/tree_builder/types.rs b/xml5ever/src/tree_builder/types.rs
index 327258b9..4c031abe 100644
--- a/xml5ever/src/tree_builder/types.rs
+++ b/xml5ever/src/tree_builder/types.rs
@@ -16,22 +16,22 @@ use crate::tokenizer::{Doctype, Pi, Tag};
 
 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
 pub enum XmlPhase {
-    StartPhase,
-    MainPhase,
-    EndPhase,
+    Start,
+    Main,
+    End,
 }
 
 /// A subset/refinement of `tokenizer::XToken`.  Everything else is handled
 /// specially at the beginning of `process_token`.
 #[derive(PartialEq, Eq, Clone, Debug)]
 pub enum Token {
-    TagToken(Tag),
-    DoctypeToken(Doctype),
-    CommentToken(StrTendril),
-    CharacterTokens(StrTendril),
-    PIToken(Pi),
-    NullCharacterToken,
-    EOFToken,
+    Tag(Tag),
+    Doctype(Doctype),
+    Comment(StrTendril),
+    Characters(StrTendril),
+    Pi(Pi),
+    NullCharacter,
+    Eof,
 }
 
 pub enum XmlProcessResult {


Test patch:
diff --git a/rcdom/tests/html-driver.rs b/rcdom/tests/html-driver.rs
index 04648723..9510c312 100644
--- a/rcdom/tests/html-driver.rs
+++ b/rcdom/tests/html-driver.rs
@@ -12,7 +12,7 @@ fn from_utf8() {
     let document: SerializableHandle = dom.document.clone().into();
     serialize::serialize(&mut serialized, &document, Default::default()).unwrap();
     assert_eq!(
-        String::from_utf8(serialized).unwrap().replace(" ", ""),
+        String::from_utf8(serialized).unwrap().replace(' ', ""),
         "<html><head><title>Test</title></head><body></body></html>"
     );
 }
diff --git a/rcdom/tests/html-serializer.rs b/rcdom/tests/html-serializer.rs
index d599cbb8..e4e6562b 100644
--- a/rcdom/tests/html-serializer.rs
+++ b/rcdom/tests/html-serializer.rs
@@ -34,9 +34,9 @@ impl Serialize for Tokens {
         S: Serializer,
     {
         for t in self.0.iter() {
-            match t {
+            match &t {
                 // TODO: check whether this is an IE conditional comment or a spec comment
-                &Token::TagToken(ref tag) => {
+                Token::TagToken(tag) => {
                     let name = QualName::new(
                         None,
                         "http://www.w3.org/1999/xhtml".into(),
@@ -50,14 +50,15 @@ impl Serialize for Tokens {
                         TagKind::EndTag => serializer.end_elem(name)?,
                     }
                 },
-                &Token::DoctypeToken(ref dt) => match dt.name {
-                    Some(ref name) => serializer.write_doctype(&name)?,
-                    None => {},
+                Token::DoctypeToken(dt) => {
+                    if let Some(name) = &dt.name {
+                        serializer.write_doctype(name)?
+                    }
                 },
-                &Token::CommentToken(ref chars) => serializer.write_comment(&chars)?,
-                &Token::CharacterTokens(ref chars) => serializer.write_text(&chars)?,
-                &Token::NullCharacterToken | &Token::EOFToken => {},
-                &Token::ParseError(ref e) => println!("parse error: {:#?}", e),
+                Token::CommentToken(chars) => serializer.write_comment(chars)?,
+                Token::CharacterTokens(chars) => serializer.write_text(chars)?,
+                Token::NullCharacterToken | &Token::EOFToken => {},
+                Token::ParseError(e) => println!("parse error: {e:#?}"),
             }
         }
         Ok(())
@@ -66,8 +67,8 @@ impl Serialize for Tokens {
 
 fn tokenize_and_serialize(input: StrTendril) -> StrTendril {
     let mut input = {
-        let mut q = ::html5ever::tokenizer::BufferQueue::new();
-        q.push_front(input.into());
+        let mut q = ::html5ever::tokenizer::BufferQueue::default();
+        q.push_front(input);
         q
     };
     let mut tokenizer = Tokenizer::new(Tokens(vec![]), Default::default());
@@ -251,7 +252,7 @@ fn deep_tree() {
         QualName::new(None, ns!(html), local_name!("div")),
         vec![],
     );
-    let src = String::from("<b>".repeat(60_000));
+    let src = "<b>".repeat(60_000);
     let dom = parser.one(src);
     let opts = SerializeOpts::default();
     let mut ret_val = Vec::new();
diff --git a/rcdom/tests/html-tokenizer.rs b/rcdom/tests/html-tokenizer.rs
index 9fa68e37..f67caf8f 100644
--- a/rcdom/tests/html-tokenizer.rs
+++ b/rcdom/tests/html-tokenizer.rs
@@ -11,7 +11,9 @@ mod foreach_html5lib_test;
 
 use foreach_html5lib_test::foreach_html5lib_test;
 use html5ever::tendril::*;
-use html5ever::tokenizer::states::{Plaintext, RawData, Rawtext, Rcdata, ScriptData, CdataSection, Data};
+use html5ever::tokenizer::states::{
+    CdataSection, Data, Plaintext, RawData, Rawtext, Rcdata, ScriptData,
+};
 use html5ever::tokenizer::BufferQueue;
 use html5ever::tokenizer::{CharacterTokens, EOFToken, NullCharacterToken, ParseError};
 use html5ever::tokenizer::{CommentToken, DoctypeToken, TagToken, Token};
@@ -20,17 +22,14 @@ use html5ever::tokenizer::{TokenSink, TokenSinkResult, Tokenizer, TokenizerOpts}
 use html5ever::{namespace_url, ns, Attribute, LocalName, QualName};
 use rustc_test::{DynTestFn, DynTestName, TestDesc, TestDescAndFn};
 use serde_json::{Map, Value};
-use std::borrow::Cow;
 use std::ffi::OsStr;
-use std::io::Read;
 use std::fs::File;
-use std::mem::replace;
+use std::io::Read;
 use std::path::Path;
-use std::{char, env};
-
+use std::{char, env, mem};
 
 #[derive(Debug)]
-struct TestError(Cow<'static, str>);
+struct TestError;
 
 impl PartialEq for TestError {
     fn eq(&self, _: &TestError) -> bool {
@@ -58,7 +57,7 @@ fn splits(s: &str, n: usize) -> Vec<Vec<StrTendril>> {
         }
     }
 
-    out.extend(splits(s, n - 1).into_iter());
+    out.extend(splits(s, n - 1));
     out.truncate(MAX_SPLITS);
     out
 }
@@ -76,7 +75,7 @@ impl TokenLogger {
             tokens: vec![],
             errors: vec![],
             current_str: StrTendril::new(),
-            exact_errors: exact_errors,
+            exact_errors,
         }
     }
 
@@ -88,12 +87,12 @@ impl TokenLogger {
 
     fn finish_str(&mut self) {
         if self.current_str.len() > 0 {
-            let s = replace(&mut self.current_str, StrTendril::new());
+            let s = mem::take(&mut self.current_str);
             self.tokens.push(CharacterTokens(s));
         }
     }
 
-    fn get_tokens(mut self) -> (Vec<Token>, Vec<TestError>){
+    fn get_tokens(mut self) -> (Vec<Token>, Vec<TestError>) {
         self.finish_str();
         (self.tokens, self.errors)
     }
@@ -112,9 +111,9 @@ impl TokenSink for TokenLogger {
                 self.current_str.push_char('\0');
             },
 
-            ParseError(e) => {
+            ParseError(_) => {
                 if self.exact_errors {
-                    self.errors.push(TestError(e));
+                    self.errors.push(TestError);
                 }
             },
 
@@ -143,7 +142,7 @@ impl TokenSink for TokenLogger {
 fn tokenize(input: Vec<StrTendril>, opts: TokenizerOpts) -> (Vec<Token>, Vec<TestError>) {
     let sink = TokenLogger::new(opts.exact_errors);
     let mut tok = Tokenizer::new(sink, opts);
-    let mut buffer = BufferQueue::new();
+    let mut buffer = BufferQueue::default();
     for chunk in input.into_iter() {
         buffer.push_back(chunk);
         let _ = tok.feed(&mut buffer);
@@ -158,9 +157,9 @@ trait JsonExt: Sized {
     fn get_tendril(&self) -> StrTendril;
     fn get_nullable_tendril(&self) -> Option<StrTendril>;
     fn get_bool(&self) -> bool;
-    fn get_obj<'t>(&'t self) -> &'t Map<String, Self>;
-    fn get_list<'t>(&'t self) -> &'t Vec<Self>;
-    fn find<'t>(&'t self, key: &str) -> &'t Self;
+    fn get_obj(&self) -> &Map<String, Self>;
+    fn get_list(&self) -> &Vec<Self>;
+    fn find(&self, key: &str) -> &Self;
 }
 
 impl JsonExt for Value {
@@ -193,22 +192,22 @@ impl JsonExt for Value {
         }
     }
 
-    fn get_obj<'t>(&'t self) -> &'t Map<String, Value> {
-        match *self {
-            Value::Object(ref m) => &*m,
+    fn get_obj(&self) -> &Map<String, Value> {
+        match self {
+            Value::Object(m) => m,
             _ => panic!("Value::get_obj: not an Object"),
         }
     }
 
-    fn get_list<'t>(&'t self) -> &'t Vec<Value> {
-        match *self {
-            Value::Array(ref m) => m,
+    fn get_list(&self) -> &Vec<Value> {
+        match self {
+            Value::Array(m) => m,
             _ => panic!("Value::get_list: not an Array"),
         }
     }
 
-    fn find<'t>(&'t self, key: &str) -> &'t Value {
-        self.get_obj().get(&key.to_string()).unwrap()
+    fn find(&self, key: &str) -> &Value {
+        self.get_obj().get(key).unwrap()
     }
 }
 
@@ -260,7 +259,11 @@ fn json_to_token(js: &Value) -> Token {
 }
 
 // Parse the "output" field of the test case into a vector of tokens.
-fn json_to_tokens(js_tokens: &Value, js_errors: &[Value], exact_errors: bool) -> (Vec<Token>, Vec<TestError>) {
+fn json_to_tokens(
+    js_tokens: &Value,
+    js_errors: &[Value],
+    exact_errors: bool,
+) -> (Vec<Token>, Vec<TestError>) {
     // Use a TokenLogger so that we combine character tokens separated
     // by an ignored error.
     let mut sink = TokenLogger::new(exact_errors);
@@ -309,12 +312,12 @@ fn unescape(s: &str) -> Option<String> {
 }
 
 fn unescape_json(js: &Value) -> Value {
-    match *js {
+    match js {
         // unwrap is OK here because the spec'd *output* of the tokenizer never
         // contains a lone surrogate.
-        Value::String(ref s) => Value::String(unescape(&s).unwrap()),
-        Value::Array(ref xs) => Value::Array(xs.iter().map(unescape_json).collect()),
-        Value::Object(ref obj) => {
+        Value::String(s) => Value::String(unescape(s).unwrap()),
+        Value::Array(xs) => Value::Array(xs.iter().map(unescape_json).collect()),
+        Value::Object(obj) => {
             let mut new_obj = Map::new();
             for (k, v) in obj.iter() {
                 new_obj.insert(k.clone(), unescape_json(v));
@@ -325,7 +328,13 @@ fn unescape_json(js: &Value) -> Value {
     }
 }
 
-fn mk_test(desc: String, input: String, expect: Value, expect_errors: Vec<Value>, opts: TokenizerOpts) -> TestDescAndFn {
+fn mk_test(
+    desc: String,
+    input: String,
+    expect: Value,
+    expect_errors: Vec<Value>,
+    opts: TokenizerOpts,
+) -> TestDescAndFn {
     TestDescAndFn {
         desc: TestDesc::new(DynTestName(desc)),
         testfn: DynTestFn(Box::new(move || {
@@ -353,7 +362,11 @@ fn mk_tests(tests: &mut Vec<TestDescAndFn>, filename: &str, js: &Value) {
     let obj = js.get_obj();
     let mut input = js.find("input").get_str();
     let mut expect = js.find("output").clone();
-    let expect_errors = js.get("errors").map(JsonExt::get_list).map(Vec::as_slice).unwrap_or_default();
+    let expect_errors = js
+        .get("errors")
+        .map(JsonExt::get_list)
+        .map(Vec::as_slice)
+        .unwrap_or_default();
     let desc = format!("tok: {}: {}", filename, js.find("description").get_str());
 
     // "Double-escaped" tests require additional processing of
@@ -374,7 +387,7 @@ fn mk_tests(tests: &mut Vec<TestDescAndFn>, filename: &str, js: &Value) {
 
     // Some tests want to start in a state other than Data.
     let state_overrides = match obj.get(&"initialStates".to_string()) {
-        Some(&Value::Array(ref xs)) => xs
+        Some(Value::Array(xs)) => xs
             .iter()
             .map(|s| {
                 Some(match &s.get_str()[..] {
@@ -396,9 +409,8 @@ fn mk_tests(tests: &mut Vec<TestDescAndFn>, filename: &str, js: &Value) {
     for state in state_overrides.into_iter() {
         for &exact_errors in [false, true].iter() {
             let mut newdesc = desc.clone();
-            match state {
-                Some(s) => newdesc = format!("{} (in state {:?})", newdesc, s),
-                None => (),
+            if let Some(s) = state {
+                newdesc = format!("{} (in state {:?})", newdesc, s)
             };
             if exact_errors {
                 newdesc = format!("{} (exact errors)", newdesc);
@@ -410,7 +422,7 @@ fn mk_tests(tests: &mut Vec<TestDescAndFn>, filename: &str, js: &Value) {
                 expect.clone(),
                 expect_errors.to_owned(),
                 TokenizerOpts {
-                    exact_errors: exact_errors,
+                    exact_errors,
                     initial_state: state,
                     last_start_tag_name: start_tag.clone(),
 
@@ -430,24 +442,17 @@ fn tests(src_dir: &Path) -> Vec<TestDescAndFn> {
 
     let mut add_test = |path: &Path, mut file: File| {
         let mut s = String::new();
-        file.read_to_string(&mut s)
-            .ok()
-            .expect("file reading error");
-        let js: Value = serde_json::from_str(&s).ok().expect("json parse error");
-
-        match js.get_obj().get(&"tests".to_string()) {
-            Some(&Value::Array(ref lst)) => {
-                for test in lst.iter() {
-                    mk_tests(
-                        &mut tests,
-                        path.file_name().unwrap().to_str().unwrap(),
-                        test,
-                    )
-                }
-            },
-
-            // xmlViolation.test doesn't follow this format.
-            _ => (),
+        file.read_to_string(&mut s).expect("file reading error");
+        let js: Value = serde_json::from_str(&s).expect("json parse error");
+
+        if let Some(Value::Array(lst)) = js.get_obj().get("tests") {
+            for test in lst.iter() {
+                mk_tests(
+                    &mut tests,
+                    path.file_name().unwrap().to_str().unwrap(),
+                    test,
+                )
+            }
         }
     };
 
@@ -455,14 +460,14 @@ fn tests(src_dir: &Path) -> Vec<TestDescAndFn> {
         src_dir,
         "html5lib-tests/tokenizer",
         OsStr::new("test"),
-        &mut add_test
+        &mut add_test,
     );
 
     foreach_html5lib_test(
         src_dir,
         "custom-html5lib-tokenizer-tests",
         OsStr::new("test"),
-        &mut add_test
+        &mut add_test,
     );
 
     tests
diff --git a/rcdom/tests/html-tree-builder.rs b/rcdom/tests/html-tree-builder.rs
index e17ea695..d22207d3 100644
--- a/rcdom/tests/html-tree-builder.rs
+++ b/rcdom/tests/html-tree-builder.rs
@@ -18,10 +18,8 @@ use foreach_html5lib_test::foreach_html5lib_test;
 use std::collections::{HashMap, HashSet};
 use std::ffi::OsStr;
 use std::io::BufRead;
-use std::iter::repeat;
-use std::mem::replace;
 use std::path::Path;
-use std::{env, fs, io};
+use std::{env, fs, io, iter, mem};
 use test::{DynTestName, TestDesc, TestDescAndFn, TestFn};
 
 use html5ever::tendril::{StrTendril, TendrilSink};
@@ -39,14 +37,14 @@ fn parse_tests<It: Iterator<Item = String>>(mut lines: It) -> Vec<HashMap<String
         match key.take() {
             None => (),
             Some(key) => {
-                assert!(test.insert(key, replace(&mut val, String::new())).is_none());
+                assert!(test.insert(key, mem::take(&mut val)).is_none());
             }
         }
     ));
 
     macro_rules! finish_test ( () => (
         if !test.is_empty() {
-            tests.push(replace(&mut test, HashMap::new()));
+            tests.push(mem::take(&mut test));
         }
     ));
 
@@ -54,12 +52,12 @@ fn parse_tests<It: Iterator<Item = String>>(mut lines: It) -> Vec<HashMap<String
         match lines.next() {
             None => break,
             Some(line) => {
-                if line.starts_with("#") {
+                if let Some(rest) = line.strip_prefix('#') {
                     finish_val!();
                     if line == "#data" {
                         finish_test!();
                     }
-                    key = Some(line[1..].to_string());
+                    key = Some(rest.to_owned());
                 } else {
                     val.push_str(&line);
                     val.push('\n');
@@ -74,8 +72,8 @@ fn parse_tests<It: Iterator<Item = String>>(mut lines: It) -> Vec<HashMap<String
 }
 
 fn serialize(buf: &mut String, indent: usize, handle: Handle) {
-    buf.push_str("|");
-    buf.push_str(&repeat(" ").take(indent).collect::<String>());
+    buf.push('|');
+    buf.extend(iter::repeat(" ").take(indent));
 
     let node = handle;
     match node.data {
@@ -87,7 +85,7 @@ fn serialize(buf: &mut String, indent: usize, handle: Handle) {
             ref system_id,
         } => {
             buf.push_str("<!DOCTYPE ");
-            buf.push_str(&name);
+            buf.push_str(name);
             if !public_id.is_empty() || !system_id.is_empty() {
                 buf.push_str(&format!(" \"{}\" \"{}\"", public_id, system_id));
             }
@@ -95,14 +93,14 @@ fn serialize(buf: &mut String, indent: usize, handle: Handle) {
         },
 
         NodeData::Text { ref contents } => {
-            buf.push_str("\"");
+            buf.push('"');
             buf.push_str(&contents.borrow());
             buf.push_str("\"\n");
         },
 
         NodeData::Comment { ref contents } => {
             buf.push_str("<!-- ");
-            buf.push_str(&contents);
+            buf.push_str(contents);
             buf.push_str(" -->\n");
         },
 
@@ -111,13 +109,13 @@ fn serialize(buf: &mut String, indent: usize, handle: Handle) {
             ref attrs,
             ..
         } => {
-            buf.push_str("<");
+            buf.push('<');
             match name.ns {
                 ns!(svg) => buf.push_str("svg "),
                 ns!(mathml) => buf.push_str("math "),
                 _ => (),
             }
-            buf.push_str(&*name.local);
+            buf.push_str(&name.local);
             buf.push_str(">\n");
 
             let mut attrs = attrs.borrow().clone();
@@ -125,8 +123,8 @@ fn serialize(buf: &mut String, indent: usize, handle: Handle) {
             // FIXME: sort by UTF-16 code unit
 
             for attr in attrs.into_iter() {
-                buf.push_str("|");
-                buf.push_str(&repeat(" ").take(indent + 2).collect::<String>());
+                buf.push('|');
+                buf.extend(iter::repeat(" ").take(indent + 2));
                 match attr.name.ns {
                     ns!(xlink) => buf.push_str("xlink "),
                     ns!(xml) => buf.push_str("xml "),
@@ -150,8 +148,8 @@ fn serialize(buf: &mut String, indent: usize, handle: Handle) {
     } = node.data
     {
         if let Some(ref content) = &*template_contents.borrow() {
-            buf.push_str("|");
-            buf.push_str(&repeat(" ").take(indent + 2).collect::<String>());
+            buf.push('|');
+            buf.extend(iter::repeat(" ").take(indent + 2));
             buf.push_str("content\n");
             for child in content.children.borrow().iter() {
                 serialize(buf, indent + 4, child.clone());
@@ -211,7 +209,7 @@ fn make_test_desc_with_scripting_flag(
 
     TestDescAndFn {
         desc: TestDesc {
-            ignore: ignore,
+            ignore,
             ..TestDesc::new(DynTestName(name))
         },
         testfn: TestFn::dyn_test_fn(move || {
@@ -251,10 +249,10 @@ fn make_test_desc_with_scripting_flag(
 }
 
 fn context_name(context: &str) -> QualName {
-    if context.starts_with("svg ") {
-        QualName::new(None, ns!(svg), LocalName::from(&context[4..]))
-    } else if context.starts_with("math ") {
-        QualName::new(None, ns!(mathml), LocalName::from(&context[5..]))
+    if let Some(cx) = context.strip_prefix("svg ") {
+        QualName::new(None, ns!(svg), LocalName::from(cx))
+    } else if let Some(cx) = context.strip_prefix("math ") {
+        QualName::new(None, ns!(mathml), LocalName::from(cx))
     } else {
         QualName::new(None, ns!(html), LocalName::from(context))
     }
@@ -269,7 +267,7 @@ fn tests(src_dir: &Path, ignores: &HashSet<String>) -> Vec<TestDescAndFn> {
         OsStr::new("dat"),
         |path, file| {
             let buf = io::BufReader::new(file);
-            let lines = buf.lines().map(|res| res.ok().expect("couldn't read"));
+            let lines = buf.lines().map(|res| res.expect("couldn't read"));
             let data = parse_tests(lines);
 
             for (i, test) in data.into_iter().enumerate() {
@@ -292,7 +290,7 @@ fn main() {
     let src_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
     let mut ignores = HashSet::new();
     {
-        let f = fs::File::open(&src_dir.join("data/test/ignore")).unwrap();
+        let f = fs::File::open(src_dir.join("data/test/ignore")).unwrap();
         let r = io::BufReader::new(f);
         for ln in r.lines() {
             ignores.insert(ln.unwrap().trim_end().to_string());
diff --git a/rcdom/tests/xml-tokenizer.rs b/rcdom/tests/xml-tokenizer.rs
index 79f8fc77..cbdf10c3 100644
--- a/rcdom/tests/xml-tokenizer.rs
+++ b/rcdom/tests/xml-tokenizer.rs
@@ -9,11 +9,10 @@
 
 use serde_json::{Map, Value};
 use std::borrow::Cow::Borrowed;
-use std::env;
 use std::ffi::OsStr;
 use std::io::Read;
-use std::mem::replace;
 use std::path::Path;
+use std::{env, mem};
 
 use rustc_test::{DynTestFn, DynTestName, TestDesc, TestDescAndFn};
 use util::find_tests::foreach_xml5lib_test;
@@ -51,7 +50,7 @@ fn splits(s: &str, n: usize) -> Vec<Vec<StrTendril>> {
         }
     }
 
-    out.extend(splits(s, n - 1).into_iter());
+    out.extend(splits(s, n - 1));
     out
 }
 
@@ -66,7 +65,7 @@ impl TokenLogger {
         TokenLogger {
             tokens: vec![],
             current_str: StrTendril::new(),
-            exact_errors: exact_errors,
+            exact_errors,
         }
     }
 
@@ -78,7 +77,7 @@ impl TokenLogger {
 
     fn finish_str(&mut self) {
         if self.current_str.len() > 0 {
-            let s = replace(&mut self.current_str, StrTendril::new());
+            let s = mem::take(&mut self.current_str);
             self.tokens.push(CharacterTokens(s));
         }
     }
@@ -129,13 +128,13 @@ impl TokenSink for TokenLogger {
 fn tokenize_xml(input: Vec<StrTendril>, opts: XmlTokenizerOpts) -> Vec<Token> {
     let sink = TokenLogger::new(opts.exact_errors);
     let mut tok = XmlTokenizer::new(sink, opts);
-    let mut buf = BufferQueue::new();
+    let mut buf = BufferQueue::default();
 
     for chunk in input.into_iter() {
         buf.push_back(chunk);
-        let _ = tok.feed(&mut buf);
+        tok.feed(&mut buf);
     }
-    let _ = tok.feed(&mut buf);
+    tok.feed(&mut buf);
     tok.end();
     tok.sink.get_tokens()
 }
@@ -145,9 +144,9 @@ trait JsonExt: Sized {
     fn get_tendril(&self) -> StrTendril;
     fn get_nullable_tendril(&self) -> Option<StrTendril>;
     fn get_bool(&self) -> bool;
-    fn get_obj<'t>(&'t self) -> &'t Map<String, Self>;
-    fn get_list<'t>(&'t self) -> &'t Vec<Self>;
-    fn find<'t>(&'t self, key: &str) -> &'t Self;
+    fn get_obj(&self) -> &Map<String, Self>;
+    fn get_list(&self) -> &Vec<Self>;
+    fn find(&self, key: &str) -> &Self;
 }
 
 impl JsonExt for Value {
@@ -180,21 +179,21 @@ impl JsonExt for Value {
         }
     }
 
-    fn get_obj<'t>(&'t self) -> &'t Map<String, Value> {
-        match *self {
-            Value::Object(ref m) => &*m,
+    fn get_obj(&self) -> &Map<String, Value> {
+        match self {
+            Value::Object(m) => m,
             _ => panic!("Value::get_obj: not an Object"),
         }
     }
 
-    fn get_list<'t>(&'t self) -> &'t Vec<Value> {
-        match *self {
-            Value::Array(ref m) => m,
+    fn get_list(&self) -> &Vec<Value> {
+        match self {
+            Value::Array(m) => m,
             _ => panic!("Value::get_list: not an Array"),
         }
     }
 
-    fn find<'t>(&'t self, key: &str) -> &'t Value {
+    fn find(&self, key: &str) -> &Value {
         self.get_obj().get(&key.to_string()).unwrap()
     }
 }
@@ -296,7 +295,7 @@ fn mk_xml_test(
                 // Also clone opts.  If we don't, we get the wrong
                 // result but the compiler doesn't catch it!
                 // Possibly mozilla/rust#12223.
-                let output = tokenize_xml(input.clone(), opts.clone());
+                let output = tokenize_xml(input.clone(), opts);
                 let expect = json_to_tokens(&expect, opts.exact_errors);
                 if output != expect {
                     panic!(
@@ -321,9 +320,8 @@ fn mk_xml_tests(tests: &mut Vec<TestDescAndFn>, filename: &str, js: &Value) {
     for state in state_overrides.into_iter() {
         for &exact_errors in [false, true].iter() {
             let mut newdesc = desc.clone();
-            match state {
-                Some(s) => newdesc = format!("{} (in state {:?})", newdesc, s),
-                None => (),
+            if let Some(s) = state {
+                newdesc = format!("{} (in state {:?})", newdesc, s)
             };
             if exact_errors {
                 newdesc = format!("{} (exact errors)", newdesc);
@@ -334,7 +332,7 @@ fn mk_xml_tests(tests: &mut Vec<TestDescAndFn>, filename: &str, js: &Value) {
                 String::from(input),
                 expect.clone(),
                 XmlTokenizerOpts {
-                    exact_errors: exact_errors,
+                    exact_errors,
                     initial_state: state,
 
                     // Not discarding a BOM is what the test suite expects; see
@@ -356,23 +354,17 @@ fn tests(src_dir: &Path) -> Vec<TestDescAndFn> {
         OsStr::new("test"),
         |path, mut file| {
             let mut s = String::new();
-            file.read_to_string(&mut s)
-                .ok()
-                .expect("file reading error");
-            let js: Value = serde_json::from_str(&s).ok().expect("json parse error");
-
-            match js["tests"] {
-                Value::Array(ref lst) => {
-                    for test in lst.iter() {
-                        mk_xml_tests(
-                            &mut tests,
-                            path.file_name().unwrap().to_str().unwrap(),
-                            test,
-                        );
-                    }
-                },
-
-                _ => (),
+            file.read_to_string(&mut s).expect("file reading error");
+            let js: Value = serde_json::from_str(&s).expect("json parse error");
+
+            if let Value::Array(ref lst) = js["tests"] {
+                for test in lst.iter() {
+                    mk_xml_tests(
+                        &mut tests,
+                        path.file_name().unwrap().to_str().unwrap(),
+                        test,
+                    );
+                }
             }
         },
     );
diff --git a/rcdom/tests/xml-tree-builder.rs b/rcdom/tests/xml-tree-builder.rs
index 03c558a4..98365c75 100644
--- a/rcdom/tests/xml-tree-builder.rs
+++ b/rcdom/tests/xml-tree-builder.rs
@@ -13,10 +13,8 @@ use rustc_test::{DynTestFn, DynTestName, TestDesc, TestDescAndFn};
 use std::collections::{HashMap, HashSet};
 use std::ffi::OsStr;
 use std::io::BufRead;
-use std::iter::repeat;
-use std::mem::replace;
 use std::path::Path;
-use std::{env, fs, io};
+use std::{env, fs, io, iter, mem};
 use util::find_tests::foreach_xml5lib_test;
 use xml5ever::driver::parse_document;
 use xml5ever::tendril::TendrilSink;
@@ -35,14 +33,14 @@ fn parse_tests<It: Iterator<Item = String>>(mut lines: It) -> Vec<HashMap<String
         match key.take() {
             None => (),
             Some(key) => {
-                assert!(test.insert(key, replace(&mut val, String::new())).is_none());
+                assert!(test.insert(key, mem::take(&mut val)).is_none());
             }
         }
     ));
 
     macro_rules! finish_test ( () => (
         if !test.is_empty() {
-            tests.push(replace(&mut test, HashMap::new()));
+            tests.push(mem::take(&mut test));
         }
     ));
 
@@ -50,12 +48,12 @@ fn parse_tests<It: Iterator<Item = String>>(mut lines: It) -> Vec<HashMap<String
         match lines.next() {
             None => break,
             Some(line) => {
-                if line.starts_with("#") {
+                if let Some(rest) = line.strip_prefix('#') {
                     finish_val!();
                     if line == "#data" {
                         finish_test!();
                     }
-                    key = Some(line[1..].to_string());
+                    key = Some(rest.to_string());
                 } else {
                     val.push_str(&line);
                     val.push('\n');
@@ -70,68 +68,61 @@ fn parse_tests<It: Iterator<Item = String>>(mut lines: It) -> Vec<HashMap<String
 }
 
 fn serialize(buf: &mut String, indent: usize, handle: Handle) {
-    buf.push_str("|");
-    buf.push_str(&repeat(" ").take(indent).collect::<String>());
+    buf.push('|');
+    buf.extend(iter::repeat(" ").take(indent));
 
     let node = handle;
-    match node.data {
+    match &node.data {
         NodeData::Document => panic!("should not reach Document"),
 
         NodeData::Doctype {
-            ref name,
-            ref public_id,
-            ref system_id,
+            name,
+            public_id,
+            system_id,
         } => {
             buf.push_str("<!DOCTYPE ");
-            buf.push_str(&name);
+            buf.push_str(name);
             if !public_id.is_empty() || !system_id.is_empty() {
                 buf.push_str(&format!(" \"{}\" \"{}\"", public_id, system_id));
             }
             buf.push_str(">\n");
         },
 
-        NodeData::Text { ref contents } => {
-            buf.push_str("\"");
+        NodeData::Text { contents } => {
+            buf.push('"');
             buf.push_str(&contents.borrow());
             buf.push_str("\"\n");
         },
 
-        NodeData::ProcessingInstruction {
-            ref target,
-            ref contents,
-        } => {
+        NodeData::ProcessingInstruction { target, contents } => {
             buf.push_str("<?");
-            buf.push_str(&target);
-            buf.push_str(" ");
-            buf.push_str(&contents);
+            buf.push_str(target);
+            buf.push(' ');
+            buf.push_str(contents);
             buf.push_str("?>\n");
         },
 
-        NodeData::Comment { ref contents } => {
+        NodeData::Comment { contents } => {
             buf.push_str("<!-- ");
-            buf.push_str(&contents);
+            buf.push_str(contents);
             buf.push_str(" -->\n");
         },
 
-        NodeData::Element {
-            ref name,
-            ref attrs,
-            ..
-        } => {
-            buf.push_str("<");
+        NodeData::Element { name, attrs, .. } => {
+            buf.push('<');
 
             if name.ns != ns!() {
-                buf.push_str("{");
-                buf.push_str(&*name.ns);
-                buf.push_str("}");
+                buf.push('{');
+                buf.push_str(&name.ns);
+                buf.push('}');
             };
 
-            if let Some(ref prefix) = name.prefix {
-                buf.push_str(&*prefix);
-                buf.push_str(":");
+            if let Some(prefix) = &name.prefix {
+                buf.push_str(prefix);
+                buf.push(':');
             }
 
-            buf.push_str(&*name.local);
+            buf.push_str(&name.local);
             buf.push_str(">\n");
 
             let mut attrs = attrs.borrow().clone();
@@ -139,18 +130,18 @@ fn serialize(buf: &mut String, indent: usize, handle: Handle) {
             // FIXME: sort by UTF-16 code unit
 
             for attr in attrs.into_iter() {
-                buf.push_str("|");
-                buf.push_str(&repeat(" ").take(indent + 2).collect::<String>());
+                buf.push('|');
+                buf.extend(iter::repeat(" ").take(indent + 2));
 
-                if &*attr.name.ns != "" {
-                    buf.push_str("{");
-                    buf.push_str(&*attr.name.ns);
-                    buf.push_str("}");
+                if !attr.name.ns.is_empty() {
+                    buf.push('{');
+                    buf.push_str(&attr.name.ns);
+                    buf.push('}');
                 }
 
                 if let Some(attr_prefix) = attr.name.prefix {
-                    buf.push_str(&*attr_prefix);
-                    buf.push_str(":");
+                    buf.push_str(&attr_prefix);
+                    buf.push(':');
                 }
 
                 buf.push_str(&format!("{}=\"{}\"\n", attr.name.local, attr.value));
@@ -164,7 +155,7 @@ fn serialize(buf: &mut String, indent: usize, handle: Handle) {
 }
 
 // Ignore tests containing these strings; we don't support these features yet.
-static IGNORE_SUBSTRS: &'static [&'static str] = &["<template"];
+static IGNORE_SUBSTRS: &[&str] = &["<template"];
 
 fn make_xml_test(
     tests: &mut Vec<TestDescAndFn>,
@@ -185,7 +176,7 @@ fn make_xml_test(
 
     tests.push(TestDescAndFn {
         desc: TestDesc {
-            ignore: ignore,
+            ignore,
             ..TestDesc::new(DynTestName(name))
         },
         testfn: DynTestFn(Box::new(move || {
@@ -218,7 +209,7 @@ fn tests(src_dir: &Path, ignores: &HashSet<String>) -> Vec<TestDescAndFn> {
         OsStr::new("dat"),
         |path, file| {
             let buf = io::BufReader::new(file);
-            let lines = buf.lines().map(|res| res.ok().expect("couldn't read"));
+            let lines = buf.lines().map(|res| res.expect("couldn't read"));
             let data = parse_tests(lines);
 
             for (i, test) in data.into_iter().enumerate() {
@@ -240,7 +231,7 @@ fn main() {
     let args: Vec<_> = env::args().collect();
     let src_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
     let mut ignores = HashSet::new();
-    if let Ok(f) = fs::File::open(&src_dir.join("data/test/ignore")) {
+    if let Ok(f) = fs::File::open(src_dir.join("data/test/ignore")) {
         let r = io::BufReader::new(f);
         for ln in r.lines() {
             ignores.insert(ln.unwrap().trim_end().to_string());