about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-10-25 07:42:32 +0000
committerbors <bors@rust-lang.org>2024-10-25 07:42:32 +0000
commit97ae1df8aa9fa6dfd29dced18b232d25208c4111 (patch)
tree1d843a94b0e02cf1a2ed96993fbd4f4c7c51c11b
parent017ae1b21f7be6dcdcfc95631e54bde806653a8a (diff)
parent7f93af1a1ea4b8532750a56daacb877cc96d26ad (diff)
downloadrust-97ae1df8aa9fa6dfd29dced18b232d25208c4111.tar.gz
rust-97ae1df8aa9fa6dfd29dced18b232d25208c4111.zip
Auto merge of #132128 - workingjubilee:rollup-uwqp2i2, r=workingjubilee
Rollup of 4 pull requests

Successful merges:

 - #131457 (Expand `ptr::fn_addr_eq()` documentation.)
 - #132085 (Update StableMIR doc to reflect current status)
 - #132118 (Add support for `~const` item bounds)
 - #132125 (coverage: Emit LLVM intrinsics using the normal helper method)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs100
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs8
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp39
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs11
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs51
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs8
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs8
-rw-r--r--compiler/stable_mir/README.md110
-rw-r--r--library/core/src/ptr/mod.rs40
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs2
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr15
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr28
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs35
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.stderr15
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs28
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.stderr15
20 files changed, 273 insertions, 259 deletions
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 45738068509..7c52cba096b 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -1725,16 +1725,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
     fn fptosi_sat(&mut self, val: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> {
         self.fptoint_sat(true, val, dest_ty)
     }
-
-    fn instrprof_increment(
-        &mut self,
-        _fn_name: RValue<'gcc>,
-        _hash: RValue<'gcc>,
-        _num_counters: RValue<'gcc>,
-        _index: RValue<'gcc>,
-    ) {
-        unimplemented!();
-    }
 }
 
 impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index dbf5298d64b..8702532c36e 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -1165,39 +1165,6 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         self.call_lifetime_intrinsic("llvm.lifetime.end.p0i8", ptr, size);
     }
 
-    fn instrprof_increment(
-        &mut self,
-        fn_name: &'ll Value,
-        hash: &'ll Value,
-        num_counters: &'ll Value,
-        index: &'ll Value,
-    ) {
-        debug!(
-            "instrprof_increment() with args ({:?}, {:?}, {:?}, {:?})",
-            fn_name, hash, num_counters, index
-        );
-
-        let llfn = unsafe { llvm::LLVMRustGetInstrProfIncrementIntrinsic(self.cx().llmod) };
-        let llty = self.cx.type_func(
-            &[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32(), self.cx.type_i32()],
-            self.cx.type_void(),
-        );
-        let args = &[fn_name, hash, num_counters, index];
-        let args = self.check_call("call", llty, llfn, args);
-
-        unsafe {
-            let _ = llvm::LLVMRustBuildCall(
-                self.llbuilder,
-                llty,
-                llfn,
-                args.as_ptr() as *const &llvm::Value,
-                args.len() as c_uint,
-                [].as_ptr(),
-                0 as c_uint,
-            );
-        }
-    }
-
     fn call(
         &mut self,
         llty: &'ll Type,
@@ -1667,6 +1634,18 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         kcfi_bundle
     }
 
+    /// Emits a call to `llvm.instrprof.increment`. Used by coverage instrumentation.
+    #[instrument(level = "debug", skip(self))]
+    pub(crate) fn instrprof_increment(
+        &mut self,
+        fn_name: &'ll Value,
+        hash: &'ll Value,
+        num_counters: &'ll Value,
+        index: &'ll Value,
+    ) {
+        self.call_intrinsic("llvm.instrprof.increment", &[fn_name, hash, num_counters, index]);
+    }
+
     /// Emits a call to `llvm.instrprof.mcdc.parameters`.
     ///
     /// This doesn't produce any code directly, but is used as input by
@@ -1676,40 +1655,21 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
     ///
     /// [`CodeGenPGO::emitMCDCParameters`]:
     ///     https://github.com/rust-lang/llvm-project/blob/5399a24/clang/lib/CodeGen/CodeGenPGO.cpp#L1124
