about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-01-15 13:56:16 +0000
committerbors <bors@rust-lang.org>2019-01-15 13:56:16 +0000
commit14ea6e50c1534a23cb51375552c14568db9ee130 (patch)
tree6758b33999db15ce1380535345a94afb2cb8d788
parent920192490f3eea0cf3b2e58e28912eb68423fdde (diff)
parent9947b3060c165ef2677c0e0454991a53ef743224 (diff)
downloadrust-14ea6e50c1534a23cb51375552c14568db9ee130.tar.gz
rust-14ea6e50c1534a23cb51375552c14568db9ee130.zip
Auto merge of #57630 - Centril:rollup, r=Centril
Rollup of 8 pull requests

Successful merges:

 - #56044 (Drop partially bound function parameters in the expected order)
 - #57352 (forbid manually impl'ing one of an object type's marker traits)
 - #57456 (RawVec doesn't always abort on allocation errors)
 - #57467 (Implement `check_attribute` to forbid `#[allow_internal_unsafe]`)
 - #57579 (Add core::iter::once_with())
 - #57587 (Add 'rustc-env:RUST_BACKTRACE=0' to const-pat-ice test)
 - #57608 (Simplify 'product' factorial example)
 - #57614 ([rustdoc] Fix crates filtering box not being filled)

Failed merges:

r? @ghost
-rw-r--r--src/liballoc/raw_vec.rs2
-rw-r--r--src/libcore/iter/iterator.rs2
-rw-r--r--src/libcore/iter/mod.rs2
-rw-r--r--src/libcore/iter/sources.rs113
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/tests/iter.rs18
-rw-r--r--src/libcore/tests/lib.rs1
-rw-r--r--src/librustc_lint/builtin.rs43
-rw-r--r--src/librustc_lint/lib.rs2
-rw-r--r--src/librustc_mir/build/mod.rs14
-rw-r--r--src/librustc_typeck/coherence/mod.rs17
-rw-r--r--src/librustdoc/html/static/main.js2
-rw-r--r--src/libsyntax/ast.rs4
-rw-r--r--src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs68
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs29
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr37
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs29
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr37
-rw-r--r--src/test/ui/lint/lint-forbid-internal-unsafe.rs16
-rw-r--r--src/test/ui/lint/lint-forbid-internal-unsafe.stderr14
-rw-r--r--src/test/ui/pattern/const-pat-ice.rs1
21 files changed, 417 insertions, 35 deletions
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index c05452bcf4d..5e4aac9ce78 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -22,7 +22,7 @@ use boxed::Box;
 /// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics)
 /// * Guards against 32-bit systems allocating more than isize::MAX bytes
 /// * Guards against overflowing your length
