]> git.lizzy.rs Git - rust.git/commitdiff
Fix merge conflicts
authorChristian Poveda <christianpoveda@protonmail.com>
Mon, 21 Oct 2019 13:49:49 +0000 (08:49 -0500)
committerChristian Poveda <christianpoveda@protonmail.com>
Mon, 21 Oct 2019 13:49:49 +0000 (08:49 -0500)
13 files changed:
miri
rust-version
src/bin/cargo-miri.rs
src/eval.rs
src/helpers.rs
src/lib.rs
src/machine.rs
src/shims/env.rs
src/shims/foreign_items.rs
src/shims/fs.rs
src/shims/intrinsics.rs
src/shims/tls.rs
src/stacked_borrows.rs

diff --git a/miri b/miri
index 6de2391137ac6ed915b0f754c913573c609ef22e..c3d7ae0280c7788de95903e546faf85a9828e65f 100755 (executable)
--- a/miri
+++ b/miri
@@ -54,7 +54,7 @@ build_sysroot() {
     # Build once, for the user to see.
     cargo run $CARGO_BUILD_FLAGS --bin cargo-miri -- miri setup "$@"
     # Call again, to just set env var.
-    eval $(cargo run $CARGO_BUILD_FLAGS -q --bin cargo-miri -- miri setup --env "$@")
+    export MIRI_SYSROOT="$(cargo run $CARGO_BUILD_FLAGS -q --bin cargo-miri -- miri setup --print-sysroot "$@")"
 }
 
 # Prepare and set MIRI_SYSROOT.  Respects `MIRI_TEST_TARGET` and takes into account
