about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/util/classify.rs35
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs10
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs4
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs5
-rw-r--r--compiler/rustc_middle/src/traits/select.rs6
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs8
-rw-r--r--compiler/rustc_privacy/src/lib.rs63
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs28
-rw-r--r--compiler/rustc_resolve/src/effective_visibilities.rs4
-rw-r--r--compiler/rustc_resolve/src/late.rs2
-rw-r--r--compiler/rustc_resolve/src/lib.rs17
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs14
-rw-r--r--library/std/src/macros.rs6
-rw-r--r--src/bootstrap/Cargo.lock7
-rw-r--r--src/bootstrap/Cargo.toml1
-rw-r--r--src/bootstrap/src/core/build_steps/setup.rs3
-rw-r--r--src/bootstrap/src/core/download.rs4
-rw-r--r--src/bootstrap/src/lib.rs3
-rw-r--r--src/bootstrap/src/tests/builder.rs16
-rw-r--r--src/bootstrap/src/tests/helpers.rs59
-rw-r--r--src/bootstrap/src/tests/setup.rs3
-rw-r--r--src/bootstrap/src/utils/helpers.rs12
-rw-r--r--tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff104
-rw-r--r--tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff104
-rw-r--r--tests/mir-opt/gvn.rs18
-rw-r--r--tests/ui/macros/issue-118786.rs16
-rw-r--r--tests/ui/macros/issue-118786.stderr47
-rw-r--r--tests/ui/parser/bad-let-else-statement.rs164
-rw-r--r--tests/ui/parser/bad-let-else-statement.stderr232
-rw-r--r--tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr30
-rw-r--r--tests/ui/traits/issue-117794.rs10
-rw-r--r--tests/ui/traits/issue-117794.stderr9
37 files changed, 911 insertions, 158 deletions
diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs
index 821fca6656c..4dece079783 100644
--- a/compiler/rustc_ast/src/util/classify.rs
+++ b/compiler/rustc_ast/src/util/classify.rs
@@ -40,15 +40,44 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
             | Range(_, Some(e), _)
             | Ret(Some(e))
             | Unary(_, e)
-            | Yield(Some(e)) => {
+            | Yield(Some(e))
+            | Yeet(Some(e))
+            | Become(e) => {
                 expr = e;
             }
             Closure(closure) => {
                 expr = &closure.body;
             }
             Gen(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..)
-            | TryBlock(..) | While(..) => break Some(expr),
-            _ => break None,
+            | TryBlock(..) | While(..) | ConstBlock(_) => break Some(expr),
+
+            // FIXME: These can end in `}`, but changing these would break stable code.
+            InlineAsm(_) | OffsetOf(_, _) | MacCall(_) | IncludedBytes(_) | FormatArgs(_) => {
+                break None;
+            }
+
+            Break(_, None)
+            | Range(_, None, _)
+            | Ret(None)
+            | Yield(None)
+            | Array(_)
+            | Call(_, _)
+            | MethodCall(_)
+            | Tup(_)
+            | Lit(_)
+            | Cast(_, _)
+            | Type(_, _)
+            | Await(_, _)
+            | Field(_, _)
+            | Index(_, _, _)
+            | Underscore
+            | Path(_, _)
+            | Continue(_)
+            | Repeat(_, _)
+            | Paren(_)
+            | Try(_)
+            | Yeet(None)
+            | Err => break None,
         }
     }
 }
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 5c9e43f1e06..96ed3eee02e 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -59,10 +59,8 @@ use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
 use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
 use rustc_index::{Idx, IndexSlice, IndexVec};
-use rustc_middle::{
-    span_bug,
-    ty::{ResolverAstLowering, TyCtxt},
-};
+use rustc_middle::span_bug;
+use rustc_middle::ty::{ResolverAstLowering, TyCtxt, Visibility};
 use rustc_session::parse::{add_feature_diagnostics, feature_err};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{DesugaringKind, Span, DUMMY_SP};
@@ -1653,6 +1651,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         );
         debug!(?opaque_ty_def_id);
 
+        // Meaningless, but provided so that all items have visibilities.
+        let parent_mod = self.tcx.parent_module_from_def_id(opaque_ty_def_id).to_def_id();
+        self.tcx.feed_local_def_id(opaque_ty_def_id).visibility(Visibility::Restricted(parent_mod));
+
         // Map from captured (old) lifetime to synthetic (new) lifetime.
         // Used to resolve lifetimes in the bounds of the opaque.
         let mut captured_to_synthesized_mapping = FxHashMap::default();
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 393eec3997b..14d22cbe2dd 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -236,6 +236,13 @@ fn expand_macro<'cx>(
                             target_sp.open = source_sp.open.with_ctxt(ctxt);
                             target_sp.close = source_sp.close.with_ctxt(ctxt);
                         }
+                        (
+                            TokenTree::Delimited(target_sp, ..),
+                            mbe::TokenTree::MetaVar(source_sp, ..),
+                        ) => {
+                            target_sp.open = source_sp.with_ctxt(ctxt);
+                            target_sp.close = source_sp.with_ctxt(ctxt).shrink_to_hi();
+                        }
                         _ => {
                             let sp = rhs_tt.span().with_ctxt(ctxt);
                             tt.set_span(sp);
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index bf0d9d4856a..3785b61f2f7 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -278,6 +278,10 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
 
     let mir_opaque_ty = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied();
     if let Some(mir_opaque_ty) = mir_opaque_ty {
+        if mir_opaque_ty.references_error() {
+            return mir_opaque_ty.ty;
+        }
+
         let scope = tcx.local_def_id_to_hir_id(owner_def_id);
         debug!(?scope);
         let mut locator = RpitConstraintChecker { def_id, tcx, found: mir_opaque_ty };
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 598c26de23f..81f34c7b8b0 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -1142,7 +1142,10 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
         tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher);
         tcx.stable_crate_id(LOCAL_CRATE).hash_stable(&mut hcx, &mut stable_hasher);
         // Hash visibility information since it does not appear in HIR.
-        resolutions.visibilities.hash_stable(&mut hcx, &mut stable_hasher);
+        // FIXME: Figure out how to remove `visibilities_for_hashing` by hashing visibilities on
+        // the fly in the resolver, storing only their accumulated hash in `ResolverGlobalCtxt`,
+        // and combining it with other hashes here.
+        resolutions.visibilities_for_hashing.hash_stable(&mut hcx, &mut stable_hasher);
         stable_hasher.finish()
     });
 
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index e8e2907eb33..c52103eb247 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -125,10 +125,8 @@ pub enum SelectionCandidate<'tcx> {
 
     /// This is a trait matching with a projected type as `Self`, and we found
     /// an applicable bound in the trait definition. The `usize` is an index
