about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-11-01 05:34:00 +0000
committerbors <bors@rust-lang.org>2022-11-01 05:34:00 +0000
commitdc05f60c1ff4e2cb2e6eb80c9b3afa612ce28c7f (patch)
treeb0ae44f23cbf5efc6300d241a6eb94cac1d61915
parent024207ab43aceb49f2ca957509c503ccf12089d7 (diff)
parent669e3cde1c24c10223fca6dfe51c2ee6d722545b (diff)
downloadrust-dc05f60c1ff4e2cb2e6eb80c9b3afa612ce28c7f.tar.gz
rust-dc05f60c1ff4e2cb2e6eb80c9b3afa612ce28c7f.zip
Auto merge of #103829 - JohnTitor:rollup-o03nzr8, r=JohnTitor
Rollup of 10 pull requests

Successful merges:

 - #103007 (Add better python discovery)
 - #103674 (Update note about unstable split-debuginfo flag.)
 - #103692 (Add `walk_generic_arg`)
 - #103749 (Reduce span of let else irrefutable_let_patterns warning)
 - #103772 (better error for `rustc_strict_coherence` misuse)
 - #103788 (Fix ICE in checking transmutability of NaughtyLenArray)
 - #103793 (rustdoc: add margins to all impl-item toggles, not just methods)
 - #103798 (interpret: move type_name implementation to an interpreter-independent helper file)
 - #103799 (Remove generation of tuple struct fields in the search index)
 - #103805 (Enable RUSTC_BOOTSTRAP for a few steps)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs14
-rw-r--r--compiler/rustc_const_eval/src/util/mod.rs2
-rw-r--r--compiler/rustc_const_eval/src/util/type_name.rs (renamed from compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs)8
-rw-r--r--compiler/rustc_error_messages/locales/en-US/middle.ftl4
-rw-r--r--compiler/rustc_hir/src/intravisit.rs16
-rw-r--r--compiler/rustc_middle/src/error.rs9
-rw-r--r--compiler/rustc_middle/src/traits/specialization_graph.rs17
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs18
-rw-r--r--compiler/rustc_transmute/src/layout/tree.rs3
-rw-r--r--src/bootstrap/test.rs3
-rw-r--r--src/doc/rustc/src/codegen-options/index.md6
-rw-r--r--src/librustdoc/formats/cache.rs37
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css14
-rw-r--r--src/test/rustdoc-gui/method-margins.goml17
-rw-r--r--src/test/rustdoc-gui/src/test_docs/lib.rs17
-rw-r--r--src/test/rustdoc/no-unit-struct-field.rs18
-rw-r--r--src/test/ui/coherence/strict-coherence-needs-negative-coherence.rs7
-rw-r--r--src/test/ui/coherence/strict-coherence-needs-negative-coherence.stderr10
-rw-r--r--src/test/ui/let-else/let-else-irrefutable.rs8
-rw-r--r--src/test/ui/let-else/let-else-irrefutable.stderr15
-rw-r--r--src/test/ui/transmutability/arrays/issue-103783-array-length.rs24
-rw-r--r--src/test/ui/transmutability/arrays/issue-103783-array-length.stderr9
-rwxr-xr-xx6
-rwxr-xr-xx.ps113
24 files changed, 238 insertions, 57 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 8637d6a7767..b92a6878847 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -7,7 +7,9 @@ use std::convert::TryFrom;
 use rustc_hir::def_id::DefId;
 use rustc_middle::mir::{
     self,
-    interpret::{ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar},
+    interpret::{
+        Allocation, ConstAllocation, ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar,
+    },
     BinOp, NonDivergingIntrinsic,
 };
 use rustc_middle::ty;
@@ -23,7 +25,6 @@ use super::{
 };
 
 mod caller_location;
-mod type_name;
 
 fn numeric_intrinsic<Prov>(name: Symbol, bits: u128, kind: Primitive) -> Scalar<Prov> {
     let size = match kind {
@@ -42,6 +43,13 @@ fn numeric_intrinsic<Prov>(name: Symbol, bits: u128, kind: Primitive) -> Scalar<
     Scalar::from_uint(bits_out, size)
 }
 
+/// Directly returns an `Allocation` containing an absolute path representation of the given type.
+pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> {
+    let path = crate::util::type_name(tcx, ty);
+    let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes());
+    tcx.intern_const_alloc(alloc)
+}
+
 /// The logic for all nullary intrinsics is implemented here. These intrinsics don't get evaluated
 /// inside an `InterpCx` and instead have their value computed directly from rustc internal info.
 pub(crate) fn eval_nullary_intrinsic<'tcx>(
