about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-11-24 17:24:47 +0000
committerbors <bors@rust-lang.org>2023-11-24 17:24:47 +0000
commit42ae1a76154289ccc972deeb43318b164f01539e (patch)
tree0b07eb03e1606cddfcdbb59bf228fa22b9680809
parent4fd68eb47bad1c121417ac4450b2f0456150db86 (diff)
parent592ee1224503f80b1439ae14d330e44730df2462 (diff)
downloadrust-42ae1a76154289ccc972deeb43318b164f01539e.tar.gz
rust-42ae1a76154289ccc972deeb43318b164f01539e.zip
Auto merge of #118248 - compiler-errors:rollup-tye3vgj, r=compiler-errors
Rollup of 7 pull requests

Successful merges:

 - #118187 (Recompile LLVM when it changes in the git sources)
 - #118210 (intercrate ambiguity causes: ignore candidates which don't apply)
 - #118215 (Add common trait for crate definitions)
 - #118238 (memcpy assumptions: update GCC link)
 - #118243 (EvalCtxt::commit_if_ok don't inherit nested goals)
 - #118245 (Add `Span` to `TraitBoundModifier`)
 - #118246 (Remove a hack for effects)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_ast/src/ast.rs7
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs4
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs5
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs2
-rw-r--r--compiler/rustc_expand/src/build.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs7
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs12
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs37
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/commit_if_ok.rs6
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs7
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs6
-rw-r--r--compiler/stable_mir/src/crate_def.rs69
-rw-r--r--compiler/stable_mir/src/lib.rs27
-rw-r--r--compiler/stable_mir/src/mir/mono.rs32
-rw-r--r--compiler/stable_mir/src/mir/pretty.rs1
-rw-r--r--compiler/stable_mir/src/ty.rs73
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs9
-rw-r--r--src/bootstrap/src/lib.rs43
-rw-r--r--src/tools/rustfmt/src/types.rs2
-rw-r--r--tests/ui-fulldeps/stable-mir/check_allocation.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_defs.rs106
-rw-r--r--tests/ui-fulldeps/stable-mir/crate-info.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/projections.rs1
-rw-r--r--tests/ui/error-codes/E0476.next.stderr (renamed from tests/ui/error-codes/E0476.stderr)8
-rw-r--r--tests/ui/error-codes/E0476.old.stderr31
-rw-r--r--tests/ui/error-codes/E0476.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr42
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr4
-rw-r--r--tests/ui/stats/hir-stats.stderr58
42 files changed, 485 insertions, 155 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 83fe95f16f9..10776f31c07 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -301,7 +301,7 @@ pub enum TraitBoundModifier {
     Maybe,
 
     /// `~const Trait`
-    MaybeConst,
+    MaybeConst(Span),
 
     /// `~const !Trait`
     //
@@ -317,8 +317,7 @@ pub enum TraitBoundModifier {
 impl TraitBoundModifier {
     pub fn to_constness(self) -> Const {
         match self {
-            // FIXME(effects) span
-            Self::MaybeConst => Const::Yes(DUMMY_SP),
+            Self::MaybeConst(span) => Const::Yes(span),
             _ => Const::No,
         }
     }
@@ -3155,7 +3154,7 @@ mod size_asserts {
     static_assert_size!(ForeignItem, 96);
     static_assert_size!(ForeignItemKind, 24);
     static_assert_size!(GenericArg, 24);
-    static_assert_size!(GenericBound, 56);
+    static_assert_size!(GenericBound, 64);
     static_assert_size!(Generics, 40);
     static_assert_size!(Impl, 136);
     static_assert_size!(Item, 136);
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index e9554f10776..96af090bccd 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1369,7 +1369,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             GenericBound::Trait(
                                 ty,
                                 modifier @ (TraitBoundModifier::None
-                                | TraitBoundModifier::MaybeConst
+                                | TraitBoundModifier::MaybeConst(_)
                                 | TraitBoundModifier::Negative),
                             ) => {
                                 Some(this.lower_poly_trait_ref(ty, itctx, modifier.to_constness()))
@@ -2227,7 +2227,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
         match f {
             TraitBoundModifier::None => hir::TraitBoundModifier::None,
-            TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst,
+            TraitBoundModifier::MaybeConst(_) => hir::TraitBoundModifier::MaybeConst,
 
             TraitBoundModifier::Negative => {
                 if self.tcx.features().negative_bounds {
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 1a45c8eb1a5..45b5e63bd1b 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -1203,7 +1203,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 (BoundKind::TraitObject, TraitBoundModifier::Maybe) => {
                     self.err_handler().emit_err(errors::OptionalTraitObject { span: poly.span });
                 }
-                (_, TraitBoundModifier::MaybeConst)
+                (_, &TraitBoundModifier::MaybeConst(span))
                     if let Some(reason) = &self.disallow_tilde_const =>
                 {
                     let reason = match reason {
@@ -1224,8 +1224,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         }
                         DisallowTildeConstContext::Item => errors::TildeConstReason::Item,
                     };
-                    self.err_handler()
-                        .emit_err(errors::TildeConstDisallowed { span: bound.span(), reason });
+                    self.err_handler().emit_err(errors::TildeConstDisallowed { span, reason });
                 }
                 (_, TraitBoundModifier::MaybeConstMaybe) => {
                     self.err_handler().emit_err(errors::OptionalConstExclusive {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index da91c3c8a19..a3bf47328ea 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1515,7 +1515,7 @@ impl<'a> State<'a> {
                         TraitBoundModifier::Maybe => {
                             self.word("?");
                         }
-                        TraitBoundModifier::MaybeConst => {
+                        TraitBoundModifier::MaybeConst(_) => {
                             self.word_space("~const");
                         }
                         TraitBoundModifier::MaybeConstNegative => {
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index 7de46994434..9a8d0d691f0 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -4,7 +4,7 @@ use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, PatKind,
 use rustc_ast::{attr, token, util::literal};
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
 use thin_vec::{thin_vec, ThinVec};
 
 impl<'a> ExtCtxt<'a> {
@@ -135,7 +135,7 @@ impl<'a> ExtCtxt<'a> {
         ast::GenericBound::Trait(
             self.poly_trait_ref(path.span, path),
             if is_const {
-                ast::TraitBoundModifier::MaybeConst
+                ast::TraitBoundModifier::MaybeConst(DUMMY_SP)
             } else {
                 ast::TraitBoundModifier::None
             },
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index a9f67f984da..6d4bd981b7b 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -526,14 +526,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
         };
 
-        if let ty::FnDef(did, callee_args) = *ty.kind() {
+        if let ty::FnDef(did, _) = *ty.kind() {
             let fn_sig = ty.fn_sig(tcx);
 
-            // HACK: whenever we get a FnDef in a non-const context, enforce effects to get the
-            // default `host = true` to avoid inference errors later.
-            if tcx.hir().body_const_context(self.body_id).is_none() {
-                self.enforce_context_effects(expr.hir_id, qpath.span(), did, callee_args);
-            }
             if tcx.fn_sig(did).skip_binder().abi() == RustIntrinsic
                 && tcx.item_name(did) == sym::transmute
             {
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 75617b1b3ea..b1a57c3dfd9 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -37,7 +37,7 @@ impl BoundModifiers {
             (BoundPolarity::Positive, None) => TraitBoundModifier::None,
             (BoundPolarity::Negative(_), None) => TraitBoundModifier::Negative,
             (BoundPolarity::Maybe(_), None) => TraitBoundModifier::Maybe,
-            (BoundPolarity::Positive, Some(_)) => TraitBoundModifier::MaybeConst,
+            (BoundPolarity::Positive, Some(sp)) => TraitBoundModifier::MaybeConst(sp),
             (BoundPolarity::Negative(_), Some(_)) => TraitBoundModifier::MaybeConstNegative,
             (BoundPolarity::Maybe(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe,
         }
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index fe226ef60ed..202ca1b156a 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -11,8 +11,8 @@ use stable_mir::mir::alloc::AllocId;
 use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
 use stable_mir::ty::{
     AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const,
-    ExistentialTraitRef, FloatTy, GenericArgKind, GenericArgs, IntTy, Region, RigidTy, TraitRef,
-    Ty, UintTy,
+    ExistentialTraitRef, FloatTy, GenericArgKind, GenericArgs, IntTy, Region, RigidTy, Span,
+    TraitRef, Ty, UintTy,
 };
 use stable_mir::{CrateItem, DefId};
 
@@ -279,6 +279,14 @@ impl<'tcx> RustcInternal<'tcx> for AdtDef {
     }
 }
 
+impl<'tcx> RustcInternal<'tcx> for Span {
+    type T = rustc_span::Span;
+
+    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        tables[*self]
+    }
+}
+
 impl<'tcx, T> RustcInternal<'tcx> for &T
 where
     T: RustcInternal<'tcx>,
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 8b469882cd1..9921a89eb23 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -14,6 +14,7 @@ use rustc_hir::def::DefKind;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{alloc_range, AllocId};
 use rustc_middle::mir::mono::MonoItem;
+use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
 use rustc_middle::ty::{self, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, Variance};
 use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_target::abi::FieldIdx;
@@ -28,7 +29,7 @@ use stable_mir::ty::{
     EarlyParamRegion, FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability,
     RigidTy, Span, TyKind, UintTy,
 };
-use stable_mir::{self, opaque, Context, CrateItem, Error, Filename, ItemKind};
+use stable_mir::{self, opaque, Context, Crate, CrateItem, Error, Filename, ItemKind, Symbol};
 use std::cell::RefCell;
 use tracing::debug;
 
@@ -61,9 +62,18 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
         crates
     }
 
-    fn name_of_def_id(&self, def_id: stable_mir::DefId) -> String {
+    fn def_name(&self, def_id: stable_mir::DefId, trimmed: bool) -> Symbol {
         let tables = self.0.borrow();
-        tables.tcx.def_path_str(tables[def_id])
+        if trimmed {
+            with_forced_trimmed_paths!(tables.tcx.def_path_str(tables[def_id]))
+        } else {
+            with_no_trimmed_paths!(tables.tcx.def_path_str(tables[def_id]))
+        }
+    }
+
+    fn krate(&self, def_id: stable_mir::DefId) -> Crate {
+        let tables = self.0.borrow();
+        smir_crate(tables.tcx, tables[def_id].krate)
     }
 
     fn span_to_string(&self, span: stable_mir::ty::Span) -> String {
@@ -240,12 +250,29 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
         tables.create_def_id(def_id)
     }
 
-    fn instance_mangled_name(&self, def: InstanceDef) -> String {
+    fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol {
         let tables = self.0.borrow_mut();
-        let instance = tables.instances[def];
+        let instance = tables.instances[instance];
         tables.tcx.symbol_name(instance).name.to_string()
     }
 
+    /// Retrieve the instance name for diagnostic messages.
+    ///
+    /// This will return the specialized name, e.g., `Vec<char>::new`.
+    fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol {
+        let tables = self.0.borrow_mut();
+        let instance = tables.instances[def];
+        if trimmed {
+            with_forced_trimmed_paths!(
+                tables.tcx.def_path_str_with_args(instance.def_id(), instance.args)
+            )
+        } else {
+            with_no_trimmed_paths!(
+                tables.tcx.def_path_str_with_args(instance.def_id(), instance.args)
+            )
+        }
+    }
+
     fn mono_instance(&self, item: stable_mir::CrateItem) -> stable_mir::mir::mono::Instance {
         let mut tables = self.0.borrow_mut();
         let def_id = tables[item.0];
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/commit_if_ok.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/commit_if_ok.rs
index c47152c601c..67b6801059a 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/commit_if_ok.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/commit_if_ok.rs
@@ -1,4 +1,4 @@
-use super::EvalCtxt;
+use super::{EvalCtxt, NestedGoals};
 use crate::solve::inspect;
 use rustc_middle::traits::query::NoSolution;
 
@@ -14,7 +14,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
             predefined_opaques_in_body: self.predefined_opaques_in_body,
             max_input_universe: self.max_input_universe,
             search_graph: self.search_graph,
-            nested_goals: self.nested_goals.clone(),
+            nested_goals: NestedGoals::new(),
             tainted: self.tainted,
             inspect: self.inspect.new_probe(),
         };
@@ -32,7 +32,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
                 tainted,
                 inspect,
             } = nested_ecx;
-            self.nested_goals = nested_goals;
+            self.nested_goals.extend(nested_goals);
             self.tainted = tainted;
             self.inspect.integrate_snapshot(inspect);
         } else {
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index ded7874b62a..f8860ee87d2 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -108,7 +108,7 @@ pub(super) struct NestedGoals<'tcx> {
     pub(super) goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
 }
 
-impl NestedGoals<'_> {
+impl<'tcx> NestedGoals<'tcx> {
     pub(super) fn new() -> Self {
         Self { normalizes_to_hack_goal: None, goals: Vec::new() }
     }
@@ -116,6 +116,11 @@ impl NestedGoals<'_> {
     pub(super) fn is_empty(&self) -> bool {
         self.normalizes_to_hack_goal.is_none() && self.goals.is_empty()
     }
+
+    pub(super) fn extend(&mut self, other: NestedGoals<'tcx>) {
+        assert_eq!(other.normalizes_to_hack_goal, None);
+        self.goals.extend(other.goals)
+    }
 }
 
 #[derive(PartialEq, Eq, Debug, Hash, HashStable, Clone, Copy)]
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index 65d061ab3f4..0cf4799f86d 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -334,11 +334,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             }
         }
 
-        // FIXME(@lcnr): If the normalization of the alias adds an inference constraint which
-        // causes a previously added goal to fail, then we treat the alias as rigid.
-        //
-        // These feels like a potential issue, I should look into writing some tests here
-        // and then probably changing `commit_if_ok` to not inherit the parent goals.
         match self.commit_if_ok(|this| {
             let normalized_ty = this.next_ty_infer();
             let normalizes_to_goal = Goal::new(
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 9119792e324..f3993ec2566 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -1050,8 +1050,10 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
         let mut ambiguity_cause = None;
         for cand in goal.candidates() {
             // FIXME: boiiii, using string comparisions here sure is scuffed.
-            if let inspect::ProbeKind::MiscCandidate { name: "coherence unknowable", result: _ } =
-                cand.kind()
+            if let inspect::ProbeKind::MiscCandidate {
+                name: "coherence unknowable",
+                result: Ok(_),
+            } = cand.kind()
             {
                 let lazily_normalize_ty = |ty: Ty<'tcx>| {
                     let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(infcx);
diff --git a/compiler/stable_mir/src/crate_def.rs b/compiler/stable_mir/src/crate_def.rs
new file mode 100644
index 00000000000..70ca9e6825e
--- /dev/null
+++ b/compiler/stable_mir/src/crate_def.rs
@@ -0,0 +1,69 @@
+//! Module that define a common trait for things that represent a crate definition,
+//! such as, a function, a trait, an enum, and any other definitions.
+
+use crate::ty::Span;
+use crate::{with, Crate, Symbol};
+
+/// A unique identification number for each item accessible for the current compilation unit.
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+pub struct DefId(pub(crate) usize);
+
+/// A trait for retrieving information about a particular definition.
+///
+/// Implementors must provide the implementation of `def_id` which will be used to retrieve
+/// information about a crate's definition.
+pub trait CrateDef {
+    /// Retrieve the unique identifier for the current definition.
+    fn def_id(&self) -> DefId;
+
+    /// Return the fully qualified name of the current definition.
+    fn name(&self) -> Symbol {
+        let def_id = self.def_id();
+        with(|cx| cx.def_name(def_id, false))
+    }
+
+    /// Return a trimmed name of this definition.
+    ///
+    /// This can be used to print more user friendly diagnostic messages.
+    ///
+    /// If a symbol name can only be imported from one place for a type, and as
+    /// long as it was not glob-imported anywhere in the current crate, we trim its
+    /// path and print only the name.
+    ///
+    /// For example, this function may shorten `std::vec::Vec` to just `Vec`,
+    /// as long as there is no other `Vec` importable anywhere.
+    fn trimmed_name(&self) -> Symbol {
+        let def_id = self.def_id();
+        with(|cx| cx.def_name(def_id, true))
+    }
+
+    /// Return information about the crate where this definition is declared.
+    ///
+    /// This will return the crate number and its name.
+    fn krate(&self) -> Crate {
+        let def_id = self.def_id();
+        with(|cx| cx.krate(def_id))
+    }
+
+    /// Return the span of this definition.
+    fn span(&self) -> Span {
+        let def_id = self.def_id();
+        with(|cx| cx.span_of_an_item(def_id))
+    }
+}
+
+macro_rules! crate_def {
+    ( $(#[$attr:meta])*
+      $vis:vis $name:ident $(;)?
+    ) => {
+        $(#[$attr])*
+        #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
+        $vis struct $name(pub DefId);
+
+        impl CrateDef for $name {
+            fn def_id(&self) -> DefId {
+                self.0
+            }
+        }
+    };
+}
diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs
index 6c1b723a8da..1b1faea4953 100644
--- a/compiler/stable_mir/src/lib.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -32,11 +32,15 @@ use self::ty::{
 extern crate scoped_tls;
 
 #[macro_use]
+pub mod crate_def;
+#[macro_use]
 pub mod error;
 pub mod mir;
 pub mod ty;
 pub mod visitor;
 
+pub use crate::crate_def::CrateDef;
+pub use crate::crate_def::DefId;
 use crate::mir::alloc::{AllocId, GlobalAlloc};
 use crate::mir::pretty::function_name;
 use crate::mir::Mutability;
@@ -51,15 +55,11 @@ pub type Symbol = String;
 /// The number that identifies a crate.
 pub type CrateNum = usize;
 
-/// A unique identification number for each item accessible for the current compilation unit.
-#[derive(Clone, Copy, PartialEq, Eq, Hash)]
-pub struct DefId(usize);
-
 impl Debug for DefId {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("DefId")
             .field("id", &self.0)
-            .field("name", &with(|cx| cx.name_of_def_id(*self)))
+            .field("name", &with(|cx| cx.def_name(*self, false)))
             .finish()
     }
 }
@@ -100,9 +100,10 @@ pub enum ItemKind {
 
 pub type Filename = String;
 
-/// Holds information about an item in the crate.
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub struct CrateItem(pub DefId);
+crate_def! {
+    /// Holds information about an item in a crate.
+    pub CrateItem;
+}
 
 impl CrateItem {
     pub fn body(&self) -> mir::Body {
@@ -113,10 +114,6 @@ impl CrateItem {
         with(|cx| cx.span_of_an_item(self.0))
     }
 
-    pub fn name(&self) -> String {
-        with(|cx| cx.name_of_def_id(self.0))
-    }
-
     pub fn kind(&self) -> ItemKind {
         with(|cx| cx.item_kind(*self))
     }
@@ -205,7 +202,7 @@ pub trait Context {
     fn find_crates(&self, name: &str) -> Vec<Crate>;
 
     /// Returns the name of given `DefId`
-    fn name_of_def_id(&self, def_id: DefId) -> String;
+    fn def_name(&self, def_id: DefId, trimmed: bool) -> Symbol;
 
     /// Returns printable, human readable form of `Span`
     fn span_to_string(&self, span: Span) -> String;
@@ -260,7 +257,7 @@ pub trait Context {
     fn instance_def_id(&self, instance: InstanceDef) -> DefId;
 
     /// Get the instance mangled name.
-    fn instance_mangled_name(&self, instance: InstanceDef) -> String;
+    fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol;
 
     /// Convert a non-generic crate item into an instance.
     /// This function will panic if the item is generic.
@@ -294,6 +291,8 @@ pub trait Context {
 
     /// Retrieve the id for the virtual table.
     fn vtable_allocation(&self, global_alloc: &GlobalAlloc) -> Option<AllocId>;
+    fn krate(&self, def_id: DefId) -> Crate;
+    fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol;
 }
 
 // A thread local variable that stores a pointer to the tables mapping between TyCtxt
diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/stable_mir/src/mir/mono.rs
index 9cec963cf84..8e884f17573 100644
--- a/compiler/stable_mir/src/mir/mono.rs
+++ b/compiler/stable_mir/src/mir/mono.rs
@@ -1,6 +1,7 @@
+use crate::crate_def::CrateDef;
 use crate::mir::Body;
 use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
-use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque};
+use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque, Symbol};
 use std::fmt::{Debug, Formatter};
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
@@ -47,10 +48,29 @@ impl Instance {
         with(|context| context.instance_ty(self.def))
     }
 
-    pub fn mangled_name(&self) -> String {
+    /// Retrieve the instance's mangled name used for calling the given instance.
+    ///
+    /// This will also look up the correct name of instances from upstream crates.
+    pub fn mangled_name(&self) -> Symbol {
         with(|context| context.instance_mangled_name(self.def))
     }
 
+    /// Retrieve the instance name for diagnostic messages.
+    ///
+    /// This will return the specialized name, e.g., `std::vec::Vec<u8>::new`.
+    pub fn name(&self) -> Symbol {
+        with(|context| context.instance_name(self.def, false))
+    }
+
+    /// Return a trimmed name of the given instance including its args.
+    ///
+    /// If a symbol name can only be imported from one place for a type, and as
+    /// long as it was not glob-imported anywhere in the current crate, we trim its
+    /// path and print only the name.
+    pub fn trimmed_name(&self) -> Symbol {
+        with(|context| context.instance_name(self.def, true))
+    }
+
     /// Resolve an instance starting from a function definition and generic arguments.
     pub fn resolve(def: FnDef, args: &GenericArgs) -> Result<Instance, crate::Error> {
         with(|context| {
@@ -104,6 +124,8 @@ impl TryFrom<CrateItem> for Instance {
 
     fn try_from(item: CrateItem) -> Result<Self, Self::Error> {
         with(|context| {
+            // FIXME(celinval):
+            // - Return `Err` if instance does not have a body.
             if !context.requires_monomorphization(item.0) {
                 Ok(context.mono_instance(item))
             } else {
@@ -148,8 +170,10 @@ impl From<StaticDef> for CrateItem {
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 pub struct InstanceDef(usize);
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
-pub struct StaticDef(pub DefId);
+crate_def! {
+    /// Holds information about a static variable definition.
+    pub StaticDef;
+}
 
 impl TryFrom<CrateItem> for StaticDef {
     type Error = crate::Error;
diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs
index c7422d66c0e..c16d7ddf335 100644
--- a/compiler/stable_mir/src/mir/pretty.rs
+++ b/compiler/stable_mir/src/mir/pretty.rs
@@ -1,3 +1,4 @@
+use crate::crate_def::CrateDef;
 use crate::mir::{Operand, Rvalue, StatementKind};
 use crate::ty::{DynKind, FloatTy, IntTy, RigidTy, TyKind, UintTy};
 use crate::{with, Body, CrateItem, Mutability};
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index 19b7abaf2a8..80558657deb 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -3,6 +3,7 @@ use super::{
     mir::{Body, Mutability},
     with, DefId, Error, Symbol,
 };
+use crate::crate_def::CrateDef;
 use crate::mir::alloc::AllocId;
 use crate::{Filename, Opaque};
 use std::fmt::{self, Debug, Display, Formatter};
@@ -295,11 +296,15 @@ pub enum Movability {
     Movable,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ForeignDef(pub DefId);
+crate_def! {
+    /// Hold information about a ForeignItem in a crate.
+    pub ForeignDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct FnDef(pub DefId);
+crate_def! {
+    /// Hold information about a function definition in a crate.
+    pub FnDef;
+}
 
 impl FnDef {
     pub fn body(&self) -> Body {
@@ -307,20 +312,25 @@ impl FnDef {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ClosureDef(pub DefId);
+crate_def! {
+    pub ClosureDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct CoroutineDef(pub DefId);
+crate_def! {
+    pub CoroutineDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ParamDef(pub DefId);
+crate_def! {
+    pub ParamDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct BrNamedDef(pub DefId);
+crate_def! {
+    pub BrNamedDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct AdtDef(pub DefId);
+crate_def! {
+    pub AdtDef;
+}
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
 pub enum AdtKind {
@@ -363,26 +373,33 @@ impl AdtKind {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct AliasDef(pub DefId);
+crate_def! {
+    pub AliasDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct TraitDef(pub DefId);
+crate_def! {
+    pub TraitDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct GenericDef(pub DefId);
+crate_def! {
+    pub GenericDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ConstDef(pub DefId);
+crate_def! {
+    pub ConstDef;
+}
 
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct ImplDef(pub DefId);
+crate_def! {
+    pub ImplDef;
+}
 
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct RegionDef(pub DefId);
+crate_def! {
+    pub RegionDef;
+}
 
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct CoroutineWitnessDef(pub DefId);
+crate_def! {
+    pub CoroutineWitnessDef;
+}
 
 /// A list of generic arguments.
 #[derive(Clone, Debug, Eq, PartialEq)]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 921a0fb6a9f..d44cf299c27 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -27,7 +27,7 @@
 //!   the `n` parameter is 0, the function is assumed to not be UB. Furthermore, for `memcpy`, if
 //!   source and target pointer are equal, the function is assumed to not be UB.
 //!   (Note that these are standard assumptions among compilers:
-//!   [clang](https://reviews.llvm.org/D86993) and [GCC](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=32667) do the same.)
+//!   [clang](https://reviews.llvm.org/D86993) and [GCC](https://gcc.gnu.org/onlinedocs/gcc/Standards.html#C-Language) do the same.)
 //!   These functions are often provided by the system libc, but can also be provided by the
 //!   [compiler-builtins crate](https://crates.io/crates/compiler_builtins).
 //!   Note that the library does not guarantee that it will always make these assumptions, so Rust
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index a1f6fac8a51..f710c01ca33 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -20,7 +20,7 @@ use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
 use crate::core::config::{Config, TargetSelection};
 use crate::utils::channel;
 use crate::utils::helpers::{self, exe, get_clang_cl_resource_dir, output, t, up_to_date};
-use crate::{CLang, GitRepo, Kind};
+use crate::{generate_smart_stamp_hash, CLang, GitRepo, Kind};
 
 use build_helper::ci::CiEnv;
 use build_helper::git::get_git_merge_base;
@@ -105,8 +105,13 @@ pub fn prebuilt_llvm_config(
     let llvm_cmake_dir = out_dir.join("lib/cmake/llvm");
     let res = LlvmResult { llvm_config: build_llvm_config, llvm_cmake_dir };
 
+    let smart_stamp_hash = generate_smart_stamp_hash(
+        &builder.config.src.join("src/llvm-project"),
+        &builder.in_tree_llvm_info.sha().unwrap_or_default(),
+    );
+
     let stamp = out_dir.join("llvm-finished-building");
-    let stamp = HashStamp::new(stamp, builder.in_tree_llvm_info.sha());
+    let stamp = HashStamp::new(stamp, Some(&smart_stamp_hash));
 
     if stamp.is_done() {
         if stamp.hash.is_none() {
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 62ec208ee60..736a9b312f0 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -31,6 +31,7 @@ use build_helper::exit;
 use build_helper::util::fail;
 use filetime::FileTime;
 use once_cell::sync::OnceCell;
+use sha2::digest::Digest;
 use termcolor::{ColorChoice, StandardStream, WriteColor};
 use utils::channel::GitInfo;
 
@@ -1918,3 +1919,45 @@ pub fn find_recent_config_change_ids(current_id: usize) -> Vec<ChangeInfo> {
         .cloned()
         .collect()
 }
+
+/// Computes a hash representing the state of a repository/submodule and additional input.
+///
+/// It uses `git diff` for the actual changes, and `git status` for including the untracked
+/// files in the specified directory. The additional input is also incorporated into the
+/// computation of the hash.
+///
+/// # Parameters
+///
+/// - `dir`: A reference to the directory path of the target repository/submodule.
+/// - `additional_input`: An additional input to be included in the hash.
+///
+/// # Panics
+///
+/// In case of errors during `git` command execution (e.g., in tarball sources), default values
+/// are used to prevent panics.
+pub fn generate_smart_stamp_hash(dir: &Path, additional_input: &str) -> String {
+    let diff = Command::new("git")
+        .current_dir(dir)
+        .arg("diff")
+        .output()
+        .map(|o| String::from_utf8(o.stdout).unwrap_or_default())
+        .unwrap_or_default();
+
+    let status = Command::new("git")
+        .current_dir(dir)
+        .arg("status")
+        .arg("--porcelain")
+        .arg("-z")
+        .arg("--untracked-files=normal")
+        .output()
+        .map(|o| String::from_utf8(o.stdout).unwrap_or_default())
+        .unwrap_or_default();
+
+    let mut hasher = sha2::Sha256::new();
+
+    hasher.update(diff);
+    hasher.update(status);
+    hasher.update(additional_input);
+
+    hex::encode(hasher.finalize().as_slice())
+}
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 127aff913e3..8ca27150371 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -546,7 +546,7 @@ impl Rewrite for ast::GenericBound {
                     ast::TraitBoundModifier::Maybe => poly_trait_ref
                         .rewrite(context, shape.offset_left(1)?)
                         .map(|s| format!("?{}", s)),
-                    ast::TraitBoundModifier::MaybeConst => poly_trait_ref
+                    ast::TraitBoundModifier::MaybeConst(_) => poly_trait_ref
                         .rewrite(context, shape.offset_left(7)?)
                         .map(|s| format!("~const {}", s)),
                     ast::TraitBoundModifier::MaybeConstMaybe => poly_trait_ref
diff --git a/tests/ui-fulldeps/stable-mir/check_allocation.rs b/tests/ui-fulldeps/stable-mir/check_allocation.rs
index e5fb7311c0b..170b1fd73b1 100644
--- a/tests/ui-fulldeps/stable-mir/check_allocation.rs
+++ b/tests/ui-fulldeps/stable-mir/check_allocation.rs
@@ -24,6 +24,7 @@ extern crate stable_mir;
 use rustc_middle::ty::TyCtxt;
 use rustc_smir::rustc_internal;
 use stable_mir::{CrateItem, CrateItems, ItemKind};
+use stable_mir::crate_def::CrateDef;
 use stable_mir::mir::alloc::GlobalAlloc;
 use stable_mir::mir::mono::StaticDef;
 use std::ascii::Char;
diff --git a/tests/ui-fulldeps/stable-mir/check_defs.rs b/tests/ui-fulldeps/stable-mir/check_defs.rs
new file mode 100644
index 00000000000..bbb49596288
--- /dev/null
+++ b/tests/ui-fulldeps/stable-mir/check_defs.rs
@@ -0,0 +1,106 @@
+// run-pass
+//! Test that users are able to use stable mir APIs to retrieve information about crate definitions.
+
+// ignore-stage1
+// ignore-cross-compile
+// ignore-remote
+// ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
+// edition: 2021
+
+#![feature(rustc_private)]
+#![feature(assert_matches)]
+#![feature(control_flow_enum)]
+
+extern crate rustc_middle;
+#[macro_use]
+extern crate rustc_smir;
+extern crate rustc_driver;
+extern crate rustc_interface;
+extern crate stable_mir;
+
+use mir::{mono::Instance, TerminatorKind::*};
+use rustc_middle::ty::TyCtxt;
+use rustc_smir::rustc_internal;
+use stable_mir::ty::{RigidTy, TyKind};
+use stable_mir::*;
+use std::io::Write;
+use std::ops::ControlFlow;
+
+const CRATE_NAME: &str = "input";
+
+/// This function uses the Stable MIR APIs to get information about the test crate.
+fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
+    let entry = stable_mir::entry_fn().unwrap();
+    let main_fn = Instance::try_from(entry).unwrap();
+    assert_eq!(main_fn.name(), "main");
+    assert_eq!(main_fn.trimmed_name(), "main");
+
+    let instances = get_instances(main_fn.body().unwrap());
+    assert_eq!(instances.len(), 2);
+    test_fn(instances[0], "from_u32", "std::char::from_u32", "core");
+    test_fn(instances[1], "Vec::<u8>::new", "std::vec::Vec::<u8>::new", "alloc");
+    ControlFlow::Continue(())
+}
+
+fn test_fn(instance: Instance, expected_trimmed: &str, expected_qualified: &str, krate: &str) {
+    let trimmed = instance.trimmed_name();
+    let qualified = instance.name();
+    assert_eq!(&trimmed, expected_trimmed);
+    assert_eq!(&qualified, expected_qualified);
+
+    let item = CrateItem::try_from(instance).unwrap();
+    let trimmed = item.trimmed_name();
+    let qualified = item.name();
+    assert_eq!(trimmed, expected_trimmed.replace("u8", "T"));
+    assert_eq!(qualified, expected_qualified.replace("u8", "T"));
+    assert_eq!(&item.krate().name, krate);
+}
+
+/// Inspect the instance body
+fn get_instances(body: mir::Body) -> Vec<Instance> {
+    body.blocks.iter().filter_map(|bb| {
+        match &bb.terminator.kind {
+            Call { func, .. } => {
+                let TyKind::RigidTy(ty) = func.ty(body.locals()).unwrap().kind() else { unreachable!
+                () };
+                let RigidTy::FnDef(def, args) = ty else { unreachable!() };
+                Instance::resolve(def, &args).ok()
+            }
+            _ => {
+                None
+            }
+        }
+    }).collect::<Vec<_>>()
+}
+
+/// This test will generate and analyze a dummy crate using the stable mir.
+/// For that, it will first write the dummy crate into a file.
+/// Then it will create a `StableMir` using custom arguments and then
+/// it will run the compiler.
+fn main() {
+    let path = "defs_input.rs";
+    generate_input(&path).unwrap();
+    let args = vec![
+        "rustc".to_string(),
+        "-Cpanic=abort".to_string(),
+        "--crate-name".to_string(),
+        CRATE_NAME.to_string(),
+        path.to_string(),
+    ];
+    run!(args, tcx, test_stable_mir(tcx)).unwrap();
+}
+
+fn generate_input(path: &str) -> std::io::Result<()> {
+    let mut file = std::fs::File::create(path)?;
+    write!(
+        file,
+        r#"
+
+        fn main() {{
+            let _c = core::char::from_u32(99);
+            let _v = Vec::<u8>::new();
+        }}
+    "#
+    )?;
+    Ok(())
+}
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index 4164f041022..c2035430a33 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -23,6 +23,7 @@ use rustc_hir::def::DefKind;
 use rustc_middle::ty::TyCtxt;
 use rustc_smir::rustc_internal;
 use stable_mir::ItemKind;
+use stable_mir::crate_def::CrateDef;
 use stable_mir::mir::mono::Instance;
 use stable_mir::ty::{RigidTy, TyKind};
 use std::assert_matches::assert_matches;
diff --git a/tests/ui-fulldeps/stable-mir/projections.rs b/tests/ui-fulldeps/stable-mir/projections.rs
index 29930763591..8c3fda7b6bb 100644
--- a/tests/ui-fulldeps/stable-mir/projections.rs
+++ b/tests/ui-fulldeps/stable-mir/projections.rs
@@ -21,6 +21,7 @@ extern crate stable_mir;
 
 use rustc_middle::ty::TyCtxt;
 use rustc_smir::rustc_internal;
+use stable_mir::crate_def::CrateDef;
 use stable_mir::mir::{ProjectionElem, Rvalue, StatementKind};
 use stable_mir::ty::{RigidTy, TyKind, UintTy};
 use stable_mir::ItemKind;
diff --git a/tests/ui/error-codes/E0476.stderr b/tests/ui/error-codes/E0476.next.stderr
index 0378ac6e8ec..454dbecc7d0 100644
--- a/tests/ui/error-codes/E0476.stderr
+++ b/tests/ui/error-codes/E0476.next.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `CoerceUnsized<&Wrapper<_>>` for type `&Wrapper<_>`
-  --> $DIR/E0476.rs:9:1
+  --> $DIR/E0476.rs:11:1
    |
 LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,18 +9,18 @@ LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S
              where 'b: 'a, T: Unsize<U>, T: ?Sized, U: ?Sized;
 
 error[E0476]: lifetime of the source pointer does not outlive lifetime bound of the object type
-  --> $DIR/E0476.rs:9:1
+  --> $DIR/E0476.rs:11:1
    |
 LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: object type is valid for the lifetime `'a` as defined here
-  --> $DIR/E0476.rs:9:6
+  --> $DIR/E0476.rs:11:6
    |
 LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
    |      ^^
 note: source pointer is only valid for the lifetime `'b` as defined here
-  --> $DIR/E0476.rs:9:10
+  --> $DIR/E0476.rs:11:10
    |
 LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
    |          ^^
diff --git a/tests/ui/error-codes/E0476.old.stderr b/tests/ui/error-codes/E0476.old.stderr
new file mode 100644
index 00000000000..454dbecc7d0
--- /dev/null
+++ b/tests/ui/error-codes/E0476.old.stderr
@@ -0,0 +1,31 @@
+error[E0119]: conflicting implementations of trait `CoerceUnsized<&Wrapper<_>>` for type `&Wrapper<_>`
+  --> $DIR/E0476.rs:11:1
+   |
+LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: conflicting implementation in crate `core`:
+           - impl<'a, 'b, T, U> CoerceUnsized<&'a U> for &'b T
+             where 'b: 'a, T: Unsize<U>, T: ?Sized, U: ?Sized;
+
+error[E0476]: lifetime of the source pointer does not outlive lifetime bound of the object type
+  --> $DIR/E0476.rs:11:1
+   |
+LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: object type is valid for the lifetime `'a` as defined here
+  --> $DIR/E0476.rs:11:6
+   |
+LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+   |      ^^
+note: source pointer is only valid for the lifetime `'b` as defined here
+  --> $DIR/E0476.rs:11:10
+   |
+LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {}
+   |          ^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0119, E0476.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/error-codes/E0476.rs b/tests/ui/error-codes/E0476.rs
index d5e4b8d2372..e9afc756726 100644
--- a/tests/ui/error-codes/E0476.rs
+++ b/tests/ui/error-codes/E0476.rs
@@ -1,3 +1,5 @@
+// revisions: old next
+//[next] compile-flags: -Ztrait-solver=next-coherence
 #![feature(coerce_unsized)]
 #![feature(unsize)]
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr
index e6b663c47d7..1b88839984f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage.stderr
@@ -2,7 +2,7 @@ error: `~const` is not allowed here
   --> $DIR/assoc-type-const-bound-usage.rs:7:17
    |
 LL |     type Assoc: ~const Foo;
-   |                 ^^^^^^^^^^
+   |                 ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr
index 7df16ca5a3b..290ef6e2f5f 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr
@@ -2,7 +2,7 @@ error: `~const` is not allowed here
   --> $DIR/assoc-type.rs:17:15
    |
 LL |     type Bar: ~const std::ops::Add;
-   |               ^^^^^^^^^^^^^^^^^^^^
+   |               ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr
index 9210f642706..db48c170d1c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr
@@ -2,7 +2,7 @@ error: `~const` is not allowed here
   --> $DIR/const-bound-on-not-const-associated-fn.rs:9:40
    |
 LL |     fn do_something_else() where Self: ~const MyTrait;
-   |                                        ^^^^^^^^^^^^^^
+   |                                        ^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
   --> $DIR/const-bound-on-not-const-associated-fn.rs:9:8
@@ -14,7 +14,7 @@ error: `~const` is not allowed here
   --> $DIR/const-bound-on-not-const-associated-fn.rs:20:32
    |
 LL |     pub fn foo(&self) where T: ~const MyTrait {
-   |                                ^^^^^^^^^^^^^^
+   |                                ^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
   --> $DIR/const-bound-on-not-const-associated-fn.rs:20:12
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
index be75e852e0a..217b02f68ad 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr
@@ -2,7 +2,7 @@ error: `~const` is not allowed here
   --> $DIR/const-drop.rs:67:38
    |
 LL |     pub struct ConstDropWithBound<T: ~const SomeTrait>(pub core::marker::PhantomData<T>);
-   |                                      ^^^^^^^^^^^^^^^^
+   |                                      ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
index be75e852e0a..217b02f68ad 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr
@@ -2,7 +2,7 @@ error: `~const` is not allowed here
   --> $DIR/const-drop.rs:67:38
    |
 LL |     pub struct ConstDropWithBound<T: ~const SomeTrait>(pub core::marker::PhantomData<T>);
-   |                                      ^^^^^^^^^^^^^^^^
+   |                                      ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr
index 204f0f9f89f..12bcdb034bc 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr
@@ -2,7 +2,7 @@ error: `~const` is not allowed here
   --> $DIR/super-traits-fail-2.rs:11:12
    |
 LL | trait Bar: ~const Foo {}
-   |            ^^^^^^^^^^
+   |            ^^^^^^
    |
 note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
   --> $DIR/super-traits-fail-2.rs:11:1
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr
index 06330958b8e..d705244c0ee 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr
@@ -2,7 +2,7 @@ error: `~const` is not allowed here
   --> $DIR/super-traits-fail-2.rs:11:12
    |
 LL | trait Bar: ~const Foo {}
-   |            ^^^^^^^^^^
+   |            ^^^^^^
    |
 note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
   --> $DIR/super-traits-fail-2.rs:11:1
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
index 77b13a351e2..e10c51ef45a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr
@@ -2,7 +2,7 @@ error: `~const` is not allowed here
   --> $DIR/super-traits-fail-3.rs:13:12
    |
 LL | trait Bar: ~const Foo {}
-   |            ^^^^^^^^^^
+   |            ^^^^^^
    |
 note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
   --> $DIR/super-traits-fail-3.rs:13:1
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr
index 2e41eb9b4c4..34f6515b572 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr
@@ -2,7 +2,7 @@ error: `~const` is not allowed here
   --> $DIR/super-traits-fail-3.rs:13:12
    |
 LL | trait Bar: ~const Foo {}
-   |            ^^^^^^^^^^
+   |            ^^^^^^
    |
 note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
   --> $DIR/super-traits-fail-3.rs:13:1
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr
index be7a83dc184..b479793814c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr
@@ -2,7 +2,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-and-const-params.rs:9:15
    |
 LL |     fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
-   |               ^^^^^^^^^^^^
+   |               ^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
   --> $DIR/tilde-const-and-const-params.rs:9:8
@@ -14,7 +14,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-and-const-params.rs:27:11
    |
 LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
-   |           ^^^^^^^^^^^^
+   |           ^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
   --> $DIR/tilde-const-and-const-params.rs:27:4
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr
index c14f9a99035..c6e18924fd8 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr
@@ -2,7 +2,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:7:26
    |
 LL | fn non_const_function<T: ~const Trait>() {}
-   |                          ^^^^^^^^^^^^
+   |                          ^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
   --> $DIR/tilde-const-invalid-places.rs:7:4
@@ -14,7 +14,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:9:18
    |
 LL | struct Struct<T: ~const Trait> { field: T }
-   |                  ^^^^^^^^^^^^
+   |                  ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -22,7 +22,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:10:23
    |
 LL | struct TupleStruct<T: ~const Trait>(T);
-   |                       ^^^^^^^^^^^^
+   |                       ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -30,7 +30,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:11:22
    |
 LL | struct UnitStruct<T: ~const Trait>;
-   |                      ^^^^^^^^^^^^
+   |                      ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -38,7 +38,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:13:14
    |
 LL | enum Enum<T: ~const Trait> { Variant(T) }
-   |              ^^^^^^^^^^^^
+   |              ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -46,7 +46,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:15:16
    |
 LL | union Union<T: ~const Trait> { field: T }
-   |                ^^^^^^^^^^^^
+   |                ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -54,7 +54,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:17:14
    |
 LL | type Type<T: ~const Trait> = T;
-   |              ^^^^^^^^^^^^
+   |              ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -62,7 +62,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:19:19
    |
 LL | const CONSTANT<T: ~const Trait>: () = ();
-   |                   ^^^^^^^^^^^^
+   |                   ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -70,7 +70,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:23:18
    |
 LL |     type Type<T: ~const Trait>: ~const Trait;
-   |                  ^^^^^^^^^^^^
+   |                  ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -78,7 +78,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:23:33
    |
 LL |     type Type<T: ~const Trait>: ~const Trait;
-   |                                 ^^^^^^^^^^^^
+   |                                 ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -86,7 +86,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:26:30
    |
 LL |     fn non_const_function<T: ~const Trait>();
-   |                              ^^^^^^^^^^^^
+   |                              ^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
   --> $DIR/tilde-const-invalid-places.rs:26:8
@@ -98,7 +98,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:27:23
    |
 LL |     const CONSTANT<T: ~const Trait>: ();
-   |                       ^^^^^^^^^^^^
+   |                       ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -106,7 +106,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:32:18
    |
 LL |     type Type<T: ~const Trait> = ();
-   |                  ^^^^^^^^^^^^
+   |                  ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -114,7 +114,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:33:30
    |
 LL |     fn non_const_function<T: ~const Trait>() {}
-   |                              ^^^^^^^^^^^^
+   |                              ^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
   --> $DIR/tilde-const-invalid-places.rs:33:8
@@ -126,7 +126,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:34:23
    |
 LL |     const CONSTANT<T: ~const Trait>: () = ();
-   |                       ^^^^^^^^^^^^
+   |                       ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -134,7 +134,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:41:18
    |
 LL |     type Type<T: ~const Trait> = ();
-   |                  ^^^^^^^^^^^^
+   |                  ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -142,7 +142,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:43:30
    |
 LL |     fn non_const_function<T: ~const Trait>() {}
-   |                              ^^^^^^^^^^^^
+   |                              ^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
   --> $DIR/tilde-const-invalid-places.rs:43:8
@@ -154,7 +154,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:44:23
    |
 LL |     const CONSTANT<T: ~const Trait>: () = ();
-   |                       ^^^^^^^^^^^^
+   |                       ^^^^^^
    |
    = note: this item cannot have `~const` trait bounds
 
@@ -162,7 +162,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:49:15
    |
 LL | trait Child0: ~const Trait {}
-   |               ^^^^^^^^^^^^
+   |               ^^^^^^
    |
 note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
   --> $DIR/tilde-const-invalid-places.rs:49:1
@@ -174,7 +174,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:50:26
    |
 LL | trait Child1 where Self: ~const Trait {}
-   |                          ^^^^^^^^^^^^
+   |                          ^^^^^^
    |
 note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds
   --> $DIR/tilde-const-invalid-places.rs:50:1
@@ -186,7 +186,7 @@ error: `~const` is not allowed here
   --> $DIR/tilde-const-invalid-places.rs:53:9
    |
 LL | impl<T: ~const Trait> Trait for T {}
-   |         ^^^^^^^^^^^^
+   |         ^^^^^^
    |
 note: this impl is not `const`, so it cannot have `~const` trait bounds
   --> $DIR/tilde-const-invalid-places.rs:53:1
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr
index 3d6fedbabbf..abe24b662a2 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr
@@ -2,7 +2,7 @@ error: `~const` is not allowed here
   --> $DIR/trait-where-clause.rs:8:24
    |
 LL |     fn b() where Self: ~const Bar;
-   |                        ^^^^^^^^^^
+   |                        ^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
   --> $DIR/trait-where-clause.rs:8:8
@@ -14,7 +14,7 @@ error: `~const` is not allowed here
   --> $DIR/trait-where-clause.rs:10:13
    |
 LL |     fn c<T: ~const Bar>();
-   |             ^^^^^^^^^^
+   |             ^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
   --> $DIR/trait-where-clause.rs:10:8
diff --git a/tests/ui/stats/hir-stats.stderr b/tests/ui/stats/hir-stats.stderr
index 813e65e45a2..e6da83296ce 100644
--- a/tests/ui/stats/hir-stats.stderr
+++ b/tests/ui/stats/hir-stats.stderr
@@ -21,31 +21,31 @@ ast-stats-1 - Local                     32 ( 0.5%)             1
 ast-stats-1 - MacCall                   32 ( 0.5%)             1
 ast-stats-1 - Expr                      96 ( 1.5%)             3
 ast-stats-1 Param                    160 ( 2.5%)             4            40
-ast-stats-1 Block                    192 ( 3.0%)             6            32
+ast-stats-1 Block                    192 ( 2.9%)             6            32
 ast-stats-1 Variant                  208 ( 3.2%)             2           104
-ast-stats-1 GenericBound             224 ( 3.5%)             4            56
-ast-stats-1 - Trait                    224 ( 3.5%)             4
+ast-stats-1 GenericBound             256 ( 3.9%)             4            64
+ast-stats-1 - Trait                    256 ( 3.9%)             4
 ast-stats-1 AssocItem                352 ( 5.4%)             4            88
 ast-stats-1 - Type                     176 ( 2.7%)             2
 ast-stats-1 - Fn                       176 ( 2.7%)             2
 ast-stats-1 GenericParam             480 ( 7.4%)             5            96
-ast-stats-1 Pat                      504 ( 7.8%)             7            72
+ast-stats-1 Pat                      504 ( 7.7%)             7            72
 ast-stats-1 - Struct                    72 ( 1.1%)             1
 ast-stats-1 - Wild                      72 ( 1.1%)             1
 ast-stats-1 - Ident                    360 ( 5.5%)             5
-ast-stats-1 Expr                     576 ( 8.9%)             8            72
+ast-stats-1 Expr                     576 ( 8.8%)             8            72
 ast-stats-1 - Path                      72 ( 1.1%)             1
 ast-stats-1 - Match                     72 ( 1.1%)             1
 ast-stats-1 - Struct                    72 ( 1.1%)             1
 ast-stats-1 - Lit                      144 ( 2.2%)             2
 ast-stats-1 - Block                    216 ( 3.3%)             3
-ast-stats-1 PathSegment              720 (11.1%)            30            24
-ast-stats-1 Ty                       896 (13.8%)            14            64
+ast-stats-1 PathSegment              720 (11.0%)            30            24
+ast-stats-1 Ty                       896 (13.7%)            14            64
 ast-stats-1 - Ptr                       64 ( 1.0%)             1
 ast-stats-1 - Ref                       64 ( 1.0%)             1
 ast-stats-1 - ImplicitSelf             128 ( 2.0%)             2
-ast-stats-1 - Path                     640 ( 9.9%)            10
-ast-stats-1 Item                   1_224 (18.9%)             9           136
+ast-stats-1 - Path                     640 ( 9.8%)            10
+ast-stats-1 Item                   1_224 (18.8%)             9           136
 ast-stats-1 - Trait                    136 ( 2.1%)             1
 ast-stats-1 - Enum                     136 ( 2.1%)             1
 ast-stats-1 - ForeignMod               136 ( 2.1%)             1
@@ -53,7 +53,7 @@ ast-stats-1 - Impl                     136 ( 2.1%)             1
 ast-stats-1 - Fn                       272 ( 4.2%)             2
 ast-stats-1 - Use                      408 ( 6.3%)             3
 ast-stats-1 ----------------------------------------------------------------
-ast-stats-1 Total                  6_488
+ast-stats-1 Total                  6_520
 ast-stats-1
 ast-stats-2 POST EXPANSION AST STATS
 ast-stats-2 Name                Accumulated Size         Count     Item Size
@@ -65,28 +65,28 @@ ast-stats-2 ExprField                 48 ( 0.7%)             1            48
 ast-stats-2 WherePredicate            56 ( 0.8%)             1            56
 ast-stats-2 - BoundPredicate            56 ( 0.8%)             1
 ast-stats-2 Local                     72 ( 1.0%)             1            72
-ast-stats-2 Arm                       96 ( 1.4%)             2            48
-ast-stats-2 ForeignItem               96 ( 1.4%)             1            96
-ast-stats-2 - Fn                        96 ( 1.4%)             1
+ast-stats-2 Arm                       96 ( 1.3%)             2            48
+ast-stats-2 ForeignItem               96 ( 1.3%)             1            96
+ast-stats-2 - Fn                        96 ( 1.3%)             1
 ast-stats-2 InlineAsm                120 ( 1.7%)             1           120
 ast-stats-2 FnDecl                   120 ( 1.7%)             5            24
 ast-stats-2 Attribute                128 ( 1.8%)             4            32
-ast-stats-2 - DocComment                32 ( 0.5%)             1
-ast-stats-2 - Normal                    96 ( 1.4%)             3
-ast-stats-2 FieldDef                 160 ( 2.3%)             2            80
-ast-stats-2 Stmt                     160 ( 2.3%)             5            32
-ast-stats-2 - Local                     32 ( 0.5%)             1
-ast-stats-2 - Semi                      32 ( 0.5%)             1
-ast-stats-2 - Expr                      96 ( 1.4%)             3
-ast-stats-2 Param                    160 ( 2.3%)             4            40
+ast-stats-2 - DocComment                32 ( 0.4%)             1
+ast-stats-2 - Normal                    96 ( 1.3%)             3
+ast-stats-2 FieldDef                 160 ( 2.2%)             2            80
+ast-stats-2 Stmt                     160 ( 2.2%)             5            32
+ast-stats-2 - Local                     32 ( 0.4%)             1
+ast-stats-2 - Semi                      32 ( 0.4%)             1
+ast-stats-2 - Expr                      96 ( 1.3%)             3
+ast-stats-2 Param                    160 ( 2.2%)             4            40
 ast-stats-2 Block                    192 ( 2.7%)             6            32
 ast-stats-2 Variant                  208 ( 2.9%)             2           104
-ast-stats-2 GenericBound             224 ( 3.2%)             4            56
-ast-stats-2 - Trait                    224 ( 3.2%)             4
-ast-stats-2 AssocItem                352 ( 5.0%)             4            88
+ast-stats-2 GenericBound             256 ( 3.6%)             4            64
+ast-stats-2 - Trait                    256 ( 3.6%)             4
+ast-stats-2 AssocItem                352 ( 4.9%)             4            88
 ast-stats-2 - Type                     176 ( 2.5%)             2
 ast-stats-2 - Fn                       176 ( 2.5%)             2
-ast-stats-2 GenericParam             480 ( 6.8%)             5            96
+ast-stats-2 GenericParam             480 ( 6.7%)             5            96
 ast-stats-2 Pat                      504 ( 7.1%)             7            72
 ast-stats-2 - Struct                    72 ( 1.0%)             1
 ast-stats-2 - Wild                      72 ( 1.0%)             1
@@ -98,22 +98,22 @@ ast-stats-2 - Struct                    72 ( 1.0%)             1
 ast-stats-2 - InlineAsm                 72 ( 1.0%)             1
 ast-stats-2 - Lit                      144 ( 2.0%)             2
 ast-stats-2 - Block                    216 ( 3.0%)             3
-ast-stats-2 PathSegment              792 (11.2%)            33            24
+ast-stats-2 PathSegment              792 (11.1%)            33            24
 ast-stats-2 Ty                       896 (12.6%)            14            64
 ast-stats-2 - Ptr                       64 ( 0.9%)             1
 ast-stats-2 - Ref                       64 ( 0.9%)             1
 ast-stats-2 - ImplicitSelf             128 ( 1.8%)             2
 ast-stats-2 - Path                     640 ( 9.0%)            10
-ast-stats-2 Item                   1_496 (21.1%)            11           136
+ast-stats-2 Item                   1_496 (21.0%)            11           136
 ast-stats-2 - Trait                    136 ( 1.9%)             1
 ast-stats-2 - Enum                     136 ( 1.9%)             1
 ast-stats-2 - ExternCrate              136 ( 1.9%)             1
 ast-stats-2 - ForeignMod               136 ( 1.9%)             1
 ast-stats-2 - Impl                     136 ( 1.9%)             1
 ast-stats-2 - Fn                       272 ( 3.8%)             2
-ast-stats-2 - Use                      544 ( 7.7%)             4
+ast-stats-2 - Use                      544 ( 7.6%)             4
 ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 Total                  7_088
+ast-stats-2 Total                  7_120
 ast-stats-2
 hir-stats HIR STATS
 hir-stats Name                Accumulated Size         Count     Item Size