index 0f59c13723c7dc5f129899b6b5c42f96bcf9f81b..8e2cace3385016ed9e9b486330e65c35d649f642 100644 (file)
@@ -1 +1 @@
-fa0f7d0080d8e7e9eb20aa9cbf8013f96c81287f
+7979016aff545f7b41cc517031026020b340989d
index b189dc1f808c3bf81588844622a345a3d26bfdb3..b889ce52f386d5c1c65bda34039abc111ad6d980 100644 (file)
@@ -259,6 +259,10 @@ fn setup(ask_user: bool) {
 
     // First, we need xargo.
     if xargo_version().map_or(true, |v| v < (0, 3, 16)) {
+        if std::env::var("XARGO").is_ok() {
+            // The user manually gave us a xargo binary; don't do anything automatically.
+            show_error(format!("Your xargo is too old; please upgrade to the latest version"))
+        }
         let mut cmd = cargo();
         cmd.args(&["install", "xargo", "-f"]);
         ask_to_run(cmd, ask_user, "install a recent enough xargo");
@@ -310,7 +314,7 @@ fn setup(ask_user: bool) {
     File::create(dir.join("lib.rs")).unwrap();
     // Prepare xargo invocation.
     let target = get_arg_flag_value("--target");
-    let print_env = !ask_user && has_arg_flag("--env"); // whether we just print the necessary environment variable
+    let print_sysroot = !ask_user && has_arg_flag("--print-sysroot"); // whether we just print the sysroot path
     let mut command = xargo();
     command.arg("build").arg("-q");
     command.current_dir(&dir);
@@ -339,13 +343,9 @@ fn setup(ask_user: bool) {
     };
     let sysroot = if is_host { dir.join("HOST") } else { PathBuf::from(dir) };
     std::env::set_var("MIRI_SYSROOT", &sysroot); // pass the env var to the processes we spawn, which will turn it into "--sysroot" flags
-    if print_env {
-        // Escape an arbitrary string for the shell: by wrapping it in `'`, the only special
-        // character we have to worry about is `'` itself. Everything else is taken literally
-        // in these strings. `'` is encoded as `'"'"'`: the outer `'` end and being a
-        // `'`-quoted string, respectively; the `"'"` in the middle represents a single `'`.
-        // (We could use `'\''` instead of `'"'"'` if we wanted but let's avoid backslashes.)
-        println!("MIRI_SYSROOT='{}'", sysroot.display().to_string().replace('\'', r#"'"'"'"#));
+    if print_sysroot {
+        // Print just the sysroot and nothing else; this way we do not need any escaping.
+        println!("{}", sysroot.display());
     } else if !ask_user {
         println!("A libstd for Miri is now available in `{}`.", sysroot.display());
     }
index bb0bad0ea03d729053ca4b063b5072a43a781e05..f4a8d176172d47908e0734a98c310e937a93c422 100644 (file)
@@ -162,7 +162,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
             MiriMemoryKind::Env.into(),
         );
         ecx.machine.cmd_line = Some(cmd_ptr);
-        // Store the UTF-16 string.
+        // Store the UTF-16 string. We just allocated so we know the bounds are fine.
         let char_size = Size::from_bytes(2);
         let cmd_alloc = ecx.memory.get_mut(cmd_ptr.alloc_id)?;
         let mut cur_ptr = cmd_ptr;
@@ -177,17 +177,13 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
         }
     }
 
-    assert!(
-        args.next().is_none(),
-        "start lang item has more arguments than expected"
-    );
+    args.next().expect_none("start lang item has more arguments than expected");
 
     // Set the last_error to 0
     let errno_layout = ecx.layout_of(ecx.tcx.types.u32)?;
     let errno_place = ecx.allocate(errno_layout, MiriMemoryKind::Static.into());
     ecx.write_scalar(Scalar::from_u32(0), errno_place.into())?;
-    let errno_ptr = ecx.check_mplace_access(errno_place.into(), Some(Size::from_bits(32)))?;
-    ecx.machine.last_error = errno_ptr;
+    ecx.machine.last_error = Some(errno_place);
 
     Ok(ecx)
 }
index 4d84106dbe86f7f75413c7e4d92116e9aba3ed59..c82971810c0212cb1f51a9fe5b4b5998903d2945 100644 (file)
@@ -95,6 +95,7 @@ fn gen_random(
         }
         let this = self.eval_context_mut();
 
+        // Don't forget the bounds check.
         let ptr = this.memory.check_ptr_access(
             ptr,
             Size::from_bytes(len as u64),
@@ -346,6 +347,70 @@ fn check_no_isolation(&mut self, name: &str) -> InterpResult<'tcx> {
         Ok(())
     }
 
+    /// Sets the last error variable.
+    fn set_last_error(&mut self, scalar: Scalar<Tag>) -> InterpResult<'tcx> {
+        let this = self.eval_context_mut();
+        let errno_place = this.machine.last_error.unwrap();
+        this.write_scalar(scalar, errno_place.into())
+    }
+
+    /// Gets the last error variable.
+    fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Tag>> {
+        let this = self.eval_context_mut();
+        let errno_place = this.machine.last_error.unwrap();
+        this.read_scalar(errno_place.into())?.not_undef()
+    }
+
+    /// Sets the last OS error using a `std::io::Error`. This function tries to produce the most
+    /// similar OS error from the `std::io::ErrorKind` and sets it as the last OS error.
+    fn set_last_error_from_io_error(&mut self, e: std::io::Error) -> InterpResult<'tcx> {
+        use std::io::ErrorKind::*;
+        let this = self.eval_context_mut();
+        let target = &this.tcx.tcx.sess.target.target;
+        let last_error = if target.options.target_family == Some("unix".to_owned()) {
+            this.eval_libc(match e.kind() {
+                ConnectionRefused => "ECONNREFUSED",
+                ConnectionReset => "ECONNRESET",
+                PermissionDenied => "EPERM",
+                BrokenPipe => "EPIPE",
+                NotConnected => "ENOTCONN",
+                ConnectionAborted => "ECONNABORTED",
+                AddrNotAvailable => "EADDRNOTAVAIL",
+                AddrInUse => "EADDRINUSE",
+                NotFound => "ENOENT",
+                Interrupted => "EINTR",
+                InvalidInput => "EINVAL",
+                TimedOut => "ETIMEDOUT",
+                AlreadyExists => "EEXIST",
+                WouldBlock => "EWOULDBLOCK",
+                _ => throw_unsup_format!("The {} error cannot be transformed into a raw os error", e)
+            })?
+        } else {
+            // FIXME: we have to implement the windows' equivalent of this.
+            throw_unsup_format!("Setting the last OS error from an io::Error is unsupported for {}.", target.target_os)
+        };
+        this.set_last_error(last_error)
+    }
+
+    /// Helper function that consumes an `std::io::Result<T>` and returns an
+    /// `InterpResult<'tcx,T>::Ok` instead. In case the result is an error, this function returns
+    /// `Ok(-1)` and sets the last OS error accordingly.
+    ///
+    /// This function uses `T: From<i32>` instead of `i32` directly because some IO related
+    /// functions return different integer types (like `read`, that returns an `i64`)
+    fn try_unwrap_io_result<T: From<i32>>(
+        &mut self,
+        result: std::io::Result<T>,
+    ) -> InterpResult<'tcx, T> {
+        match result {
+            Ok(ok) => Ok(ok),
+            Err(e) => {
+                self.eval_context_mut().set_last_error_from_io_error(e)?;
+                Ok((-1).into())
+            }
+        }
+    }
+
     /// Helper function to read an OsString from a null-terminated sequence of bytes, which is what
     /// the Unix APIs usually handle.
     fn read_os_string_from_c_string(&mut self, scalar: Scalar<Tag>) -> InterpResult<'tcx, OsString> {