-    /// into the list returned by `tcx.item_bounds`. The constness is the
-    /// constness of the bound in the trait.
-    // FIXME(effects) do we need this constness
-    ProjectionCandidate(usize, ty::BoundConstness),
+    /// into the list returned by `tcx.item_bounds`.
+    ProjectionCandidate(usize),
 
     /// Implementation of a `Fn`-family trait by one of the anonymous types
     /// generated for an `||` expression.
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index febab23ea35..6513bf501e1 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -152,7 +152,7 @@ pub struct ResolverOutputs {
 
 #[derive(Debug)]
 pub struct ResolverGlobalCtxt {
-    pub visibilities: FxHashMap<LocalDefId, Visibility>,
+    pub visibilities_for_hashing: Vec<(LocalDefId, Visibility)>,
     /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
     pub expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
     pub effective_visibilities: EffectiveVisibilities,
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index b21988e179d..3b8adf7e86b 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -644,12 +644,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             {
                 if let Some(offset) = self.evaluated[idx].as_ref()
                     && let Ok(offset) = self.ecx.read_target_usize(offset)
+                    && let Some(min_length) = offset.checked_add(1)
                 {
-                    projection.to_mut()[i] = ProjectionElem::ConstantIndex {
-                        offset,
-                        min_length: offset + 1,
-                        from_end: false,
-                    };
+                    projection.to_mut()[i] =
+                        ProjectionElem::ConstantIndex { offset, min_length, from_end: false };
                 } else if let Some(new_idx) = self.try_as_local(idx, location) {
                     projection.to_mut()[i] = ProjectionElem::Index(new_idx);
                     self.reused_locals.insert(new_idx);
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 6a8e23d9a8f..61f6a2b18ae 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -23,12 +23,11 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, CRATE_DEF_ID};
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, Node, PatKind};
+use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, PatKind};
 use rustc_middle::bug;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
 use rustc_middle::query::Providers;
-use rustc_middle::span_bug;
 use rustc_middle::ty::GenericArgs;
 use rustc_middle::ty::{self, Const, GenericParamDefKind};
 use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
@@ -1766,7 +1765,15 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
 
 pub fn provide(providers: &mut Providers) {
     *providers = Providers {
-        visibility,
+        visibility: |tcx, def_id| {
+            // Unique types created for closures participate in type privacy checking.
+            // They have visibilities inherited from the module they are defined in.
+            // FIXME: Consider evaluating visibilities for closures eagerly, like for all
+            // other nodes. However, unlike for others, for closures it may cause a perf
+            // regression, because closure visibilities are not commonly queried.
+            assert_eq!(tcx.def_kind(def_id), DefKind::Closure);
+            ty::Visibility::Restricted(tcx.parent_module_from_def_id(def_id).to_def_id())
+        },
         effective_visibilities,
         check_private_in_public,
         check_mod_privacy,
@@ -1774,56 +1781,6 @@ pub fn provide(providers: &mut Providers) {
     };
 }
 
-fn visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility<DefId> {
-    local_visibility(tcx, def_id).to_def_id()
-}
-
-fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility {
-    match tcx.resolutions(()).visibilities.get(&def_id) {
-        Some(vis) => *vis,
-        None => {
-            let hir_id = tcx.local_def_id_to_hir_id(def_id);
-            match tcx.hir_node(hir_id) {
-                // Unique types created for closures participate in type privacy checking.
-                // They have visibilities inherited from the module they are defined in.
-                Node::Expr(hir::Expr { kind: hir::ExprKind::Closure{..}, .. })
-                // - AST lowering creates dummy `use` items which don't
-                //   get their entries in the resolver's visibility table.
-                // - AST lowering also creates opaque type items with inherited visibilities.
-                //   Visibility on them should have no effect, but to avoid the visibility
-                //   query failing on some items, we provide it for opaque types as well.
-                | Node::Item(hir::Item {
-                    kind: hir::ItemKind::Use(_, hir::UseKind::ListStem)
-                        | hir::ItemKind::OpaqueTy(..),
-                    ..
-                }) => ty::Visibility::Restricted(tcx.parent_module(hir_id).to_local_def_id()),
-                // Visibilities of trait impl items are inherited from their traits
-                // and are not filled in resolve.
-                Node::ImplItem(impl_item) => {
-                    match tcx.hir_node_by_def_id(tcx.hir().get_parent_item(hir_id).def_id) {
-                        Node::Item(hir::Item {
-                            kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(tr), .. }),
-                            ..
-                        }) => tr.path.res.opt_def_id().map_or_else(
-                            || {
-                                tcx.sess.span_delayed_bug(tr.path.span, "trait without a def-id");
-                                ty::Visibility::Public
-                            },
-                            |def_id| tcx.visibility(def_id).expect_local(),
-                        ),
-                        _ => span_bug!(impl_item.span, "the parent is not a trait impl"),
-                    }
-                }
-                _ => span_bug!(
-                    tcx.def_span(def_id),
-                    "visibility table unexpectedly missing a def-id: {:?}",
-                    def_id,
-                ),
-            }
-        }
-    }
-}
-
 fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     // Check privacy of names not checked in previous compilation stages.
     let mut visitor = NamePrivacyVisitor {
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 213b320ed1a..7ff3c523685 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -236,7 +236,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                     // (i.e. variants, fields, and trait items) inherits from the visibility
                     // of the enum or trait.
                     ModuleKind::Def(DefKind::Enum | DefKind::Trait, def_id, _) => {
-                        self.r.visibilities[&def_id.expect_local()]
+                        self.r.tcx.visibility(def_id).expect_local()
                     }
                     // Otherwise, the visibility is restricted to the nearest parent `mod` item.
                     _ => ty::Visibility::Restricted(
@@ -404,6 +404,10 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
             parent_prefix, use_tree, nested
         );
 
+        if nested {
+            self.r.feed_visibility(self.r.local_def_id(id), vis);
+        }
+
         let mut prefix_iter = parent_prefix
             .iter()
             .cloned()
@@ -442,8 +446,6 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                 let mut source = module_path.pop().unwrap();
                 let mut type_ns_only = false;
 
-                self.r.visibilities.insert(self.r.local_def_id(id), vis);
-
                 if nested {
                     // Correctly handle `self`
                     if source.ident.name == kw::SelfLower {
@@ -557,7 +559,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                     max_vis: Cell::new(None),
                     id,
                 };
-                self.r.visibilities.insert(self.r.local_def_id(id), vis);
+
                 self.add_import(prefix, kind, use_tree.span, item, root_span, item.id, vis);
             }
             ast::UseTreeKind::Nested(ref items) => {
@@ -636,7 +638,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         let def_kind = self.r.tcx.def_kind(def_id);
         let res = Res::Def(def_kind, def_id);
 
-        self.r.visibilities.insert(local_def_id, vis);
+        self.r.feed_visibility(local_def_id, vis);
 
         match item.kind {
             ItemKind::Use(ref use_tree) => {
@@ -753,7 +755,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                     let ctor_def_id = self.r.local_def_id(ctor_node_id);
                     let ctor_res = self.res(ctor_def_id);
                     self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion));
-                    self.r.visibilities.insert(ctor_def_id, ctor_vis);
+                    self.r.feed_visibility(ctor_def_id, ctor_vis);
                     // We need the field visibility spans also for the constructor for E0603.
                     self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata);
 
@@ -897,7 +899,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         let expansion = self.parent_scope.expansion;
         let vis = self.resolve_visibility(&item.vis);
         self.r.define(parent, item.ident, ns, (self.res(def_id), vis, item.span, expansion));
-        self.r.visibilities.insert(local_def_id, vis);
+        self.r.feed_visibility(local_def_id, vis);
     }
 
     fn build_reduced_graph_for_block(&mut self, block: &Block) {
@@ -1228,7 +1230,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                 self.r.check_reserved_macro_name(ident, res);
                 self.insert_unused_macro(ident, def_id, item.id);
             }
