diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs
index 5865042859dca..d3fb3a47c5906 100644
--- a/src/librustc_error_codes/error_codes.rs
+++ b/src/librustc_error_codes/error_codes.rs
@@ -437,6 +437,7 @@ E0751: include_str!("./error_codes/E0751.md"),
 E0752: include_str!("./error_codes/E0752.md"),
 E0753: include_str!("./error_codes/E0753.md"),
 E0754: include_str!("./error_codes/E0754.md"),
+E0758: include_str!("./error_codes/E0758.md"),
 ;
 //  E0006, // merged with E0005
 //  E0008, // cannot bind by-move into a pattern guard
diff --git a/src/librustc_error_codes/error_codes/E0758.md b/src/librustc_error_codes/error_codes/E0758.md
new file mode 100644
index 0000000000000..ddca4b3d75f77
--- /dev/null
+++ b/src/librustc_error_codes/error_codes/E0758.md
@@ -0,0 +1,20 @@
+A multi-line (doc-)comment is unterminated.
+
+Erroneous code example:
+
+```compile_fail,E0758
+/* I am not terminated!
+```
+
+The same goes for doc comments:
+
+```compile_fail,E0758
+/*! I am not terminated!
+```
+
+You need to end your multi-line comment with `*/` in order to fix this error:
+
+```
+/* I am terminated! */
+/*! I am also terminated! */
+```
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index b048240ca8dc1..3db16a71bab15 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -50,7 +50,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.go_to_block(target_block);
             }
 