index 06ec33a914bf751f232d2b04cee2cfb60e880eb8..59acff358678a817cb7065ff77859868b0c481d4 100644 (file)
@@ -1,4 +1,5 @@
 #![feature(rustc_private)]
+#![feature(option_expect_none, option_unwrap_none)]
 
 #![warn(rust_2018_idioms)]
 #![allow(clippy::cast_lossless)]
index d20346ba468a1dfc9268bb85f723a5b0c4b8dd08..7904e1cc123b359fbc08603f7325c5abbad80b5d 100644 (file)
@@ -91,8 +91,8 @@ pub struct Evaluator<'tcx> {
     pub(crate) argv: Option<Pointer<Tag>>,
     pub(crate) cmd_line: Option<Pointer<Tag>>,
 
-    /// Last OS error.
-    pub(crate) last_error: Option<Pointer<Tag>>,
+    /// Last OS error location in memory. It is a 32-bit integer.
+    pub(crate) last_error: Option<MPlaceTy<'tcx, Tag>>,
 
     /// TLS state.
     pub(crate) tls: TlsData<'tcx>,
@@ -244,10 +244,7 @@ fn box_alloc(
         ecx.write_scalar(Scalar::from_uint(align, arg.layout.size), arg)?;
 
         // No more arguments.
-        assert!(
-            args.next().is_none(),
-            "`exchange_malloc` lang item has more arguments than expected"
-        );
+        args.next().expect_none("`exchange_malloc` lang item has more arguments than expected");
         Ok(())
     }
 
index 7e2df4f985d19e48449c1693356e226a7303ce46..979b3b6cfa45186713752af16be6151cc4dafe53 100644 (file)
@@ -134,7 +134,7 @@ fn getcwd(
                 let erange = this.eval_libc("ERANGE")?;
                 this.set_last_error(erange)?;
             }
-            Err(e) => this.consume_io_error(e)?,
+            Err(e) => this.set_last_error_from_io_error(e)?,
         }
         Ok(Scalar::ptr_null(&*this.tcx))
     }