-            self.r.visibilities.insert(def_id, vis);
+            self.r.feed_visibility(def_id, vis);
             let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Binding(
                 self.r.arenas.alloc_macro_rules_binding(MacroRulesBinding {
                     parent_macro_rules_scope: parent_scope.macro_rules,
@@ -1252,7 +1254,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                 self.insert_unused_macro(ident, def_id, item.id);
             }
             self.r.define(module, ident, MacroNS, (res, vis, span, expansion));
-            self.r.visibilities.insert(def_id, vis);
+            self.r.feed_visibility(def_id, vis);
             self.parent_scope.macro_rules
         }
     }
@@ -1354,7 +1356,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
             // Trait impl item visibility is inherited from its trait when not specified
             // explicitly. In that case we cannot determine it here in early resolve,
             // so we leave a hole in the visibility table to be filled later.
-            self.r.visibilities.insert(local_def_id, vis);
+            self.r.feed_visibility(local_def_id, vis);
         }
 
         if ctxt == AssocCtxt::Trait {
@@ -1432,7 +1434,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
             self.visit_invoc(sf.id);
         } else {
             let vis = self.resolve_visibility(&sf.vis);
-            self.r.visibilities.insert(self.r.local_def_id(sf.id), vis);
+            self.r.feed_visibility(self.r.local_def_id(sf.id), vis);
             visit::walk_field_def(self, sf);
         }
     }
@@ -1453,7 +1455,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         let def_id = self.r.local_def_id(variant.id);
         let vis = self.resolve_visibility(&variant.vis);
         self.r.define(parent, ident, TypeNS, (self.res(def_id), vis, variant.span, expn_id));
-        self.r.visibilities.insert(def_id, vis);
+        self.r.feed_visibility(def_id, vis);
 
         // If the variant is marked as non_exhaustive then lower the visibility to within the crate.
         let ctor_vis =
@@ -1468,7 +1470,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
             let ctor_def_id = self.r.local_def_id(ctor_node_id);
             let ctor_res = self.res(ctor_def_id);
             self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id));
-            self.r.visibilities.insert(ctor_def_id, ctor_vis);
+            self.r.feed_visibility(ctor_def_id, ctor_vis);
         }
 
         // Record field names for error reporting.
diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs
index a71c50dd82f..50352169221 100644
--- a/compiler/rustc_resolve/src/effective_visibilities.rs
+++ b/compiler/rustc_resolve/src/effective_visibilities.rs
@@ -186,7 +186,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
     ) -> Option<Option<Visibility>> {
         match parent_id {
             ParentId::Def(def_id) => (nominal_vis != self.current_private_vis
-                && self.r.visibilities[&def_id] != self.current_private_vis)
+                && self.r.tcx.local_visibility(def_id) != self.current_private_vis)
                 .then_some(Some(self.current_private_vis)),
             ParentId::Import(_) => Some(None),
         }
@@ -222,7 +222,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
     }
 
     fn update_field(&mut self, def_id: LocalDefId, parent_id: LocalDefId) {
-        self.update_def(def_id, self.r.visibilities[&def_id], ParentId::Def(parent_id));
+        self.update_def(def_id, self.r.tcx.local_visibility(def_id), ParentId::Def(parent_id));
     }
 }
 
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 9c96e9a9bd7..037179350f0 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -3112,6 +3112,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             | (DefKind::AssocFn, AssocItemKind::Fn(..))
             | (DefKind::AssocConst, AssocItemKind::Const(..)) => {
                 self.r.record_partial_res(id, PartialRes::new(res));
+                let vis = self.r.tcx.visibility(id_in_trait).expect_local();
+                self.r.feed_visibility(self.r.local_def_id(id), vis);
                 return;
             }
             _ => {}
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 70e0eb12c01..ad637472b47 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1007,8 +1007,7 @@ pub struct Resolver<'a, 'tcx> {
 
     /// Maps glob imports to the names of items actually imported.
     glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
-    /// Visibilities in "lowered" form, for all entities that have them.
-    visibilities: FxHashMap<LocalDefId, ty::Visibility>,
+    visibilities_for_hashing: Vec<(LocalDefId, ty::Visibility)>,
     used_imports: FxHashSet<NodeId>,
     maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
 
@@ -1295,9 +1294,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             &mut FxHashMap::default(),
         );
 
-        let mut visibilities = FxHashMap::default();
-        visibilities.insert(CRATE_DEF_ID, ty::Visibility::Public);
-
         let mut def_id_to_node_id = IndexVec::default();
         assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), CRATE_DEF_ID);
         let mut node_id_to_def_id = FxHashMap::default();
@@ -1363,7 +1359,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             ast_transform_scopes: FxHashMap::default(),
 
             glob_map: Default::default(),
-            visibilities,
+            visibilities_for_hashing: Default::default(),
             used_imports: FxHashSet::default(),
             maybe_unused_trait_imports: Default::default(),
 
@@ -1450,6 +1446,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         let root_parent_scope = ParentScope::module(graph_root, &resolver);
         resolver.invocation_parent_scopes.insert(LocalExpnId::ROOT, root_parent_scope);
+        resolver.feed_visibility(CRATE_DEF_ID, ty::Visibility::Public);
 
         resolver
     }
@@ -1497,10 +1494,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         Default::default()
     }
 
