diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 0c954ac6e5f6..4c23f84bd007 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -15,7 +15,7 @@ use rustc_middle::ty::layout::{
 use rustc_middle::ty::{
     self, query::TyCtxtAt, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable,
 };
-use rustc_mir_dataflow::storage::AlwaysLiveLocals;
+use rustc_mir_dataflow::storage::always_live_locals;
 use rustc_query_system::ich::StableHashingContext;
 use rustc_session::Limit;
 use rustc_span::{Pos, Span};
@@ -715,7 +715,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
         // Now mark those locals as dead that we do not want to initialize
         // Mark locals that use `Storage*` annotations as dead on function entry.
-        let always_live = AlwaysLiveLocals::new(self.body());
+        let always_live = always_live_locals(self.body());
         for local in locals.indices() {
             if !always_live.contains(local) {
                 locals[local].value = LocalValue::Dead;
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 665b07c9f89c..3f54d8642970 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -14,7 +14,7 @@ use rustc_middle::mir::{
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable};
 use rustc_mir_dataflow::impls::MaybeStorageLive;
-use rustc_mir_dataflow::storage::AlwaysLiveLocals;
+use rustc_mir_dataflow::storage::always_live_locals;
 use rustc_mir_dataflow::{Analysis, ResultsCursor};
 use rustc_target::abi::{Size, VariantIdx};
 
@@ -48,7 +48,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
         let param_env = tcx.param_env(def_id);
         let mir_phase = self.mir_phase;
 
-        let always_live_locals = AlwaysLiveLocals::new(body);
+        let always_live_locals = always_live_locals(body);
         let storage_liveness = MaybeStorageLive::new(always_live_locals)
             .into_engine(tcx, body)
             .iterate_to_fixpoint()
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 6d79e662a427..f90bb7f23686 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1542,11 +1542,19 @@ extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *hig
     auto C = unwrap<llvm::ConstantInt>(CV);
     if (C->getBitWidth() > 128) { return false; }
     APInt AP;
+#if LLVM_VERSION_GE(15, 0)
+    if (sext) {
+        AP = C->getValue().sext(128);
+    } else {
+        AP = C->getValue().zext(128);
+    }
+#else
     if (sext) {
         AP = C->getValue().sextOrSelf(128);
     } else {
         AP = C->getValue().zextOrSelf(128);
     }
+#endif
     *low = AP.getLoBits(64).getZExtValue();
     *high = AP.getHiBits(64).getZExtValue();
     return true;
diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
index 2de5a9d6991f..f3b5544aa8b9 100644
--- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
@@ -109,7 +109,7 @@ where
     /// For backward analyses, this is the state that will be propagated to its
     /// predecessors (ignoring edge-specific effects).
     pub fn seek_to_block_start(&mut self, block: BasicBlock) {
-        if A::Direction::is_forward() {
+        if A::Direction::IS_FORWARD {
             self.seek_to_block_entry(block)
         } else {
             self.seek_after(Location { block, statement_index: 0 }, Effect::Primary)
@@ -123,7 +123,7 @@ where
     /// For forward analyses, this is the state that will be propagated to its
     /// successors (ignoring edge-specific effects).
     pub fn seek_to_block_end(&mut self, block: BasicBlock) {
-        if A::Direction::is_backward() {
+        if A::Direction::IS_BACKWARD {
             self.seek_to_block_entry(block)
         } else {
             self.seek_after(self.body.terminator_loc(block), Effect::Primary)
@@ -157,7 +157,7 @@ where
             self.seek_to_block_entry(target.block);
         } else if let Some(curr_effect) = self.pos.curr_effect_index {
             let mut ord = curr_effect.statement_index.cmp(&target.statement_index);
-            if A::Direction::is_backward() {
+            if A::Direction::IS_BACKWARD {
                 ord = ord.reverse()
             }
 
@@ -173,7 +173,7 @@ where
         debug_assert_eq!(target.block, self.pos.block);
 
         let block_data = &self.body[target.block];
-        let next_effect = if A::Direction::is_forward() {
+        let next_effect = if A::Direction::IS_FORWARD {
             #[rustfmt::skip]
             self.pos.curr_effect_index.map_or_else(
                 || Effect::Before.at_index(0),
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index 3a492b45849c..05a4d7bbf3e6 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -9,11 +9,9 @@ use super::{
 };
 
 pub trait Direction {
-    fn is_forward() -> bool;
+    const IS_FORWARD: bool;
 
-    fn is_backward() -> bool {
-        !Self::is_forward()
-    }
+    const IS_BACKWARD: bool = !Self::IS_FORWARD;
 
     /// Applies all effects between the given `EffectIndex`s.
     ///
@@ -68,9 +66,7 @@ pub trait Direction {
 pub struct Backward;
 
 impl Direction for Backward {
-    fn is_forward() -> bool {
-        false
-    }
+    const IS_FORWARD: bool = false;
 
     fn apply_effects_in_block<'tcx, A>(
         analysis: &A,
@@ -338,9 +334,7 @@ where
 pub struct Forward;
 
 impl Direction for Forward {
-    fn is_forward() -> bool {
-        true
-    }
+    const IS_FORWARD: bool = true;
 
     fn apply_effects_in_block<'tcx, A>(
         analysis: &A,
diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs
index 50efb4c1dc42..20e14a77c1e5 100644
--- a/compiler/rustc_mir_dataflow/src/framework/engine.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs
@@ -147,7 +147,7 @@ where
         let mut entry_sets = IndexVec::from_elem(bottom_value.clone(), body.basic_blocks());
         analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]);
 
-        if A::Direction::is_backward() && entry_sets[mir::START_BLOCK] != bottom_value {
+        if A::Direction::IS_BACKWARD && entry_sets[mir::START_BLOCK] != bottom_value {
             bug!("`initialize_start_block` is not yet supported for backward dataflow analyses");
         }
 
@@ -200,7 +200,7 @@ where
         let mut dirty_queue: WorkQueue<BasicBlock> =
             WorkQueue::with_none(body.basic_blocks().len());
 
-        if A::Direction::is_forward() {
+        if A::Direction::IS_FORWARD {
             for (bb, _) in traversal::reverse_postorder(body) {
                 dirty_queue.insert(bb);
             }
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
index 3834c232ab6b..59a2053ec700 100644
--- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -216,7 +216,7 @@ where
         // Write the full dataflow state immediately after the terminator if it differs from the
         // state at block entry.
         self.results.seek_to_block_end(block);
-        if self.results.get() != &block_start_state || A::Direction::is_backward() {
+        if self.results.get() != &block_start_state || A::Direction::IS_BACKWARD {
             let after_terminator_name = match terminator.kind {
                 mir::TerminatorKind::Call { target: Some(_), .. } => "(on unwind)",
                 _ => "(on end)",
@@ -390,7 +390,7 @@ where
         let mut afters = diffs.after.into_iter();
 
         let next_in_dataflow_order = |it: &mut std::vec::IntoIter<_>| {
-            if A::Direction::is_forward() { it.next().unwrap() } else { it.next_back().unwrap() }
+            if A::Direction::IS_FORWARD { it.next().unwrap() } else { it.next_back().unwrap() }
         };
 
         for (i, statement) in body[block].statements.iter().enumerate() {
@@ -527,7 +527,7 @@ where
         _block_data: &mir::BasicBlockData<'tcx>,
         _block: BasicBlock,
     ) {
-        if A::Direction::is_forward() {
+        if A::Direction::IS_FORWARD {
             self.prev_state.clone_from(state);
         }
     }
@@ -538,7 +538,7 @@ where
         _block_data: &mir::BasicBlockData<'tcx>,
         _block: BasicBlock,
     ) {
-        if A::Direction::is_backward() {
+        if A::Direction::IS_BACKWARD {
             self.prev_state.clone_from(state);
         }
     }
diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs
index 74c3b44f4250..d9461fd3abd8 100644
--- a/compiler/rustc_mir_dataflow/src/framework/tests.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs
@@ -140,7 +140,7 @@ impl<D: Direction> MockAnalysis<'_, D> {
             SeekTarget::After(loc) => Effect::Primary.at_index(loc.statement_index),
         };
 
-        let mut pos = if D::is_forward() {
+        let mut pos = if D::IS_FORWARD {
             Effect::Before.at_index(0)
         } else {
             Effect::Before.at_index(self.body[block].statements.len())
@@ -153,7 +153,7 @@ impl<D: Direction> MockAnalysis<'_, D> {
                 return ret;
             }
 
-            if D::is_forward() {
+            if D::IS_FORWARD {
                 pos = pos.next_in_forward_order();
             } else {
                 pos = pos.next_in_backward_order();
diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
index 356a6b7765e1..33d294181472 100644
--- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
@@ -1,6 +1,5 @@
 pub use super::*;
 
-use crate::storage::AlwaysLiveLocals;
 use crate::{CallReturnPlaces, GenKill, Results, ResultsRefCursor};
 use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
@@ -8,11 +7,11 @@ use std::cell::RefCell;
 
 #[derive(Clone)]
 pub struct MaybeStorageLive {
-    always_live_locals: AlwaysLiveLocals,
+    always_live_locals: BitSet<Local>,
 }
 
 impl MaybeStorageLive {
-    pub fn new(always_live_locals: AlwaysLiveLocals) -> Self {
+    pub fn new(always_live_locals: BitSet<Local>) -> Self {
         MaybeStorageLive { always_live_locals }
     }
 }
diff --git a/compiler/rustc_mir_dataflow/src/storage.rs b/compiler/rustc_mir_dataflow/src/storage.rs
index 218d4557215f..4a354c4c65b0 100644
--- a/compiler/rustc_mir_dataflow/src/storage.rs
+++ b/compiler/rustc_mir_dataflow/src/storage.rs
@@ -7,35 +7,17 @@ use rustc_middle::mir::{self, Local};
 //
 // FIXME: Currently, we need to traverse the entire MIR to compute this. We should instead store it
 // as a field in the `LocalDecl` for each `Local`.
-#[derive(Debug, Clone)]
-pub struct AlwaysLiveLocals(BitSet<Local>);
+pub fn always_live_locals(body: &mir::Body<'_>) -> BitSet<Local> {
+    let mut always_live_locals = BitSet::new_filled(body.local_decls.len());
 
-impl AlwaysLiveLocals {
-    pub fn new(body: &mir::Body<'_>) -> Self {
-        let mut always_live_locals = AlwaysLiveLocals(BitSet::new_filled(body.local_decls.len()));
-
-        for block in body.basic_blocks() {
-            for statement in &block.statements {
-                use mir::StatementKind::{StorageDead, StorageLive};
-                if let StorageLive(l) | StorageDead(l) = statement.kind {
-                    always_live_locals.0.remove(l);
-                }
+    for block in body.basic_blocks() {
+        for statement in &block.statements {
+            use mir::StatementKind::{StorageDead, StorageLive};
+            if let StorageLive(l) | StorageDead(l) = statement.kind {
+                always_live_locals.remove(l);
             }
         }
-
-        always_live_locals
     }
 
-    pub fn into_inner(self) -> BitSet<Local> {
-        self.0
-    }
-}
-
-impl std::ops::Deref for AlwaysLiveLocals {
-    type Target = BitSet<Local>;
-
-    #[inline]
-    fn deref(&self) -> &Self::Target {
-        &self.0
-    }
+    always_live_locals
 }
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 9eb77f602137..89895fddd0cf 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -228,7 +228,7 @@ struct TransformVisitor<'tcx> {
     suspension_points: Vec<SuspensionPoint<'tcx>>,
 
     // The set of locals that have no `StorageLive`/`StorageDead` annotations.
-    always_live_locals: storage::AlwaysLiveLocals,
+    always_live_locals: BitSet<Local>,
 
     // The original RETURN_PLACE local
     new_ret_local: Local,
@@ -450,7 +450,7 @@ struct LivenessInfo {
 fn locals_live_across_suspend_points<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
-    always_live_locals: &storage::AlwaysLiveLocals,
+    always_live_locals: &BitSet<Local>,
     movable: bool,
 ) -> LivenessInfo {
     let body_ref: &Body<'_> = &body;
@@ -615,7 +615,7 @@ impl ops::Deref for GeneratorSavedLocals {
 fn compute_storage_conflicts<'mir, 'tcx>(
     body: &'mir Body<'tcx>,
     saved_locals: &GeneratorSavedLocals,
-    always_live_locals: storage::AlwaysLiveLocals,
+    always_live_locals: BitSet<Local>,
     requires_storage: rustc_mir_dataflow::Results<'tcx, MaybeRequiresStorage<'mir, 'tcx>>,
 ) -> BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal> {
     assert_eq!(body.local_decls.len(), saved_locals.domain_size());
@@ -625,7 +625,7 @@ fn compute_storage_conflicts<'mir, 'tcx>(
 
     // Locals that are always live or ones that need to be stored across
     // suspension points are not eligible for overlap.
-    let mut ineligible_locals = always_live_locals.into_inner();
+    let mut ineligible_locals = always_live_locals;
     ineligible_locals.intersect(&**saved_locals);
 
     // Compute the storage conflicts for all eligible locals.
@@ -1300,7 +1300,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
             },
         );
 
-        let always_live_locals = storage::AlwaysLiveLocals::new(&body);
+        let always_live_locals = storage::always_live_locals(&body);
 
         let liveness_info =
             locals_live_across_suspend_points(tcx, body, &always_live_locals, movable);
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index b83fdd02da91..b9f49c19465d 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -1577,18 +1577,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         name: Symbol,
     ) -> ErrorGuaranteed {
         let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type");
-        if let (true, Ok(snippet)) = (
-            self.tcx()
-                .resolutions(())
-                .confused_type_with_std_module
-                .keys()
-                .any(|full_span| full_span.contains(span)),
-            self.tcx().sess.source_map().span_to_snippet(span),
-        ) {
+        if self
+            .tcx()
+            .resolutions(())
+            .confused_type_with_std_module
+            .keys()
+            .any(|full_span| full_span.contains(span))
+        {
             err.span_suggestion(
-                span,
+                span.shrink_to_lo(),
                 "you are looking for the module in `std`, not the primitive type",
-                format!("std::{}", snippet),
+                "std::".to_string(),
                 Applicability::MachineApplicable,
             );
         } else {
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 0e198907c8d5..4071c389266d 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -327,26 +327,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     );
                 }
                 if let Some(span) = tcx.resolutions(()).confused_type_with_std_module.get(&span) {
-                    if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(*span) {
-                        err.span_suggestion(
-                            *span,
-                            "you are looking for the module in `std`, \
-                                     not the primitive type",
-                            format!("std::{}", snippet),
-                            Applicability::MachineApplicable,
-                        );
-                    }
+                    err.span_suggestion(
+                        span.shrink_to_lo(),
+                        "you are looking for the module in `std`, not the primitive type",
+                        "std::".to_string(),
+                        Applicability::MachineApplicable,
+                    );
                 }
                 if let ty::RawPtr(_) = &actual.kind() {
                     err.note(
                         "try using `<*const T>::as_ref()` to get a reference to the \
-                                      type behind the pointer: https://doc.rust-lang.org/std/\
-                                      primitive.pointer.html#method.as_ref",
+                         type behind the pointer: https://doc.rust-lang.org/std/\
+                         primitive.pointer.html#method.as_ref",
                     );
                     err.note(
-                        "using `<*const T>::as_ref()` on a pointer \
-                                      which is unaligned or points to invalid \
-                                      or uninitialized memory is undefined behavior",
+                        "using `<*const T>::as_ref()` on a pointer which is unaligned or points \
+                         to invalid or uninitialized memory is undefined behavior",
                     );
                 }
 
diff --git a/src/test/ui/async-await/issues/issue-95307.rs b/src/test/ui/async-await/issues/issue-95307.rs
new file mode 100644
index 000000000000..f7e48070ccde
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-95307.rs
@@ -0,0 +1,13 @@
+// edition:2018
+
+// Regression test for #95307.
+// The ICE occurred on all the editions, specifying edition:2018 to reduce diagnostics.
+
+pub trait C {
+    async fn new() -> [u8; _];
+    //~^ ERROR: functions in traits cannot be declared `async`
+    //~| ERROR: using `_` for array lengths is unstable
+    //~| ERROR: in expressions, `_` can only be used on the left-hand side of an assignment
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-95307.stderr b/src/test/ui/async-await/issues/issue-95307.stderr
new file mode 100644
index 000000000000..60fca71eb4b6
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-95307.stderr
@@ -0,0 +1,30 @@
+error[E0706]: functions in traits cannot be declared `async`
+  --> $DIR/issue-95307.rs:7:5
+   |
+LL |     async fn new() -> [u8; _];
+   |     -----^^^^^^^^^^^^^^^^^^^^^
+   |     |
+   |     `async` because of this
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error[E0658]: using `_` for array lengths is unstable
+  --> $DIR/issue-95307.rs:7:28
+   |
+LL |     async fn new() -> [u8; _];
+   |                            ^
+   |
+   = note: see issue #85077 <https://github.com/rust-lang/rust/issues/85077> for more information
+   = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable
+
+error: in expressions, `_` can only be used on the left-hand side of an assignment
+  --> $DIR/issue-95307.rs:7:28
+   |
+LL |     async fn new() -> [u8; _];
+   |                            ^ `_` not allowed here
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0658, E0706.
+For more information about an error, try `rustc --explain E0658`.
diff --git a/src/test/ui/suggestions/suggest-std-when-using-type.stderr b/src/test/ui/suggestions/suggest-std-when-using-type.stderr
index 4255281d9a7a..2840fa121a75 100644
--- a/src/test/ui/suggestions/suggest-std-when-using-type.stderr
+++ b/src/test/ui/suggestions/suggest-std-when-using-type.stderr
@@ -7,7 +7,7 @@ LL |     let pi = f32::consts::PI;
 help: you are looking for the module in `std`, not the primitive type
    |
 LL |     let pi = std::f32::consts::PI;
-   |              ~~~~~~~~~~~~~~~~
+   |              +++++
 
 error[E0599]: no function or associated item named `from_utf8` found for type `str` in the current scope
   --> $DIR/suggest-std-when-using-type.rs:5:14
@@ -18,7 +18,7 @@ LL |         str::from_utf8(bytes)
 help: you are looking for the module in `std`, not the primitive type
    |
 LL |         std::str::from_utf8(bytes)
-   |         ~~~~~~~~~~~~~~~~~~~
+   |         +++++
 
 error: aborting due to 2 previous errors