+    #[instrument(level = "debug", skip(self))]
     pub(crate) fn mcdc_parameters(
         &mut self,
         fn_name: &'ll Value,
         hash: &'ll Value,
         bitmap_bits: &'ll Value,
     ) {
-        debug!("mcdc_parameters() with args ({:?}, {:?}, {:?})", fn_name, hash, bitmap_bits);
-
         assert!(
             crate::llvm_util::get_version() >= (19, 0, 0),
             "MCDC intrinsics require LLVM 19 or later"
         );
-
-        let llfn = unsafe { llvm::LLVMRustGetInstrProfMCDCParametersIntrinsic(self.cx().llmod) };
-        let llty = self.cx.type_func(
-            &[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32()],
-            self.cx.type_void(),
-        );
-        let args = &[fn_name, hash, bitmap_bits];
-        let args = self.check_call("call", llty, llfn, args);
-
-        unsafe {
-            let _ = llvm::LLVMRustBuildCall(
-                self.llbuilder,
-                llty,
-                llfn,
-                args.as_ptr() as *const &llvm::Value,
-                args.len() as c_uint,
-                [].as_ptr(),
-                0 as c_uint,
-            );
-        }
+        self.call_intrinsic("llvm.instrprof.mcdc.parameters", &[fn_name, hash, bitmap_bits]);
     }
 
+    #[instrument(level = "debug", skip(self))]
     pub(crate) fn mcdc_tvbitmap_update(
         &mut self,
         fn_name: &'ll Value,
@@ -1717,39 +1677,21 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
         bitmap_index: &'ll Value,
         mcdc_temp: &'ll Value,
     ) {
-        debug!(
-            "mcdc_tvbitmap_update() with args ({:?}, {:?}, {:?}, {:?})",
-            fn_name, hash, bitmap_index, mcdc_temp
-        );
         assert!(
             crate::llvm_util::get_version() >= (19, 0, 0),
             "MCDC intrinsics require LLVM 19 or later"
         );
-
-        let llfn =
-            unsafe { llvm::LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(self.cx().llmod) };
-        let llty = self.cx.type_func(
-            &[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32(), self.cx.type_ptr()],
-            self.cx.type_void(),
-        );
         let args = &[fn_name, hash, bitmap_index, mcdc_temp];
-        let args = self.check_call("call", llty, llfn, args);
-        unsafe {
-            let _ = llvm::LLVMRustBuildCall(
-                self.llbuilder,
-                llty,
-                llfn,
-                args.as_ptr() as *const &llvm::Value,
-                args.len() as c_uint,
-                [].as_ptr(),
-                0 as c_uint,
-            );
-        }
+        self.call_intrinsic("llvm.instrprof.mcdc.tvbitmap.update", args);
+    }
+
+    #[instrument(level = "debug", skip(self))]
+    pub(crate) fn mcdc_condbitmap_reset(&mut self, mcdc_temp: &'ll Value) {
         self.store(self.const_i32(0), mcdc_temp, self.tcx.data_layout.i32_align.abi);
     }
 
