diff --git a/.appveyor.yml b/.appveyor.yml
index e5c2f4fb72..294ef26be0 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -46,6 +46,7 @@ build_script:
 test_script:
     - set RUST_TEST_NOCAPTURE=1
     - set RUST_BACKTRACE=1
+    - set CARGO_INCREMENTAL=0
     # Test host miri: 32bit Windows
     - cargo miri setup
     - set MIRI_SYSROOT=%USERPROFILE%\AppData\Local\rust-lang\miri\cache\HOST
diff --git a/.travis.yml b/.travis.yml
index 137ae4fe66..a074d6b14d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,6 +19,7 @@ env:
   global:
   - RUST_TEST_NOCAPTURE=1
   - RUST_BACKTRACE=1
+  - CARGO_INCREMENTAL=0
 
 before_script:
 # Compute the rust version we use. We do not use "language: rust" to have more control here.
diff --git a/miri b/miri
index 0cda9e8092..8cd2cfc3ae 100755
--- a/miri
+++ b/miri
@@ -49,7 +49,10 @@ fi
 # We enable debug-assertions to get tracing.
 # We enable line-only debuginfo for backtraces.
 export RUSTFLAGS="-C link-args=-Wl,-rpath,$LIBDIR -C debug-assertions -C debuginfo=1 $RUSTC_EXTRA_FLAGS"
-export CARGO_INCREMENTAL=1
+if [ -z "$CARGO_INCREMENTAL" ]; then
+    # Default CARGO_INCREMENTAL to 1.
+    export CARGO_INCREMENTAL=1
+fi
 
 ## Helper functions
 
diff --git a/rust-version b/rust-version
index a812b46de1..e3dc200835 100644
--- a/rust-version
+++ b/rust-version
@@ -1 +1 @@
-9a12971da5c08f9a95d54bdaef5cd83698ed4509
+537ccdf3ac44c8c7a8d36cbdbe6fb224afabb7ae
diff --git a/src/diagnostics.rs b/src/diagnostics.rs
index a528960cb2..9ff4340211 100644
--- a/src/diagnostics.rs
+++ b/src/diagnostics.rs
@@ -129,15 +129,12 @@ fn report_msg<'tcx, 'mir>(
         err.help(help);
     }
     // Add backtrace
-    let frames = ecx.generate_stacktrace(None);
-    // We iterate with indices because we need to look at the next frame (the caller).
-    for idx in 0..frames.len() {
-        let frame_info = &frames[idx];
-        let call_site_is_local = frames
-            .get(idx + 1)
-            .map_or(false, |caller_info| caller_info.instance.def_id().is_local());
-        if call_site_is_local {
-            err.span_note(frame_info.call_site, &frame_info.to_string());
+    let frames = ecx.generate_stacktrace();
+    for (idx, frame_info) in frames.iter().enumerate() {
+        let is_local = frame_info.instance.def_id().is_local();
+        // No span for non-local frames and the first frame (which is the error site).
+        if is_local && idx > 0 {
+            err.span_note(frame_info.span, &frame_info.to_string());
         } else {
             err.note(&frame_info.to_string());
         }
diff --git a/src/eval.rs b/src/eval.rs
index a4867bd5de..46e66bc0a8 100644
--- a/src/eval.rs
+++ b/src/eval.rs
@@ -6,7 +6,7 @@ use std::convert::TryFrom;
 use rand::rngs::StdRng;
 use rand::SeedableRng;
 
-use rustc_middle::ty::layout::LayoutOf;
+use rustc_target::abi::LayoutOf;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_hir::def_id::DefId;
 
diff --git a/src/helpers.rs b/src/helpers.rs
index 15f1b286de..9f46a0c1ce 100644
--- a/src/helpers.rs
+++ b/src/helpers.rs
@@ -4,13 +4,9 @@ use std::mem;
 use log::trace;
 
 use rustc_middle::mir;
-use rustc_middle::ty::{
-    self,
-    layout::{self, LayoutOf, Size, TyAndLayout},
-    List, TyCtxt,
-};
+use rustc_middle::ty::{self, List, TyCtxt, layout::TyAndLayout};
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
-use rustc_span::source_map::DUMMY_SP;
+use rustc_target::abi::{LayoutOf, Size, FieldsShape, Variants};
 
 use rand::RngCore;
 
@@ -73,17 +69,23 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
             .not_undef()
     }
 
+    /// Helper function to get a `libc` constant as an `i32`.
+    fn eval_libc_i32(&mut self, name: &str) -> InterpResult<'tcx, i32> {
+        // TODO: Cache the result.
+        self.eval_libc(name)?.to_i32()
+    }
+
     /// Helper function to get a `windows` constant as a `Scalar`.
-    fn eval_windows(&mut self, name: &str) -> InterpResult<'tcx, Scalar<Tag>> {
+    fn eval_windows(&mut self, module: &str, name: &str) -> InterpResult<'tcx, Scalar<Tag>> {
         self.eval_context_mut()
-            .eval_path_scalar(&["std", "sys", "windows", "c", name])?
+            .eval_path_scalar(&["std", "sys", "windows", module, name])?
             .not_undef()
     }
 