@@ -55,7 +63,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
     Ok(match name {
         sym::type_name => {
             ensure_monomorphic_enough(tcx, tp_ty)?;
-            let alloc = type_name::alloc_type_name(tcx, tp_ty);
+            let alloc = alloc_type_name(tcx, tp_ty);
             ConstValue::Slice { data: alloc, start: 0, end: alloc.inner().len() }
         }
         sym::needs_drop => {
diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs
index 7a05cfd235f..4d0f81a4060 100644
--- a/compiler/rustc_const_eval/src/util/mod.rs
+++ b/compiler/rustc_const_eval/src/util/mod.rs
@@ -4,9 +4,11 @@ mod call_kind;
 pub mod collect_writes;
 mod find_self_call;
 mod might_permit_raw_init;
+mod type_name;
 
 pub use self::aggregate::expand_aggregate;
 pub use self::alignment::is_disaligned;
 pub use self::call_kind::{call_kind, CallDesugaringKind, CallKind};
 pub use self::find_self_call::find_self_call;
 pub use self::might_permit_raw_init::might_permit_raw_init;
+pub use self::type_name::type_name;
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs
index b15606baee5..221efc6f981 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics/type_name.rs
+++ b/compiler/rustc_const_eval/src/util/type_name.rs
@@ -1,7 +1,6 @@
 use rustc_data_structures::intern::Interned;
 use rustc_hir::def_id::CrateNum;
 use rustc_hir::definitions::DisambiguatedDefPathData;
-use rustc_middle::mir::interpret::{Allocation, ConstAllocation};
 use rustc_middle::ty::{
     self,
     print::{PrettyPrinter, Print, Printer},
@@ -193,9 +192,6 @@ impl Write for AbsolutePathPrinter<'_> {
     }
 }
 
-/// Directly returns an `Allocation` containing an absolute path representation of the given type.
-pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> {
-    let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path;
-    let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes());
-    tcx.intern_const_alloc(alloc)
+pub fn type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> String {
+    AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path
 }
diff --git a/compiler/rustc_error_messages/locales/en-US/middle.ftl b/compiler/rustc_error_messages/locales/en-US/middle.ftl
index b9e4499d47f..81d8e8a473b 100644
--- a/compiler/rustc_error_messages/locales/en-US/middle.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/middle.ftl
@@ -27,3 +27,7 @@ middle_values_too_big =
 
 middle_cannot_be_normalized =
     unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized
+
+middle_strict_coherence_needs_negative_coherence =
+    to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
+    .label = due to this attribute
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index be77e6fd36a..9ee5e25c9bf 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -410,12 +410,7 @@ pub trait Visitor<'v>: Sized {
         walk_inf(self, inf);
     }
     fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg<'v>) {
-        match generic_arg {
-            GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
-            GenericArg::Type(ty) => self.visit_ty(ty),
-            GenericArg::Const(ct) => self.visit_anon_const(&ct.value),
-            GenericArg::Infer(inf) => self.visit_infer(inf),
-        }
+        walk_generic_arg(self, generic_arg);
     }
     fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
         walk_lifetime(self, lifetime)
@@ -480,6 +475,15 @@ pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) {
     visitor.visit_ident(label.ident);
 }
 