+    #[instrument(level = "debug", skip(self))]
     pub(crate) fn mcdc_condbitmap_update(&mut self, cond_index: &'ll Value, mcdc_temp: &'ll Value) {
-        debug!("mcdc_condbitmap_update() with args ({:?}, {:?})", cond_index, mcdc_temp);
         assert!(
             crate::llvm_util::get_version() >= (19, 0, 0),
             "MCDC intrinsics require LLVM 19 or later"
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 2f830d6f941..fb845c0087b 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -1099,6 +1099,10 @@ impl<'ll> CodegenCx<'ll, '_> {
 
         if self.sess().instrument_coverage() {
             ifn!("llvm.instrprof.increment", fn(ptr, t_i64, t_i32, t_i32) -> void);
+            if crate::llvm_util::get_version() >= (19, 0, 0) {
+                ifn!("llvm.instrprof.mcdc.parameters", fn(ptr, t_i64, t_i32) -> void);
+                ifn!("llvm.instrprof.mcdc.tvbitmap.update", fn(ptr, t_i64, t_i32, ptr) -> void);
+            }
         }
 
         ifn!("llvm.type.test", fn(ptr, t_metadata) -> i1);
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index b2956945911..36b1747f2fd 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -208,6 +208,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
                 let hash = bx.const_u64(function_coverage_info.function_source_hash);
                 let bitmap_index = bx.const_u32(bitmap_idx);
                 bx.mcdc_tvbitmap_update(fn_name, hash, bitmap_index, cond_bitmap);
+                bx.mcdc_condbitmap_reset(cond_bitmap);
             }
         }
     }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 50e6c1494a8..10e55a4f7f6 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1615,10 +1615,6 @@ unsafe extern "C" {
     pub fn LLVMRustSetAllowReassoc(Instr: &Value);
 
     // Miscellaneous instructions
-    pub fn LLVMRustGetInstrProfIncrementIntrinsic(M: &Module) -> &Value;
-    pub fn LLVMRustGetInstrProfMCDCParametersIntrinsic(M: &Module) -> &Value;
-    pub fn LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(M: &Module) -> &Value;
-
     pub fn LLVMRustBuildCall<'a>(
         B: &Builder<'a>,
         Ty: &'a Type,
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index c0c1085e949..50a51714146 100644
--- a/compiler/rustc_codegen_ssa/src/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -437,14 +437,6 @@ pub trait BuilderMethods<'a, 'tcx>:
     /// Called for `StorageDead`
     fn lifetime_end(&mut self, ptr: Self::Value, size: Size);
 
-    fn instrprof_increment(
-        &mut self,
-        fn_name: Self::Value,
-        hash: Self::Value,
-        num_counters: Self::Value,
-        index: Self::Value,
-    );
-
     fn call(
         &mut self,
         llty: Self::Type,
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 910c27da954..cb75888abd7 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1531,45 +1531,6 @@ extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMTypeRef Ty,
                                     ArrayRef<OperandBundleDef>(OpBundles)));
 }
 
-extern "C" LLVMValueRef
-LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
-#if LLVM_VERSION_GE(20, 0)
-  return wrap(llvm::Intrinsic::getOrInsertDeclaration(
-      unwrap(M), llvm::Intrinsic::instrprof_increment));
-#else
-  return wrap(llvm::Intrinsic::getDeclaration(
-      unwrap(M), llvm::Intrinsic::instrprof_increment));
-#endif
-}
-
-extern "C" LLVMValueRef
-LLVMRustGetInstrProfMCDCParametersIntrinsic(LLVMModuleRef M) {
-#if LLVM_VERSION_LT(19, 0)
-  report_fatal_error("LLVM 19.0 is required for mcdc intrinsic functions");
-#endif
-#if LLVM_VERSION_GE(20, 0)
-  return wrap(llvm::Intrinsic::getOrInsertDeclaration(
-      unwrap(M), llvm::Intrinsic::instrprof_mcdc_parameters));
-#else
-  return wrap(llvm::Intrinsic::getDeclaration(
-      unwrap(M), llvm::Intrinsic::instrprof_mcdc_parameters));
-#endif
-}
-
-extern "C" LLVMValueRef
-LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(LLVMModuleRef M) {
-#if LLVM_VERSION_LT(19, 0)
-  report_fatal_error("LLVM 19.0 is required for mcdc intrinsic functions");
-#endif
-#if LLVM_VERSION_GE(20, 0)
-  return wrap(llvm::Intrinsic::getOrInsertDeclaration(
-      unwrap(M), llvm::Intrinsic::instrprof_mcdc_tvbitmap_update));
-#else
-  return wrap(llvm::Intrinsic::getDeclaration(
-      unwrap(M), llvm::Intrinsic::instrprof_mcdc_tvbitmap_update));
-#endif
-}
-
 extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst,
                                             unsigned DstAlign, LLVMValueRef Src,
                                             unsigned SrcAlign,
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index 5e604a5d74f..f6a5f20a639 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -100,6 +100,15 @@ where
         })
     }
 
+    /// Assemble additional assumptions for an alias that are not included
+    /// in the item bounds of the alias. For now, this is limited to the
+    /// `implied_const_bounds` for an associated type.
+    fn consider_additional_alias_assumptions(
+        ecx: &mut EvalCtxt<'_, D>,
+        goal: Goal<I, Self>,
+        alias_ty: ty::AliasTy<I>,
+    ) -> Vec<Candidate<I>>;
+
     fn consider_impl_candidate(
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
@@ -594,6 +603,8 @@ where
             ));
         }
 