-    /// Helper function to get a `libc` constant as an `i32`.
-    fn eval_libc_i32(&mut self, name: &str) -> InterpResult<'tcx, i32> {
+    /// Helper function to get a `windows` constant as an `u64`.
+    fn eval_windows_u64(&mut self, module: &str, name: &str) -> InterpResult<'tcx, u64> {
         // TODO: Cache the result.
-        self.eval_libc(name)?.to_i32()
+        self.eval_windows(module, name)?.to_u64()
     }
 
     /// Helper function to get the `TyAndLayout` of a `libc` type
@@ -93,6 +95,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
         this.layout_of(ty)
     }
 
+    /// Helper function to get the `TyAndLayout` of a `windows` type
+    fn windows_ty_layout(&mut self, name: &str) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
+        let this = self.eval_context_mut();
+        let ty = this.resolve_path(&["std", "sys", "windows", "c", name]).monomorphic_ty(*this.tcx);
+        this.layout_of(ty)
+    }
+
     /// Write a 0 of the appropriate size to `dest`.
     fn write_null(&mut self, dest: PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> {
         self.eval_context_mut().write_scalar(Scalar::from_int(0, dest.layout.size), dest)
@@ -115,7 +124,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
     fn local_place(&mut self, local: mir::Local) -> InterpResult<'tcx, PlaceTy<'tcx, Tag>> {
         let this = self.eval_context_mut();
         let place = mir::Place { local: local, projection: List::empty() };
-        this.eval_place(&place)
+        this.eval_place(place)
     }
 
     /// Generate some random bytes, and write them to `dest`.
@@ -157,13 +166,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
 
         // Push frame.
         let mir = &*this.load_mir(f.def, None)?;
-        let span = this
-            .stack()
-            .last()
-            .and_then(Frame::current_source_info)
-            .map(|si| si.span)
-            .unwrap_or(DUMMY_SP);
-        this.push_stack_frame(f, span, mir, dest, stack_pop)?;
+        this.push_stack_frame(f, mir, dest, stack_pop)?;
 
         // Initialize arguments.
         let mut callee_args = this.frame().body.args_iter();
@@ -292,7 +295,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
                     // walking this value, we have to make sure it is not a
                     // `Variants::Multiple`.
                     match v.layout.variants {
-                        layout::Variants::Multiple { .. } => {
+                        Variants::Multiple { .. } => {
                             // A multi-variant enum, or generator, or so.
                             // Treat this like a union: without reading from memory,
                             // we cannot determine the variant we are in. Reading from
@@ -302,7 +305,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
                             // `UnsafeCell` action.
                             (self.unsafe_cell_action)(v)
                         }
-                        layout::Variants::Single { .. } => {
+                        Variants::Single { .. } => {
                             // Proceed further, try to find where exactly that `UnsafeCell`
                             // is hiding.
                             self.walk_value(v)
@@ -318,19 +321,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
                 fields: impl Iterator<Item = InterpResult<'tcx, MPlaceTy<'tcx, Tag>>>,
             ) -> InterpResult<'tcx> {
                 match place.layout.fields {
-                    layout::FieldPlacement::Array { .. } => {
+                    FieldsShape::Array { .. } => {
                         // For the array layout, we know the iterator will yield sorted elements so
                         // we can avoid the allocation.
                         self.walk_aggregate(place, fields)
                     }
-                    layout::FieldPlacement::Arbitrary { .. } => {
+                    FieldsShape::Arbitrary { .. } => {
                         // Gather the subplaces and sort them before visiting.
                         let mut places =
                             fields.collect::<InterpResult<'tcx, Vec<MPlaceTy<'tcx, Tag>>>>()?;
                         places.sort_by_key(|place| place.ptr.assert_ptr().offset);
                         self.walk_aggregate(place, places.into_iter().map(Ok))
                     }
-                    layout::FieldPlacement::Union { .. } => {
+                    FieldsShape::Union { .. } => {
                         // Uh, what?
                         bug!("a union is not an aggregate we should ever visit")
                     }
@@ -350,7 +353,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
         }
     }
 
-    // Writes several `ImmTy`s contiguosly into memory. This is useful when you have to pack
+    // Writes several `ImmTy`s contiguously into memory. This is useful when you have to pack
     // different values into a struct.
     fn write_packed_immediates(
         &mut self,
@@ -439,7 +442,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
             })?
         } else if target_os == "windows" {
             // FIXME: we have to finish implementing the Windows equivalent of this.
-            this.eval_windows(match e.kind() {
+            this.eval_windows("c", match e.kind() {
                 NotFound => "ERROR_FILE_NOT_FOUND",
                 _ => throw_unsup_format!("io error {} cannot be transformed into a raw os error", e)
             })?
diff --git a/src/intptrcast.rs b/src/intptrcast.rs
index 8eb28e4f47..ac27138d76 100644
--- a/src/intptrcast.rs
+++ b/src/intptrcast.rs
@@ -6,9 +6,8 @@ use log::trace;
 use rand::Rng;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_middle::ty::layout::HasDataLayout;
 use rustc_mir::interpret::{AllocCheck, AllocId, InterpResult, Memory, Machine, Pointer, PointerArithmetic};
-use rustc_target::abi::Size;
+use rustc_target::abi::{Size, HasDataLayout};
 
 use crate::{Evaluator, Tag, STACK_ADDR};
 
diff --git a/src/machine.rs b/src/machine.rs
index 4b7f3a7656..f794453228 100644
--- a/src/machine.rs
+++ b/src/machine.rs
@@ -11,14 +11,10 @@ use log::trace;
 use rand::rngs::StdRng;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_middle::mir;
-use rustc_middle::ty::{
-    self,
-    layout::{LayoutOf, Size},
-    Ty,
-};
+use rustc_middle::{mir, ty};
+use rustc_target::abi::{LayoutOf, Size};
 use rustc_ast::attr;
-use rustc_span::{source_map::Span, symbol::{sym, Symbol}};
+use rustc_span::symbol::{sym, Symbol};
 
 use crate::*;
 
@@ -253,7 +249,6 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
     #[inline(always)]
     fn find_mir_or_eval_fn(
         ecx: &mut InterpCx<'mir, 'tcx, Self>,
-        _span: Span,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, Tag>],
         ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
@@ -276,13 +271,12 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
     #[inline(always)]
     fn call_intrinsic(
         ecx: &mut rustc_mir::interpret::InterpCx<'mir, 'tcx, Self>,
-        span: Span,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, Tag>],
         ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
         unwind: Option<mir::BasicBlock>,
     ) -> InterpResult<'tcx> {
-        ecx.call_intrinsic(span, instance, args, ret, unwind)
+        ecx.call_intrinsic(instance, args, ret, unwind)
     }
 
     #[inline(always)]
@@ -305,7 +299,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
         bin_op: mir::BinOp,
         left: ImmTy<'tcx, Tag>,
         right: ImmTy<'tcx, Tag>,
-    ) -> InterpResult<'tcx, (Scalar<Tag>, bool, Ty<'tcx>)> {
+    ) -> InterpResult<'tcx, (Scalar<Tag>, bool, ty::Ty<'tcx>)> {
         ecx.binary_ptr_op(bin_op, left, right)
     }
 
diff --git a/src/operator.rs b/src/operator.rs
index 2232be713e..a28a0098e9 100644
--- a/src/operator.rs
+++ b/src/operator.rs
@@ -2,11 +2,8 @@ use std::convert::TryFrom;
 
 use log::trace;
 
-use rustc_middle::mir;
-use rustc_middle::ty::{
-    layout::{LayoutOf, Size},
-    Ty,
-};
+use rustc_middle::{mir, ty::Ty};
+use rustc_target::abi::{LayoutOf, Size};
 
 use crate::*;
 
diff --git a/src/range_map.rs b/src/range_map.rs
index 1d12d8a1ba..16ad5fd7c2 100644
--- a/src/range_map.rs
+++ b/src/range_map.rs
@@ -7,7 +7,7 @@
 
 use std::ops;
 
-use rustc_middle::ty::layout::Size;
+use rustc_target::abi::Size;
 
 #[derive(Clone, Debug)]
 struct Elem<T> {
diff --git a/src/shims/env.rs b/src/shims/env.rs
index d30e953cf5..4401682722 100644
--- a/src/shims/env.rs
+++ b/src/shims/env.rs
@@ -2,14 +2,12 @@ use std::ffi::{OsString, OsStr};
 use std::env;
 use std::convert::TryFrom;
 
-use crate::stacked_borrows::Tag;
-use crate::rustc_target::abi::LayoutOf;
-use crate::*;
-
+use rustc_target::abi::{Size, LayoutOf};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_middle::ty::layout::Size;
 use rustc_mir::interpret::Pointer;
 
+use crate::*;
+
 /// Check whether an operation that writes to a target buffer was successful.
 /// Accordingly select return value.
 /// Local helper function to be used in Windows shims.
@@ -143,7 +141,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
                 windows_check_buffer_size(this.write_os_str_to_wide_str(&var, buf_ptr, buf_size)?)
             }
             None => {
-                let envvar_not_found = this.eval_windows("ERROR_ENVVAR_NOT_FOUND")?;
+                let envvar_not_found = this.eval_windows("c", "ERROR_ENVVAR_NOT_FOUND")?;
                 this.set_last_error(envvar_not_found)?;
                 0 // return zero upon failure
             }
diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs
index da2f9d439c..7e7f17b0db 100644
--- a/src/shims/foreign_items.rs
+++ b/src/shims/foreign_items.rs
@@ -4,9 +4,8 @@ mod posix;
 use std::{convert::{TryInto, TryFrom}, iter};
 
 use rustc_hir::def_id::DefId;
-use rustc_middle::mir;
-use rustc_middle::ty;
-use rustc_middle::ty::layout::{Align, Size};
+use rustc_middle::{mir, ty};
+use rustc_target::abi::{Align, Size};
 use rustc_apfloat::Float;
 use rustc_span::symbol::sym;
 use rustc_ast::attr;
diff --git a/src/shims/foreign_items/posix.rs b/src/shims/foreign_items/posix.rs
index 2816159298..c9fd59c693 100644
--- a/src/shims/foreign_items/posix.rs
+++ b/src/shims/foreign_items/posix.rs
@@ -7,7 +7,7 @@ use log::trace;
 
 use crate::*;
 use rustc_middle::mir;
-use rustc_middle::ty::layout::{Align, LayoutOf, Size};
+use rustc_target::abi::{Align, LayoutOf, Size};
 
 impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
diff --git a/src/shims/foreign_items/windows.rs b/src/shims/foreign_items/windows.rs
index f39d477f82..276dd8fda9 100644
--- a/src/shims/foreign_items/windows.rs
+++ b/src/shims/foreign_items/windows.rs
@@ -1,8 +1,10 @@
-use crate::*;
-use rustc_middle::mir;
-use rustc_middle::ty::layout::Size;
 use std::iter;
 
+use rustc_middle::mir;
+use rustc_target::abi::Size;
+
+use crate::*;
+
 impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
     fn emulate_foreign_item_by_name(
@@ -167,6 +169,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
                 )?;
             }
 
+            // Time related shims
+            "GetSystemTimeAsFileTime" => {
+                this.GetSystemTimeAsFileTime(args[0])?;
+            }
+
             // Miscellaneous
             "SystemFunction036" => {
                 // The actual name of 'RtlGenRandom'
diff --git a/src/shims/fs.rs b/src/shims/fs.rs
index 89d067be86..52244dcfc8 100644
--- a/src/shims/fs.rs
+++ b/src/shims/fs.rs
@@ -6,7 +6,7 @@ use std::path::Path;
 use std::time::SystemTime;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_middle::ty::layout::{Align, LayoutOf, Size};
+use rustc_target::abi::{Align, LayoutOf, Size};
 
 use crate::stacked_borrows::Tag;
 use crate::*;
diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs
index 641b8b2563..844eac398d 100644
--- a/src/shims/intrinsics.rs
+++ b/src/shims/intrinsics.rs
@@ -1,11 +1,9 @@
 use std::iter;
 use std::convert::TryFrom;
 
-use rustc_middle::mir;
-use rustc_middle::ty;
-use rustc_middle::ty::layout::{Align, LayoutOf};
+use rustc_middle::{mir, ty};
 use rustc_apfloat::Float;
-use rustc_span::source_map::Span;
+use rustc_target::abi::{Align, LayoutOf};
 
 use crate::*;
 
@@ -13,14 +11,13 @@ impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tc
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
     fn call_intrinsic(
         &mut self,
-        span: Span,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, Tag>],
         ret: Option<(PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
         unwind: Option<mir::BasicBlock>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
-        if this.emulate_intrinsic(span, instance, args, ret)? {
+        if this.emulate_intrinsic(instance, args, ret)? {
             return Ok(());
         }
         let substs = instance.substs;
@@ -217,8 +214,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
                 this.write_immediate(*val, place.into())?;
             }
 
-            "breakpoint" => unimplemented!(), // halt miri
-
             #[rustfmt::skip]
             | "copy"
             | "copy_nonoverlapping"
diff --git a/src/shims/os_str.rs b/src/shims/os_str.rs
index 704994da4b..c24d6df41e 100644
--- a/src/shims/os_str.rs
+++ b/src/shims/os_str.rs
@@ -9,7 +9,7 @@ use std::os::unix::ffi::{OsStrExt, OsStringExt};
 #[cfg(windows)]
 use std::os::windows::ffi::{OsStrExt, OsStringExt};
 
-use rustc_middle::ty::layout::LayoutOf;
+use rustc_target::abi::LayoutOf;
 
 use crate::*;
 
diff --git a/src/shims/panic.rs b/src/shims/panic.rs
index 77741b7cca..33e47147a3 100644
--- a/src/shims/panic.rs
+++ b/src/shims/panic.rs
@@ -13,9 +13,8 @@
 
 use log::trace;
 
-use rustc_middle::mir;
-use rustc_middle::ty::{self, layout::LayoutOf};
-use rustc_target::spec::PanicStrategy;
+use rustc_middle::{mir, ty};
+use rustc_target::{spec::PanicStrategy, abi::LayoutOf};
 
 use crate::*;
 
@@ -51,7 +50,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
-        trace!("miri_start_panic: {:?}", this.frame().span);
+        trace!("miri_start_panic: {:?}", this.frame().instance);
 
         // Get the raw pointer stored in arg[0] (the panic payload).
         let payload = this.read_scalar(args[0])?.not_undef()?;
@@ -133,7 +132,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
         if let (true, Some(catch_unwind)) = (unwinding, extra.catch_unwind.take()) {
             // We've just popped a frame that was pushed by `try`,
             // and we are unwinding, so we should catch that.
-            trace!("unwinding: found catch_panic frame during unwinding: {:?}", this.frame().span);
+            trace!("unwinding: found catch_panic frame during unwinding: {:?}", this.frame().instance);
 
             // We set the return value of `try` to 1, since there was a panic.
             this.write_scalar(Scalar::from_i32(1), catch_unwind.dest)?;
diff --git a/src/shims/time.rs b/src/shims/time.rs
index 58db60e516..a7fca5e0dd 100644
--- a/src/shims/time.rs
+++ b/src/shims/time.rs
@@ -1,9 +1,11 @@
 use std::time::{Duration, SystemTime, Instant};
 use std::convert::TryFrom;
 
+use rustc_target::abi::LayoutOf;
+
 use crate::stacked_borrows::Tag;
 use crate::*;
-use helpers::immty_from_int_checked;
+use helpers::{immty_from_int_checked, immty_from_uint_checked};
 
 /// Returns the time elapsed between the provided time and the unix epoch as a `Duration`.
 pub fn system_time_to_duration<'tcx>(time: &SystemTime) -> InterpResult<'tcx, Duration> {
@@ -85,6 +87,34 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
         Ok(0)
     }
 
+    #[allow(non_snake_case)]
+    fn GetSystemTimeAsFileTime(&mut self, LPFILETIME_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx> {
+        let this = self.eval_context_mut();
+
+        this.assert_target_os("windows", "GetSystemTimeAsFileTime");
+        this.check_no_isolation("GetSystemTimeAsFileTime")?;
+
+        let NANOS_PER_SEC = this.eval_windows_u64("time", "NANOS_PER_SEC")?;
+        let INTERVALS_PER_SEC = this.eval_windows_u64("time", "INTERVALS_PER_SEC")?;
+        let INTERVALS_TO_UNIX_EPOCH = this.eval_windows_u64("time", "INTERVALS_TO_UNIX_EPOCH")?;
+        let NANOS_PER_INTERVAL = NANOS_PER_SEC / INTERVALS_PER_SEC;
+        let SECONDS_TO_UNIX_EPOCH = INTERVALS_TO_UNIX_EPOCH / INTERVALS_PER_SEC;
+
+        let duration = system_time_to_duration(&SystemTime::now())? + Duration::from_secs(SECONDS_TO_UNIX_EPOCH);
+        let duration_ticks = u64::try_from(duration.as_nanos() / u128::from(NANOS_PER_INTERVAL))
+            .map_err(|_| err_unsup_format!("programs running more than 2^64 Windows ticks after the Windows epoch are not supported"))?;
+
+        let dwLowDateTime = u32::try_from(duration_ticks & 0x00000000FFFFFFFF).unwrap();
+        let dwHighDateTime = u32::try_from((duration_ticks & 0xFFFFFFFF00000000) >> 32).unwrap();
+        let DWORD_tylayout = this.layout_of(this.tcx.types.u32)?;
+        let imms = [
+            immty_from_uint_checked(dwLowDateTime, DWORD_tylayout)?,
+            immty_from_uint_checked(dwHighDateTime, DWORD_tylayout)?,
+        ];
+        this.write_packed_immediates(this.deref_operand(LPFILETIME_op)?, &imms)?;
+        Ok(())
+    }
+
     fn mach_absolute_time(&self) -> InterpResult<'tcx, u64> {
         let this = self.eval_context_ref();
 
diff --git a/src/shims/tls.rs b/src/shims/tls.rs
index 76f946f724..36ad4bd9b6 100644
--- a/src/shims/tls.rs
+++ b/src/shims/tls.rs
@@ -4,8 +4,8 @@ use std::collections::BTreeMap;
 
 use log::trace;
 
-use rustc_middle::{ty, ty::layout::{Size, HasDataLayout}};
-use rustc_target::abi::LayoutOf;
+use rustc_middle::ty;
+use rustc_target::abi::{LayoutOf, Size, HasDataLayout};
 
 use crate::{HelpersEvalContextExt, InterpResult, MPlaceTy, Scalar, StackPopCleanup, Tag};
 
diff --git a/src/stacked_borrows.rs b/src/stacked_borrows.rs
index 90920069c5..89b2a8bb3e 100644
--- a/src/stacked_borrows.rs
+++ b/src/stacked_borrows.rs
@@ -10,7 +10,8 @@ use log::trace;
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_middle::mir::RetagKind;
-use rustc_middle::ty::{self, layout::Size};
+use rustc_middle::ty;
+use rustc_target::abi::Size;
 use rustc_hir::Mutability;
 
 use crate::*;
diff --git a/tests/compile-fail/deallocate-bad-alignment.rs b/tests/compile-fail/deallocate-bad-alignment.rs
index f2cd87bac6..9b5ee9a934 100644
--- a/tests/compile-fail/deallocate-bad-alignment.rs
+++ b/tests/compile-fail/deallocate-bad-alignment.rs
@@ -1,15 +1,10 @@
-#![feature(allocator_api)]
-
-extern crate alloc;
-
-use alloc::alloc::Global;
-use std::alloc::{AllocRef, Layout};
+use std::alloc::{alloc, dealloc, realloc, Layout};
 
 // error-pattern: allocation has size 1 and alignment 1, but gave size 1 and alignment 2
 
 fn main() {
     unsafe {
-        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap().0;
-        Global.dealloc(x, Layout::from_size_align_unchecked(1, 2));
+        let x = alloc(Layout::from_size_align_unchecked(1, 1));
+        dealloc(x, Layout::from_size_align_unchecked(1, 2));
     }
 }
diff --git a/tests/compile-fail/deallocate-bad-size.rs b/tests/compile-fail/deallocate-bad-size.rs
index 498a662518..39a0d48c8b 100644
--- a/tests/compile-fail/deallocate-bad-size.rs
+++ b/tests/compile-fail/deallocate-bad-size.rs
@@ -1,15 +1,10 @@
-#![feature(allocator_api)]
-
-extern crate alloc;
-
-use alloc::alloc::Global;
-use std::alloc::{AllocRef, Layout};
+use std::alloc::{alloc, dealloc, realloc, Layout};
 
 // error-pattern: allocation has size 1 and alignment 1, but gave size 2 and alignment 1
 
 fn main() {
     unsafe {
-        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap().0;
-        Global.dealloc(x, Layout::from_size_align_unchecked(2, 1));
+        let x = alloc(Layout::from_size_align_unchecked(1, 1));
+        dealloc(x, Layout::from_size_align_unchecked(2, 1));
     }
 }
diff --git a/tests/compile-fail/deallocate-twice.rs b/tests/compile-fail/deallocate-twice.rs
index a851d75b9d..3c5e8e9636 100644
--- a/tests/compile-fail/deallocate-twice.rs
+++ b/tests/compile-fail/deallocate-twice.rs
@@ -1,16 +1,11 @@
-#![feature(allocator_api)]
-
-extern crate alloc;
-
-use alloc::alloc::Global;
-use std::alloc::{AllocRef, Layout};
+use std::alloc::{alloc, dealloc, realloc, Layout};
 
 // error-pattern: dereferenced after this allocation got freed
 
 fn main() {
     unsafe {
-        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap().0;
-        Global.dealloc(x, Layout::from_size_align_unchecked(1, 1));
-        Global.dealloc(x, Layout::from_size_align_unchecked(1, 1));
+        let x = alloc(Layout::from_size_align_unchecked(1, 1));
+        dealloc(x, Layout::from_size_align_unchecked(1, 1));
+        dealloc(x, Layout::from_size_align_unchecked(1, 1));
     }
 }
diff --git a/tests/compile-fail/never_transmute_void.rs b/tests/compile-fail/never_transmute_void.rs
index 2a822ab1b5..5e9e2ac204 100644
--- a/tests/compile-fail/never_transmute_void.rs
+++ b/tests/compile-fail/never_transmute_void.rs
@@ -7,12 +7,12 @@
 enum Void {}
 
 fn f(v: Void) -> ! {
-    match v {} //~ ERROR  entering unreachable code
+    match v {} //~ ERROR entering unreachable code
 }
 
 fn main() {
     let v: Void = unsafe {
         std::mem::transmute::<(), Void>(())
     };
-    f(v); //~ inside call to `f`
+    f(v); //~ inside `main`
 }
diff --git a/tests/compile-fail/reallocate-bad-size.rs b/tests/compile-fail/reallocate-bad-size.rs
index a62c1adae7..bbdef4421b 100644
--- a/tests/compile-fail/reallocate-bad-size.rs
+++ b/tests/compile-fail/reallocate-bad-size.rs
@@ -1,15 +1,10 @@
-#![feature(allocator_api)]
-
-extern crate alloc;
-
-use alloc::alloc::Global;
-use std::alloc::{AllocRef, Layout};
+use std::alloc::{alloc, dealloc, realloc, Layout};
 
 // error-pattern: allocation has size 1 and alignment 1, but gave size 2 and alignment 1
 
 fn main() {
     unsafe {
-        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap().0;
-        Global.realloc(x, Layout::from_size_align_unchecked(2, 1), 1).unwrap();
+        let x = alloc(Layout::from_size_align_unchecked(1, 1));
+        realloc(x, Layout::from_size_align_unchecked(2, 1), 1);
     }
 }
diff --git a/tests/compile-fail/reallocate-change-alloc.rs b/tests/compile-fail/reallocate-change-alloc.rs
index 0d4b60e0a3..8130d72dee 100644
--- a/tests/compile-fail/reallocate-change-alloc.rs
+++ b/tests/compile-fail/reallocate-change-alloc.rs
@@ -1,14 +1,9 @@
-#![feature(allocator_api)]
-
-extern crate alloc;
-
-use alloc::alloc::Global;
-use std::alloc::{AllocRef, Layout};
+use std::alloc::{alloc, dealloc, realloc, Layout};
 
 fn main() {
     unsafe {
-        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap().0;
-        Global.realloc(x, Layout::from_size_align_unchecked(1, 1), 1).unwrap();
-        let _z = *(x.as_ptr() as *mut u8); //~ ERROR dereferenced after this allocation got freed
+        let x = alloc(Layout::from_size_align_unchecked(1, 1));
+        realloc(x, Layout::from_size_align_unchecked(1, 1), 1);
+        let _z = *x; //~ ERROR dereferenced after this allocation got freed
     }
 }
diff --git a/tests/compile-fail/reallocate-dangling.rs b/tests/compile-fail/reallocate-dangling.rs
index 9661d7e966..702ddc0724 100644
--- a/tests/compile-fail/reallocate-dangling.rs
+++ b/tests/compile-fail/reallocate-dangling.rs
@@ -1,16 +1,11 @@
-#![feature(allocator_api)]
-
-extern crate alloc;
-
-use alloc::alloc::Global;
-use std::alloc::{AllocRef, Layout};
+use std::alloc::{alloc, dealloc, realloc, Layout};
 
 // error-pattern: dereferenced after this allocation got freed
 
 fn main() {
     unsafe {
-        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap().0;
-        Global.dealloc(x, Layout::from_size_align_unchecked(1, 1));
-        Global.realloc(x, Layout::from_size_align_unchecked(1, 1), 1).unwrap();
+        let x = alloc(Layout::from_size_align_unchecked(1, 1));
+        dealloc(x, Layout::from_size_align_unchecked(1, 1));
+        realloc(x, Layout::from_size_align_unchecked(1, 1), 1);
     }
 }
diff --git a/tests/run-pass/heap_allocator.rs b/tests/run-pass/heap_allocator.rs
index 8077be405f..c2fcfea58c 100644
--- a/tests/run-pass/heap_allocator.rs
+++ b/tests/run-pass/heap_allocator.rs
@@ -1,7 +1,7 @@
 #![feature(allocator_api)]
 
 use std::ptr::NonNull;
-use std::alloc::{Global, AllocRef, Layout, System};
+use std::alloc::{Global, AllocRef, Layout, System, AllocInit, ReallocPlacement};
 use std::slice;
 
 fn check_alloc<T: AllocRef>(mut allocator: T) { unsafe {
@@ -9,28 +9,29 @@ fn check_alloc<T: AllocRef>(mut allocator: T) { unsafe {
         let layout = Layout::from_size_align(20, align).unwrap();
 
         for _ in 0..32 {
-            let a = allocator.alloc(layout).unwrap().0;
+            let a = allocator.alloc(layout, AllocInit::Uninitialized).unwrap().ptr;
             assert_eq!(a.as_ptr() as usize % align, 0, "pointer is incorrectly aligned");
             allocator.dealloc(a, layout);
         }
 
-        let p1 = allocator.alloc_zeroed(layout).unwrap().0;
+        let p1 = allocator.alloc(layout, AllocInit::Zeroed).unwrap().ptr;
         assert_eq!(p1.as_ptr() as usize % align, 0, "pointer is incorrectly aligned");
 
-        let p2 = allocator.realloc(p1, layout, 40).unwrap().0;
+        // old size < new size
+        let p2 = allocator.grow(p1, layout, 40, ReallocPlacement::MayMove, AllocInit::Uninitialized).unwrap().ptr;
         let layout = Layout::from_size_align(40, align).unwrap();
         assert_eq!(p2.as_ptr() as usize % align, 0, "pointer is incorrectly aligned");
         let slice = slice::from_raw_parts(p2.as_ptr(), 20);
         assert_eq!(&slice, &[0_u8; 20]);
 
         // old size == new size
-        let p3 = allocator.realloc(p2, layout, 40).unwrap().0;
+        let p3 = allocator.grow(p2, layout, 40, ReallocPlacement::MayMove, AllocInit::Uninitialized).unwrap().ptr;
         assert_eq!(p3.as_ptr() as usize % align, 0, "pointer is incorrectly aligned");
         let slice = slice::from_raw_parts(p3.as_ptr(), 20);
         assert_eq!(&slice, &[0_u8; 20]);
 
         // old size > new size
-        let p4 = allocator.realloc(p3, layout, 10).unwrap().0;
+        let p4 = allocator.shrink(p3, layout, 10, ReallocPlacement::MayMove).unwrap().ptr;
         let layout = Layout::from_size_align(10, align).unwrap();
         assert_eq!(p4.as_ptr() as usize % align, 0, "pointer is incorrectly aligned");
         let slice = slice::from_raw_parts(p4.as_ptr(), 10);
@@ -46,7 +47,7 @@ fn check_align_requests<T: AllocRef>(mut allocator: T) {
             let iterations = 32;
             unsafe {
                 let pointers: Vec<_> = (0..iterations).map(|_| {
-                    allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap().0
+                    allocator.alloc(Layout::from_size_align(size, align).unwrap(), AllocInit::Uninitialized).unwrap().ptr
                 }).collect();
                 for &ptr in &pointers {
                     assert_eq!((ptr.as_ptr() as usize) % align, 0,
@@ -67,7 +68,7 @@ fn global_to_box() {
     let l = Layout::new::<T>();
     // allocate manually with global allocator, then turn into Box and free there
     unsafe {
-        let ptr = Global.alloc(l).unwrap().0.as_ptr() as *mut T;
+        let ptr = Global.alloc(l, AllocInit::Uninitialized).unwrap().ptr.as_ptr() as *mut T;
         let b = Box::from_raw(ptr);
         drop(b);
     }
diff --git a/tests/run-pass/time.rs b/tests/run-pass/time.rs
index bbe8b4011d..a9ca28161c 100644
--- a/tests/run-pass/time.rs
+++ b/tests/run-pass/time.rs
@@ -1,18 +1,40 @@
-// ignore-windows: TODO clock shims are not implemented on Windows
 // compile-flags: -Zmiri-disable-isolation
 
 use std::time::{SystemTime, Instant};
 
 fn main() {
+    // Check `SystemTime`.
     let now1 = SystemTime::now();
     // Do some work to make time pass.
     for _ in 0..10 { drop(vec![42]); }
     let now2 = SystemTime::now();
     assert!(now2 > now1);
+    let diff = now2.duration_since(now1).unwrap();
+    assert_eq!(now1 + diff, now2);
+    assert_eq!(now2 - diff, now1);
+    // Sanity-check the time we got.
+    let seconds_since_epoch = now1.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
+    let years_since_epoch = seconds_since_epoch / 3600 / 24 / 365;
+    let year = 1970 + years_since_epoch;
+    assert!(2020 <= year && year < 2100);
 
-    let now1 = Instant::now();
-    // Do some work to make time pass.
-    for _ in 0..10 { drop(vec![42]); }
-    let now2 = Instant::now();
-    assert!(now2 > now1);
+    // Check `Instant`.
+    #[cfg(not(windows))] // `Instant` shims not yet implemented on Windows
+    {
+        let now1 = Instant::now();
+        // Do some work to make time pass.
+        for _ in 0..10 { drop(vec![42]); }
+        let now2 = Instant::now();
+        assert!(now2 > now1);
+
+        #[cfg(target_os = "linux")] // TODO: macOS does not support Instant subtraction
+        {
+            let diff = now2.duration_since(now1);
+            assert_eq!(now1 + diff, now2);
+            assert_eq!(now2 - diff, now1);
+            // Sanity-check the difference we got.
+            assert!(diff.as_micros() > 1);
+            assert!(diff.as_micros() < 1_000_000);
+        }
+    }
 }