Bug 1625660 - Update the wat crate to 1.0.13. r=rhunt
☠☠ backed out by ed3f1aeefd43 ☠ ☠
authorLars T Hansen <lhansen@mozilla.com>
Mon, 30 Mar 2020 16:16:36 +0000
changeset 521117 64918c6e2f834f6e2f26cc9493e8f50c15c01124
parent 521116 bb399a3564195c801df8699108e4bb8f72b25a1a
child 521118 91df3576d1e36ae9eacfe938990ba87d715210df
push id111490
push userlhansen@mozilla.com
push dateMon, 30 Mar 2020 17:34:25 +0000
treeherderautoland@64918c6e2f83 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrhunt
bugs1625660
milestone76.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1625660 - Update the wat crate to 1.0.13. r=rhunt Differential Revision: https://phabricator.services.mozilla.com/D68815
Cargo.lock
js/src/wasm/rust/Cargo.toml
third_party/rust/wast/.cargo-checksum.json
third_party/rust/wast/Cargo.toml
third_party/rust/wast/src/ast/expr.rs
third_party/rust/wast/src/ast/module.rs
third_party/rust/wast/src/ast/token.rs
third_party/rust/wast/src/ast/wast.rs
third_party/rust/wast/src/binary.rs
third_party/rust/wast/src/parser.rs
third_party/rust/wast/src/resolve/names.rs
third_party/rust/wat/.cargo-checksum.json
third_party/rust/wat/Cargo.lock
third_party/rust/wat/Cargo.toml
third_party/rust/wat/tests/regression/annotations.wast
third_party/rust/wat/tests/wabt.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4837,28 +4837,28 @@ checksum = "073da89bf1c84db000dd68ce660c
 [[package]]
 name = "wasmparser"
 version = "0.51.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "aeb1956b19469d1c5e63e459d29e7b5aa0f558d9f16fcef09736f8a265e6c10a"
 
 [[package]]
 name = "wast"
-version = "11.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df4d67ba9266f4fcaf2e8a1afadc5e2a959e51aecc07b1ecbdf85a6ddaf08bde"
+version = "12.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0615ba420811bcda39cf80e8a1bd75997aec09222bda35165920a07ef15cc695"
 dependencies = [
  "leb128",
 ]
 
 [[package]]
 name = "wat"