+        candidates.extend(G::consider_additional_alias_assumptions(self, goal, alias_ty));
+
         if kind != ty::Projection {
             return;
         }
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index 62b4bb0004c..8d57ad8f255 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -3,7 +3,7 @@
 
 use rustc_type_ir::fast_reject::DeepRejectCtxt;
 use rustc_type_ir::inherent::*;
-use rustc_type_ir::{self as ty, Interner};
+use rustc_type_ir::{self as ty, Interner, elaborate};
 use tracing::instrument;
 
 use super::assembly::Candidate;
@@ -70,6 +70,55 @@ where
         }
     }
 
+    /// Register additional assumptions for aliases corresponding to `~const` item bounds.
+    ///
+    /// Unlike item bounds, they are not simply implied by the well-formedness of the alias.
+    /// Instead, they only hold if the const conditons on the alias also hold. This is why
+    /// we also register the const conditions of the alias after matching the goal against
+    /// the assumption.
+    fn consider_additional_alias_assumptions(
+        ecx: &mut EvalCtxt<'_, D>,
+        goal: Goal<I, Self>,
+        alias_ty: ty::AliasTy<I>,
+    ) -> Vec<Candidate<I>> {
+        let cx = ecx.cx();
+        let mut candidates = vec![];
+
+        // FIXME(effects): We elaborate here because the implied const bounds
+        // aren't necessarily elaborated. We probably should prefix this query
+        // with `explicit_`...
+        for clause in elaborate::elaborate(
+            cx,
+            cx.implied_const_bounds(alias_ty.def_id)
+                .iter_instantiated(cx, alias_ty.args)
+                .map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.host)),
+        ) {
+            candidates.extend(Self::probe_and_match_goal_against_assumption(
+                ecx,
+                CandidateSource::AliasBound,
+                goal,
+                clause,
+                |ecx| {
+                    // Const conditions must hold for the implied const bound to hold.
+                    ecx.add_goals(
+                        GoalSource::Misc,
+                        cx.const_conditions(alias_ty.def_id)
+                            .iter_instantiated(cx, alias_ty.args)
+                            .map(|trait_ref| {
+                                goal.with(
+                                    cx,
+                                    trait_ref.to_host_effect_clause(cx, goal.predicate.host),
+                                )
+                            }),
+                    );
+                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                },
+            ));
+        }
+
+        candidates
+    }
+
     fn consider_impl_candidate(
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index c98fd853551..7287cdf74bf 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -193,6 +193,14 @@ where
         }
     }
 
+    fn consider_additional_alias_assumptions(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+        _alias_ty: ty::AliasTy<I>,
+    ) -> Vec<Candidate<I>> {
+        vec![]
+    }
+
     fn consider_impl_candidate(
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, NormalizesTo<I>>,
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 6b26f960286..08cc89d950e 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -39,6 +39,14 @@ where
         self.def_id()
     }
 