-            Call { ref func, ref args, destination, ref cleanup, .. } => {
+            Call {
+                ref func,
+                ref args,
+                destination,
+                ref cleanup,
+                from_hir_call: _from_hir_call,
+            } => {
                 let old_stack = self.frame_idx();
                 let old_loc = self.frame().loc;
                 let func = self.eval_operand(func, None)?;
diff --git a/src/librustc_mir/transform/validate.rs b/src/librustc_mir/transform/validate.rs
index a25edd131baa1..7d301b2f49648 100644
--- a/src/librustc_mir/transform/validate.rs
+++ b/src/librustc_mir/transform/validate.rs
@@ -3,10 +3,13 @@
 use super::{MirPass, MirSource};
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::{
-    mir::{Body, Location, Operand, Rvalue, Statement, StatementKind},
-    ty::{ParamEnv, TyCtxt},
+    mir::{
+        BasicBlock, Body, Location, Operand, Rvalue, Statement, StatementKind, Terminator,
+        TerminatorKind,
+    },
+    ty::{self, ParamEnv, TyCtxt},
 };
-use rustc_span::{def_id::DefId, Span, DUMMY_SP};
+use rustc_span::def_id::DefId;
 
 pub struct Validator {
     /// Describes at which point in the pipeline this validation is happening.
@@ -30,14 +33,27 @@ struct TypeChecker<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
-    fn fail(&self, span: Span, msg: impl AsRef<str>) {
+    fn fail(&self, location: Location, msg: impl AsRef<str>) {
+        let span = self.body.source_info(location).span;
         // We use `delay_span_bug` as we might see broken MIR when other errors have already
         // occurred.
         self.tcx.sess.diagnostic().delay_span_bug(
             span,
-            &format!("broken MIR in {:?} ({}): {}", self.def_id, self.when, msg.as_ref()),
+            &format!(
+                "broken MIR in {:?} ({}) at {:?}:\n{}",
+                self.def_id,
+                self.when,
+                location,
+                msg.as_ref()
+            ),
         );
     }
+
+    fn check_bb(&self, location: Location, bb: BasicBlock) {
+        if self.body.basic_blocks().get(bb).is_none() {
+            self.fail(location, format!("encountered jump to invalid basic block {:?}", bb))
+        }
+    }
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
@@ -45,12 +61,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
         // `Operand::Copy` is only supposed to be used with `Copy` types.
         if let Operand::Copy(place) = operand {
             let ty = place.ty(&self.body.local_decls, self.tcx).ty;
+            let span = self.body.source_info(location).span;
 
-            if !ty.is_copy_modulo_regions(self.tcx, self.param_env, DUMMY_SP) {
-                self.fail(
-                    DUMMY_SP,
-                    format!("`Operand::Copy` with non-`Copy` type {} at {:?}", ty, location),
-                );
+            if !ty.is_copy_modulo_regions(self.tcx, self.param_env, span) {
+                self.fail(location, format!("`Operand::Copy` with non-`Copy` type {}", ty));
             }
         }
 
@@ -65,11 +79,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 Rvalue::Use(Operand::Copy(src) | Operand::Move(src)) => {
                     if dest == src {
                         self.fail(
-                            DUMMY_SP,
-                            format!(
-                                "encountered `Assign` statement with overlapping memory at {:?}",
-                                location
-                            ),
+                            location,
+                            "encountered `Assign` statement with overlapping memory",
                         );
                     }
                 }
@@ -77,4 +88,98 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             }
         }
     }
+
+    fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
+        match &terminator.kind {
+            TerminatorKind::Goto { target } => {
+                self.check_bb(location, *target);
+            }
+            TerminatorKind::SwitchInt { targets, values, .. } => {
+                if targets.len() != values.len() + 1 {
+                    self.fail(
+                        location,
+                        format!(
+                            "encountered `SwitchInt` terminator with {} values, but {} targets (should be values+1)",
+                            values.len(),
+                            targets.len(),
+                        ),
+                    );
+                }
+                for target in targets {
+                    self.check_bb(location, *target);
+                }
+            }
+            TerminatorKind::Drop { target, unwind, .. } => {
+                self.check_bb(location, *target);
+                if let Some(unwind) = unwind {
+                    self.check_bb(location, *unwind);
+                }
+            }
+            TerminatorKind::DropAndReplace { target, unwind, .. } => {
+                self.check_bb(location, *target);
+                if let Some(unwind) = unwind {
+                    self.check_bb(location, *unwind);
+                }
+            }
+            TerminatorKind::Call { func, destination, cleanup, .. } => {
+                let func_ty = func.ty(&self.body.local_decls, self.tcx);
+                match func_ty.kind {
+                    ty::FnPtr(..) | ty::FnDef(..) => {}
+                    _ => self.fail(
+                        location,
+                        format!("encountered non-callable type {} in `Call` terminator", func_ty),
+                    ),
+                }
+                if let Some((_, target)) = destination {
+                    self.check_bb(location, *target);
+                }
+                if let Some(cleanup) = cleanup {
+                    self.check_bb(location, *cleanup);
+                }
+            }
+            TerminatorKind::Assert { cond, target, cleanup, .. } => {
+                let cond_ty = cond.ty(&self.body.local_decls, self.tcx);
+                if cond_ty != self.tcx.types.bool {
+                    self.fail(
+                        location,
+                        format!(
+                            "encountered non-boolean condition of type {} in `Assert` terminator",
+                            cond_ty
+                        ),
+                    );
+                }
+                self.check_bb(location, *target);
+                if let Some(cleanup) = cleanup {
+                    self.check_bb(location, *cleanup);
+                }
+            }
+            TerminatorKind::Yield { resume, drop, .. } => {
+                self.check_bb(location, *resume);
+                if let Some(drop) = drop {
+                    self.check_bb(location, *drop);
+                }
+            }
+            TerminatorKind::FalseEdges { real_target, imaginary_target } => {
+                self.check_bb(location, *real_target);
+                self.check_bb(location, *imaginary_target);
+            }
+            TerminatorKind::FalseUnwind { real_target, unwind } => {
+                self.check_bb(location, *real_target);
+                if let Some(unwind) = unwind {
+                    self.check_bb(location, *unwind);
+                }
+            }
+            TerminatorKind::InlineAsm { destination, .. } => {
+                if let Some(destination) = destination {
+                    self.check_bb(location, *destination);
+                }
+            }
+            // Nothing to validate for these.
+            TerminatorKind::Resume
+            | TerminatorKind::Abort
+            | TerminatorKind::Return
+            | TerminatorKind::Unreachable
+            | TerminatorKind::GeneratorDrop => {}
+        }
+    }
 }
diff --git a/src/librustc_parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs
index 7e59f06e44ae3..9bc6a50acad04 100644
--- a/src/librustc_parse/lexer/mod.rs
+++ b/src/librustc_parse/lexer/mod.rs
@@ -191,7 +191,15 @@ impl<'a> StringReader<'a> {
                         "unterminated block comment"
                     };
                     let last_bpos = self.pos;