-version = "1.0.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a9400dc1c8512087b2d974b1b9b0a6c4e6e26e7e8acf629e3e351165a1ed301"
+version = "1.0.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "095f615fbfcae695e3a4cea7d9f02f70561c81274c0142f45a12bf1e154d08bd"
 dependencies = [
  "wast",
 ]
 
 [[package]]
 name = "webdriver"
 version = "0.40.2"
 dependencies = [
--- a/js/src/wasm/rust/Cargo.toml
+++ b/js/src/wasm/rust/Cargo.toml
@@ -4,10 +4,10 @@ version = "0.1.0"
 authors = ["The Spidermonkey developers"]
 edition = "2018"
 
 [lib]
 crate-type = ["rlib"]
 name = "wasm_rust"
 
 [dependencies]
-wat = { version = "1.0.12" }
+wat = { version = "1.0.13" }
 wasmparser = { version = "0.48.2" }
--- a/third_party/rust/wast/.cargo-checksum.json
+++ b/third_party/rust/wast/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"024dfda3c577aff8df638038afab60592e156745cb30f633e2964ee20c4821db","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"ad8c69458e8f19f6a796d1d791d15f014a045ed11616fe27d987aa37b49599a0","src/ast/assert_expr.rs":"0f6310eccb8a602722a13b2230cfa56dbc470e4c0ba5eb300237a81dc1bfff43","src/ast/custom.rs":"4c926ba719013537696e075c9acd8043da92a833cd28b0d843abcbfb71080fc3","src/ast/event.rs":"18f5106a87635d50b5f3b13fedd08247d3eb8158df454790151acadd41d1e0ab","src/ast/export.rs":"f296bd3238c7f9886f626d619d3a41ff0797bd51cb7bec7053278a62d8cb5355","src/ast/expr.rs":"c8ef762bbea3135d8f6a1d652d1d55ef97bfa03c9bda4a28dfedeb1d2bd84741","src/ast/func.rs":"149d947957414548b65739212a2cf1362f0ec9ecdda517653ae83949aa8a89f5","src/ast/gc.rs":"90049f183f359158e6664e7a038ee50082b2e7935450a799f9edce0d4e6a828c","src/ast/global.rs":"41b617886012277e7377600047611b78564c2c594d8c0792de1509b89676244f","src/ast/import.rs":"53f39569b8486cd5fde6b3a826bc7dc221fc925afa043e45a0a1550987332ba7","src/ast/memory.rs":"836135f8f5a7bffa90ddaad1a862b9133d9c0e680b63736daa3e2377c23cb785","src/ast/mod.rs":"f6cf3886ca07283a4f38b2524d00d46d96b55327c8c6d9dd1e2e30a2d9acaad5","src/ast/module.rs":"9f34d3d945c71fef57bb38d5ec129d2fd5787b95bbffff76cc58a724f3e70aed","src/ast/table.rs":"74e9a0588515dd039c76e8e775470ee752607f06ece3e05c7d6a4141adfb89ea","src/ast/token.rs":"0bceed5587ca46d7c5c6865fb04e2afc0eba05d503bc9055840ce7d88456a8b4","src/ast/types.rs":"12261956028dade22d921737cd90165d885bfc00d8a01d841486b511611e281e","src/ast/wast.rs":"e2a69b8fd2ff84f7f69934d1e4c7651645efd8d90d5a3ee4762576f5d5dfee29","src/binary.rs":"23fc7334a9daec9747aa88eddfeca12af99ef8f3093cafba1f09152d2e319cc8","src/lexer.rs":"1e62516a22ca89aa9510d255c264a27776a86c831b4c22a1fd00d20272e7b96c","src/lib.rs":"5fc7614c3d4a89f5fcac328d4a82cecaa445e0620bdf6bd55308cb1ead73d297","src/parser.rs":"eb0a681be02f27e1ecda97f4d8a2a0336e23be9d30a1d66a36d226ef019a4c58","src/resolve/expand.rs":"f7ecf82bb00d7c770f78f5582ec5427c25189ff11943c052572ffab2f996b12c","src/resolve/mod.rs":"916ce2c88f633e36609767f3bccfabef4438586e98475cc8f0e4cbea5d2caaf4","src/resolve/names.rs":"82b990dab9c8f58f5e20ccff1d03a90e848727b3a33b1ad1434c43c5dc06869d","src/resolve/tyexpand.rs":"69701f2fc566fd5da4b253643a91e3048dd3c41795d5fed6ac94a386ec01947a"},"package":"df4d67ba9266f4fcaf2e8a1afadc5e2a959e51aecc07b1ecbdf85a6ddaf08bde"}
\ No newline at end of file
+{"files":{"Cargo.toml":"2fcd4e5b104f6cd5f0d5aa528d37f95cf787004b836acae5be5858938e6d629f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"ad8c69458e8f19f6a796d1d791d15f014a045ed11616fe27d987aa37b49599a0","src/ast/assert_expr.rs":"0f6310eccb8a602722a13b2230cfa56dbc470e4c0ba5eb300237a81dc1bfff43","src/ast/custom.rs":"4c926ba719013537696e075c9acd8043da92a833cd28b0d843abcbfb71080fc3","src/ast/event.rs":"18f5106a87635d50b5f3b13fedd08247d3eb8158df454790151acadd41d1e0ab","src/ast/export.rs":"f296bd3238c7f9886f626d619d3a41ff0797bd51cb7bec7053278a62d8cb5355","src/ast/expr.rs":"d83bb97f2588c6086e34d0aa060e99a528fdda0ca9c7aa83c6fa2a7125b8b8e9","src/ast/func.rs":"149d947957414548b65739212a2cf1362f0ec9ecdda517653ae83949aa8a89f5","src/ast/gc.rs":"90049f183f359158e6664e7a038ee50082b2e7935450a799f9edce0d4e6a828c","src/ast/global.rs":"41b617886012277e7377600047611b78564c2c594d8c0792de1509b89676244f","src/ast/import.rs":"53f39569b8486cd5fde6b3a826bc7dc221fc925afa043e45a0a1550987332ba7","src/ast/memory.rs":"836135f8f5a7bffa90ddaad1a862b9133d9c0e680b63736daa3e2377c23cb785","src/ast/mod.rs":"f6cf3886ca07283a4f38b2524d00d46d96b55327c8c6d9dd1e2e30a2d9acaad5","src/ast/module.rs":"65abd96046703915c84fee8b6d5bd6e2782450f59582ba08939660fc8df5de2e","src/ast/table.rs":"74e9a0588515dd039c76e8e775470ee752607f06ece3e05c7d6a4141adfb89ea","src/ast/token.rs":"cdaaa6f50a9868ed7d0ec7088447ba94e3df5c81d38bc471c55d0968c249f73c","src/ast/types.rs":"12261956028dade22d921737cd90165d885bfc00d8a01d841486b511611e281e","src/ast/wast.rs":"9e64d00baf809d09181a06073a3fa9ac5907ac8248336cfd2089735d017075e3","src/binary.rs":"becf5819190a2411dbe01caa4a646a76c0a6db5e0c4bc8f3029cbb6bd9434914","src/lexer.rs":"1e62516a22ca89aa9510d255c264a27776a86c831b4c22a1fd00d20272e7b96c","src/lib.rs":"5fc7614c3d4a89f5fcac328d4a82cecaa445e0620bdf6bd55308cb1ead73d297","src/parser.rs":"f62dc8251809b395820cd511071e864bf2748db60b37b16ec0d130a17ead7d5d","src/resolve/expand.rs":"f7ecf82bb00d7c770f78f5582ec5427c25189ff11943c052572ffab2f996b12c","src/resolve/mod.rs":"916ce2c88f633e36609767f3bccfabef4438586e98475cc8f0e4cbea5d2caaf4","src/resolve/names.rs":"cf7eeabe4ae525d387292f48184e4a28a1b6e3d9732ab35627a034f159b29cc5","src/resolve/tyexpand.rs":"69701f2fc566fd5da4b253643a91e3048dd3c41795d5fed6ac94a386ec01947a"},"package":"0615ba420811bcda39cf80e8a1bd75997aec09222bda35165920a07ef15cc695"}
\ No newline at end of file
--- a/third_party/rust/wast/Cargo.toml
+++ b/third_party/rust/wast/Cargo.toml
@@ -8,17 +8,17 @@
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 edition = "2018"
 name = "wast"
-version = "11.0.0"
+version = "12.0.0"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 description = "Customizable Rust parsers for the WebAssembly Text formats WAT and WAST\n"
 homepage = "https://github.com/bytecodealliance/wat/tree/master/crates/wast"
 documentation = "https://docs.rs/wast"
 readme = "README.md"
 license = "Apache-2.0 WITH LLVM-exception"
 repository = "https://github.com/bytecodealliance/wat/tree/master/crates/wast"
 [dependencies.leb128]
--- a/third_party/rust/wast/src/ast/expr.rs
+++ b/third_party/rust/wast/src/ast/expr.rs
@@ -832,16 +832,20 @@ instructions! {
         I32x4Load16x4U(MemArg<8>) : [0xfd, 0xd5] : "i32x4.load16x4_u",
         I64x2Load32x2S(MemArg<8>) : [0xfd, 0xd6] : "i64x2.load32x2_s",
         I64x2Load32x2U(MemArg<8>) : [0xfd, 0xd7] : "i64x2.load32x2_u",
         V128Andnot : [0xfd, 0xd8] : "v128.andnot",
 
         I8x16AvgrU : [0xfd, 0xd9] : "i8x16.avgr_u",
         I16x8AvgrU : [0xfd, 0xda] : "i16x8.avgr_u",
 
+        I8x16Abs : [0xfd, 0xe1] : "i8x16.abs",
+        I16x8Abs : [0xfd, 0xe2] : "i16x8.abs",
+        I32x4Abs : [0xfd, 0xe3] : "i32x4.abs",
+
         Try(BlockType<'a>) : [0x06] : "try",
         Catch : [0x07] : "catch",
         Throw(ast::Index<'a>) : [0x08] : "throw",
         Rethrow : [0x09] : "rethrow",
         BrOnExn(BrOnExn<'a>) : [0x0a] : "br_on_exn",
     }
 }
 
--- a/third_party/rust/wast/src/ast/module.rs
+++ b/third_party/rust/wast/src/ast/module.rs
@@ -10,22 +10,22 @@ pub use crate::resolve::Names;
 /// of s-expressions that are module fields.
 pub struct Wat<'a> {
     #[allow(missing_docs)]
     pub module: Module<'a>,
 }
 
 impl<'a> Parse<'a> for Wat<'a> {
     fn parse(parser: Parser<'a>) -> Result<Self> {
+        if !parser.has_tokens() {
+            return Err(parser.error("expected at least one module field"));
+        }
         let _r = parser.register_annotation("custom");
         let module = if !parser.peek2::<kw::module>() {
             let fields = ModuleField::parse_remaining(parser)?;
-            if fields.is_empty() {
-                return Err(parser.error("expected at least one module field"));
-            }
             Module {
                 span: ast::Span { offset: 0 },
                 id: None,
                 name: None,
                 kind: ModuleKind::Text(fields),
             }
         } else {
             parser.parens(|parser| parser.parse())?
--- a/third_party/rust/wast/src/ast/token.rs
+++ b/third_party/rust/wast/src/ast/token.rs
@@ -1,17 +1,17 @@
+use crate::ast::annotation;
 use crate::lexer::FloatVal;
 use crate::parser::{Cursor, Parse, Parser, Peek, Result};
 use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::str;
-use crate::ast::annotation;
 
 /// A position in the original source stream, used to render errors.
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)]
 pub struct Span {
     pub(crate) offset: usize,
 }
 
 impl Span {
     /// Returns the line/column information of this span within `text`.
     /// Line and column numbers are 0-indexed. User presentation is typically
     /// 1-indexed, but 0-indexing is appropriate for internal use with
@@ -230,17 +230,17 @@ impl Peek for &'_ [u8] {
 
     fn display() -> &'static str {
         "string"
     }
 }
 
 impl<'a> Parse<'a> for &'a str {
     fn parse(parser: Parser<'a>) -> Result<Self> {
-        str::from_utf8(parser.parse()?).map_err(|_| parser.error("invalid UTF-8 encoding"))
+        str::from_utf8(parser.parse()?).map_err(|_| parser.error("malformed UTF-8 encoding"))
     }
 }
 
 impl Parse<'_> for String {
     fn parse(parser: Parser<'_>) -> Result<Self> {
         Ok(<&str>::parse(parser)?.to_string())
     }
 }
--- a/third_party/rust/wast/src/ast/wast.rs
+++ b/third_party/rust/wast/src/ast/wast.rs
@@ -48,16 +48,20 @@ impl Peek for WastDirectiveToken {
 
 /// The different kinds of directives found in a `*.wast` file.
 ///
 /// It's not entirely clear to me what all of these are per se, but they're only
 /// really interesting to test harnesses mostly.
 #[allow(missing_docs)]
 pub enum WastDirective<'a> {
     Module(ast::Module<'a>),
+    QuoteModule {
+        span: ast::Span,
+        source: Vec<&'a [u8]>,
+    },
     AssertMalformed {
         span: ast::Span,
         module: QuoteModule<'a>,
         message: &'a str,
     },
     AssertInvalid {
         span: ast::Span,
         module: ast::Module<'a>,
@@ -93,31 +97,42 @@ pub enum WastDirective<'a> {
 
 impl WastDirective<'_> {
     /// Returns the location in the source that this directive was defined at
     pub fn span(&self) -> ast::Span {
         match self {
             WastDirective::Module(m) => m.span,
             WastDirective::AssertMalformed { span, .. }
             | WastDirective::Register { span, .. }
+            | WastDirective::QuoteModule{ span, .. }
             | WastDirective::AssertTrap { span, .. }
             | WastDirective::AssertReturn { span, .. }
             | WastDirective::AssertExhaustion { span, .. }
             | WastDirective::AssertUnlinkable { span, .. }
             | WastDirective::AssertInvalid { span, .. } => *span,
             WastDirective::Invoke(i) => i.span,
         }
     }
 }
 
 impl<'a> Parse<'a> for WastDirective<'a> {
     fn parse(parser: Parser<'a>) -> Result<Self> {
         let mut l = parser.lookahead1();
         if l.peek::<kw::module>() {
-            Ok(WastDirective::Module(parser.parse()?))
+            if parser.peek2::<kw::quote>() {
+                parser.parse::<kw::module>()?;
+                let span = parser.parse::<kw::quote>()?.0;
+                let mut source = Vec::new();
+                while !parser.is_empty() {
+                    source.push(parser.parse()?);
+                }
+                Ok(WastDirective::QuoteModule { span, source })
+            } else {
+                Ok(WastDirective::Module(parser.parse()?))
+            }
         } else if l.peek::<kw::assert_malformed>() {
             let span = parser.parse::<kw::assert_malformed>()?.0;
             Ok(WastDirective::AssertMalformed {
                 span,
                 module: parser.parens(|p| p.parse())?,
                 message: parser.parse()?,
             })
         } else if l.peek::<kw::assert_invalid>() {
@@ -291,17 +306,17 @@ impl<'a> Parse<'a> for WastInvoke<'a> {
             args,
         })
     }
 }
 
 #[allow(missing_docs)]
 pub enum QuoteModule<'a> {
     Module(ast::Module<'a>),
-    Quote(Vec<&'a str>),
+    Quote(Vec<&'a [u8]>),
 }
 
 impl<'a> Parse<'a> for QuoteModule<'a> {
     fn parse(parser: Parser<'a>) -> Result<Self> {
         if parser.peek2::<kw::quote>() {
             parser.parse::<kw::module>()?;
             parser.parse::<kw::quote>()?;
             let mut src = Vec::new();
--- a/third_party/rust/wast/src/binary.rs
+++ b/third_party/rust/wast/src/binary.rs
@@ -55,18 +55,18 @@ pub fn encode(module: &Module<'_>) -> Ve
         e.section(42, gc);
     }
     e.section_list(1, Type, &types);
     e.section_list(2, Import, &imports);
     let functys = funcs.iter().map(|f| &f.ty).collect::<Vec<_>>();
     e.section_list(3, Func, &functys);
     e.section_list(4, Table, &tables);
     e.section_list(5, Memory, &memories);
+    e.section_list(13, Event, &events);
     e.section_list(6, Global, &globals);
-    e.section_list(13, Event, &events);
     e.section_list(7, Export, &exports);
     e.custom_sections(Before(Start));
     if let Some(start) = start.get(0) {
         e.section(8, start);
     }
     e.custom_sections(After(Start));
     e.section_list(9, Elem, &elem);
     if contains_bulk_memory(&funcs) {
--- a/third_party/rust/wast/src/parser.rs
+++ b/third_party/rust/wast/src/parser.rs
@@ -324,27 +324,86 @@ impl ParseBuffer<'_> {
     /// # Errors
     ///
     /// Returns an error if `input` fails to lex.
     pub fn new(input: &str) -> Result<ParseBuffer<'_>> {
         let mut tokens = Vec::new();
         for token in Lexer::new(input) {
             tokens.push((token?, Cell::new(NextTokenAt::Unknown)));
         }
-        Ok(ParseBuffer {
+        let ret = ParseBuffer {
             tokens: tokens.into_boxed_slice(),
             cur: Cell::new(0),
             input,
             known_annotations: Default::default(),
-        })
+        };
+        ret.validate_annotations()?;
+        Ok(ret)
     }
 
     fn parser(&self) -> Parser<'_> {
         Parser { buf: self }
     }
+
+    // Validates that all annotations properly parse in that they have balanced
+    // delimiters. This is required since while parsing we generally skip
+    // annotations and there's no real opportunity to return a parse error.
+    fn validate_annotations(&self) -> Result<()> {
+        use crate::lexer::Source::*;
+        use crate::lexer::Token::*;
+        enum State {
+            None,
+            LParen,
+            Annotation { depth: usize, span: Span },
+        }
+        let mut state = State::None;
+        for token in self.tokens.iter() {
+            state = match (&token.0, state) {
+                // From nothing, a `(` starts the search for an annotation
+                (Token(LParen(_)), State::None) => State::LParen,
+                // ... otherwise in nothing we alwyas preserve that state.
+                (_, State::None) => State::None,
+
+                // If the previous state was an `LParen`, we may have an
+                // annotation if the next keyword is reserved
+                (Token(Reserved(s)), State::LParen) if s.starts_with("@") && s.len() > 0 => {
+                    let offset = self.input_pos(s);
+                    State::Annotation {
+                        span: Span { offset },
+                        depth: 1,
+                    }
+                }
+                // ... otherwise anything after an `LParen` kills the lparen
+                // state.
+                (_, State::LParen) => State::None,
+
+                // Once we're in an annotation we need to balance parentheses,
+                // so handle the depth changes.
+                (Token(LParen(_)), State::Annotation { span, depth }) => State::Annotation {
+                    span,
+                    depth: depth + 1,
+                },
+                (Token(RParen(_)), State::Annotation { depth: 1, .. }) => State::None,
+                (Token(RParen(_)), State::Annotation { span, depth }) => State::Annotation {
+                    span,
+                    depth: depth - 1,
+                },
+                // ... and otherwise all tokens are allowed in annotations.
+                (_, s @ State::Annotation { .. }) => s,
+            };
+        }
+        if let State::Annotation { span, .. } = state {
+            return Err(Error::new(span, format!("unclosed annotation")));
+        }
+        Ok(())
+    }
+
+    fn input_pos(&self, src: &str) -> usize {
+        src.as_ptr() as usize - self.input.as_ptr() as usize
+    }
 }
 
 impl<'a> Parser<'a> {
     /// Returns whether there are no more `Token` tokens to parse from this
     /// [`Parser`].
     ///
     /// This indicates that either we've reached the end of the input, or we're
     /// a sub-[`Parser`] inside of a parenthesized expression and we've hit the
@@ -354,16 +413,21 @@ impl<'a> Parser<'a> {
     /// and whitespace are not considered for whether this parser is empty.
     pub fn is_empty(self) -> bool {
         match self.cursor().advance_token() {
             Some(Token::RParen(_)) | None => true,
             Some(_) => false, // more tokens to parse!
         }
     }
 
+    pub(crate) fn has_tokens(self) -> bool {
+        let cursor = self.cursor();
+        cursor.cur < self.buf.tokens.len()
+    }
+
     /// Parses a `T` from this [`Parser`].
     ///
     /// This method has a trivial definition (it simply calls
     /// [`T::parse`](Parse::parse)) but is here for syntactic purposes. This is
     /// what you'll call 99% of the time in a [`Parse`] implementation in order
     /// to parse sub-items.
     ///
     /// Typically you always want to use `?` with the result of this method, you
@@ -630,20 +694,16 @@ impl<'a> Parser<'a> {
     pub fn error(self, msg: impl fmt::Display) -> Error {
         self.error_at(self.cursor().cur_span(), &msg)
     }
 
     fn error_at(self, span: Span, msg: &dyn fmt::Display) -> Error {
         Error::parse(span, self.buf.input, msg.to_string())
     }
 
-    fn input_pos(self, src: &'a str) -> usize {
-        src.as_ptr() as usize - self.buf.input.as_ptr() as usize
-    }
-
     /// Returns the span of the current token
     pub fn cur_span(&self) -> Span {
         self.cursor().cur_span()
     }
 
     /// Registers a new known annotation with this parser to allow parsing
     /// annotations with this name.
     ///
@@ -797,17 +857,17 @@ impl<'a> Parser<'a> {
 }
 
 impl<'a> Cursor<'a> {
     /// Returns the span of the next `Token` token.
     ///
     /// Does not take into account whitespace or comments.
     pub fn cur_span(&self) -> Span {
         let offset = match self.clone().advance_token() {
-            Some(t) => self.parser.input_pos(t.src()),
+            Some(t) => self.parser.buf.input_pos(t.src()),
             None => self.parser.buf.input.len(),
         };
         Span { offset }
     }
 
     /// Same as [`Parser::error`], but works with the current token in this
     /// [`Cursor`] instead.
     pub fn error(&self, msg: impl fmt::Display) -> Error {
--- a/third_party/rust/wast/src/resolve/names.rs
+++ b/third_party/rust/wast/src/resolve/names.rs
@@ -336,17 +336,17 @@ impl<'a> Namespace<'a> {
                 // This is technically incorrect behavior but no one is
                 // hopefully relying on this too much. To get the spec tests
                 // passing we ignore errors for elem/data segments. Once the
                 // spec tests get updated enough we can remove this condition
                 // and return errors for them.
                 if desc != "elem" && desc != "data" {
                     return Err(Error::new(
                         name.span(),
-                        format!("duplicate identifier for {}", desc),
+                        format!("duplicate {} identifier", desc),
                     ));
                 }
             }
         }
         self.count += 1;
         Ok(index)
     }
 
--- a/third_party/rust/wat/.cargo-checksum.json
+++ b/third_party/rust/wat/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"CODE_OF_CONDUCT.md":"a13aaaf393818bd91207c618724d3fb74944ca5161201822a84af951bcf655ef","Cargo.lock":"03517218971dc8dc3399b19f2e5b782e374cdebd8fb5e27ff24e879fe83588ad","Cargo.toml":"d4063537eb48a4d5fd385fbeee4502db8a4461aec2c520bee69e4ab1045895d1","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","ORG_CODE_OF_CONDUCT.md":"59c4c4435538496193cd73e89b2cd971d1011dba573158cf108abe6af6603e6b","README.md":"142745665518b56481bc91d609db9f055526b78bd88af85a969910b2089a67ab","SECURITY.md":"4d75afb09dd28eb5982e3a1f768ee398d90204669ceef3240a16b31dcf04148a","examples/wat2wasm.rs":"732f98472727c7a76bf08e0a9984032925b556cc357fbcd24007e00b9b80fb13","src/lib.rs":"03652351228b7f7a520f4e7f1e689fa34a37b8e5e0fc8367a167cc893cdbc449","tests/annotations.rs":"e7532c26a8671391576da77b13fb47d756a785a66945b1bc9b5621d5b6d7f2fc","tests/comments.rs":"0513f64a2094dfa422ce30b0e6ff2d266fd240be54be702120558ff62fd9e703","tests/parse-fail.rs":"0f1d5dffd1e6145105571222096703c89c4f4a46e25c848faa730f731155ea1c","tests/parse-fail/bad-name.wat":"e5ff5d410007779a0de6609ea4cc693f0e603d36a106b8f5098c1980dd9f8124","tests/parse-fail/bad-name.wat.err":"fb5638476c1b85d9d1919e3dbcb0f16f82d088a4a22d4a0c186d7b8ba6e1902b","tests/parse-fail/bad-name2.wat":"5a6a4d0c19e5f2e48d7cebf361aca9b9000b7ef0c652997b5bd0ffaadbd2ca8a","tests/parse-fail/bad-name2.wat.err":"129707cce45f1e3cfb3e2ca5c702182e16ca5eeb2dbb2edd0710b004a8e194a5","tests/parse-fail/bad-name3.wat":"c19133d738cc84e9174301f27d4050c216bda81c7e9918d03ac792b088f24a05","tests/parse-fail/bad-name3.wat.err":"84ea63d40a619a0782ec6e94fce63921188ab87b1c3875eacae0a371144ed83a","tests/parse-fail/block1.wat":"91e74b5c3b43be692e7a6ae74fbfa674c4b6197299eb61338c4eccf282b18f17","tests/parse-fail/block1.wat.err":"40a083ae496b41dee7002cc6a664c5db0c5e4d904ae03b815773a769c4493fca","tests/parse-fail/block2.wat":"a8c07b4c09d51f10a8ffdf19806586022552398701cd90eb6d09816d45df06e5","tests/parse-fail/block2.wat.err":"33c842ec5dd0f2fdd3a9ce8187dd98b45ceee48c12810802af809d05b9cd25e9","tests/parse-fail/block3.wat":"29739abfbabd7c55f00ddfbbb9ebd818b4a114ef2336d50514f0842f7e075905","tests/parse-fail/block3.wat.err":"fc667ae2e71a260f62a3c7393bc97272e7c0ff38b17594f4370847b8a5019060","tests/parse-fail/inline1.wat":"4e9767d67207aace2ac5e6f63a30e7510e4aa245ba35420539509e2254470272","tests/parse-fail/inline1.wat.err":"0143017a9825e518baa6009bae2c8d63520051dedd3437705bbe36b038a57f41","tests/parse-fail/string1.wat":"620d46d585ce94b382b5fde628c1399f3e562014b7a44af46e92f7bd045ca86e","tests/parse-fail/string1.wat.err":"fc53f3a1c4a65d8f25e5af51dec7699f45cecba114ca9c7871781bc70f664320","tests/parse-fail/string10.wat":"f7409dd45e153a1b11cb23e38f4ed87da12bedde38f8f0ccfe91037b0a4d97bd","tests/parse-fail/string10.wat.err":"ce677db5e37e0ed81ca357ed6b5edb21d85c27303ee194855bea7a88457efb6a","tests/parse-fail/string11.wat":"f6e0400b8c6a2014efa1ac676c567e140d8f86b5f4d5129773e6d67af537b615","tests/parse-fail/string11.wat.err":"4c6a550d29eda38a4e1bf7a589596f11655dc779479d7b8d466cfc53f815a742","tests/parse-fail/string12.wat":"23e30070eef22271651cce096a801fc4f79f3c37343c88bb8d2fc99b32d3b8b9","tests/parse-fail/string12.wat.err":"6e9a2ec052068bb234da56404087c03a66705846d82c095605530243fdce38f3","tests/parse-fail/string13.wat":"81a305b981159ee10e140749ea3220c9edaaff53605e63c21995de47382b5faf","tests/parse-fail/string13.wat.err":"ac0c51a1964abc1a1104858d16c124a4e5495705bc3adc0ab123cd0ba8ab9ee9","tests/parse-fail/string14.wat":"c45c2cc9f7afbfbd4be8e513106d22f7e5e817091448576c6bdf0701b81d95dd","tests/parse-fail/string14.wat.err":"cc3f6b0c093d878373ab29726b8ac0620b982a4842ec521b8661e864eed1ef05","tests/parse-fail/string15.wat":"b5e0d5ade40de53b2d767a132e28376bb8c7a6f6238c4d8c248ae717c41d7f1f","tests/parse-fail/string15.wat.err":"6549a0575bc228c2e12ec197e40bb5fdc665325a0242ca8a62e7a8dc5de6aee8","tests/parse-fail/string16.wat":"38c3688cee80a9d089d239aa06eb1d27c5364ad2bd270aca57d05997c20aa682","tests/parse-fail/string16.wat.err":"4274b3bbe4df4cf0373619b1fcd082d0c802990817d2aca26ed885168c80e489","tests/parse-fail/string2.wat":"1172964aed31537b8c466d1f045f3e756926e7b221f80b2aff4a9a6721ea0beb","tests/parse-fail/string2.wat.err":"4618d3b20a78a077337eb5d6cae14ac39d9853762f011fbd23cff8921618dbde","tests/parse-fail/string3.wat":"07e0fbcd6270c1db100917c151ee4ac3f935e4ee1b27bce3c453b22b4b74f4d6","tests/parse-fail/string3.wat.err":"84833a2f45216097a871ae88beb515ebeb8dab5d7c007ec98f1fcf1b20f7558d","tests/parse-fail/string4.wat":"c970da2051b0613bdd1de4664f10424e14f2ebabe604175d4fb9b763b37af577","tests/parse-fail/string4.wat.err":"406706594d305c560fabd66417ad4fc276939990b5e701bd9d13fc223d207219","tests/parse-fail/string5.wat":"386cf314bb05acdaaabdf4da1caf140167271a26bd08bf34c3a7427d4bc4431f","tests/parse-fail/string5.wat.err":"1e56b44a23a37b2b2ad05aa9dd7e1e18191b5cc22151f93bbcf9d618779a57bd","tests/parse-fail/string6.wat":"8f1fe2825ff96f2acee9130a7721f86fcc93c221baa9411bf1fb6f0870d38ccb","tests/parse-fail/string6.wat.err":"d55dfd84d94e893f167ae73b7a080aefb2bfb05cc8a1ec201c4d3066fb8549b4","tests/parse-fail/string7.wat":"b12f8c75313d7f834489d3c353422f90bc945b37139586446eda82e334a97cde","tests/parse-fail/string7.wat.err":"4cee0ca61992c249dd0faaf2529a073cf8deeb36111a3f69b43695e5682560a2","tests/parse-fail/string8.wat":"4c2e0e1f883bb4e8cba9313497ed792130e5848e62bde7716102788d7467be10","tests/parse-fail/string8.wat.err":"840c6def7c60dd7c2b7261549cab435ba78c9b3a937adf6d5d9595ff8af01c91","tests/parse-fail/string9.wat":"2b7670caed2b0688d535de6e4e416f35fa717cfbe096a6cc764a669085c8f52f","tests/parse-fail/string9.wat.err":"37b5a9c3af9631500f31f9e5e3efa821b8d96063c57d60fd01df6be6a5c323e1","tests/parse-fail/unbalanced.wat":"f664fbef53a0308f864ba496d38044eb90482636e32586512939d4930729f3fe","tests/parse-fail/unbalanced.wat.err":"aba579f7b836856e69afe05da8328aabe0643d94e369898e686aa7bb0b07e9c9","tests/recursive.rs":"ad8a2b07bf955121a7c9e326ed35f9b2bc56b440c8cc0bbde24d423a79945c1a","tests/regression.rs":"654e2b3103ee56f92f5b3b2985ceea5cecf5328420accef94359ccff074bd7f7","tests/regression/annotations.wast":"fda32272aea7a0eb64fc63abd7574c2ab61af6e4df9860d76a6252f5a88b8d1b","tests/regression/atomics.wat":"a108dfdf4e9bb2354d1e7fedcd5400895b83d61e2a490822126b052f817bb181","tests/regression/blockty.wat":"0065feef652cb61ac373872087e47f814a41123e186c330e4e528bd826aac65c","tests/regression/comments.wat":"4f53ed7a57032c2a46c3500fa67f67ee99fe11356ea4da7cbd5fb5f0622a87b7","tests/regression/dummy.wat":"3584af5e1ab0b1da09b5326237be4b178de0bb388d6093efd94e6aec56c20a74","tests/regression/duplicate.wast":"4165aa6a0b63f8da9711d8c87b0050bec7782c1a4d2458be650da62d97d95af6","tests/regression/float1.wat":"ac6d63cafac2fb07350b12cf9f51c103befd45bcad533fe219a243cb85bdcc33","tests/regression/fuzz1.wat":"040b9ab7057921fbd10f92ce19043127308a91d68a8bb36ab2693eb63e416127","tests/regression/gc-ref-global-import.wat":"119d5ce3b368c87fd60285afd05ecee0ef0708f431680ab27d07e4816facf9ca","tests/regression/gc-ref.wat":"e43018a372af39ee8fdab2b138521f99d9d2e20e471ce65162a4675cb798625e","tests/regression/gc-struct.wat":"0435930a8c0f32c7ca86c9729170c55f0d8eb16d8375c512acb6fc1c210f26b9","tests/regression/invalid-ty.wat":"c39a6983fbb6bb4a1d1707c9090b21722a045971d413061be1c8303fe08822a2","tests/regression/invalid-ty2.wat":"9ad7058686938288cc6eee992d1dc7297ef6bcfd5df4114b85e9a2538e80cf05","tests/regression/table-copy.wat":"21499c333dff7133939891ebd0a4c80cc9600e269f3e46b9045b653c95a650a7","tests/regression/table-init.wat":"5f63eba7e9459a58a7a2af48121d137747eefe22457bafa00c87c36772597a2d","tests/regression/table-opt-idx.wat":"de12f59cdb7e843bb08b6be3a5f8649d59d68eef9389650580ef607ebe710ef8","tests/wabt.rs":"1edb4ee7aa7084258878091c2f3c5c8413059da8e7ac00581ede8ffb3470a505"},"package":"9a9400dc1c8512087b2d974b1b9b0a6c4e6e26e7e8acf629e3e351165a1ed301"}
\ No newline at end of file
+{"files":{"CODE_OF_CONDUCT.md":"a13aaaf393818bd91207c618724d3fb74944ca5161201822a84af951bcf655ef","Cargo.lock":"a3a4aea3dfe0d543849ea6d9bfda9a4e88d286d989edd8fe4e327af3be17ce2d","Cargo.toml":"7eaa1d096d1099c808226ec9dbcde5e78eb0d130ebc0153ef158bccf82c3b791","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","ORG_CODE_OF_CONDUCT.md":"59c4c4435538496193cd73e89b2cd971d1011dba573158cf108abe6af6603e6b","README.md":"142745665518b56481bc91d609db9f055526b78bd88af85a969910b2089a67ab","SECURITY.md":"4d75afb09dd28eb5982e3a1f768ee398d90204669ceef3240a16b31dcf04148a","examples/wat2wasm.rs":"732f98472727c7a76bf08e0a9984032925b556cc357fbcd24007e00b9b80fb13","src/lib.rs":"03652351228b7f7a520f4e7f1e689fa34a37b8e5e0fc8367a167cc893cdbc449","tests/annotations.rs":"e7532c26a8671391576da77b13fb47d756a785a66945b1bc9b5621d5b6d7f2fc","tests/comments.rs":"0513f64a2094dfa422ce30b0e6ff2d266fd240be54be702120558ff62fd9e703","tests/parse-fail.rs":"0f1d5dffd1e6145105571222096703c89c4f4a46e25c848faa730f731155ea1c","tests/parse-fail/bad-name.wat":"e5ff5d410007779a0de6609ea4cc693f0e603d36a106b8f5098c1980dd9f8124","tests/parse-fail/bad-name.wat.err":"fb5638476c1b85d9d1919e3dbcb0f16f82d088a4a22d4a0c186d7b8ba6e1902b","tests/parse-fail/bad-name2.wat":"5a6a4d0c19e5f2e48d7cebf361aca9b9000b7ef0c652997b5bd0ffaadbd2ca8a","tests/parse-fail/bad-name2.wat.err":"129707cce45f1e3cfb3e2ca5c702182e16ca5eeb2dbb2edd0710b004a8e194a5","tests/parse-fail/bad-name3.wat":"c19133d738cc84e9174301f27d4050c216bda81c7e9918d03ac792b088f24a05","tests/parse-fail/bad-name3.wat.err":"84ea63d40a619a0782ec6e94fce63921188ab87b1c3875eacae0a371144ed83a","tests/parse-fail/block1.wat":"91e74b5c3b43be692e7a6ae74fbfa674c4b6197299eb61338c4eccf282b18f17","tests/parse-fail/block1.wat.err":"40a083ae496b41dee7002cc6a664c5db0c5e4d904ae03b815773a769c4493fca","tests/parse-fail/block2.wat":"a8c07b4c09d51f10a8ffdf19806586022552398701cd90eb6d09816d45df06e5","tests/parse-fail/block2.wat.err":"33c842ec5dd0f2fdd3a9ce8187dd98b45ceee48c12810802af809d05b9cd25e9","tests/parse-fail/block3.wat":"29739abfbabd7c55f00ddfbbb9ebd818b4a114ef2336d50514f0842f7e075905","tests/parse-fail/block3.wat.err":"fc667ae2e71a260f62a3c7393bc97272e7c0ff38b17594f4370847b8a5019060","tests/parse-fail/inline1.wat":"4e9767d67207aace2ac5e6f63a30e7510e4aa245ba35420539509e2254470272","tests/parse-fail/inline1.wat.err":"0143017a9825e518baa6009bae2c8d63520051dedd3437705bbe36b038a57f41","tests/parse-fail/string1.wat":"620d46d585ce94b382b5fde628c1399f3e562014b7a44af46e92f7bd045ca86e","tests/parse-fail/string1.wat.err":"fc53f3a1c4a65d8f25e5af51dec7699f45cecba114ca9c7871781bc70f664320","tests/parse-fail/string10.wat":"f7409dd45e153a1b11cb23e38f4ed87da12bedde38f8f0ccfe91037b0a4d97bd","tests/parse-fail/string10.wat.err":"ce677db5e37e0ed81ca357ed6b5edb21d85c27303ee194855bea7a88457efb6a","tests/parse-fail/string11.wat":"f6e0400b8c6a2014efa1ac676c567e140d8f86b5f4d5129773e6d67af537b615","tests/parse-fail/string11.wat.err":"4c6a550d29eda38a4e1bf7a589596f11655dc779479d7b8d466cfc53f815a742","tests/parse-fail/string12.wat":"23e30070eef22271651cce096a801fc4f79f3c37343c88bb8d2fc99b32d3b8b9","tests/parse-fail/string12.wat.err":"6e9a2ec052068bb234da56404087c03a66705846d82c095605530243fdce38f3","tests/parse-fail/string13.wat":"81a305b981159ee10e140749ea3220c9edaaff53605e63c21995de47382b5faf","tests/parse-fail/string13.wat.err":"ac0c51a1964abc1a1104858d16c124a4e5495705bc3adc0ab123cd0ba8ab9ee9","tests/parse-fail/string14.wat":"c45c2cc9f7afbfbd4be8e513106d22f7e5e817091448576c6bdf0701b81d95dd","tests/parse-fail/string14.wat.err":"cc3f6b0c093d878373ab29726b8ac0620b982a4842ec521b8661e864eed1ef05","tests/parse-fail/string15.wat":"b5e0d5ade40de53b2d767a132e28376bb8c7a6f6238c4d8c248ae717c41d7f1f","tests/parse-fail/string15.wat.err":"6549a0575bc228c2e12ec197e40bb5fdc665325a0242ca8a62e7a8dc5de6aee8","tests/parse-fail/string16.wat":"38c3688cee80a9d089d239aa06eb1d27c5364ad2bd270aca57d05997c20aa682","tests/parse-fail/string16.wat.err":"4274b3bbe4df4cf0373619b1fcd082d0c802990817d2aca26ed885168c80e489","tests/parse-fail/string2.wat":"1172964aed31537b8c466d1f045f3e756926e7b221f80b2aff4a9a6721ea0beb","tests/parse-fail/string2.wat.err":"4618d3b20a78a077337eb5d6cae14ac39d9853762f011fbd23cff8921618dbde","tests/parse-fail/string3.wat":"07e0fbcd6270c1db100917c151ee4ac3f935e4ee1b27bce3c453b22b4b74f4d6","tests/parse-fail/string3.wat.err":"84833a2f45216097a871ae88beb515ebeb8dab5d7c007ec98f1fcf1b20f7558d","tests/parse-fail/string4.wat":"c970da2051b0613bdd1de4664f10424e14f2ebabe604175d4fb9b763b37af577","tests/parse-fail/string4.wat.err":"406706594d305c560fabd66417ad4fc276939990b5e701bd9d13fc223d207219","tests/parse-fail/string5.wat":"386cf314bb05acdaaabdf4da1caf140167271a26bd08bf34c3a7427d4bc4431f","tests/parse-fail/string5.wat.err":"1e56b44a23a37b2b2ad05aa9dd7e1e18191b5cc22151f93bbcf9d618779a57bd","tests/parse-fail/string6.wat":"8f1fe2825ff96f2acee9130a7721f86fcc93c221baa9411bf1fb6f0870d38ccb","tests/parse-fail/string6.wat.err":"d55dfd84d94e893f167ae73b7a080aefb2bfb05cc8a1ec201c4d3066fb8549b4","tests/parse-fail/string7.wat":"b12f8c75313d7f834489d3c353422f90bc945b37139586446eda82e334a97cde","tests/parse-fail/string7.wat.err":"4cee0ca61992c249dd0faaf2529a073cf8deeb36111a3f69b43695e5682560a2","tests/parse-fail/string8.wat":"4c2e0e1f883bb4e8cba9313497ed792130e5848e62bde7716102788d7467be10","tests/parse-fail/string8.wat.err":"840c6def7c60dd7c2b7261549cab435ba78c9b3a937adf6d5d9595ff8af01c91","tests/parse-fail/string9.wat":"2b7670caed2b0688d535de6e4e416f35fa717cfbe096a6cc764a669085c8f52f","tests/parse-fail/string9.wat.err":"37b5a9c3af9631500f31f9e5e3efa821b8d96063c57d60fd01df6be6a5c323e1","tests/parse-fail/unbalanced.wat":"f664fbef53a0308f864ba496d38044eb90482636e32586512939d4930729f3fe","tests/parse-fail/unbalanced.wat.err":"aba579f7b836856e69afe05da8328aabe0643d94e369898e686aa7bb0b07e9c9","tests/recursive.rs":"ad8a2b07bf955121a7c9e326ed35f9b2bc56b440c8cc0bbde24d423a79945c1a","tests/regression.rs":"654e2b3103ee56f92f5b3b2985ceea5cecf5328420accef94359ccff074bd7f7","tests/regression/atomics.wat":"a108dfdf4e9bb2354d1e7fedcd5400895b83d61e2a490822126b052f817bb181","tests/regression/blockty.wat":"0065feef652cb61ac373872087e47f814a41123e186c330e4e528bd826aac65c","tests/regression/comments.wat":"4f53ed7a57032c2a46c3500fa67f67ee99fe11356ea4da7cbd5fb5f0622a87b7","tests/regression/dummy.wat":"3584af5e1ab0b1da09b5326237be4b178de0bb388d6093efd94e6aec56c20a74","tests/regression/duplicate.wast":"4165aa6a0b63f8da9711d8c87b0050bec7782c1a4d2458be650da62d97d95af6","tests/regression/float1.wat":"ac6d63cafac2fb07350b12cf9f51c103befd45bcad533fe219a243cb85bdcc33","tests/regression/fuzz1.wat":"040b9ab7057921fbd10f92ce19043127308a91d68a8bb36ab2693eb63e416127","tests/regression/gc-ref-global-import.wat":"119d5ce3b368c87fd60285afd05ecee0ef0708f431680ab27d07e4816facf9ca","tests/regression/gc-ref.wat":"e43018a372af39ee8fdab2b138521f99d9d2e20e471ce65162a4675cb798625e","tests/regression/gc-struct.wat":"0435930a8c0f32c7ca86c9729170c55f0d8eb16d8375c512acb6fc1c210f26b9","tests/regression/invalid-ty.wat":"c39a6983fbb6bb4a1d1707c9090b21722a045971d413061be1c8303fe08822a2","tests/regression/invalid-ty2.wat":"9ad7058686938288cc6eee992d1dc7297ef6bcfd5df4114b85e9a2538e80cf05","tests/regression/table-copy.wat":"21499c333dff7133939891ebd0a4c80cc9600e269f3e46b9045b653c95a650a7","tests/regression/table-init.wat":"5f63eba7e9459a58a7a2af48121d137747eefe22457bafa00c87c36772597a2d","tests/regression/table-opt-idx.wat":"de12f59cdb7e843bb08b6be3a5f8649d59d68eef9389650580ef607ebe710ef8","tests/wabt.rs":"e65492063f3fb099bd9c16b4ea5e3e5909b94dcd39fac76253970cc27f5815e9"},"package":"095f615fbfcae695e3a4cea7d9f02f70561c81274c0142f45a12bf1e154d08bd"}
\ No newline at end of file
--- a/third_party/rust/wat/Cargo.lock
+++ b/third_party/rust/wat/Cargo.lock
@@ -318,26 +318,26 @@ checksum = "cccddf32554fecc6acb585f82a32
 [[package]]
 name = "wasmparser"
 version = "0.51.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a40d24f114a3f24b459ec292019220cff6388673b4a2c0a11483665b599ef15c"
 
 [[package]]
 name = "wast"
-version = "11.0.0"
+version = "12.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df4d67ba9266f4fcaf2e8a1afadc5e2a959e51aecc07b1ecbdf85a6ddaf08bde"
+checksum = "0615ba420811bcda39cf80e8a1bd75997aec09222bda35165920a07ef15cc695"
 dependencies = [
  "leb128",
 ]
 
 [[package]]
 name = "wat"
-version = "1.0.12"
+version = "1.0.13"
 dependencies = [
  "anyhow",
  "getopts",
  "rayon",
  "serde_json",
  "tempfile",
  "wasmparser",
  "wast",
--- a/third_party/rust/wat/Cargo.toml
+++ b/third_party/rust/wat/Cargo.toml
@@ -8,17 +8,17 @@
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 edition = "2018"
 name = "wat"
-version = "1.0.12"
+version = "1.0.13"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 exclude = ["tests/wabt", "tests/testsuite"]
 description = "Rust parser for the WebAssembly Text format, WAT\n"
 homepage = "https://github.com/bytecodealliance/wat"
 documentation = "https://docs.rs/wat"
 readme = "README.md"
 license = "Apache-2.0 WITH LLVM-exception"
 repository = "https://github.com/bytecodealliance/wat"
@@ -30,17 +30,17 @@ overflow-checks = true
 [[test]]
 name = "wabt"
 harness = false
 
 [[test]]
 name = "parse-fail"
 harness = false
 [dependencies.wast]
-version = "11.0.0"
+version = "12.0.0"
 [dev-dependencies.anyhow]
 version = "1.0"
 
 [dev-dependencies.getopts]
 version = "0.2"
 
 [dev-dependencies.rayon]
 version = "1.0"
deleted file mode 100644
--- a/third_party/rust/wat/tests/regression/annotations.wast
+++ /dev/null
@@ -1,147 +0,0 @@
-(@a)
-(@aas-3!@$d-@#4)
-(@@) (@$) (@+) (@0) (@.) (@!$@#$23414@#$)
-(@a x y z)
-(@a x-y $yz "aa" -2 0.3 0x3)
-(@a x-y$yz"aa"-2)
-(@a block func module i32.add)
-(@a 0x 8q 0xfa #4g0-.@f#^&@#$*0sf -- @#)
-(@a , ; ] [ }} }x{ ({) ,{{};}] ;)
-(@a (bla) () (5-g) ("aa" a) ($x) (bla bla) (x (y)) ")" "(" x")"y)
-(@a @ @x (@x) (@x y) (@) (@ x) (@(@(@(@)))))
-(@a (;bla;) (; ) ;)
-  ;; bla)
-  ;; bla (@x
-)
-
-(assert_malformed (module quote "( @a)") "unknown operator")
-
-(assert_malformed (module quote "(@)") "malformed annotation id")
-(assert_malformed (module quote "(@ )") "malformed annotation id")
-(assert_malformed (module quote "(@ x)") "malformed annotation id")
-(assert_malformed (module quote "(@(@a)x)") "malformed annotation id")
-
-(assert_malformed (module quote "(@x ") "unclosed annotation")
-(assert_malformed (module quote "(@x ()") "unclosed annotation")
-(assert_malformed (module quote "(@x (y (z))") "unclosed annotation")
-(assert_malformed (module quote "(@x (@y )") "unclosed annotation")
-
-(assert_malformed (module quote "(@x))") "unexpected token")
-(assert_malformed (module quote "(@x ()))") "unexpected token")
-(assert_malformed (module quote "(@x (y (z))))") "unexpected token")
-(assert_malformed (module quote "(@x (@y )))") "unexpected token")
-
-(assert_malformed (module quote "(@x \"") "unclosed string")
-(assert_malformed (module quote "(@x \")") "unclosed string")
-
-(assert_malformed (module quote "((@a)@b)") "unknown operator")
-(assert_malformed (module quote "(func $(@a))") "unknown operator")
-(assert_malformed (module quote "(func $(@a)f)") "unknown operator")
-
-((@a) module (@a) $m (@a) (@a)
-  ((@a) import (@a) "spectest" (@a) "global_i32" (@a)
-    ((@a) global (@a) $g (@a) i32 (@a)) (@a)
-  ) (@a)
-  ((@a) import (@a) "spectest" (@a) "table" (@a)
-    ((@a) table (@a) $t (@a) 10 (@a) 20 (@a) funcref (@a)) (@a)
-  ) (@a)
-  ((@a) import (@a) "spectest" (@a) "memory" (@a)
-    ((@a) memory (@a) $m (@a) 1 (@a) 2 (@a)) (@a)
-  ) (@a)
-  ((@a) import (@a) "spectest" (@a) "print_i32_f32" (@a)
-    ((@a) func (@a) $f (@a)
-      ((@a) param (@a) i32 (@a) f32 (@a)) (@a)
-      ((@a) result (@a)) (@a)
-    ) (@a)
-  ) (@a)
-
-  ((@a) export (@a) "g" (@a)
-    ((@a) global (@a) $g (@a)) (@a)
-  ) (@a)
-  ((@a) export (@a) "t" (@a)
-    ((@a) table (@a) $t (@a)) (@a)
-  ) (@a)
-  ((@a) export (@a) "m" (@a)
-    ((@a) memory (@a) $m (@a)) (@a)
-  ) (@a)
-  ((@a) export (@a) "f" (@a)
-    ((@a) func (@a) $f (@a)) (@a)
-  ) (@a)
-) (@a)
-
-((@a) module (@a) $m (@a) (@a)
-  ((@a) global (@a) $g (@a)
-    ((@a) export (@a) "g" (@a)) (@a)
-    ((@a) import (@a) "spectest" (@a) "global_i32" (@a)) (@a)
-    i32 (@a)
-  ) (@a)
-  ((@a) table (@a) $t (@a)
-    ((@a) export (@a) "t" (@a)) (@a)
-    ((@a) import (@a) "spectest" (@a) "table" (@a)) (@a)
-    10 (@a) 20 (@a)
-    funcref (@a)
-  ) (@a)
-  ((@a) memory (@a) $m (@a)
-    ((@a) export (@a) "m" (@a)) (@a)
-    ((@a) import (@a) "spectest" (@a) "memory" (@a)) (@a)
-    1 (@a) 2 (@a)
-  ) (@a)
-  ((@a) func (@a) $f (@a)
-    ((@a) export (@a) "f" (@a)) (@a)
-    ((@a) import (@a) "spectest" (@a) "print_i32_f32" (@a)) (@a)
-    ((@a) param (@a) i32 (@a) f32 (@a)) (@a)
-    ((@a) result (@a)) (@a)
-  ) (@a)
-) (@a)
-
-((@a) module (@a) $m (@a) (@a)
-  ((@a) type (@a) $T (@a)
-    ((@a) func (@a)
-      ((@a) param (@a) i32 (@a) i64 (@a)) (@a)
-      ((@a) param (@a) $x (@a) i32 (@a)) (@a)
-      ((@a) result (@a) i32 (@a)) (@a)
-    ) (@a)
-  ) (@a)
-
-  ((@a) global (@a) $g (@a)
-    ((@a) export (@a) "g" (@a)) (@a)
-    i32 (@a)
-    ((@a) i32.const (@a) 42 (@a)) (@a)
-  ) (@a)
-  ((@a) table (@a) $t (@a)
-    ((@a) export (@a) "t" (@a)) (@a)
-    10 (@a) 20 (@a)
-    funcref (@a)
-  ) (@a)
-  ((@a) memory (@a) $m (@a)
-    ((@a) export (@a) "m" (@a)) (@a)
-    1 (@a) 2 (@a)
-  ) (@a)
-  ((@a) func (@a) $f (@a)
-    ((@a) export (@a) "f" (@a)) (@a)
-    ((@a) param (@a) i32 (@a) i64 (@a)) (@a)
-    ((@a) param (@a) $x (@a) i32 (@a)) (@a)
-    ((@a) result (@a) i32 (@a)) (@a)
-    ((@a) local (@a) i32 (@a) i32 (@a)) (@a)
-    ((@a) local (@a) $y (@a) i32 (@a)) (@a)
-    ((@a) block (@a)
-      ((@a) result (@a) i32 (@a)) (@a)
-      ((@a) i32.add (@a)
-        ((@a) local.get (@a) $x (@a)) (@a)
-        ((@a) local.get (@a) 0 (@a)) (@a)
-      )
-    )
-  ) (@a)
-
-  ((@a) elem (@a)
-    ((@a) offset (@a) ((@a) i32.const (@a) 0 (@a)) (@a)) (@a)
-    $f (@a) $f (@a) (@a) $f (@a)
-  ) (@a)
-  ((@a) data (@a)
-    ((@a) offset (@a) ((@a) i32.const (@a) 0 (@a)) (@a)) (@a)
-    "bla" (@a) "\43" (@a) (@a) "" (@a)
-  ) (@a)
-
-  (func $s)
-  ((@a) start (@a) $s (@a)) (@a)
-) (@a)
--- a/third_party/rust/wat/tests/wabt.rs
+++ b/third_party/rust/wat/tests/wabt.rs
@@ -7,16 +7,17 @@
 //! This also has support for handling `*.wast` files from the official test
 //! suite which involve parsing as a wast file and handling assertions. Also has
 //! rudimentary support for running some of the assertions.
 
 use rayon::prelude::*;
 use std::fs;
 use std::path::{Path, PathBuf};
 use std::process::Command;
+use std::str;
 use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
 use wast::parser::ParseBuffer;
 use wast::*;
 
 fn main() {
     let tests = find_tests();
     let filter = std::env::args().nth(1);
 
@@ -133,33 +134,35 @@ fn test_wast(test: &Path, contents: &str
                             }
                         }
                         // Skip these for the same reason we skip
                         // `module/binary-module.txt` in `binary_compare` below.
                         ModuleKind::Binary(_) => {}
                     }
                 }
 
+                WastDirective::QuoteModule { source, span } => {
+                    if let Err(e) = parse_quote_module(span, &source) {
+                        let (line, col) = span.linecol_in(&contents);
+                        anyhow::bail!(
+                            "in test {}:{}:{} parsed with\nerror: {}",
+                            test.display(),
+                            line + 1,
+                            col + 1,
+                            e,
+                        );
+                    }
+                }
+
                 WastDirective::AssertMalformed {
                     span,
                     module: QuoteModule::Quote(source),
                     message,
                 } => {
-                    let source = source.join(" ");
-                    let result = ParseBuffer::new(&source)
-                        .map_err(|e| e.into())
-                        .and_then(|b| -> Result<(), wast::Error> {
-                            let mut wat = parser::parse::<Wat>(&b)?;
-                            wat.module.encode()?;
-                            Ok(())
-                        })
-                        .map_err(|mut e| {
-                            e.set_text(&source);
-                            e
-                        });
+                    let result = parse_quote_module(span, &source);
                     let (line, col) = span.linecol_in(&contents);
                     match result {
                         Ok(()) => anyhow::bail!(
                             "\
                              test {}:{}:{} parsed successfully\n\
                              but should have failed with: {}\
                              ",
                             test.display(),
@@ -203,38 +206,72 @@ fn test_wast(test: &Path, contents: &str
     let mut s = format!("{} test failures in {}:", errors.len(), test.display());
     for error in errors {
         s.push_str("\n\n\t--------------------------------\n\n\t");
         s.push_str(&error.to_string().replace("\n", "\n\t"));
     }
     anyhow::bail!("{}", s)
 }
 
+fn parse_quote_module(span: Span, source: &[&[u8]]) -> Result<(), wast::Error> {
+    let mut ret = String::new();
+    for src in source {
+        match str::from_utf8(src) {
+            Ok(s) => ret.push_str(s),
+            Err(_) => {
+                return Err(wast::Error::new(
+                    span,
+                    "malformed UTF-8 encoding".to_string(),
+                ))
+            }
+        }
+        ret.push_str(" ");
+    }
+    let buf = ParseBuffer::new(&ret)?;
+    let mut wat = parser::parse::<Wat>(&buf)?;
+    wat.module.encode()?;
+    Ok(())
+}
+
 fn error_matches(error: &str, message: &str) -> bool {
     if error.contains(message) {
         return true;
     }
     if message == "unknown operator"
         || message == "unexpected token"
         || message == "wrong number of lane literals"
         || message == "type mismatch"
         || message == "malformed lane index"
         || message == "expected i8 literal"
         || message == "invalid lane length"
         || message == "unclosed annotation"
         || message == "malformed annotation id"
         || message == "alignment must be a power of two"
     {
-        return error.contains("expected ") || error.contains("constant out of range");
+        return error.contains("expected ")
+            || error.contains("constant out of range")
+            || error.contains("extra tokens remaining");
+    }
+
+    if message == "illegal character" {
+        return error.contains("unexpected character");
     }
 
     if message == "unclosed string" {
         return error.contains("unexpected end-of-file");
     }
 
+    if message == "invalid UTF-8 encoding" {
+        return error.contains("malformed UTF-8 encoding");
+    }
+
+    if message == "duplicate identifier" {
+        return error.contains("duplicate") && error.contains("identifier");
+    }
+
     return false;
 }
 
 fn find_tests() -> Vec<PathBuf> {
     let mut tests = Vec::new();
     if !Path::new("tests/wabt").exists() {
         panic!("submodules need to be checked out");
     }
@@ -244,16 +281,17 @@ fn find_tests() -> Vec<PathBuf> {
     find_tests("tests/wabt/test/parse".as_ref(), &mut tests);
     find_tests("tests/wabt/test/roundtrip".as_ref(), &mut tests);
     find_tests("tests/wabt/test/spec".as_ref(), &mut tests);
     find_tests("tests/wabt/test/typecheck".as_ref(), &mut tests);
     find_tests("tests/wabt/third_party/testsuite".as_ref(), &mut tests);
     find_tests("tests/regression".as_ref(), &mut tests);
     find_tests("tests/testsuite".as_ref(), &mut tests);
     tests.sort();
+
     return tests;
 
     fn find_tests(path: &Path, tests: &mut Vec<PathBuf>) {
         for f in path.read_dir().unwrap() {
             let f = f.unwrap();
             if f.file_type().unwrap().is_dir() {
                 find_tests(&f.path(), tests);
                 continue;
@@ -449,16 +487,27 @@ fn skip_test(test: &Path, contents: &str
 
     // We've made the opinionated decision that well-known annotations like
     // `@custom` and `@name` must be well-formed. This test, however, uses
     // `@custom` in ways the spec doesn't specify, so we skip it.
     if test.ends_with("test/parse/annotations.txt") {
         return true;
     }
 
-    // Waiting for https://github.com/WebAssembly/annotations/pull/7 to make its
-    // way into the testsuite repo.
-    if test.ends_with("testsuite/proposals/annotations/annotations.wast") {
+    // Currently wabt's implemented syntax is slightly different from ours
+    if contents.contains("--enable-gc") {
+        return true;
+    }
+
+    // Waiting for wabt to recognize the integer abs simd opcodes; they have been added
+    // upstream in the spec test suite, https://github.com/WebAssembly/simd/pull/197,
+    // but need to be pulled, filed https://github.com/WebAssembly/wabt/issues/1379.
+    if test.ends_with("wabt/third_party/testsuite/proposals/simd/simd_f32x4.wast") {
+        return true;
+    }
+
+    // wait for wabt to catch up on the annotations spec test
+    if test.ends_with("wabt/third_party/testsuite/proposals/annotations/annotations.wast") {
         return true;
     }
 
     false
 }