+    fn consider_additional_alias_assumptions(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+        _alias_ty: ty::AliasTy<I>,
+    ) -> Vec<Candidate<I>> {
+        vec![]
+    }
+
     fn consider_impl_candidate(
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, TraitPredicate<I>>,
diff --git a/compiler/stable_mir/README.md b/compiler/stable_mir/README.md
index 31dee955f49..ab2546e377a 100644
--- a/compiler/stable_mir/README.md
+++ b/compiler/stable_mir/README.md
@@ -1,93 +1,33 @@
-This crate is regularly synced with its mirror in the rustc repo at `compiler/rustc_smir`.
+This crate is currently developed in-tree together with the compiler.
 
-We use `git subtree` for this to preserve commits and allow the rustc repo to
-edit these crates without having to touch this repo. This keeps the crates compiling
-while allowing us to independently work on them here. The effort of keeping them in
-sync is pushed entirely onto us, without affecting rustc workflows negatively.
-This may change in the future, but changes to policy should only be done via a
-compiler team MCP.
+Our goal is to start publishing `stable_mir` into crates.io.
+Until then, users will use this as any other rustc crate, by installing
+the rustup component `rustc-dev`, and declaring `stable-mir` as an external crate.
 
-## Instructions for working on this crate locally
-
-Since the crate is the same in the rustc repo and here, the dependencies on rustc_* crates
-will only either work here or there, but never in both places at the same time. Thus we use
-optional dependencies on the rustc_* crates, requiring local development to use
-
-```
-cargo build --no-default-features -Zavoid-dev-deps
-```
-
-in order to compile successfully.
-
-## Instructions for syncing
-
-### Updating this repository
-
-In the rustc repo, execute
-
-```
-git subtree push --prefix=compiler/rustc_smir url_to_your_fork_of_project_stable_mir some_feature_branch
-```
-
-and then open a PR of your `some_feature_branch` against https://github.com/rust-lang/project-stable-mir
-
-### Updating the rustc library
-
-First we need to bump our stack limit, as the rustc repo otherwise quickly hits that:
-
-```
-ulimit -s 60000
-```
-
-#### Maximum function recursion depth (1000) reached
-
-Then we need to disable `dash` as the default shell for sh scripts, as otherwise we run into a
-hard limit of a recursion depth of 1000:
-
-```
-sudo dpkg-reconfigure dash
-```
-
-and then select `No` to disable dash.
-
-
-#### Patching your `git worktree`
-
-The regular git worktree does not scale to repos of the size of the rustc repo.
-So download the `git-subtree.sh` from https://github.com/gitgitgadget/git/pull/493/files and run
-
-```
-sudo cp --backup /path/to/patched/git-subtree.sh /usr/lib/git-core/git-subtree
-sudo chmod --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree
-sudo chown --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree
-```
-
-#### Actually doing a sync
-
-In the rustc repo, execute
-
-```
-git subtree pull --prefix=compiler/rustc_smir https://github.com/rust-lang/project-stable-mir smir
-```
-
-Note: only ever sync to rustc from the project-stable-mir's `smir` branch. Do not sync with your own forks.
-
-Then open a PR against rustc just like a regular PR.
+See the StableMIR ["Getting Started"](https://rust-lang.github.io/project-stable-mir/getting-started.html)
+guide for more information.
 
 ## Stable MIR Design
 
-The stable-mir will follow a similar approach to proc-macro2. It’s
-implementation will eventually be broken down into two main crates:
+The stable-mir will follow a similar approach to proc-macro2. Its
+implementation is split between two main crates:
 
 - `stable_mir`: Public crate, to be published on crates.io, which will contain
-the stable data structure as well as proxy APIs to make calls to the
-compiler.
-- `rustc_smir`: The compiler crate that will translate from internal MIR to
-SMIR. This crate will also implement APIs that will be invoked by
-stable-mir to query the compiler for more information.
+the stable data structure as well as calls to `rustc_smir` APIs. The
+translation between stable and internal constructs will also be done in this crate,
+however, this is currently implemented in the `rustc_smir` crate.[^translation].
+- `rustc_smir`: This crate implements the public APIs to the compiler.
+It is responsible for gathering all the information requested, and providing
+the data in its unstable form.
+
+[^translation]: This is currently implemented in the `rustc_smir` crate,
+but we are working to change that.
 
-This will help tools to communicate with the rust compiler via stable APIs. Tools will depend on
-`stable_mir` crate, which will invoke the compiler using APIs defined in `rustc_smir`. I.e.:
+I.e.,
+tools will depend on `stable_mir` crate,
+which will invoke the compiler using APIs defined in `rustc_smir`.
+
+I.e.:
 
 ```
     ┌──────────────────────────────────┐           ┌──────────────────────────────────┐
@@ -104,9 +44,3 @@ This will help tools to communicate with the rust compiler via stable APIs. Tool
 
 More details can be found here:
 https://hackmd.io/XhnYHKKuR6-LChhobvlT-g?view
-
-For now, the code for these two crates are in separate modules of this crate.
-The modules have the same name for simplicity. We also have a third module,
-`rustc_internal` which will expose APIs and definitions that allow users to
-gather information from internal MIR constructs that haven't been exposed in
-the `stable_mir` module.
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index ea185f0fbe5..03cab232742 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -2107,13 +2107,39 @@ pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool {
 
 /// Compares the *addresses* of the two function pointers for equality.
 ///
-/// Function pointers comparisons can have surprising results since
-/// they are never guaranteed to be unique and could vary between different
-/// code generation units. Furthermore, different functions could have the
-/// same address after being merged together.
+/// This is the same as `f == g`, but using this function makes clear that the potentially
+/// surprising semantics of function pointer comparison are involved.
+///
+/// There are **very few guarantees** about how functions are compiled and they have no intrinsic
+/// “identity”; in particular, this comparison:
+///
+/// * May return `true` unexpectedly, in cases where functions are equivalent.
+///
+///   For example, the following program is likely (but not guaranteed) to print `(true, true)`
+///   when compiled with optimization:
+///
+///   ```
+///   # #![feature(ptr_fn_addr_eq)]
+///   let f: fn(i32) -> i32 = |x| x;
+///   let g: fn(i32) -> i32 = |x| x + 0;  // different closure, different body
+///   let h: fn(u32) -> u32 = |x| x + 0;  // different signature too
+///   dbg!(std::ptr::fn_addr_eq(f, g), std::ptr::fn_addr_eq(f, h)); // not guaranteed to be equal
+///   ```
+///
+/// * May return `false` in any case.
+///
+///   This is particularly likely with generic functions but may happen with any function.
+///   (From an implementation perspective, this is possible because functions may sometimes be
+///   processed more than once by the compiler, resulting in duplicate machine code.)
+///
+/// Despite these false positives and false negatives, this comparison can still be useful.
+/// Specifically, if
+///
+/// * `T` is the same type as `U`, `T` is a [subtype] of `U`, or `U` is a [subtype] of `T`, and
+/// * `ptr::fn_addr_eq(f, g)` returns true,
+///
+/// then calling `f` and calling `g` will be equivalent.
 ///
-/// This is the same as `f == g` but using this function makes clear
-/// that you are aware of these potentially surprising semantics.
 ///
 /// # Examples
 ///
@@ -2125,6 +2151,8 @@ pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool {
 /// fn b() { println!("b"); }
 /// assert!(!ptr::fn_addr_eq(a as fn(), b as fn()));
 /// ```
+///
+/// [subtype]: https://doc.rust-lang.org/reference/subtyping.html
 #[unstable(feature = "ptr_fn_addr_eq", issue = "129322")]
 #[inline(always)]
 #[must_use = "function pointer comparison produces a value"]
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs
index 5a54e8eec91..bbf88917905 100644
--- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs
@@ -1,5 +1,5 @@
 //@ compile-flags: -Znext-solver
-//@ known-bug: unknown
+//@ check-pass
 
 #![allow(incomplete_features)]
 #![feature(const_trait_impl, effects)]
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr
deleted file mode 100644
index 35069a5a52f..00000000000
--- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error[E0271]: type mismatch resolving `<T as Trait>::Assoc == T`
-  --> $DIR/assoc-type-const-bound-usage-0.rs:14:5
-   |
-LL |     T::Assoc::func()
-   |     ^^^^^^^^^^^^^^^^ types differ
-
-error[E0271]: type mismatch resolving `<T as Trait>::Assoc == T`
-  --> $DIR/assoc-type-const-bound-usage-0.rs:18:5
-   |
-LL |     <T as Trait>::Assoc::func()
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr
index ed9182c7334..b8768bd5541 100644
--- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr
@@ -6,18 +6,30 @@ LL | #![feature(const_trait_impl, effects, generic_const_exprs)]
    |
    = help: remove one of these features
 
-error[E0271]: type mismatch resolving `<T as Trait>::Assoc == T`
-  --> $DIR/assoc-type-const-bound-usage-1.rs:15:44
+error[E0284]: type annotations needed: cannot normalize `unqualified<T>::{constant#0}`
+  --> $DIR/assoc-type-const-bound-usage-1.rs:15:37
    |
 LL | fn unqualified<T: const Trait>() -> Type<{ T::Assoc::func() }> {
-   |                                            ^^^^^^^^^^^^^^^^ types differ
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `unqualified<T>::{constant#0}`
 
-error[E0271]: type mismatch resolving `<T as Trait>::Assoc == T`
-  --> $DIR/assoc-type-const-bound-usage-1.rs:19:42
+error[E0284]: type annotations needed: cannot normalize `qualified<T>::{constant#0}`
+  --> $DIR/assoc-type-const-bound-usage-1.rs:19:35
    |
 LL | fn qualified<T: const Trait>() -> Type<{ <T as Trait>::Assoc::func() }> {
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `qualified<T>::{constant#0}`
 
-error: aborting due to 3 previous errors
+error[E0284]: type annotations needed: cannot normalize `unqualified<T>::{constant#0}`
+  --> $DIR/assoc-type-const-bound-usage-1.rs:16:5
+   |
+LL |     Type
+   |     ^^^^ cannot normalize `unqualified<T>::{constant#0}`
+
+error[E0284]: type annotations needed: cannot normalize `qualified<T>::{constant#0}`
+  --> $DIR/assoc-type-const-bound-usage-1.rs:20:5
+   |
+LL |     Type
+   |     ^^^^ cannot normalize `qualified<T>::{constant#0}`
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs
new file mode 100644
index 00000000000..5e873082781
--- /dev/null
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs
@@ -0,0 +1,35 @@
+//@ compile-flags: -Znext-solver
+
+// Check that `~const` item bounds only hold if the where clauses on the
+// associated type are also const.
+// i.e. check that we validate the const conditions for the associated type
+// when considering one of implied const bounds.
+
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Trait {
+    type Assoc<U>: ~const Trait
+    where
+        U: ~const Other;
+
+    fn func();
+}
+
+#[const_trait]
+trait Other {}
+
+const fn fails<T: ~const Trait, U: Other>() {
+    T::Assoc::<U>::func();
+    //~^ ERROR the trait bound `<T as Trait>::Assoc<U>: ~const Trait` is not satisfied
+    <T as Trait>::Assoc::<U>::func();
+    //~^ ERROR the trait bound `<T as Trait>::Assoc<U>: ~const Trait` is not satisfied
+}
+
+const fn works<T: ~const Trait, U: ~const Other>() {
+    T::Assoc::<U>::func();
+    <T as Trait>::Assoc::<U>::func();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.stderr
new file mode 100644
index 00000000000..1f6532c7a57
--- /dev/null
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `<T as Trait>::Assoc<U>: ~const Trait` is not satisfied
+  --> $DIR/assoc-type-const-bound-usage-fail-2.rs:24:5
+   |
+LL |     T::Assoc::<U>::func();
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `<T as Trait>::Assoc<U>: ~const Trait` is not satisfied
+  --> $DIR/assoc-type-const-bound-usage-fail-2.rs:26:5
+   |
+LL |     <T as Trait>::Assoc::<U>::func();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs
new file mode 100644
index 00000000000..73b3d142f7c
--- /dev/null
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs
@@ -0,0 +1,28 @@
+//@ compile-flags: -Znext-solver
+
+// Check that `~const` item bounds only hold if the parent trait is `~const`.
+// i.e. check that we validate the const conditions for the associated type
+// when considering one of implied const bounds.
+
+#![allow(incomplete_features)]
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Trait {
+    type Assoc: ~const Trait;
+    fn func();
+}
+
+const fn unqualified<T: Trait>() {
+    T::Assoc::func();
+    //~^ ERROR the trait bound `T: ~const Trait` is not satisfied
+    <T as Trait>::Assoc::func();
+    //~^ ERROR the trait bound `T: ~const Trait` is not satisfied
+}
+
+const fn works<T: ~const Trait>() {
+    T::Assoc::func();
+    <T as Trait>::Assoc::func();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.stderr
new file mode 100644
index 00000000000..fb08e74eb7f
--- /dev/null
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `T: ~const Trait` is not satisfied
+  --> $DIR/assoc-type-const-bound-usage-fail.rs:17:5
+   |
+LL |     T::Assoc::func();
+   |     ^^^^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `T: ~const Trait` is not satisfied
+  --> $DIR/assoc-type-const-bound-usage-fail.rs:19:5
+   |
+LL |     <T as Trait>::Assoc::func();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.