+    fn feed_visibility(&mut self, def_id: LocalDefId, vis: ty::Visibility) {
+        self.tcx.feed_local_def_id(def_id).visibility(vis.to_def_id());
+        self.visibilities_for_hashing.push((def_id, vis));
+    }
+
     pub fn into_outputs(self) -> ResolverOutputs {
         let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect();
         let expn_that_defined = self.expn_that_defined;
-        let visibilities = self.visibilities;
         let extern_crate_map = self.extern_crate_map;
         let maybe_unused_trait_imports = self.maybe_unused_trait_imports;
         let glob_map = self.glob_map;
@@ -1517,7 +1518,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         let global_ctxt = ResolverGlobalCtxt {
             expn_that_defined,
-            visibilities,
+            visibilities_for_hashing: self.visibilities_for_hashing,
             effective_visibilities,
             extern_crate_map,
             module_children: self.module_children,
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 9cbddd2bb2b..045d7e444b6 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -116,12 +116,13 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
     fn register_predicate_obligation(
         &mut self,
         infcx: &InferCtxt<'tcx>,
-        obligation: PredicateObligation<'tcx>,
+        mut obligation: PredicateObligation<'tcx>,
     ) {
         assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots());
         // this helps to reduce duplicate errors, as well as making
         // debug output much nicer to read and so on.
-        let obligation = infcx.resolve_vars_if_possible(obligation);
+        debug_assert!(!obligation.param_env.has_non_region_infer());
+        obligation.predicate = infcx.resolve_vars_if_possible(obligation.predicate);
 
         debug!(?obligation, "register_predicate_obligation");
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index c7d0ab71644..cd7fd028a46 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -154,10 +154,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             .infcx
             .probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
 
-        // FIXME(effects) proper constness needed?
-        candidates.vec.extend(
-            result.into_iter().map(|idx| ProjectionCandidate(idx, ty::BoundConstness::NotConst)),
-        );
+        candidates.vec.extend(result.into_iter().map(|idx| ProjectionCandidate(idx)));
     }
 
     /// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller
@@ -585,7 +582,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }
 
                 ty::Alias(ty::Opaque, _) => {
-                    if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(..))) {
+                    if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(_))) {
                         // We do not generate an auto impl candidate for `impl Trait`s which already
                         // reference our auto trait.
                         //
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 7e3d304d1cd..bcaf6aff66b 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -71,7 +71,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 ImplSource::Builtin(BuiltinImplSource::Misc, data)
             }
 