-                    self.fatal_span_(start, last_bpos, msg).raise();
+                    self.sess
+                        .span_diagnostic
+                        .struct_span_fatal_with_code(
+                            self.mk_sp(start, last_bpos),
+                            msg,
+                            error_code!(E0758),
+                        )
+                        .emit();
+                    FatalError.raise();
                 }
 
                 if is_doc_comment {
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index cbb2878011c5f..59fadfc41b06e 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -680,7 +680,9 @@ impl<'a> Resolver<'a> {
                                 Res::Def(DefKind::Ctor(..), did) => this.parent(did),
                                 _ => res.opt_def_id(),
                             };
-                            candidates.push(ImportSuggestion { did, descr: res.descr(), path });
+                            if candidates.iter().all(|v: &ImportSuggestion| v.did != did) {
+                                candidates.push(ImportSuggestion { did, descr: res.descr(), path });
+                            }
                         }
                     }
                 }
diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs
index f78a6207a3ab5..19caf64c63f1e 100644
--- a/src/librustc_trait_selection/opaque_types.rs
+++ b/src/librustc_trait_selection/opaque_types.rs
@@ -1253,9 +1253,6 @@ pub fn may_define_opaque_type(
 ///
 /// Requires that trait definitions have been processed so that we can
 /// elaborate predicates and walk supertraits.
-//
-// FIXME: callers may only have a `&[Predicate]`, not a `Vec`, so that's
-// what this code should accept.
 crate fn required_region_bounds(
     tcx: TyCtxt<'tcx>,
     erased_self_ty: Ty<'tcx>,
diff --git a/src/libstd/os/linux/raw.rs b/src/libstd/os/linux/raw.rs
index 0caec97bb7b90..eb8589eb58f47 100644
--- a/src/libstd/os/linux/raw.rs
+++ b/src/libstd/os/linux/raw.rs
@@ -170,7 +170,7 @@ mod arch {
 
 #[cfg(target_arch = "hexagon")]
 mod arch {
-    use crate::os::raw::{c_int, c_long, c_longlong, culonglong};
+    use crate::os::raw::{c_int, c_long, c_longlong, c_ulonglong};
 
     #[stable(feature = "raw_ext", since = "1.1.0")]
     pub type blkcnt_t = c_longlong;
diff --git a/src/test/ui/issues/issue-17546.stderr b/src/test/ui/issues/issue-17546.stderr
index 8bf40790f0b24..95939cf6b3840 100644
--- a/src/test/ui/issues/issue-17546.stderr
+++ b/src/test/ui/issues/issue-17546.stderr
@@ -30,11 +30,10 @@ LL |     use std::fmt::Result;
    |
 LL |     use std::io::Result;
    |
-LL |     use std::prelude::v1::Result;
-   |
 LL |     use std::result::Result;
    |
-     and 1 other candidate
+LL |     use std::thread::Result;
+   |
 
 error[E0573]: expected type, found variant `Result`
   --> $DIR/issue-17546.rs:30:13
@@ -48,11 +47,10 @@ LL | use std::fmt::Result;
    |
 LL | use std::io::Result;
    |
-LL | use std::prelude::v1::Result;
-   |
 LL | use std::result::Result;
    |
-     and 1 other candidate
+LL | use std::thread::Result;
+   |
 
 error[E0573]: expected type, found variant `NoResult`
   --> $DIR/issue-17546.rs:35:15
diff --git a/src/test/ui/no-implicit-prelude-nested.stderr b/src/test/ui/no-implicit-prelude-nested.stderr
index 8a26366d751d3..198b630c52c8f 100644
--- a/src/test/ui/no-implicit-prelude-nested.stderr
+++ b/src/test/ui/no-implicit-prelude-nested.stderr
@@ -15,12 +15,10 @@ error[E0404]: expected trait, found derive macro `Clone`
 LL |         impl Clone for Test {}
    |              ^^^^^ not a trait
    |
-help: consider importing one of these items instead
+help: consider importing this trait instead
    |
 LL |         use std::clone::Clone;
    |
-LL |         use std::prelude::v1::Clone;
-   |
 
 error[E0405]: cannot find trait `Iterator` in this scope
   --> $DIR/no-implicit-prelude-nested.rs:13:14
@@ -28,12 +26,10 @@ error[E0405]: cannot find trait `Iterator` in this scope
 LL |         impl Iterator for Test {}
    |              ^^^^^^^^ not found in this scope
    |
-help: consider importing one of these items
+help: consider importing this trait
    |
 LL |         use std::iter::Iterator;
    |
-LL |         use std::prelude::v1::Iterator;
-   |
 
 error[E0405]: cannot find trait `ToString` in this scope
   --> $DIR/no-implicit-prelude-nested.rs:14:14
@@ -41,9 +37,7 @@ error[E0405]: cannot find trait `ToString` in this scope
 LL |         impl ToString for Test {}
    |              ^^^^^^^^ not found in this scope
    |
-help: consider importing one of these items
-   |
-LL |         use std::prelude::v1::ToString;
+help: consider importing this trait
    |
 LL |         use std::string::ToString;
    |
@@ -60,12 +54,10 @@ error[E0425]: cannot find function `drop` in this scope
 LL |             drop(2)
    |             ^^^^ not found in this scope
    |
-help: consider importing one of these items
+help: consider importing this function
    |
 LL |         use std::mem::drop;
    |
-LL |         use std::prelude::v1::drop;
-   |
 
 error[E0405]: cannot find trait `Add` in this scope
   --> $DIR/no-implicit-prelude-nested.rs:23:10
@@ -84,12 +76,10 @@ error[E0404]: expected trait, found derive macro `Clone`
 LL |     impl Clone for Test {}
    |          ^^^^^ not a trait
    |
-help: consider importing one of these items instead
+help: consider importing this trait instead
    |
 LL |     use std::clone::Clone;
    |
-LL |     use std::prelude::v1::Clone;
-   |
 
 error[E0405]: cannot find trait `Iterator` in this scope
   --> $DIR/no-implicit-prelude-nested.rs:25:10
@@ -97,12 +87,10 @@ error[E0405]: cannot find trait `Iterator` in this scope
 LL |     impl Iterator for Test {}
    |          ^^^^^^^^ not found in this scope
    |
-help: consider importing one of these items
+help: consider importing this trait
    |
 LL |     use std::iter::Iterator;
    |
-LL |     use std::prelude::v1::Iterator;
-   |
 
 error[E0405]: cannot find trait `ToString` in this scope
   --> $DIR/no-implicit-prelude-nested.rs:26:10
@@ -110,9 +98,7 @@ error[E0405]: cannot find trait `ToString` in this scope
 LL |     impl ToString for Test {}
    |          ^^^^^^^^ not found in this scope
    |
-help: consider importing one of these items
-   |
-LL |     use std::prelude::v1::ToString;
+help: consider importing this trait
    |
 LL |     use std::string::ToString;
    |
@@ -129,12 +115,10 @@ error[E0425]: cannot find function `drop` in this scope
 LL |         drop(2)
    |         ^^^^ not found in this scope
    |
-help: consider importing one of these items
+help: consider importing this function
    |
 LL |     use std::mem::drop;
    |
-LL |     use std::prelude::v1::drop;
-   |
 
 error[E0405]: cannot find trait `Add` in this scope
   --> $DIR/no-implicit-prelude-nested.rs:38:14
@@ -153,12 +137,10 @@ error[E0404]: expected trait, found derive macro `Clone`
 LL |         impl Clone for Test {}
    |              ^^^^^ not a trait
    |
-help: consider importing one of these items instead
+help: consider importing this trait instead
    |
 LL |         use std::clone::Clone;
    |
-LL |         use std::prelude::v1::Clone;
-   |
 
 error[E0405]: cannot find trait `Iterator` in this scope
   --> $DIR/no-implicit-prelude-nested.rs:40:14
@@ -166,12 +148,10 @@ error[E0405]: cannot find trait `Iterator` in this scope
 LL |         impl Iterator for Test {}
    |              ^^^^^^^^ not found in this scope
    |
-help: consider importing one of these items
+help: consider importing this trait
    |
 LL |         use std::iter::Iterator;
    |
-LL |         use std::prelude::v1::Iterator;
-   |
 
 error[E0405]: cannot find trait `ToString` in this scope
   --> $DIR/no-implicit-prelude-nested.rs:41:14
@@ -179,9 +159,7 @@ error[E0405]: cannot find trait `ToString` in this scope
 LL |         impl ToString for Test {}
    |              ^^^^^^^^ not found in this scope
    |
-help: consider importing one of these items
-   |
-LL |         use std::prelude::v1::ToString;
+help: consider importing this trait
    |
 LL |         use std::string::ToString;
    |
@@ -198,12 +176,10 @@ error[E0425]: cannot find function `drop` in this scope
 LL |             drop(2)
    |             ^^^^ not found in this scope
    |
-help: consider importing one of these items
+help: consider importing this function
    |
 LL |         use std::mem::drop;
    |
-LL |         use std::prelude::v1::drop;
-   |
 
 error: aborting due to 18 previous errors
 
diff --git a/src/test/ui/no-implicit-prelude.stderr b/src/test/ui/no-implicit-prelude.stderr
index 9cda4f64c79d0..36a9b65b7d161 100644
--- a/src/test/ui/no-implicit-prelude.stderr
+++ b/src/test/ui/no-implicit-prelude.stderr
@@ -15,12 +15,10 @@ error[E0404]: expected trait, found derive macro `Clone`
 LL | impl Clone for Test {}
    |      ^^^^^ not a trait
    |
-help: consider importing one of these items instead
+help: consider importing this trait instead
    |
 LL | use std::clone::Clone;
    |
-LL | use std::prelude::v1::Clone;
-   |
 
 error[E0405]: cannot find trait `Iterator` in this scope
   --> $DIR/no-implicit-prelude.rs:12:6
@@ -28,12 +26,10 @@ error[E0405]: cannot find trait `Iterator` in this scope
 LL | impl Iterator for Test {}
    |      ^^^^^^^^ not found in this scope
    |
-help: consider importing one of these items
+help: consider importing this trait
    |
 LL | use std::iter::Iterator;
    |
-LL | use std::prelude::v1::Iterator;
-   |
 
 error[E0405]: cannot find trait `ToString` in this scope
   --> $DIR/no-implicit-prelude.rs:13:6
@@ -41,9 +37,7 @@ error[E0405]: cannot find trait `ToString` in this scope
 LL | impl ToString for Test {}
    |      ^^^^^^^^ not found in this scope
    |
-help: consider importing one of these items
-   |
-LL | use std::prelude::v1::ToString;
+help: consider importing this trait
    |
 LL | use std::string::ToString;
    |
@@ -60,12 +54,10 @@ error[E0425]: cannot find function `drop` in this scope
 LL |     drop(2)
    |     ^^^^ not found in this scope
    |
-help: consider importing one of these items
+help: consider importing this function
    |
 LL | use std::mem::drop;
    |
-LL | use std::prelude::v1::drop;
-   |
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/resolve/use_suggestion_placement.stderr b/src/test/ui/resolve/use_suggestion_placement.stderr
index 9c337f515adbc..3f91760fe216b 100644
--- a/src/test/ui/resolve/use_suggestion_placement.stderr
+++ b/src/test/ui/resolve/use_suggestion_placement.stderr
@@ -26,12 +26,10 @@ error[E0412]: cannot find type `HashMap` in this scope
 LL |     type Dict<K, V> = HashMap<K, V>;
    |                       ^^^^^^^ not found in this scope
    |
-help: consider importing one of these items
+help: consider importing this struct
    |
 LL | use std::collections::HashMap;
    |
-LL | use std::collections::hash_map::HashMap;
-   |
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/unterminated-comment.rs b/src/test/ui/unterminated-comment.rs
new file mode 100644
index 0000000000000..1cfdfb1fb4575
--- /dev/null
+++ b/src/test/ui/unterminated-comment.rs
@@ -0,0 +1 @@
+/* //~ ERROR E0758
diff --git a/src/test/ui/unterminated-comment.stderr b/src/test/ui/unterminated-comment.stderr
new file mode 100644
index 0000000000000..c513fafeeb35c
--- /dev/null
+++ b/src/test/ui/unterminated-comment.stderr
@@ -0,0 +1,9 @@
+error[E0758]: unterminated block comment
+  --> $DIR/unterminated-comment.rs:1:1
+   |
+LL | /*
+   | ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0758`.
diff --git a/src/test/ui/unterminated-doc-comment.rs b/src/test/ui/unterminated-doc-comment.rs
new file mode 100644
index 0000000000000..82546fe73da4f
--- /dev/null
+++ b/src/test/ui/unterminated-doc-comment.rs
@@ -0,0 +1 @@
+/*! //~ ERROR E0758
diff --git a/src/test/ui/unterminated-doc-comment.stderr b/src/test/ui/unterminated-doc-comment.stderr
new file mode 100644
index 0000000000000..2d5e537973ea8
--- /dev/null
+++ b/src/test/ui/unterminated-doc-comment.stderr
@@ -0,0 +1,9 @@
+error[E0758]: unterminated block doc-comment
+  --> $DIR/unterminated-doc-comment.rs:1:1
+   |
+LL | /*!
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0758`.