@@ -149,7 +149,7 @@ fn chdir(&mut self, path_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
         match env::set_current_dir(path) {
             Ok(()) => Ok(0),
             Err(e) => {
-                this.consume_io_error(e)?;
+                this.set_last_error_from_io_error(e)?;
                 Ok(-1)
             }
         }
index cfbb02f608130deda2e6ecc30c078bc8ddc8f9ff..1933aee1151dc3b3b4cef7b8a5a610ca1ff55b90 100644 (file)
@@ -50,7 +50,7 @@ fn malloc(&mut self, size: u64, zero_init: bool, kind: MiriMemoryKind) -> Scalar
                 .memory
                 .allocate(Size::from_bytes(size), align, kind.into());
             if zero_init {
-                // We just allocated this, the access cannot fail
+                // We just allocated this, the access is definitely in-bounds.
                 this.memory
                     .get_mut(ptr.alloc_id)
                     .unwrap()
@@ -227,7 +227,7 @@ fn emulate_foreign_item(
                     Align::from_bytes(align).unwrap(),
                     MiriMemoryKind::Rust.into(),
                 );
-                // We just allocated this, the access cannot fail
+                // We just allocated this, the access is definitely in-bounds.
                 this.memory
                     .get_mut(ptr.alloc_id)
                     .unwrap()
@@ -349,10 +349,7 @@ fn emulate_foreign_item(
                 let arg_dest = this.local_place(arg_local)?;
                 this.write_scalar(data, arg_dest)?;
 
-                assert!(
-                    args.next().is_none(),
-                    "__rust_maybe_catch_panic argument has more arguments than expected"
-                );
+                args.next().expect_none("__rust_maybe_catch_panic argument has more arguments than expected");
 
                 // We ourselves will return `0`, eventually (because we will not return if we paniced).
                 this.write_null(dest)?;
@@ -417,8 +414,8 @@ fn emulate_foreign_item(
             }
 
             "__errno_location" | "__error" => {
-                let errno_scalar: Scalar<Tag> = this.machine.last_error.unwrap().into();
-                this.write_scalar(errno_scalar, dest)?;
+                let errno_place = this.machine.last_error.unwrap();
+                this.write_scalar(errno_place.to_ref().to_scalar()?, dest)?;
             }
 
             "getenv" => {
@@ -643,7 +640,7 @@ fn emulate_foreign_item(
 
             // Hook pthread calls that go to the thread-local storage memory subsystem.
             "pthread_key_create" => {
-                let key_ptr = this.read_scalar(args[0])?.not_undef()?;
+                let key_place = this.deref_operand(args[0])?;
 
                 // Extract the function type out of the signature (that seems easier than constructing it ourselves).
                 let dtor = match this.test_null(this.read_scalar(args[1])?.not_undef()?)? {
@@ -668,16 +665,7 @@ fn emulate_foreign_item(
                     throw_unsup!(OutOfTls);
                 }
 
-                let key_ptr = this
-                    .memory
-                    .check_ptr_access(key_ptr, key_layout.size, key_layout.align.abi)?
-                    .expect("cannot be a ZST");
-                this.memory.get_mut(key_ptr.alloc_id)?.write_scalar(
-                    tcx,
-                    key_ptr,
-                    Scalar::from_uint(key, key_layout.size).into(),
-                    key_layout.size,
-                )?;
+                this.write_scalar(Scalar::from_uint(key, key_layout.size), key_place.into())?;
 
                 // Return success (`0`).
                 this.write_null(dest)?;
@@ -856,6 +844,7 @@ fn emulate_foreign_item(
                 let system_info_ptr = this
                     .check_mplace_access(system_info, None)?
                     .expect("cannot be a ZST");
+                // We rely on `deref_operand` doing bounds checks for us.
                 // Initialize with `0`.
                 this.memory
                     .get_mut(system_info_ptr.alloc_id)?
@@ -988,33 +977,6 @@ fn eval_path_scalar(
         }
         return Ok(None);
     }
-
-    fn set_last_error(&mut self, scalar: Scalar<Tag>) -> InterpResult<'tcx> {
-        let this = self.eval_context_mut();
-        let errno_ptr = this.machine.last_error.unwrap();
-        this.memory.get_mut(errno_ptr.alloc_id)?.write_scalar(
-            &*this.tcx,
-            errno_ptr,
-            scalar.into(),
-            Size::from_bits(32),
-        )
-    }
-
-    fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Tag>> {
-        let this = self.eval_context_mut();
-        let errno_ptr = this.machine.last_error.unwrap();
-        this.memory
-            .get(errno_ptr.alloc_id)?
-            .read_scalar(&*this.tcx, errno_ptr, Size::from_bits(32))?
-            .not_undef()
-    }
-
-    fn consume_io_error(&mut self, e: std::io::Error) -> InterpResult<'tcx> {
-        self.eval_context_mut().set_last_error(Scalar::from_int(
-            e.raw_os_error().unwrap(),
-            Size::from_bits(32),
-        ))
-    }
 }
 
 // Shims the linux 'getrandom()' syscall.
index 7cc574f05f1360a6010157cfb91b0ea75fa29aaa..08c9f3ec06e78cdb39e9c51cd387d42b9aedfdbb 100644 (file)
@@ -7,6 +7,7 @@
 use crate::stacked_borrows::Tag;
 use crate::*;
 
+#[derive(Debug)]
 pub struct FileHandle {
     file: File,
 }
@@ -20,7 +21,7 @@ impl Default for FileHandler {
     fn default() -> Self {
         FileHandler {
             handles: Default::default(),
-            // 0, 1 and 2 are reserved for stdin, stdout and stderr
+            // 0, 1 and 2 are reserved for stdin, stdout and stderr.
             low: 3,
         }
     }
@@ -99,11 +100,11 @@ fn open(
         let fd = options.open(path).map(|file| {
             let mut fh = &mut this.machine.file_handler;
             fh.low += 1;
-            fh.handles.insert(fh.low, FileHandle { file });
+            fh.handles.insert(fh.low, FileHandle { file }).unwrap_none();
             fh.low
         });
 
-        this.consume_result(fd)
+        this.try_unwrap_io_result(fd)
     }
 
     fn fcntl(
@@ -118,7 +119,7 @@ fn fcntl(
 
         let fd = this.read_scalar(fd_op)?.to_i32()?;
         let cmd = this.read_scalar(cmd_op)?.to_i32()?;
-        // We only support getting the flags for a descriptor
+        // We only support getting the flags for a descriptor.
         if cmd == this.eval_libc_i32("F_GETFD")? {
             // Currently this is the only flag that `F_GETFD` returns. It is OK to just return the
             // `FD_CLOEXEC` value without checking if the flag is set for the file because `std`
@@ -139,7 +140,7 @@ fn close(&mut self, fd_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
         let fd = this.read_scalar(fd_op)?.to_i32()?;
 
         this.remove_handle_and(fd, |handle, this| {
-            this.consume_result(handle.file.sync_all().map(|_| 0i32))
+            this.try_unwrap_io_result(handle.file.sync_all().map(|_| 0i32))
         })
     }
 
@@ -154,25 +155,24 @@ fn read(
         this.check_no_isolation("read")?;
 
         let count = this.read_scalar(count_op)?.to_usize(&*this.tcx)?;
-        // Reading zero bytes should not change `buf`
+        // Reading zero bytes should not change `buf`.
         if count == 0 {
             return Ok(0);
         }
         let fd = this.read_scalar(fd_op)?.to_i32()?;
         let buf_scalar = this.read_scalar(buf_op)?.not_undef()?;
 
-        // Remove the file handle to avoid borrowing issues
+        // Remove the file handle to avoid borrowing issues.
         this.remove_handle_and(fd, |mut handle, this| {
-            // Don't use `?` to avoid returning before reinserting the handle
+            // Don't use `?` to avoid returning before reinserting the handle.
             let bytes = this.force_ptr(buf_scalar).and_then(|buf| {
                 this.memory
                     .get_mut(buf.alloc_id)?
                     .get_bytes_mut(&*this.tcx, buf, Size::from_bytes(count))
                     .map(|buffer| handle.file.read(buffer))
             });
-            // Reinsert the file handle
-            this.machine.file_handler.handles.insert(fd, handle);
-            this.consume_result(bytes?.map(|bytes| bytes as i64))
+            this.machine.file_handler.handles.insert(fd, handle).unwrap_none();
+            this.try_unwrap_io_result(bytes?.map(|bytes| bytes as i64))
         })
     }
 
@@ -187,7 +187,7 @@ fn write(
         this.check_no_isolation("write")?;
 
         let count = this.read_scalar(count_op)?.to_usize(&*this.tcx)?;
-        // Writing zero bytes should not change `buf`
+        // Writing zero bytes should not change `buf`.
         if count == 0 {
             return Ok(0);
         }
@@ -200,8 +200,8 @@ fn write(
                     .get_bytes(&*this.tcx, buf, Size::from_bytes(count))
                     .map(|bytes| handle.file.write(bytes).map(|bytes| bytes as i64))
             });
-            this.machine.file_handler.handles.insert(fd, handle);
-            this.consume_result(bytes?)
+            this.machine.file_handler.handles.insert(fd, handle).unwrap_none();
+            this.try_unwrap_io_result(bytes?)
         })
     }
 
@@ -214,7 +214,7 @@ fn unlink( &mut self, path_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
 
         let result = remove_file(path).map(|_| 0);
 
-        this.consume_result(result)
+        this.try_unwrap_io_result(result)
     }
 
     /// Helper function that gets a `FileHandle` immutable reference and allows to manipulate it
@@ -224,7 +224,7 @@ fn unlink( &mut self, path_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
     /// and sets `Evaluator::last_error` to `libc::EBADF` (invalid file descriptor).
     ///
     /// This function uses `T: From<i32>` instead of `i32` directly because some IO related
-    /// functions return different integer types (like `read`, that returns an `i64`)
+    /// functions return different integer types (like `read`, that returns an `i64`).
     fn get_handle_and<F, T: From<i32>>(&mut self, fd: i32, f: F) -> InterpResult<'tcx, T>
     where
         F: Fn(&FileHandle) -> InterpResult<'tcx, T>,
@@ -248,7 +248,7 @@ fn get_handle_and<F, T: From<i32>>(&mut self, fd: i32, f: F) -> InterpResult<'tc
     /// and sets `Evaluator::last_error` to `libc::EBADF` (invalid file descriptor).
     ///
     /// This function uses `T: From<i32>` instead of `i32` directly because some IO related
-    /// functions return different integer types (like `read`, that returns an `i64`)
+    /// functions return different integer types (like `read`, that returns an `i64`).
     fn remove_handle_and<F, T: From<i32>>(&mut self, fd: i32, mut f: F) -> InterpResult<'tcx, T>
     where
         F: FnMut(FileHandle, &mut MiriEvalContext<'mir, 'tcx>) -> InterpResult<'tcx, T>,
@@ -262,23 +262,4 @@ fn remove_handle_and<F, T: From<i32>>(&mut self, fd: i32, mut f: F) -> InterpRes
             Ok((-1).into())
         }
     }
-
-    /// Helper function that consumes an `std::io::Result<T>` and returns an
-    /// `InterpResult<'tcx,T>::Ok` instead. It is expected that the result can be converted to an
-    /// OS error using `std::io::Error::raw_os_error`.
-    ///
-    /// This function uses `T: From<i32>` instead of `i32` directly because some IO related
-    /// functions return different integer types (like `read`, that returns an `i64`)
-    fn consume_result<T: From<i32>>(
-        &mut self,
-        result: std::io::Result<T>,
-    ) -> InterpResult<'tcx, T> {
-        match result {
-            Ok(ok) => Ok(ok),
-            Err(e) => {
-                self.eval_context_mut().consume_io_error(e)?;
-                Ok((-1).into())
-            }
-        }
-    }
 }
index 4666557e200c01c97ef44aeb6626a067bd751f7c..46658760cc12ac36b50b873d08bcc2687cc78265 100644 (file)
@@ -356,9 +356,10 @@ fn call_intrinsic(
                         _ => {
                             // Do it in memory
                             let mplace = this.force_allocation(dest)?;
-                            assert!(mplace.meta.is_none());
+                            mplace.meta.unwrap_none();
                             // not a zst, must be valid pointer
                             let ptr = mplace.ptr.to_ptr()?;
+                            // we know the return place is in-bounds
                             this.memory.get_mut(ptr.alloc_id)?.write_repeat(tcx, ptr, 0, dest.layout.size)?;
                         }
                     }
@@ -546,8 +547,9 @@ fn call_intrinsic(
                         _ => {
                             // Do it in memory
                             let mplace = this.force_allocation(dest)?;
-                            assert!(mplace.meta.is_none());
+                            mplace.meta.unwrap_none();
                             let ptr = mplace.ptr.to_ptr()?;
+                            // We know the return place is in-bounds
                             this.memory
                                 .get_mut(ptr.alloc_id)?
                                 .mark_definedness(ptr, dest.layout.size, false);
index 44bedbd44d2d9817ef8e2cc854ad9c923fef3156..b6aadd31a5be673688b3dffd825ca82e9e2db13a 100644 (file)
@@ -53,7 +53,7 @@ pub fn create_tls_key(
                 data: None,
                 dtor,
             },
-        );
+        ).unwrap_none();
         trace!("New TLS key allocated: {} with dtor {:?}", new_key, dtor);
         new_key
     }
index d219c1c7583459a8252fc1e7cfe90a46f67b42c8..2188b9d5394a310557ba0cb8a2ba67054c04f075 100644 (file)
@@ -172,7 +172,7 @@ fn new_ptr(&mut self) -> PtrId {
     pub fn new_call(&mut self) -> CallId {
         let id = self.next_call_id;
         trace!("new_call: Assigning ID {}", id);
-        self.active_calls.insert(id);
+        assert!(self.active_calls.insert(id));
         self.next_call_id = NonZeroU64::new(id.get() + 1).unwrap();
         id
     }
@@ -189,7 +189,7 @@ pub fn static_base_ptr(&mut self, id: AllocId) -> Tag {
         self.base_ptr_ids.get(&id).copied().unwrap_or_else(|| {
             let tag = Tag::Tagged(self.new_ptr());
             trace!("New allocation {:?} has base tag {:?}", id, tag);
-            self.base_ptr_ids.insert(id, tag);
+            self.base_ptr_ids.insert(id, tag).unwrap_none();
             tag
         })
     }