-/// * Aborts on OOM
+/// * Aborts on OOM or calls handle_alloc_error as applicable
 /// * Avoids freeing Unique::empty()
 /// * Contains a ptr::Unique and thus endows the user with all related benefits
 ///
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 640af748172..0ad29afbade 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -2358,7 +2358,7 @@ pub trait Iterator {
     ///
     /// ```
     /// fn factorial(n: u32) -> u32 {
-    ///     (1..).take_while(|&i| i <= n).product()
+    ///     (1..=n).product()
     /// }
     /// assert_eq!(factorial(0), 1);
     /// assert_eq!(factorial(1), 1);
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index 1ef5428a789..974906b682d 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -329,6 +329,8 @@ pub use self::sources::{RepeatWith, repeat_with};
 pub use self::sources::{Empty, empty};
 #[stable(feature = "iter_once", since = "1.2.0")]
 pub use self::sources::{Once, once};
+#[unstable(feature = "iter_once_with", issue = "57581")]
+pub use self::sources::{OnceWith, once_with};
 #[unstable(feature = "iter_unfold", issue = "55977")]
 pub use self::sources::{Unfold, unfold, Successors, successors};
 
diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs
index 2a39089a8a2..2590fa6023a 100644
--- a/src/libcore/iter/sources.rs
+++ b/src/libcore/iter/sources.rs
@@ -377,6 +377,119 @@ pub fn once<T>(value: T) -> Once<T> {
     Once { inner: Some(value).into_iter() }
 }
 
+/// An iterator that repeats elements of type `A` endlessly by
+/// applying the provided closure `F: FnMut() -> A`.
+///
+/// This `struct` is created by the [`once_with`] function.
+/// See its documentation for more.
+///
+/// [`once_with`]: fn.once_with.html
+#[derive(Copy, Clone, Debug)]
+#[unstable(feature = "iter_once_with", issue = "57581")]
+pub struct OnceWith<F> {
+    gen: Option<F>,
+}
+
+#[unstable(feature = "iter_once_with", issue = "57581")]
+impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
+    type Item = A;
+
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        self.gen.take().map(|f| f())
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.gen.iter().size_hint()
+    }
+}
+
+#[unstable(feature = "iter_once_with", issue = "57581")]
+impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F> {
+    fn next_back(&mut self) -> Option<A> {
+        self.next()
+    }
+}
+
+#[unstable(feature = "iter_once_with", issue = "57581")]
+impl<A, F: FnOnce() -> A> ExactSizeIterator for OnceWith<F> {
+    fn len(&self) -> usize {
+        self.gen.iter().len()
+    }
+}
+
+#[unstable(feature = "iter_once_with", issue = "57581")]
+impl<A, F: FnOnce() -> A> FusedIterator for OnceWith<F> {}
+
+#[unstable(feature = "iter_once_with", issue = "57581")]
+unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}
+
+/// Creates an iterator that lazily generates a value exactly once by invoking
+/// the provided closure.
+///
+/// This is commonly used to adapt a single value generator into a [`chain`] of
+/// other kinds of iteration. Maybe you have an iterator that covers almost
+/// everything, but you need an extra special case. Maybe you have a function
+/// which works on iterators, but you only need to process one value.
+///
+/// Unlike [`once`], this function will lazily generate the value on request.
+///
+/// [`once`]: fn.once.html
+/// [`chain`]: trait.Iterator.html#method.chain
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// #![feature(iter_once_with)]
+///
+/// use std::iter;
+///
+/// // one is the loneliest number
+/// let mut one = iter::once_with(|| 1);
+///
+/// assert_eq!(Some(1), one.next());
+///
+/// // just one, that's all we get
+/// assert_eq!(None, one.next());
+/// ```
+///
+/// Chaining together with another iterator. Let's say that we want to iterate
+/// over each file of the `.foo` directory, but also a configuration file,
+/// `.foorc`:
+///
+/// ```no_run
+/// #![feature(iter_once_with)]
+///
+/// use std::iter;
+/// use std::fs;
+/// use std::path::PathBuf;
+///
+/// let dirs = fs::read_dir(".foo").unwrap();
+///
+/// // we need to convert from an iterator of DirEntry-s to an iterator of
+/// // PathBufs, so we use map
+/// let dirs = dirs.map(|file| file.unwrap().path());
+///
+/// // now, our iterator just for our config file
+/// let config = iter::once_with(|| PathBuf::from(".foorc"));
+///
+/// // chain the two iterators together into one big iterator
+/// let files = dirs.chain(config);
+///
+/// // this will give us all of the files in .foo as well as .foorc
+/// for f in files {
+///     println!("{:?}", f);
+/// }
+/// ```
+#[inline]
+#[unstable(feature = "iter_once_with", issue = "57581")]
+pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
+    OnceWith { gen: Some(gen) }
+}
+
 /// Creates a new iterator where each iteration calls the provided closure
 /// `F: FnMut(&mut St) -> Option<T>`.
 ///
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 8879112fcf0..33c0da8a540 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -79,6 +79,7 @@
 #![feature(extern_types)]
 #![feature(fundamental)]
 #![feature(intrinsics)]
+#![feature(iter_once_with)]
 #![feature(lang_items)]
 #![feature(link_llvm_intrinsics)]
 #![feature(never_type)]
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index cf19851c17b..3944bc749d0 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1,3 +1,4 @@
+use core::cell::Cell;
 use core::iter::*;
 use core::{i8, i16, isize};
 use core::usize;
@@ -1907,6 +1908,23 @@ fn test_once() {
 }
 
 #[test]