+pub fn walk_generic_arg<'v, V: Visitor<'v>>(visitor: &mut V, generic_arg: &'v GenericArg<'v>) {
+    match generic_arg {
+        GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt),
+        GenericArg::Type(ty) => visitor.visit_ty(ty),
+        GenericArg::Const(ct) => visitor.visit_anon_const(&ct.value),
+        GenericArg::Infer(inf) => visitor.visit_infer(inf),
+    }
+}
+
 pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
     visitor.visit_id(lifetime.hir_id);
     match lifetime.name {
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
index a7a7ac0599d..43903e6739f 100644
--- a/compiler/rustc_middle/src/error.rs
+++ b/compiler/rustc_middle/src/error.rs
@@ -55,3 +55,12 @@ pub struct ConstEvalNonIntError {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(middle_strict_coherence_needs_negative_coherence)]
+pub(crate) struct StrictCoherenceNeedsNegativeCoherence {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub attr_span: Option<Span>,
+}
diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs
index 0a2819feecf..f1c21588261 100644
--- a/compiler/rustc_middle/src/traits/specialization_graph.rs
+++ b/compiler/rustc_middle/src/traits/specialization_graph.rs
@@ -1,3 +1,4 @@
+use crate::error::StrictCoherenceNeedsNegativeCoherence;
 use crate::ty::fast_reject::SimplifiedType;
 use crate::ty::visit::TypeVisitable;
 use crate::ty::{self, TyCtxt};
@@ -65,9 +66,21 @@ impl OverlapMode {
 
         if with_negative_coherence {
             if strict_coherence { OverlapMode::Strict } else { OverlapMode::WithNegative }
-        } else if strict_coherence {
-            bug!("To use strict_coherence you need to set with_negative_coherence feature flag");
         } else {
+            if strict_coherence {
+                let attr_span = trait_id
+                    .as_local()
+                    .into_iter()
+                    .flat_map(|local_def_id| {
+                        tcx.hir().attrs(tcx.hir().local_def_id_to_hir_id(local_def_id))
+                    })
+                    .find(|attr| attr.has_name(sym::rustc_strict_coherence))
+                    .map(|attr| attr.span);
+                tcx.sess.emit_err(StrictCoherenceNeedsNegativeCoherence {
+                    span: tcx.def_span(trait_id),
+                    attr_span,
+                });
+            }
             OverlapMode::Stable
         }
     }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index a9e5e438cf5..93a3dd8962a 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -79,7 +79,10 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> {
         intravisit::walk_local(self, loc);
         let els = loc.els;
         if let Some(init) = loc.init && els.is_some() {
-            self.check_let(&loc.pat, init, loc.span);
+            // Build a span without the else { ... } as we don't want to underline
+            // the entire else block in the IDE setting.
+            let span = loc.span.with_hi(init.span.hi());
+            self.check_let(&loc.pat, init, span);
         }
 
         let (msg, sp) = match loc.source {
@@ -630,11 +633,6 @@ fn irrefutable_let_patterns(
     count: usize,
     span: Span,
 ) {
-    let span = match source {
-        LetSource::LetElse(span) => span,
-        _ => span,
-    };
-
     macro_rules! emit_diag {
         (
             $lint:expr,
@@ -680,7 +678,7 @@ fn irrefutable_let_patterns(
                 "removing the guard and adding a `let` inside the match arm"
             );
         }
-        LetSource::LetElse(..) => {
+        LetSource::LetElse => {
             emit_diag!(
                 lint,
                 "`let...else`",
@@ -1127,7 +1125,7 @@ pub enum LetSource {
     GenericLet,
     IfLet,
     IfLetGuard,
-    LetElse(Span),
+    LetElse,
     WhileLet,
 }
 
@@ -1156,8 +1154,8 @@ fn let_source_parent(tcx: TyCtxt<'_>, parent: HirId, pat_id: Option<HirId>) -> L
     let parent_parent = hir.get_parent_node(parent);
     let parent_parent_node = hir.get(parent_parent);
     match parent_parent_node {
-        hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), span, .. }) => {
-            return LetSource::LetElse(*span);
+        hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), .. }) => {
+            return LetSource::LetElse;
         }
         hir::Node::Arm(hir::Arm { guard: Some(hir::Guard::If(_)), .. }) => {
             return LetSource::IfLetGuard;
diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs
index acd4fa63d78..2bc6bc1fc23 100644
--- a/compiler/rustc_transmute/src/layout/tree.rs
+++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -284,7 +284,8 @@ pub(crate) mod rustc {
                 }
 
                 ty::Array(ty, len) => {
-                    let len = len.try_eval_usize(tcx, ParamEnv::reveal_all()).unwrap();
+                    let len =
+                        len.try_eval_usize(tcx, ParamEnv::reveal_all()).ok_or(Err::Unspecified)?;
                     let elt = Tree::from_ty(*ty, tcx)?;
                     Ok(std::iter::repeat(elt)
                         .take(len as usize)
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 944fc3557f8..e168dd571f6 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -986,6 +986,7 @@ impl Step for RustdocGUI {
                     .arg("doc")
                     .arg("--target-dir")
                     .arg(&out_dir)
+                    .env("RUSTC_BOOTSTRAP", "1")
                     .env("RUSTDOC", builder.rustdoc(self.compiler))
                     .env("RUSTC", builder.rustc(self.compiler))
                     .current_dir(path);
@@ -1725,6 +1726,8 @@ impl BookTest {
 
         let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
         let path = builder.src.join(&self.path);
+        // Books often have feature-gated example text.
+        rustbook_cmd.env("RUSTC_BOOTSTRAP", "1");
         rustbook_cmd.env("PATH", new_path).arg("test").arg(path);
         builder.add_rust_test_threads(&mut rustbook_cmd);
         builder.info(&format!("Testing rustbook {}", self.path.display()));
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index b1c3b618cec..f5a49410ea5 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -531,8 +531,10 @@ platforms. Possible values are:
   debug information. On other Unix platforms this means that `*.dwo` files will
   contain debug information.
 
-Note that `packed` and `unpacked` are gated behind `-Z unstable-options` on
-non-macOS platforms at this time.
+Note that all three options are supported on Linux and Apple platforms,
+`packed` is supported on Windows-MSVC, and all other platforms support `off`.
+Attempting to use an unsupported option requires using the nightly channel
+with the `-Z unstable-options` flag.
 
 ## strip
 
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index a0cf1ec78e2..d027fb6e876 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -316,21 +316,28 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
                         let desc = item.doc_value().map_or_else(String::new, |x| {
                             short_markdown_summary(x.as_str(), &item.link_names(self.cache))
                         });
-                        self.cache.search_index.push(IndexItem {
-                            ty: item.type_(),
-                            name: s.to_string(),
-                            path: join_with_double_colon(path),
-                            desc,
-                            parent,
-                            parent_idx: None,
-                            search_type: get_function_type_for_search(
-                                &item,
-                                self.tcx,
-                                clean_impl_generics(self.cache.parent_stack.last()).as_ref(),
-                                self.cache,
-                            ),
-                            aliases: item.attrs.get_doc_aliases(),
-                        });
+                        let ty = item.type_();
+                        let name = s.to_string();
+                        if ty != ItemType::StructField || u16::from_str_radix(&name, 10).is_err() {
+                            // In case this is a field from a tuple struct, we don't add it into
+                            // the search index because its name is something like "0", which is
+                            // not useful for rustdoc search.
+                            self.cache.search_index.push(IndexItem {
+                                ty,
+                                name,
+                                path: join_with_double_colon(path),
+                                desc,
+                                parent,
+                                parent_idx: None,
+                                search_type: get_function_type_for_search(
+                                    &item,
+                                    self.tcx,
+                                    clean_impl_generics(self.cache.parent_stack.last()).as_ref(),
+                                    self.cache,
+                                ),
+                                aliases: item.attrs.get_doc_aliases(),
+                            });
+                        }
                     }
                 }
                 (Some(parent), None) if is_inherent_impl_item => {
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 894499e5c4f..30dc8450924 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1968,24 +1968,26 @@ in storage.js
 	}
 }
 
-.method-toggle > summary,
 .implementors-toggle > summary,
 .impl,
 #implementors-list > .docblock,
 .impl-items > section,
-.methods > section
+.impl-items > .rustdoc-toggle > summary,
+.methods > section,
+.methods > .rustdoc-toggle > summary
 {
 	margin-bottom: 0.75em;
 }
 
-.method-toggle[open]:not(:last-child),
+.impl-items > .rustdoc-toggle[open]:not(:last-child),
+.methods > .rustdoc-toggle[open]:not(:last-child),
 .implementors-toggle[open]:not(:last-child) {
 	margin-bottom: 2em;
 }
 
-#trait-implementations-list .method-toggle:not(:last-child),
-#synthetic-implementations-list .method-toggle:not(:last-child),
-#blanket-implementations-list .method-toggle:not(:last-child) {
+#trait-implementations-list .impl-items > .rustdoc-toggle:not(:last-child),
+#synthetic-implementations-list .impl-items > .rustdoc-toggle:not(:last-child),
+#blanket-implementations-list .impl-items > .rustdoc-toggle:not(:last-child) {
 	margin-bottom: 1em;
 }
 
diff --git a/src/test/rustdoc-gui/method-margins.goml b/src/test/rustdoc-gui/method-margins.goml
new file mode 100644
index 00000000000..397bcd40b36
--- /dev/null
+++ b/src/test/rustdoc-gui/method-margins.goml
@@ -0,0 +1,17 @@
+goto: "file://" + |DOC_PATH| + "/test_docs/trait_members/struct.HasTrait.html#impl-TraitMembers-for-HasTrait"
+
+assert-count: ("#trait-implementations-list > .rustdoc-toggle", 1)
+
+compare-elements-css: (
+    // compare margin on type with margin on method
+    "#trait-implementations-list .impl-items > .rustdoc-toggle:nth-child(1) > summary",
+    "#trait-implementations-list .impl-items > .rustdoc-toggle:nth-child(2) > summary",
+    ["margin"]
+)
+
+compare-elements-css: (
+    // compare margin on type with margin on method
+    "#trait-implementations-list .impl-items > .rustdoc-toggle:nth-child(1)",
+    "#trait-implementations-list .impl-items > .rustdoc-toggle:nth-child(2)",
+    ["margin"]
+)
diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs
index fdf97e492aa..8eea5ad01c0 100644
--- a/src/test/rustdoc-gui/src/test_docs/lib.rs
+++ b/src/test/rustdoc-gui/src/test_docs/lib.rs
@@ -416,3 +416,20 @@ pub trait TraitWithoutGenerics {
 
     fn foo();
 }
+
+pub mod trait_members {
+    pub trait TraitMembers {
+        /// Some type
+        type Type;
+        /// Some function
+        fn function();
+        /// Some other function
+        fn function2();
+    }
+    pub struct HasTrait;
+    impl TraitMembers for HasTrait {
+        type Type = u8;
+        fn function() {}
+        fn function2() {}
+    }
+}
diff --git a/src/test/rustdoc/no-unit-struct-field.rs b/src/test/rustdoc/no-unit-struct-field.rs
new file mode 100644
index 00000000000..d301954b6b5
--- /dev/null
+++ b/src/test/rustdoc/no-unit-struct-field.rs
@@ -0,0 +1,18 @@
+// This test ensures that the tuple struct fields are not generated in the
+// search index.
+
+// @!hasraw search-index.js '"0"'
+// @!hasraw search-index.js '"1"'
+// @hasraw search-index.js '"foo_a"'
+// @hasraw search-index.js '"bar_a"'
+
+pub struct Bar(pub u32, pub u8);
+pub struct Foo {
+    pub foo_a: u8,
+}
+pub enum Enum {
+    Foo(u8),
+    Bar {
+        bar_a: u8,
+    },
+}
diff --git a/src/test/ui/coherence/strict-coherence-needs-negative-coherence.rs b/src/test/ui/coherence/strict-coherence-needs-negative-coherence.rs
new file mode 100644
index 00000000000..221683dd56f
--- /dev/null
+++ b/src/test/ui/coherence/strict-coherence-needs-negative-coherence.rs
@@ -0,0 +1,7 @@
+#![feature(rustc_attrs)]
+
+#[rustc_strict_coherence]
+trait Foo {}
+//~^ ERROR to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
+
+fn main() {}
diff --git a/src/test/ui/coherence/strict-coherence-needs-negative-coherence.stderr b/src/test/ui/coherence/strict-coherence-needs-negative-coherence.stderr
new file mode 100644
index 00000000000..b5472928778
--- /dev/null
+++ b/src/test/ui/coherence/strict-coherence-needs-negative-coherence.stderr
@@ -0,0 +1,10 @@
+error: to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
+  --> $DIR/strict-coherence-needs-negative-coherence.rs:4:1
+   |
+LL | #[rustc_strict_coherence]
+   | ------------------------- due to this attribute
+LL | trait Foo {}
+   | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/let-else/let-else-irrefutable.rs b/src/test/ui/let-else/let-else-irrefutable.rs
index 1cb68ecb8a6..f4b338eb0af 100644
--- a/src/test/ui/let-else/let-else-irrefutable.rs
+++ b/src/test/ui/let-else/let-else-irrefutable.rs
@@ -1,7 +1,11 @@
 // check-pass
 
-
-
 fn main() {
     let x = 1 else { return }; //~ WARN irrefutable `let...else` pattern
+
+    // Multiline else blocks should not get printed
+    let x = 1 else { //~ WARN irrefutable `let...else` pattern
+        eprintln!("problem case encountered");
+        return
+    };
 }
diff --git a/src/test/ui/let-else/let-else-irrefutable.stderr b/src/test/ui/let-else/let-else-irrefutable.stderr
index e0581f4d9ab..73d4e5f3483 100644
--- a/src/test/ui/let-else/let-else-irrefutable.stderr
+++ b/src/test/ui/let-else/let-else-irrefutable.stderr
@@ -1,12 +1,21 @@
 warning: irrefutable `let...else` pattern
-  --> $DIR/let-else-irrefutable.rs:6:5
+  --> $DIR/let-else-irrefutable.rs:4:5
    |
 LL |     let x = 1 else { return };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^
    |
    = note: this pattern will always match, so the `else` clause is useless
    = help: consider removing the `else` clause
    = note: `#[warn(irrefutable_let_patterns)]` on by default
 
-warning: 1 warning emitted
+warning: irrefutable `let...else` pattern
+  --> $DIR/let-else-irrefutable.rs:7:5
+   |
+LL |     let x = 1 else {
+   |     ^^^^^^^^^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: 2 warnings emitted
 
diff --git a/src/test/ui/transmutability/arrays/issue-103783-array-length.rs b/src/test/ui/transmutability/arrays/issue-103783-array-length.rs
new file mode 100644
index 00000000000..cb36e539ed1
--- /dev/null
+++ b/src/test/ui/transmutability/arrays/issue-103783-array-length.rs
@@ -0,0 +1,24 @@
+#![crate_type = "lib"]
+#![feature(transmutability)]
+#![allow(dead_code)]
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    pub struct Context;
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<
+            Src,
+            Context,
+            { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
+        >,
+    {
+    }
+}
+
+fn test() {
+    type NaughtyLenArray = [u32; 3.14159]; //~ ERROR mismatched types
+    type JustUnit = ();
+    assert::is_maybe_transmutable::<JustUnit, NaughtyLenArray>();
+}
diff --git a/src/test/ui/transmutability/arrays/issue-103783-array-length.stderr b/src/test/ui/transmutability/arrays/issue-103783-array-length.stderr
new file mode 100644
index 00000000000..37774c59e6c
--- /dev/null
+++ b/src/test/ui/transmutability/arrays/issue-103783-array-length.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-103783-array-length.rs:21:34
+   |
+LL |     type NaughtyLenArray = [u32; 3.14159];
+   |                                  ^^^^^^^ expected `usize`, found floating-point number
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/x b/x
index 704d0f791f3..4309b82627c 100755
--- a/x
+++ b/x
@@ -29,5 +29,11 @@ for SEARCH_PYTHON in py python3 python python2; do
         exec "$python" $extra_arg "$xpy" "$@"
     fi
 done
+
+python=$(bash -c "compgen -c python" | grep '^python[2-3]\.[0-9]\+$' | head -n1)
+if ! [ "$python" = "" ]; then
+    exec "$python" "$xpy" "$@"
+fi
+
 echo "$0: error: did not find python installed" >&2
 exit 1
diff --git a/x.ps1 b/x.ps1
index 86cea606591..81b98919f43 100755
--- a/x.ps1
+++ b/x.ps1
@@ -10,11 +10,15 @@ foreach ($arg in $args) {
     $xpy_args += """$arg"""
 }
 
+function Get-Application($app) {
+    return Get-Command $app -ErrorAction SilentlyContinue -CommandType Application
+}
+
 foreach ($python in "py", "python3", "python", "python2") {
     # NOTE: this only tests that the command exists in PATH, not that it's actually
     # executable. The latter is not possible in a portable way, see
     # https://github.com/PowerShell/PowerShell/issues/12625.
-    if (Get-Command $python -ErrorAction SilentlyContinue) {
+    if (Get-Application $python) {
         if ($python -eq "py") {
             # Use python3, not python2
             $xpy_args = @("-3") + $xpy_args
@@ -24,5 +28,12 @@ foreach ($python in "py", "python3", "python", "python2") {
     }
 }
 
+$found = (Get-Application "python*" | Where-Object {$_.name -match '^python[2-3]\.[0-9]+(\.exe)?$'})
+if (($null -ne $found) -and ($found.Length -ge 1)) {
+    $python = $found[0]
+    $process = Start-Process -NoNewWindow -Wait -PassThru $python $xpy_args
+    Exit $process.ExitCode
+}
+
 Write-Error "${PSCommandPath}: error: did not find python installed"
 Exit 1