-            ProjectionCandidate(idx, _) => {
+            ProjectionCandidate(idx) => {
                 let obligations = self.confirm_projection_candidate(obligation, idx)?;
                 ImplSource::Param(obligations)
             }
@@ -1313,7 +1313,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // If we have a projection type, make sure to normalize it so we replace it
                 // with a fresh infer variable
                 ty::Alias(ty::Projection | ty::Inherent, ..) => {
-                    // FIXME(effects) this needs constness
                     let predicate = normalize_with_depth_to(
                         self,
                         obligation.param_env,
@@ -1344,7 +1343,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // since it's either not `const Drop` (and we raise an error during selection),
                 // or it's an ADT (and we need to check for a custom impl during selection)
                 _ => {
-                    // FIXME(effects) this needs constness
                     let predicate = self_ty.rebind(ty::TraitPredicate {
                         trait_ref: ty::TraitRef::from_lang_item(
                             self.tcx(),
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 7f31a2529f5..9886e33ca3b 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1883,7 +1883,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 | BuiltinCandidate { .. }
                 | TraitAliasCandidate
                 | ObjectCandidate(_)
-                | ProjectionCandidate(..),
+                | ProjectionCandidate(_),
             ) => {
                 // We have a where clause so don't go around looking
                 // for impls. Arbitrarily give param candidates priority
@@ -1893,7 +1893,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 // here (see issue #50825).
                 DropVictim::drop_if(!is_global(other_cand))
             }
-            (ObjectCandidate(_) | ProjectionCandidate(..), ParamCandidate(ref victim_cand)) => {
+            (ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(ref victim_cand)) => {
                 // Prefer these to a global where-clause bound
                 // (see issue #50825).
                 if is_global(victim_cand) { DropVictim::Yes } else { DropVictim::No }
@@ -1921,20 +1921,20 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 )
             }
 
-            (ProjectionCandidate(i, _), ProjectionCandidate(j, _))
+            (ProjectionCandidate(i), ProjectionCandidate(j))
             | (ObjectCandidate(i), ObjectCandidate(j)) => {
                 // Arbitrarily pick the lower numbered candidate for backwards
                 // compatibility reasons. Don't let this affect inference.
                 DropVictim::drop_if(i < j && !has_non_region_infer)
             }
-            (ObjectCandidate(_), ProjectionCandidate(..))
-            | (ProjectionCandidate(..), ObjectCandidate(_)) => {
+            (ObjectCandidate(_), ProjectionCandidate(_))
+            | (ProjectionCandidate(_), ObjectCandidate(_)) => {
                 bug!("Have both object and projection candidate")
             }
 
             // Arbitrarily give projection and object candidates priority.
             (
-                ObjectCandidate(_) | ProjectionCandidate(..),
+                ObjectCandidate(_) | ProjectionCandidate(_),
                 ImplCandidate(..)
                 | AutoImplCandidate
                 | ClosureCandidate { .. }
@@ -1964,7 +1964,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 | TraitUpcastingUnsizeCandidate(_)
                 | BuiltinCandidate { .. }
                 | TraitAliasCandidate,
-                ObjectCandidate(_) | ProjectionCandidate(..),
+                ObjectCandidate(_) | ProjectionCandidate(_),
             ) => DropVictim::No,
 
             (&ImplCandidate(other_def), &ImplCandidate(victim_def)) => {
diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs
index 34b8b6b97b5..58df83bd79d 100644
--- a/library/std/src/macros.rs
+++ b/library/std/src/macros.rs
@@ -355,15 +355,15 @@ macro_rules! dbg {
     // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!`
     // will be malformed.
     () => {
-        $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!())
+        $crate::eprintln!("[{}:{}:{}]", $crate::file!(), $crate::line!(), $crate::column!())
     };
     ($val:expr $(,)?) => {
         // Use of `match` here is intentional because it affects the lifetimes
         // of temporaries - https://stackoverflow.com/a/48732525/1063961
         match $val {
             tmp => {
-                $crate::eprintln!("[{}:{}] {} = {:#?}",
-                    $crate::file!(), $crate::line!(), $crate::stringify!($val), &tmp);
+                $crate::eprintln!("[{}:{}:{}] {} = {:#?}",
+                    $crate::file!(), $crate::line!(), $crate::column!(), $crate::stringify!($val), &tmp);
                 tmp
             }
         }
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index f452b944e75..f8e6d629ba3 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -55,7 +55,6 @@ dependencies = [
  "cmake",
  "fd-lock",
  "filetime",
- "hex",
  "home",
  "ignore",
  "junction",
@@ -314,12 +313,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
 
 [[package]]
-name = "hex"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
-
-[[package]]
 name = "home"
 version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 24951cf20fa..077d1954b7b 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -39,7 +39,6 @@ clap = { version = "4.4.7", default-features = false, features = ["std", "usage"
 clap_complete = "4.4.3"
 cmake = "0.1.38"
 filetime = "0.2"
-hex = "0.4"
 home = "0.5.4"
 ignore = "0.4.10"
 libc = "0.2.150"
diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs
index fe84b95f90c..9c897ae1bb7 100644
--- a/src/bootstrap/src/core/build_steps/setup.rs
+++ b/src/bootstrap/src/core/build_steps/setup.rs
@@ -1,6 +1,7 @@
 use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
 use crate::t;
 use crate::utils::change_tracker::CONFIG_CHANGE_HISTORY;
+use crate::utils::helpers::hex_encode;
 use crate::Config;
 use sha2::Digest;
 use std::env::consts::EXE_SUFFIX;
@@ -566,7 +567,7 @@ fn create_vscode_settings_maybe(config: &Config) -> io::Result<bool> {
     if let Ok(current) = fs::read_to_string(&vscode_settings) {
         let mut hasher = sha2::Sha256::new();
         hasher.update(&current);
-        let hash = hex::encode(hasher.finalize().as_slice());
+        let hash = hex_encode(hasher.finalize().as_slice());
         if hash == *current_hash {
             return Ok(true);
         } else if historical_hashes.contains(&hash.as_str()) {
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index 1f2ee6a6b73..ec404ab8580 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -11,9 +11,9 @@ use std::{
 use build_helper::ci::CiEnv;
 use xz2::bufread::XzDecoder;
 
-use crate::core::build_steps::llvm::detect_llvm_sha;
 use crate::core::config::RustfmtMetadata;
 use crate::utils::helpers::{check_run, exe, program_out_of_date};
+use crate::{core::build_steps::llvm::detect_llvm_sha, utils::helpers::hex_encode};
 use crate::{t, Config};
 
 static SHOULD_FIX_BINS_AND_DYLIBS: OnceLock<bool> = OnceLock::new();
@@ -345,7 +345,7 @@ impl Config {
             reader.consume(l);
         }
 
-        let checksum = hex::encode(hasher.finalize().as_slice());
+        let checksum = hex_encode(hasher.finalize().as_slice());
         let verified = checksum == expected;
 
         if !verified {
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 9efb4990cab..871318de595 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -34,6 +34,7 @@ use filetime::FileTime;
 use sha2::digest::Digest;
 use termcolor::{ColorChoice, StandardStream, WriteColor};
 use utils::channel::GitInfo;
+use utils::helpers::hex_encode;
 
 use crate::core::builder;
 use crate::core::builder::Kind;
@@ -1871,7 +1872,7 @@ pub fn generate_smart_stamp_hash(dir: &Path, additional_input: &str) -> String {
     hasher.update(status);
     hasher.update(additional_input);
 
-    hex::encode(hasher.finalize().as_slice())
+    hex_encode(hasher.finalize().as_slice())
 }
 
 /// Ensures that the behavior dump directory is properly initialized.
diff --git a/src/bootstrap/src/tests/builder.rs b/src/bootstrap/src/tests/builder.rs
index 744015e8e82..700ebcf5e37 100644
--- a/src/bootstrap/src/tests/builder.rs
+++ b/src/bootstrap/src/tests/builder.rs
@@ -156,22 +156,6 @@ fn alias_and_path_for_library() {
     assert_eq!(first(cache.all::<doc::Std>()), &[doc_std!(A => A, stage = 0)]);
 }
 
-#[test]
-fn test_beta_rev_parsing() {
-    use crate::utils::helpers::extract_beta_rev;
-
-    // single digit revision
-    assert_eq!(extract_beta_rev("1.99.9-beta.7 (xxxxxx)"), Some("7".to_string()));
-    // multiple digits
-    assert_eq!(extract_beta_rev("1.99.9-beta.777 (xxxxxx)"), Some("777".to_string()));
-    // nightly channel (no beta revision)
-    assert_eq!(extract_beta_rev("1.99.9-nightly (xxxxxx)"), None);
-    // stable channel (no beta revision)
-    assert_eq!(extract_beta_rev("1.99.9 (xxxxxxx)"), None);
-    // invalid string
-    assert_eq!(extract_beta_rev("invalid"), None);
-}
-
 mod defaults {
     use super::{configure, first, run_build};
     use crate::core::builder::*;
diff --git a/src/bootstrap/src/tests/helpers.rs b/src/bootstrap/src/tests/helpers.rs
new file mode 100644
index 00000000000..afe18aebafa
--- /dev/null
+++ b/src/bootstrap/src/tests/helpers.rs
@@ -0,0 +1,59 @@
+use crate::utils::helpers::{extract_beta_rev, hex_encode, make};
+use std::path::PathBuf;
+
+#[test]
+fn test_make() {
+    for (host, make_path) in vec![
+        ("dragonfly", PathBuf::from("gmake")),
+        ("netbsd", PathBuf::from("gmake")),
+        ("freebsd", PathBuf::from("gmake")),
+        ("openbsd", PathBuf::from("gmake")),
+        ("linux", PathBuf::from("make")),
+        // for checking the default
+        ("_", PathBuf::from("make")),
+    ] {
+        assert_eq!(make(host), make_path);
+    }
+}
+
+#[cfg(unix)]
+#[test]
+fn test_absolute_unix() {
+    use crate::utils::helpers::absolute_unix;
+
+    // Test an absolute path
+    let path = PathBuf::from("/home/user/file.txt");
+    assert_eq!(absolute_unix(&path).unwrap(), PathBuf::from("/home/user/file.txt"));
+
+    // Test an absolute path with double leading slashes
+    let path = PathBuf::from("//root//file.txt");
+    assert_eq!(absolute_unix(&path).unwrap(), PathBuf::from("//root/file.txt"));
+
+    // Test a relative path
+    let path = PathBuf::from("relative/path");
+    assert_eq!(
+        absolute_unix(&path).unwrap(),
+        std::env::current_dir().unwrap().join("relative/path")
+    );
+}
+
+#[test]
+fn test_beta_rev_parsing() {
+    // single digit revision
+    assert_eq!(extract_beta_rev("1.99.9-beta.7 (xxxxxx)"), Some("7".to_string()));
+    // multiple digits
+    assert_eq!(extract_beta_rev("1.99.9-beta.777 (xxxxxx)"), Some("777".to_string()));
+    // nightly channel (no beta revision)
+    assert_eq!(extract_beta_rev("1.99.9-nightly (xxxxxx)"), None);
+    // stable channel (no beta revision)
+    assert_eq!(extract_beta_rev("1.99.9 (xxxxxxx)"), None);
+    // invalid string
+    assert_eq!(extract_beta_rev("invalid"), None);
+}
+
+#[test]
+fn test_string_to_hex_encode() {
+    let input_string = "Hello, World!";
+    let hex_string = hex_encode(input_string);
+    assert_eq!(hex_string, "48656c6c6f2c20576f726c6421");
+}
diff --git a/src/bootstrap/src/tests/setup.rs b/src/bootstrap/src/tests/setup.rs
index 0fe6e4a4644..3e4d66c7454 100644
--- a/src/bootstrap/src/tests/setup.rs
+++ b/src/bootstrap/src/tests/setup.rs
@@ -1,11 +1,12 @@
 use super::{RUST_ANALYZER_SETTINGS, SETTINGS_HASHES};
+use crate::utils::helpers::hex_encode;
 use sha2::Digest;
 
 #[test]
 fn check_matching_settings_hash() {
     let mut hasher = sha2::Sha256::new();
     hasher.update(&RUST_ANALYZER_SETTINGS);
-    let hash = hex::encode(hasher.finalize().as_slice());
+    let hash = hex_encode(hasher.finalize().as_slice());
     assert_eq!(
         &hash,
         SETTINGS_HASHES.last().unwrap(),
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 031d56beb67..0c4297db6cc 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -20,6 +20,10 @@ use crate::LldMode;
 
 pub use crate::utils::dylib::{dylib_path, dylib_path_var};
 
+#[cfg(test)]
+#[path = "../tests/helpers.rs"]
+mod tests;
+
 /// A helper macro to `unwrap` a result except also print out details like:
 ///
 /// * The file/line of the panic
@@ -540,3 +544,11 @@ pub fn add_rustdoc_cargo_linker_args(
         cmd.env("RUSTDOCFLAGS", flags);
     }
 }
+
+/// Converts `T` into a hexadecimal `String`.
+pub fn hex_encode<T>(input: T) -> String
+where
+    T: AsRef<[u8]>,
+{
+    input.as_ref().iter().map(|x| format!("{:02x}", x)).collect()
+}
diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff
new file mode 100644
index 00000000000..4b1e3379114
--- /dev/null
+++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff
@@ -0,0 +1,104 @@
+- // MIR for `constant_index_overflow` before GVN
++ // MIR for `constant_index_overflow` after GVN
+  
+  fn constant_index_overflow(_1: &[T]) -> () {
+      debug x => _1;
+      let mut _0: ();
+      let _2: usize;
+      let mut _4: bool;
+      let mut _5: usize;
+      let mut _6: usize;
+      let mut _7: &[T];
+      let _8: usize;
+      let mut _9: usize;
+      let mut _10: bool;
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
+      let mut _14: T;
+      scope 1 {
+          debug a => _2;
+          let _3: T;
+          scope 2 {
+              debug b => _3;
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_2);
+-         _2 = const _ as usize (IntToInt);
++         nop;
++         _2 = const usize::MAX;
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+-         _5 = _2;
++         _5 = const usize::MAX;
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = &(*_1);
+          _6 = core::slice::<impl [T]>::len(move _7) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_7);
+-         _4 = Lt(move _5, move _6);
++         _4 = Lt(const usize::MAX, move _6);
+          switchInt(move _4) -> [0: bb4, otherwise: bb2];
+      }
+  
+      bb2: {
+          StorageDead(_6);
+          StorageDead(_5);
+          StorageLive(_8);
+-         _8 = _2;
++         _8 = const usize::MAX;
+          _9 = Len((*_1));
+-         _10 = Lt(_8, _9);
+-         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind unreachable];
++         _10 = Lt(const usize::MAX, _9);
++         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, const usize::MAX) -> [success: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+-         _3 = (*_1)[_8];
++         _3 = (*_1)[_2];
+          StorageDead(_8);
+          goto -> bb6;
+      }
+  
+      bb4: {
+          StorageDead(_6);
+          StorageDead(_5);
+          StorageLive(_11);
+          _11 = const 0_usize;
+          _12 = Len((*_1));
+-         _13 = Lt(_11, _12);
+-         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind unreachable];
++         _13 = Lt(const 0_usize, _12);
++         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 0_usize) -> [success: bb5, unwind unreachable];
+      }
+  
+      bb5: {
+-         _3 = (*_1)[_11];
++         _3 = (*_1)[0 of 1];
+          StorageDead(_11);
+          goto -> bb6;
+      }
+  
+      bb6: {
+          StorageDead(_4);
+          StorageLive(_14);
+          _14 = _3;
+          _0 = opaque::<T>(move _14) -> [return: bb7, unwind unreachable];
+      }
+  
+      bb7: {
+          StorageDead(_14);
+          StorageDead(_3);
+-         StorageDead(_2);
++         nop;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..8abcd7e9387
--- /dev/null
+++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff
@@ -0,0 +1,104 @@
+- // MIR for `constant_index_overflow` before GVN
++ // MIR for `constant_index_overflow` after GVN
+  
+  fn constant_index_overflow(_1: &[T]) -> () {
+      debug x => _1;
+      let mut _0: ();
+      let _2: usize;
+      let mut _4: bool;
+      let mut _5: usize;
+      let mut _6: usize;
+      let mut _7: &[T];
+      let _8: usize;
+      let mut _9: usize;
+      let mut _10: bool;
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
+      let mut _14: T;
+      scope 1 {
+          debug a => _2;
+          let _3: T;
+          scope 2 {
+              debug b => _3;
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_2);
+-         _2 = const _ as usize (IntToInt);
++         nop;
++         _2 = const usize::MAX;
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+-         _5 = _2;
++         _5 = const usize::MAX;
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = &(*_1);
+          _6 = core::slice::<impl [T]>::len(move _7) -> [return: bb1, unwind continue];
+      }
+  
+      bb1: {
+          StorageDead(_7);
+-         _4 = Lt(move _5, move _6);
++         _4 = Lt(const usize::MAX, move _6);
+          switchInt(move _4) -> [0: bb4, otherwise: bb2];
+      }
+  
+      bb2: {
+          StorageDead(_6);
+          StorageDead(_5);
+          StorageLive(_8);
+-         _8 = _2;
++         _8 = const usize::MAX;
+          _9 = Len((*_1));
+-         _10 = Lt(_8, _9);
+-         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, _8) -> [success: bb3, unwind continue];
++         _10 = Lt(const usize::MAX, _9);
++         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, const usize::MAX) -> [success: bb3, unwind continue];
+      }
+  
+      bb3: {
+-         _3 = (*_1)[_8];
++         _3 = (*_1)[_2];
+          StorageDead(_8);
+          goto -> bb6;
+      }
+  
+      bb4: {
+          StorageDead(_6);
+          StorageDead(_5);
+          StorageLive(_11);
+          _11 = const 0_usize;
+          _12 = Len((*_1));
+-         _13 = Lt(_11, _12);
+-         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, _11) -> [success: bb5, unwind continue];
++         _13 = Lt(const 0_usize, _12);
++         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, const 0_usize) -> [success: bb5, unwind continue];
+      }
+  
+      bb5: {
+-         _3 = (*_1)[_11];
++         _3 = (*_1)[0 of 1];
+          StorageDead(_11);
+          goto -> bb6;
+      }
+  
+      bb6: {
+          StorageDead(_4);
+          StorageLive(_14);
+          _14 = _3;
+          _0 = opaque::<T>(move _14) -> [return: bb7, unwind continue];
+      }
+  
+      bb7: {
+          StorageDead(_14);
+          StorageDead(_3);
+-         StorageDead(_2);
++         nop;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs
index 6e082acdbd3..db131f7f97d 100644
--- a/tests/mir-opt/gvn.rs
+++ b/tests/mir-opt/gvn.rs
@@ -609,6 +609,22 @@ fn indirect_static() {
     })
 }
 
+/// Verify that having constant index `u64::MAX` does not yield to an overflow in rustc.
+fn constant_index_overflow<T: Copy>(x: &[T]) {
+    // CHECK-LABEL: fn constant_index_overflow(
+    // CHECK: debug a => [[a:_.*]];
+    // CHECK: debug b => [[b:_.*]];
+    // CHECK: [[a]] = const usize::MAX;
+    // CHECK-NOT: = (*_1)[{{.*}} of 0];
+    // CHECK: [[b]] = (*_1)[[[a]]];
+    // CHECK-NOT: = (*_1)[{{.*}} of 0];
+    // CHECK: [[b]] = (*_1)[0 of 1];
+    // CHECK-NOT: = (*_1)[{{.*}} of 0];
+    let a = u64::MAX as usize;
+    let b = if a < x.len() { x[a] } else { x[0] };
+    opaque(b)
+}
+
 fn main() {
     subexpression_elimination(2, 4, 5);
     wrap_unwrap(5);
@@ -627,6 +643,7 @@ fn main() {
     repeat();
     fn_pointers();
     indirect_static();
+    constant_index_overflow(&[5, 3]);
 }
 
 #[inline(never)]
@@ -653,3 +670,4 @@ fn identity<T>(x: T) -> T {
 // EMIT_MIR gvn.repeat.GVN.diff
 // EMIT_MIR gvn.fn_pointers.GVN.diff
 // EMIT_MIR gvn.indirect_static.GVN.diff
+// EMIT_MIR gvn.constant_index_overflow.GVN.diff
diff --git a/tests/ui/macros/issue-118786.rs b/tests/ui/macros/issue-118786.rs
new file mode 100644
index 00000000000..84af3a65113
--- /dev/null
+++ b/tests/ui/macros/issue-118786.rs
@@ -0,0 +1,16 @@
+// compile-flags: --crate-type lib -O -C debug-assertions=yes
+
+// Regression test for issue 118786
+
+macro_rules! make_macro {
+    ($macro_name:tt) => {
+        macro_rules! $macro_name {
+        //~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon
+        //~| ERROR macro expansion ignores token `{` and any following
+        //~| ERROR cannot find macro `macro_rules` in this scope
+            () => {}
+        }
+    }
+}
+
+make_macro!((meow));
diff --git a/tests/ui/macros/issue-118786.stderr b/tests/ui/macros/issue-118786.stderr
new file mode 100644
index 00000000000..ca3a40f31c1
--- /dev/null
+++ b/tests/ui/macros/issue-118786.stderr
@@ -0,0 +1,47 @@
+error: macros that expand to items must be delimited with braces or followed by a semicolon
+  --> $DIR/issue-118786.rs:7:22
+   |
+LL |         macro_rules! $macro_name {
+   |                      ^^^^^^^^^^^
+   |
+help: change the delimiters to curly braces
+   |
+LL |         macro_rules! {} {
+   |                      ~          +
+help: add a semicolon
+   |
+LL |         macro_rules! $macro_name; {
+   |                                 +
+
+error: macro expansion ignores token `{` and any following
+  --> $DIR/issue-118786.rs:7:34
+   |
+LL |         macro_rules! $macro_name {
+   |                                  ^
+...
+LL | make_macro!((meow));
+   | ------------------- caused by the macro expansion here
+   |
+   = note: the usage of `make_macro!` is likely invalid in item context
+
+error: cannot find macro `macro_rules` in this scope
+  --> $DIR/issue-118786.rs:7:9
+   |
+LL |         macro_rules! $macro_name {
+   |         ^^^^^^^^^^^
+...
+LL | make_macro!((meow));
+   | ------------------- in this macro invocation
+   |
+note: maybe you have forgotten to define a name for this `macro_rules!`
+  --> $DIR/issue-118786.rs:7:9
+   |
+LL |         macro_rules! $macro_name {
+   |         ^^^^^^^^^^^
+...
+LL | make_macro!((meow));
+   | ------------------- in this macro invocation
+   = note: this error originates in the macro `make_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/parser/bad-let-else-statement.rs b/tests/ui/parser/bad-let-else-statement.rs
new file mode 100644
index 00000000000..7b927c89ba0
--- /dev/null
+++ b/tests/ui/parser/bad-let-else-statement.rs
@@ -0,0 +1,164 @@
+#![feature(inline_const)]
+#![feature(yeet_expr)]
+#![allow(incomplete_features)] // Necessary for now, while explicit_tail_calls is incomplete
+#![feature(explicit_tail_calls)]
+
+fn a() {
+    let foo = {
+        1
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+fn b() {
+    let foo = for i in 1..2 {
+        break;
+    } else {
+        //~^ ERROR `for...else` loops are not supported
+        return;
+    };
+}
+
+fn c() {
+    let foo = if true {
+        1
+    } else {
+        0
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+fn d() {
+    let foo = loop {
+        break;
+    } else {
+        //~^ ERROR loop...else` loops are not supported
+        return;
+    };
+}
+
+fn e() {
+    let foo = match true {
+        true => 1,
+        false => 0
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+struct X {a: i32}
+fn f() {
+    let foo = X {
+        a: 1
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+fn g() {
+    let foo = while false {
+        break;
+    } else {
+        //~^ ERROR `while...else` loops are not supported
+        return;
+    };
+}
+
+fn h() {
+    let foo = const {
+        1
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+fn i() {
+    let foo = &{
+        1
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+fn j() {
+    let bar = 0;
+    let foo = bar = {
+        1
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+fn k() {
+    let foo = 1 + {
+        1
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+fn l() {
+    let foo = 1..{
+        1
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+fn m() {
+    let foo = return {
+        ()
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+fn n() {
+    let foo = -{
+        1
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+fn o() -> Result<(), ()> {
+    let foo = do yeet {
+        ()
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return Ok(());
+    };
+}
+
+fn p() {
+    let foo = become {
+        ()
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+fn q() {
+    let foo = |x: i32| {
+        x
+    } else {
+        //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+        return;
+    };
+}
+
+fn main() {}
diff --git a/tests/ui/parser/bad-let-else-statement.stderr b/tests/ui/parser/bad-let-else-statement.stderr
new file mode 100644
index 00000000000..7cbda25e417
--- /dev/null
+++ b/tests/ui/parser/bad-let-else-statement.stderr
@@ -0,0 +1,232 @@
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:9:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = ({
+LL |         1
+LL ~     }) else {
+   |
+
+error: `for...else` loops are not supported
+  --> $DIR/bad-let-else-statement.rs:18:7
+   |
+LL |       let foo = for i in 1..2 {
+   |                 --- `else` is attached to this loop
+LL |           break;
+LL |       } else {
+   |  _______^
+LL | |
+LL | |         return;
+LL | |     };
+   | |_____^
+   |
+   = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:29:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = (if true {
+LL |         1
+LL |     } else {
+LL |         0
+LL ~     }) else {
+   |
+
+error: `loop...else` loops are not supported
+  --> $DIR/bad-let-else-statement.rs:38:7
+   |
+LL |       let foo = loop {
+   |                 ---- `else` is attached to this loop
+LL |           break;
+LL |       } else {
+   |  _______^
+LL | |
+LL | |         return;
+LL | |     };
+   | |_____^
+   |
+   = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:48:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = (match true {
+LL |         true => 1,
+LL |         false => 0
+LL ~     }) else {
+   |
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:58:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = (X {
+LL |         a: 1
+LL ~     }) else {
+   |
+
+error: `while...else` loops are not supported
+  --> $DIR/bad-let-else-statement.rs:67:7
+   |
+LL |       let foo = while false {
+   |                 ----- `else` is attached to this loop
+LL |           break;
+LL |       } else {
+   |  _______^
+LL | |
+LL | |         return;
+LL | |     };
+   | |_____^
+   |
+   = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:76:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = (const {
+LL |         1
+LL ~     }) else {
+   |
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:85:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = &({
+LL |         1
+LL ~     }) else {
+   |
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:95:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = bar = ({
+LL |         1
+LL ~     }) else {
+   |
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:104:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = 1 + ({
+LL |         1
+LL ~     }) else {
+   |
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:113:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = 1..({
+LL |         1
+LL ~     }) else {
+   |
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:122:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = return ({
+LL |         ()
+LL ~     }) else {
+   |
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:131:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = -({
+LL |         1
+LL ~     }) else {
+   |
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:140:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = do yeet ({
+LL |         ()
+LL ~     }) else {
+   |
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:149:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = become ({
+LL |         ()
+LL ~     }) else {
+   |
+
+error: right curly brace `}` before `else` in a `let...else` statement not allowed
+  --> $DIR/bad-let-else-statement.rs:158:5
+   |
+LL |     } else {
+   |     ^
+   |
+help: wrap the expression in parentheses
+   |
+LL ~     let foo = |x: i32| ({
+LL |         x
+LL ~     }) else {
+   |
+
+error: aborting due to 17 previous errors
+
diff --git a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr
index 1a26f34a52d..2c018ca875d 100644
--- a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr
+++ b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr
@@ -1,28 +1,28 @@
-[$DIR/dbg-macro-expected-behavior.rs:22] Unit = Unit
-[$DIR/dbg-macro-expected-behavior.rs:23] a = Unit
-[$DIR/dbg-macro-expected-behavior.rs:29] Point { x: 42, y: 24 } = Point {
+[$DIR/dbg-macro-expected-behavior.rs:22:19] Unit = Unit
+[$DIR/dbg-macro-expected-behavior.rs:23:19] a = Unit
+[$DIR/dbg-macro-expected-behavior.rs:29:24] Point { x: 42, y: 24 } = Point {
     x: 42,
     y: 24,
 }
-[$DIR/dbg-macro-expected-behavior.rs:30] b = Point {
+[$DIR/dbg-macro-expected-behavior.rs:30:24] b = Point {
     x: 42,
     y: 24,
 }
-[$DIR/dbg-macro-expected-behavior.rs:38]
-[$DIR/dbg-macro-expected-behavior.rs:42] &a = NoCopy(
+[$DIR/dbg-macro-expected-behavior.rs:38:17]
+[$DIR/dbg-macro-expected-behavior.rs:42:27] &a = NoCopy(
     1337,
 )
-[$DIR/dbg-macro-expected-behavior.rs:42] dbg!(&a) = NoCopy(
+[$DIR/dbg-macro-expected-behavior.rs:42:22] dbg!(&a) = NoCopy(
     1337,
 )
-[$DIR/dbg-macro-expected-behavior.rs:47] f(&42) = 42
+[$DIR/dbg-macro-expected-behavior.rs:47:18] f(&42) = 42
 before
-[$DIR/dbg-macro-expected-behavior.rs:52] { foo += 1; eprintln!("before"); 7331 } = 7331
-[$DIR/dbg-macro-expected-behavior.rs:60] ("Yeah",) = (
+[$DIR/dbg-macro-expected-behavior.rs:52:22] { foo += 1; eprintln!("before"); 7331 } = 7331
+[$DIR/dbg-macro-expected-behavior.rs:60:27] ("Yeah",) = (
     "Yeah",
 )
-[$DIR/dbg-macro-expected-behavior.rs:63] 1 = 1
-[$DIR/dbg-macro-expected-behavior.rs:63] 2 = 2
-[$DIR/dbg-macro-expected-behavior.rs:67] 1u8 = 1
-[$DIR/dbg-macro-expected-behavior.rs:67] 2u32 = 2
-[$DIR/dbg-macro-expected-behavior.rs:67] "Yeah" = "Yeah"
+[$DIR/dbg-macro-expected-behavior.rs:63:29] 1 = 1
+[$DIR/dbg-macro-expected-behavior.rs:63:29] 2 = 2
+[$DIR/dbg-macro-expected-behavior.rs:67:37] 1u8 = 1
+[$DIR/dbg-macro-expected-behavior.rs:67:37] 2u32 = 2
+[$DIR/dbg-macro-expected-behavior.rs:67:37] "Yeah" = "Yeah"
diff --git a/tests/ui/traits/issue-117794.rs b/tests/ui/traits/issue-117794.rs
new file mode 100644
index 00000000000..a66d6eb10ed
--- /dev/null
+++ b/tests/ui/traits/issue-117794.rs
@@ -0,0 +1,10 @@
+trait Foo {}
+
+trait T {
+    fn a(&self) -> impl Foo {
+        self.b(|| 0)
+        //~^ ERROR no method named `b` found for reference `&Self` in the current scope
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/issue-117794.stderr b/tests/ui/traits/issue-117794.stderr
new file mode 100644
index 00000000000..af63b47f07d
--- /dev/null
+++ b/tests/ui/traits/issue-117794.stderr
@@ -0,0 +1,9 @@
+error[E0599]: no method named `b` found for reference `&Self` in the current scope
+  --> $DIR/issue-117794.rs:5:14
+   |
+LL |         self.b(|| 0)
+   |              ^ help: there is a method with a similar name: `a`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.