+fn test_once_with() {
+    let count = Cell::new(0);
+    let mut it = once_with(|| {
+        count.set(count.get() + 1);
+        42
+    });
+
+    assert_eq!(count.get(), 0);
+    assert_eq!(it.next(), Some(42));
+    assert_eq!(count.get(), 1);
+    assert_eq!(it.next(), None);
+    assert_eq!(count.get(), 1);
+    assert_eq!(it.next(), None);
+    assert_eq!(count.get(), 1);
+}
+
+#[test]
 fn test_empty() {
     let mut it = empty::<i32>();
     assert_eq!(it.next(), None);
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 72846daf16a..a9b8decfd02 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -12,6 +12,7 @@
 #![feature(hashmap_internals)]
 #![feature(iter_copied)]
 #![feature(iter_nth_back)]
+#![feature(iter_once_with)]
 #![feature(iter_unfold)]
 #![feature(pattern)]
 #![feature(range_is_empty)]
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 72bcf8edfdd..ddb397b7c7f 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -40,9 +40,9 @@ use syntax_pos::{BytePos, Span, SyntaxContext};
 use syntax::symbol::keywords;
 use syntax::errors::{Applicability, DiagnosticBuilder};
 use syntax::print::pprust::expr_to_string;
+use syntax::visit::FnKind;
 
 use rustc::hir::{self, GenericParamKind, PatKind};
-use rustc::hir::intravisit::FnKind;
 
 use nonstandard_style::{MethodLateContext, method_context};
 
@@ -216,7 +216,7 @@ impl LintPass for UnsafeCode {
 }
 
 impl UnsafeCode {
-    fn report_unsafe(&self, cx: &LateContext, span: Span, desc: &'static str) {
+    fn report_unsafe(&self, cx: &EarlyContext, span: Span, desc: &'static str) {
         // This comes from a macro that has #[allow_internal_unsafe].
         if span.allows_unsafe() {
             return;
@@ -226,23 +226,31 @@ impl UnsafeCode {
     }
 }
 
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
-    fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
-        if let hir::ExprKind::Block(ref blk, _) = e.node {
+impl EarlyLintPass for UnsafeCode {
+    fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
+        if attr.check_name("allow_internal_unsafe") {
+            self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \
+                                               macros using unsafe without triggering \
+                                               the `unsafe_code` lint at their call site");
+        }
+    }
+
+    fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) {
+        if let ast::ExprKind::Block(ref blk, _) = e.node {
             // Don't warn about generated blocks, that'll just pollute the output.
-            if blk.rules == hir::UnsafeBlock(hir::UserProvided) {
+            if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) {
                 self.report_unsafe(cx, blk.span, "usage of an `unsafe` block");
             }
         }
     }
 
-    fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
+    fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
         match it.node {
-            hir::ItemKind::Trait(_, hir::Unsafety::Unsafe, ..) => {
+            ast::ItemKind::Trait(_, ast::Unsafety::Unsafe, ..) => {
                 self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait")
             }
 
-            hir::ItemKind::Impl(hir::Unsafety::Unsafe, ..) => {
+            ast::ItemKind::Impl(ast::Unsafety::Unsafe, ..) => {
                 self.report_unsafe(cx, it.span, "implementation of an `unsafe` trait")
             }
 
@@ -251,19 +259,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
     }
 
     fn check_fn(&mut self,
-                cx: &LateContext,
-                fk: FnKind<'tcx>,
-                _: &hir::FnDecl,
-                _: &hir::Body,
+                cx: &EarlyContext,
+                fk: FnKind,
+                _: &ast::FnDecl,
                 span: Span,
                 _: ast::NodeId) {
         match fk {
-            FnKind::ItemFn(_, _, hir::FnHeader { unsafety: hir::Unsafety::Unsafe, .. }, ..) => {
+            FnKind::ItemFn(_, ast::FnHeader { unsafety: ast::Unsafety::Unsafe, .. }, ..) => {
                 self.report_unsafe(cx, span, "declaration of an `unsafe` function")
             }
 
             FnKind::Method(_, sig, ..) => {
-                if sig.header.unsafety == hir::Unsafety::Unsafe {
+                if sig.header.unsafety == ast::Unsafety::Unsafe {
                     self.report_unsafe(cx, span, "implementation of an `unsafe` method")
                 }
             }
@@ -272,9 +279,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode {
         }
     }
 
-    fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) {
-        if let hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(_)) = item.node {
-            if sig.header.unsafety == hir::Unsafety::Unsafe {
+    fn check_trait_item(&mut self, cx: &EarlyContext, item: &ast::TraitItem) {
+        if let ast::TraitItemKind::Method(ref sig, None) = item.node {
+            if sig.header.unsafety == ast::Unsafety::Unsafe {
                 self.report_unsafe(cx, item.span, "declaration of an `unsafe` method")
             }
         }
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 4dfb664451b..0d05cc1b2be 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -111,6 +111,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
     add_early_builtin!(sess,
                        UnusedParens,
                        UnusedImportBraces,
+                       UnsafeCode,
                        AnonymousParameters,
                        UnusedDocComment,
                        BadRepr,
@@ -134,7 +135,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
         NonSnakeCase: NonSnakeCase,
         NonUpperCaseGlobals: NonUpperCaseGlobals,
         NonShorthandFieldPatterns: NonShorthandFieldPatterns,
-        UnsafeCode: UnsafeCode,
         UnusedAllocation: UnusedAllocation,
         MissingCopyImplementations: MissingCopyImplementations,
         UnstableFeatures: UnstableFeatures,
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 65ae111fbc0..2bf2824d835 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -910,6 +910,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             let place = Place::Local(local);
             let &ArgInfo(ty, opt_ty_info, pattern, ref self_binding) = arg_info;
 
+            // Make sure we drop (parts of) the argument even when not matched on.
+            self.schedule_drop(
+                pattern.as_ref().map_or(ast_body.span, |pat| pat.span),
+                argument_scope, &place, ty,
+                DropKind::Value { cached_block: CachedBlock::default() },
+            );
+
             if let Some(pattern) = pattern {
                 let pattern = self.hir.pattern_from_hir(pattern);
                 let span = pattern.span;
@@ -941,13 +948,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                     }
                 }
             }
-
-            // Make sure we drop (parts of) the argument even when not matched on.
-            self.schedule_drop(
-                pattern.as_ref().map_or(ast_body.span, |pat| pat.span),
-                argument_scope, &place, ty,
-                DropKind::Value { cached_block: CachedBlock::default() },
-            );
         }
 
         // Enter the argument pattern bindings source scope, if it exists.
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index ce71be07efd..8053ed130e9 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -171,13 +171,23 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI
         // This is something like impl Trait1 for Trait2. Illegal
         // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
 
-        if let Some(principal_def_id) = data.principal_def_id() {
-            if !tcx.is_object_safe(principal_def_id) {
+        let component_def_ids = data.iter().flat_map(|predicate| {
+            match predicate.skip_binder() {
+                ty::ExistentialPredicate::Trait(tr) => Some(tr.def_id),
+                ty::ExistentialPredicate::AutoTrait(def_id) => Some(*def_id),
+                // An associated type projection necessarily comes with
+                // an additional `Trait` requirement.
+                ty::ExistentialPredicate::Projection(..) => None,
+            }
+        });
+
+        for component_def_id in component_def_ids {
+            if !tcx.is_object_safe(component_def_id) {
                 // This is an error, but it will be reported by wfcheck.  Ignore it here.
                 // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
             } else {
                 let mut supertrait_def_ids =
-                    traits::supertrait_def_ids(tcx, principal_def_id);
+                    traits::supertrait_def_ids(tcx, component_def_id);
                 if supertrait_def_ids.any(|d| d == trait_def_id) {
                     let sp = tcx.sess.source_map().def_span(tcx.span_of_impl(impl_def_id).unwrap());
                     struct_span_err!(tcx.sess,
@@ -193,6 +203,5 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI
                 }
             }
         }
-        // FIXME: also check auto-trait def-ids? (e.g. `impl Sync for Foo+Sync`)?
     }
 }
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 9db1c686090..ceadbd5afac 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -2431,7 +2431,7 @@ if (!DOMTokenList.prototype.remove) {
             return;
         }
         var crates_text = [];
-        if (crates.length > 1) {
+        if (Object.keys(crates).length > 1) {
             for (var crate in crates) {
                 if (crates.hasOwnProperty(crate)) {
                     crates_text.push(crate);
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index e3a8980a975..99ab9fbcf5f 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -853,13 +853,13 @@ pub struct Field {
 
 pub type SpannedIdent = Spanned<Ident>;
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
 pub enum BlockCheckMode {
     Default,
     Unsafe(UnsafeSource),
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
 pub enum UnsafeSource {
     CompilerGenerated,
     UserProvided,
diff --git a/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs b/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs
new file mode 100644
index 00000000000..4d5a6fbba28
--- /dev/null
+++ b/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs
@@ -0,0 +1,68 @@
+// Check that partially moved from function parameters are dropped after the
+// named bindings that move from them.
+
+// ignore-wasm32-bare compiled with panic=abort by default
+
+use std::{panic, cell::RefCell};
+
+struct LogDrop<'a>(i32, Context<'a>);
+
+#[derive(Copy, Clone)]
+struct Context<'a> {
+    panic_on: i32,
+    drops: &'a RefCell<Vec<i32>>,
+}
+
+impl<'a> Context<'a> {
+    fn record_drop(self, index: i32) {
+        self.drops.borrow_mut().push(index);
+        if index == self.panic_on {
+            panic!();
+        }
+    }
+}
+
+impl<'a> Drop for LogDrop<'a> {
+    fn drop(&mut self) {
+        self.1.record_drop(self.0);
+    }
+}
+
+fn bindings_in_params((_x, _): (LogDrop, LogDrop), (_, _y): (LogDrop, LogDrop)) {}
+fn bindings_with_let(a: (LogDrop, LogDrop), b: (LogDrop, LogDrop)) {
+    // Drop order in foo is the same as the following bindings.
+    // _temp2 is declared after _x to avoid a difference between `_: T` and
+    // `x: T` in function parameters.
+    let _temp1 = a;
+    let (_x, _) = _temp1;
+
+    let _temp2 = b;
+    let (_, _y) = _temp2;
+}
+
+fn test_drop_order(panic_on: i32, fun: fn((LogDrop, LogDrop), (LogDrop, LogDrop))) {
+    let context = Context {
+        panic_on,
+        drops: &RefCell::new(Vec::new()),
+    };
+    let one = LogDrop(1, context);
+    let two = LogDrop(2, context);
+    let three = LogDrop(3, context);
+    let four = LogDrop(4, context);
+
+    let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
+        fun((three, four), (two, one));
+    }));
+    if panic_on == 0 {
+        assert!(res.is_ok(), "should not have panicked");
+    } else {
+        assert!(res.is_err(), "should have panicked");
+    }
+    assert_eq!(*context.drops.borrow(), [1, 2, 3, 4], "incorrect drop order");
+}
+
+fn main() {
+    (0..=4).for_each(|i| test_drop_order(i, bindings_in_params));
+    (0..=4).for_each(|i| test_drop_order(i, bindings_with_let));
+    (0..=4).for_each(|i| test_drop_order(i, |(_x, _), (_, _y)| {}));
+}
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs
new file mode 100644
index 00000000000..5ea69190951
--- /dev/null
+++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs
@@ -0,0 +1,29 @@
+#![feature(optin_builtin_traits)]
+
+// Test for issue #56934 - that it is impossible to redundantly
+// implement an auto-trait for a trait object type that contains it.
+
+// Negative impl variant.
+
+auto trait Marker1 {}
+auto trait Marker2 {}
+
+trait Object: Marker1 {}
+
+// A supertrait marker is illegal...
+impl !Marker1 for dyn Object + Marker2 { }   //~ ERROR E0371
+// ...and also a direct component.
+impl !Marker2 for dyn Object + Marker2 { }   //~ ERROR E0371
+
+// But implementing a marker if it is not present is OK.
+impl !Marker2 for dyn Object {} // OK
+
+// A non-principal trait-object type is orphan even in its crate.
+impl !Send for dyn Marker2 {} //~ ERROR E0117
+
+// And impl'ing a remote marker for a local trait object is forbidden
+// by one of these special orphan-like rules.
+impl !Send for dyn Object {} //~ ERROR E0321
+impl !Send for dyn Object + Marker2 {} //~ ERROR E0321
+
+fn main() { }
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr
new file mode 100644
index 00000000000..c8a146cdd44
--- /dev/null
+++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr
@@ -0,0 +1,37 @@
+error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
+  --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:14:1
+   |
+LL | impl !Marker1 for dyn Object + Marker2 { }   //~ ERROR E0371
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
+
+error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
+  --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:16:1
+   |
+LL | impl !Marker2 for dyn Object + Marker2 { }   //~ ERROR E0371
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
+
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+  --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:22:1
+   |
+LL | impl !Send for dyn Marker2 {} //~ ERROR E0117
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
+   |
+   = note: the impl does not reference only types defined in this crate
+   = note: define and implement a trait or new type instead
+
+error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)`
+  --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:26:1
+   |
+LL | impl !Send for dyn Object {} //~ ERROR E0321
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
+
+error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker2 + 'static)`
+  --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:27:1
+   |
+LL | impl !Send for dyn Object + Marker2 {} //~ ERROR E0321
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
+
+error: aborting due to 5 previous errors
+
+Some errors occurred: E0117, E0321, E0371.
+For more information about an error, try `rustc --explain E0117`.
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs
new file mode 100644
index 00000000000..6b5689e8260
--- /dev/null
+++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs
@@ -0,0 +1,29 @@
+#![feature(optin_builtin_traits)]
+
+// Test for issue #56934 - that it is impossible to redundantly
+// implement an auto-trait for a trait object type that contains it.
+
+// Positive impl variant.
+
+auto trait Marker1 {}
+auto trait Marker2 {}
+
+trait Object: Marker1 {}
+
+// A supertrait marker is illegal...
+impl Marker1 for dyn Object + Marker2 { }   //~ ERROR E0371
+// ...and also a direct component.
+impl Marker2 for dyn Object + Marker2 { }   //~ ERROR E0371
+
+// But implementing a marker if it is not present is OK.
+impl Marker2 for dyn Object {} // OK
+
+// A non-principal trait-object type is orphan even in its crate.
+unsafe impl Send for dyn Marker2 {} //~ ERROR E0117
+
+// And impl'ing a remote marker for a local trait object is forbidden
+// by one of these special orphan-like rules.
+unsafe impl Send for dyn Object {} //~ ERROR E0321
+unsafe impl Send for dyn Object + Marker2 {} //~ ERROR E0321
+
+fn main() { }
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr
new file mode 100644
index 00000000000..78ca2f5279d
--- /dev/null
+++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr
@@ -0,0 +1,37 @@
+error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
+  --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:14:1
+   |
+LL | impl Marker1 for dyn Object + Marker2 { }   //~ ERROR E0371
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
+
+error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
+  --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:16:1
+   |
+LL | impl Marker2 for dyn Object + Marker2 { }   //~ ERROR E0371
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
+
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+  --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:22:1
+   |
+LL | unsafe impl Send for dyn Marker2 {} //~ ERROR E0117
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
+   |
+   = note: the impl does not reference only types defined in this crate
+   = note: define and implement a trait or new type instead
+
+error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)`
+  --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:26:1
+   |
+LL | unsafe impl Send for dyn Object {} //~ ERROR E0321
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
+
+error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker2 + 'static)`
+  --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:27:1
+   |
+LL | unsafe impl Send for dyn Object + Marker2 {} //~ ERROR E0321
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
+
+error: aborting due to 5 previous errors
+
+Some errors occurred: E0117, E0321, E0371.
+For more information about an error, try `rustc --explain E0117`.
diff --git a/src/test/ui/lint/lint-forbid-internal-unsafe.rs b/src/test/ui/lint/lint-forbid-internal-unsafe.rs
new file mode 100644
index 00000000000..b08fbf6f845
--- /dev/null
+++ b/src/test/ui/lint/lint-forbid-internal-unsafe.rs
@@ -0,0 +1,16 @@
+#![forbid(unsafe_code)]
+#![feature(allow_internal_unsafe)]
+
+#[allow_internal_unsafe]
+//~^ ERROR: `allow_internal_unsafe` allows defining
+macro_rules! evil {
+    ($e:expr) => {
+        unsafe {
+            $e
+        }
+    }
+}
+
+fn main() {
+    println!("{}", evil!(*(0 as *const u8)));
+}
diff --git a/src/test/ui/lint/lint-forbid-internal-unsafe.stderr b/src/test/ui/lint/lint-forbid-internal-unsafe.stderr
new file mode 100644
index 00000000000..59dab119682
--- /dev/null
+++ b/src/test/ui/lint/lint-forbid-internal-unsafe.stderr
@@ -0,0 +1,14 @@
+error: `allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site
+  --> $DIR/lint-forbid-internal-unsafe.rs:4:1
+   |
+LL | #[allow_internal_unsafe]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/lint-forbid-internal-unsafe.rs:1:11
+   |
+LL | #![forbid(unsafe_code)]
+   |           ^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pattern/const-pat-ice.rs b/src/test/ui/pattern/const-pat-ice.rs
index 6496a2ab69f..865c54be1ad 100644
--- a/src/test/ui/pattern/const-pat-ice.rs
+++ b/src/test/ui/pattern/const-pat-ice.rs
@@ -1,4 +1,5 @@
 // failure-status: 101
+// rustc-env:RUST_BACKTRACE=0
 
 // This is a repro test for an ICE in our pattern handling of constants.