Repository: rust-lang/rust-analyzer
Pull request #13817 (2022-12-21 19:23:54)

feat: Add an option to hide adjustment hints outside of `unsafe` blocks and functions
As the title suggests: this PR adds an option (namely `rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe`) that allows to hide adjustment hints outside of `unsafe` blocks and functions:

![2022-12-21_23-11](https://user-images.githubusercontent.com/38225716/208986376-d607de62-8290-4e16-b7fe-15b762dc5f60.png)

Requested by @BoxyUwU <3


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 275b77ce4a..3d9f0d7cc5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -586,9 +586,9 @@ dependencies = [
 
 [[package]]
 name = "hkalbasi-rustc-ap-rustc_abi"
-version = "0.0.20221221"
+version = "0.0.20221125"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adabaadad9aa7576f97af02241cdf5554d62fb3d51a84cb05d77ba28edd3013f"
+checksum = "29c8368a30e518c0102d670d8515f7d424d875ee615ec7a7b6d29217b57a0371"
 dependencies = [
  "bitflags",
  "hkalbasi-rustc-ap-rustc_index",
@@ -597,9 +597,9 @@ dependencies = [
 
 [[package]]
 name = "hkalbasi-rustc-ap-rustc_index"
-version = "0.0.20221221"
+version = "0.0.20221125"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4d3c48474e09afb0f5efbd6f758e05411699301a113c47d454d28ec7059d00e"
+checksum = "c07bba80d7f6a8e1efb0f3e2115ef1eecbf97292dc8cad84e4982226b9aa12e2"
 dependencies = [
  "arrayvec",
  "smallvec",
diff --git a/crates/base-db/src/fixture.rs b/crates/base-db/src/fixture.rs
index 83286cf6b7..5b7828a269 100644
--- a/crates/base-db/src/fixture.rs
+++ b/crates/base-db/src/fixture.rs
@@ -162,7 +162,6 @@ impl ChangeFixture {
                     Ok(Vec::new()),
                     false,
                     origin,
-                    meta.target_data_layout.as_deref().map(Arc::from),
                 );
                 let prev = crates.insert(crate_name.clone(), crate_id);
                 assert!(prev.is_none());
@@ -198,7 +197,6 @@ impl ChangeFixture {
                 Ok(Vec::new()),
                 false,
                 CrateOrigin::CratesIo { repo: None, name: None },
-                None,
             );
         } else {
             for (from, to, prelude) in crate_deps {
@@ -212,8 +210,6 @@ impl ChangeFixture {
                     .unwrap();
             }
         }
-        let target_layout =
-            crate_graph.iter().next().and_then(|it| crate_graph[it].target_layout.clone());
 
         if let Some(mini_core) = mini_core {
             let core_file = file_id;
@@ -238,7 +234,6 @@ impl ChangeFixture {
                 Ok(Vec::new()),
                 false,
                 CrateOrigin::Lang(LangCrateOrigin::Core),
-                target_layout.clone(),
             );
 
             for krate in all_crates {
@@ -276,7 +271,6 @@ impl ChangeFixture {
                 Ok(proc_macro),
                 true,
                 CrateOrigin::CratesIo { repo: None, name: None },
-                target_layout,
             );
 
             for krate in all_crates {
@@ -397,7 +391,6 @@ struct FileMeta {
     edition: Edition,
     env: Env,
     introduce_new_source_root: Option<SourceRootKind>,
-    target_data_layout: Option<String>,
 }
 
 fn parse_crate(crate_str: String) -> (String, CrateOrigin, Option<String>) {
@@ -441,7 +434,6 @@ impl From<Fixture> for FileMeta {
                 "library" => SourceRootKind::Library,
                 invalid => panic!("invalid source root kind '{}'", invalid),
             }),
-            target_data_layout: f.target_data_layout,
         }
     }
 }
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs
index 7aff9b1ae8..e7f0c4ec29 100644
--- a/crates/base-db/src/input.rs
+++ b/crates/base-db/src/input.rs
@@ -270,7 +270,6 @@ pub struct CrateData {
     pub display_name: Option<CrateDisplayName>,
     pub cfg_options: CfgOptions,
     pub potential_cfg_options: CfgOptions,
-    pub target_layout: Option<Arc<str>>,
     pub env: Env,
     pub dependencies: Vec<Dependency>,
     pub proc_macro: ProcMacroLoadResult,
@@ -329,7 +328,6 @@ impl CrateGraph {
         proc_macro: ProcMacroLoadResult,
         is_proc_macro: bool,
         origin: CrateOrigin,
-        target_layout: Option<Arc<str>>,
     ) -> CrateId {
         let data = CrateData {
             root_file_id,
@@ -342,7 +340,6 @@ impl CrateGraph {
             proc_macro,
             dependencies: Vec::new(),
             origin,
-            target_layout,
             is_proc_macro,
         };
         let crate_id = CrateId(self.arena.len() as u32);
@@ -652,7 +649,6 @@ mod tests {
             Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None, name: None },
-            None,
         );
         let crate2 = graph.add_crate_root(
             FileId(2u32),
@@ -665,7 +661,6 @@ mod tests {
             Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None, name: None },
-            None,
         );
         let crate3 = graph.add_crate_root(
             FileId(3u32),
@@ -678,7 +673,6 @@ mod tests {
             Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None, name: None },
-            None,
         );
         assert!(graph
             .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
@@ -705,7 +699,6 @@ mod tests {
             Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None, name: None },
-            None,
         );
         let crate2 = graph.add_crate_root(
             FileId(2u32),
@@ -718,7 +711,6 @@ mod tests {
             Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None, name: None },
-            None,
         );
         assert!(graph
             .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
@@ -742,7 +734,6 @@ mod tests {
             Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None, name: None },
-            None,
         );
         let crate2 = graph.add_crate_root(
             FileId(2u32),
@@ -755,7 +746,6 @@ mod tests {
             Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None, name: None },
-            None,
         );
         let crate3 = graph.add_crate_root(
             FileId(3u32),
@@ -768,7 +758,6 @@ mod tests {
             Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None, name: None },
-            None,
         );
         assert!(graph
             .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
@@ -792,7 +781,6 @@ mod tests {
             Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None, name: None },
-            None,
         );
         let crate2 = graph.add_crate_root(
             FileId(2u32),
@@ -805,7 +793,6 @@ mod tests {
             Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None, name: None },
-            None,
         );
         assert!(graph
             .add_dep(
diff --git a/crates/hir-def/Cargo.toml b/crates/hir-def/Cargo.toml
index 698be76656..9ecce46601 100644
--- a/crates/hir-def/Cargo.toml
+++ b/crates/hir-def/Cargo.toml
@@ -33,8 +33,8 @@ base-db = { path = "../base-db", version = "0.0.0" }
 syntax = { path = "../syntax", version = "0.0.0" }
 profile = { path = "../profile", version = "0.0.0" }
 hir-expand = { path = "../hir-expand", version = "0.0.0" }
-rustc_abi = { version = "0.0.20221221", package = "hkalbasi-rustc-ap-rustc_abi", default-features = false }
-rustc_index = { version = "0.0.20221221", package = "hkalbasi-rustc-ap-rustc_index", default-features = false }
+rustc_abi = { version = "0.0.20221125", package = "hkalbasi-rustc-ap-rustc_abi", default-features = false }
+rustc_index = { version = "0.0.20221125", package = "hkalbasi-rustc-ap-rustc_index", default-features = false }
 mbe = { path = "../mbe", version = "0.0.0" }
 cfg = { path = "../cfg", version = "0.0.0" }
 tt = { path = "../tt", version = "0.0.0" }
diff --git a/crates/hir-def/src/layout.rs b/crates/hir-def/src/layout.rs
index 6bb4cd94f8..a427c464bc 100644
--- a/crates/hir-def/src/layout.rs
+++ b/crates/hir-def/src/layout.rs
@@ -6,7 +6,7 @@ use la_arena::{Idx, RawIdx};
 pub use rustc_abi::{
     Abi, AbiAndPrefAlign, AddressSpace, Align, Endian, FieldsShape, Integer, IntegerType,
     LayoutCalculator, Niche, Primitive, ReprFlags, ReprOptions, Scalar, Size, StructKind,
-    TargetDataLayout, TargetDataLayoutErrors, WrappingRange,
+    TargetDataLayout, WrappingRange,
 };
 
 use crate::LocalEnumVariantId;
diff --git a/crates/hir-ty/Cargo.toml b/crates/hir-ty/Cargo.toml
index c72199c37f..e4dd244ab8 100644
--- a/crates/hir-ty/Cargo.toml
+++ b/crates/hir-ty/Cargo.toml
@@ -25,7 +25,7 @@ chalk-derive = "0.88.0"
 la-arena = { version = "0.3.0", path = "../../lib/la-arena" }
 once_cell = "1.15.0"
 typed-arena = "2.0.1"
-rustc_index = { version = "0.0.20221221", package = "hkalbasi-rustc-ap-rustc_index", default-features = false }
+rustc_index = { version = "0.0.20221125", package = "hkalbasi-rustc-ap-rustc_index", default-features = false }
 
 stdx = { path = "../stdx", version = "0.0.0" }
 hir-def = { path = "../hir-def", version = "0.0.0" }
diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs
index 54b244620f..23ad335aac 100644
--- a/crates/hir-ty/src/db.rs
+++ b/crates/hir-ty/src/db.rs
@@ -64,8 +64,8 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
     #[salsa::cycle(crate::layout::layout_of_adt_recover)]
     fn layout_of_adt(&self, def: AdtId, subst: Substitution) -> Result<Layout, LayoutError>;
 
-    #[salsa::invoke(crate::layout::target_data_layout_query)]
-    fn target_data_layout(&self, krate: CrateId) -> Arc<TargetDataLayout>;
+    #[salsa::invoke(crate::layout::current_target_data_layout_query)]
+    fn current_target_data_layout(&self) -> Arc<TargetDataLayout>;
 
     #[salsa::invoke(crate::lower::callable_item_sig)]
     fn callable_item_signature(&self, def: CallableDefId) -> PolyFnSig;
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 57a15d114f..9d453eef71 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -16,7 +16,7 @@ use hir_def::{
     path::{Path, PathKind},
     type_ref::{ConstScalar, TraitBoundModifier, TypeBound, TypeRef},
     visibility::Visibility,
-    HasModule, ItemContainerId, Lookup, ModuleDefId, ModuleId, TraitId,
+    HasModule, ItemContainerId, Lookup, ModuleId, TraitId,
 };
 use hir_expand::{hygiene::Hygiene, name::Name};
 use itertools::Itertools;
@@ -35,27 +35,9 @@ use crate::{
     TraitRefExt, Ty, TyExt, TyKind, WhereClause,
 };
 
-pub trait HirWrite: fmt::Write {
-    fn start_location_link(&mut self, location: ModuleDefId);
-    fn end_location_link(&mut self);
-}
-
-// String will ignore link metadata
-impl HirWrite for String {
-    fn start_location_link(&mut self, _: ModuleDefId) {}
-
-    fn end_location_link(&mut self) {}
-}
-
-// `core::Formatter` will ignore metadata
-impl HirWrite for fmt::Formatter<'_> {
-    fn start_location_link(&mut self, _: ModuleDefId) {}
-    fn end_location_link(&mut self) {}
-}
-
 pub struct HirFormatter<'a> {
     pub db: &'a dyn HirDatabase,
-    fmt: &'a mut dyn HirWrite,
+    fmt: &'a mut dyn fmt::Write,
     buf: String,
     curr_size: usize,
     pub(crate) max_size: Option<usize>,
@@ -63,16 +45,6 @@ pub struct HirFormatter<'a> {
     display_target: DisplayTarget,
 }
 
-impl HirFormatter<'_> {
-    fn start_location_link(&mut self, location: ModuleDefId) {
-        self.fmt.start_location_link(location);
-    }
-
-    fn end_location_link(&mut self) {
-        self.fmt.end_location_link();
-    }
-}
-
 pub trait HirDisplay {
     fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError>;
 
@@ -273,9 +245,12 @@ pub struct HirDisplayWrapper<'a, T> {
     display_target: DisplayTarget,
 }
 
-impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
-    pub fn write_to<F: HirWrite>(&self, f: &mut F) -> Result<(), HirDisplayError> {
-        self.t.hir_fmt(&mut HirFormatter {
+impl<'a, T> fmt::Display for HirDisplayWrapper<'a, T>
+where
+    T: HirDisplay,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self.t.hir_fmt(&mut HirFormatter {
             db: self.db,
             fmt: f,
             buf: String::with_capacity(20),
@@ -283,16 +258,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
             max_size: self.max_size,
             omit_verbose_types: self.omit_verbose_types,
             display_target: self.display_target,
-        })
-    }
-}
-
-impl<'a, T> fmt::Display for HirDisplayWrapper<'a, T>
-where
-    T: HirDisplay,
-{
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self.write_to(f) {
+        }) {
             Ok(()) => Ok(()),
             Err(HirDisplayError::FmtError) => Err(fmt::Error),
             Err(HirDisplayError::DisplaySourceCodeError(_)) => {
@@ -564,7 +530,6 @@ impl HirDisplay for Ty {
                 }
             }
             TyKind::Adt(AdtId(def_id), parameters) => {
-                f.start_location_link((*def_id).into());
                 match f.display_target {
                     DisplayTarget::Diagnostics | DisplayTarget::Test => {
                         let name = match *def_id {
@@ -589,7 +554,6 @@ impl HirDisplay for Ty {
                         }
                     }
                 }
-                f.end_location_link();
 
                 if parameters.len(Interner) > 0 {
                     let parameters_to_write = if f.display_target.is_source_code()
diff --git a/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs
index 209072176c..f4f3c723ab 100644
--- a/crates/hir-ty/src/layout.rs
+++ b/crates/hir-ty/src/layout.rs
@@ -2,7 +2,6 @@
 
 use std::sync::Arc;
 
-use base_db::CrateId;
 use chalk_ir::{AdtId, TyKind};
 use hir_def::{
     layout::{
@@ -18,7 +17,7 @@ use crate::{db::HirDatabase, Interner, Substitution, Ty};
 use self::adt::struct_variant_idx;
 pub use self::{
     adt::{layout_of_adt_query, layout_of_adt_recover},
-    target::target_data_layout_query,
+    target::current_target_data_layout_query,
 };
 
 macro_rules! user_error {
@@ -32,7 +31,6 @@ mod target;
 
 struct LayoutCx<'a> {
     db: &'a dyn HirDatabase,
-    krate: CrateId,
 }
 
 impl LayoutCalculator for LayoutCx<'_> {
@@ -43,7 +41,7 @@ impl LayoutCalculator for LayoutCx<'_> {
     }
 
     fn current_data_layout(&self) -> Arc<TargetDataLayout> {
-        self.db.target_data_layout(self.krate)
+        self.db.current_target_data_layout()
     }
 }
 
@@ -55,9 +53,9 @@ fn scalar(dl: &TargetDataLayout, value: Primitive) -> Layout {
     Layout::scalar(dl, scalar_unit(dl, value))
 }
 
-pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Layout, LayoutError> {
-    let cx = LayoutCx { db, krate };
-    let dl = &*cx.current_data_layout();
+pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty) -> Result<Layout, LayoutError> {
+    let dl = &*db.current_target_data_layout();
+    let cx = LayoutCx { db };
     Ok(match ty.kind(Interner) {
         TyKind::Adt(AdtId(def), subst) => db.layout_of_adt(*def, subst.clone())?,
         TyKind::Scalar(s) => match s {
@@ -86,7 +84,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Lay
                         chalk_ir::IntTy::I64 => Integer::I64,
                         chalk_ir::IntTy::I128 => Integer::I128,
                     },
-                    true,
+                    false,
                 ),
             ),
             chalk_ir::Scalar::Uint(i) => scalar(
@@ -100,7 +98,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Lay
                         chalk_ir::UintTy::U64 => Integer::I64,
                         chalk_ir::UintTy::U128 => Integer::I128,
                     },
-                    false,
+                    true,
                 ),
             ),
             chalk_ir::Scalar::Float(f) => scalar(
@@ -116,7 +114,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Lay
 
             let fields = tys
                 .iter(Interner)
-                .map(|k| layout_of_ty(db, k.assert_ty_ref(Interner), krate))
+                .map(|k| layout_of_ty(db, k.assert_ty_ref(Interner)))
                 .collect::<Result<Vec<_>, _>>()?;
             let fields = fields.iter().collect::<Vec<_>>();
             let fields = fields.iter().collect::<Vec<_>>();
@@ -134,7 +132,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Lay
                 },
                 _ => return Err(LayoutError::HasPlaceholder),
             };
-            let element = layout_of_ty(db, element, krate)?;
+            let element = layout_of_ty(db, element)?;
             let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow)?;
 
             let abi = if count != 0 && matches!(element.abi, Abi::Uninhabited) {
@@ -155,7 +153,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Lay
             }
         }
         TyKind::Slice(element) => {
-            let element = layout_of_ty(db, element, krate)?;
+            let element = layout_of_ty(db, element)?;
             Layout {
                 variants: Variants::Single { index: struct_variant_idx() },
                 fields: FieldsShape::Array { stride: element.size, count: 0 },
diff --git a/crates/hir-ty/src/layout/adt.rs b/crates/hir-ty/src/layout/adt.rs
index 23166a5a52..e938295535 100644
--- a/crates/hir-ty/src/layout/adt.rs
+++ b/crates/hir-ty/src/layout/adt.rs
@@ -5,7 +5,7 @@ use std::ops::Bound;
 use hir_def::{
     adt::VariantData,
     layout::{Integer, IntegerExt, Layout, LayoutCalculator, LayoutError, RustcEnumVariantIdx},
-    AdtId, EnumVariantId, HasModule, LocalEnumVariantId, VariantId,
+    AdtId, EnumVariantId, LocalEnumVariantId, VariantId,
 };
 use la_arena::RawIdx;
 use smallvec::SmallVec;
@@ -23,12 +23,12 @@ pub fn layout_of_adt_query(
     def: AdtId,
     subst: Substitution,
 ) -> Result<Layout, LayoutError> {
-    let cx = LayoutCx { db, krate: def.module(db.upcast()).krate() };
-    let dl = cx.current_data_layout();
+    let dl = db.current_target_data_layout();
+    let cx = LayoutCx { db };
     let handle_variant = |def: VariantId, var: &VariantData| {
         var.fields()
             .iter()
-            .map(|(fd, _)| layout_of_ty(db, &field_ty(db, def, fd, &subst), cx.krate))
+            .map(|(fd, _)| layout_of_ty(db, &field_ty(db, def, fd, &subst)))
             .collect::<Result<Vec<_>, _>>()
     };
     let (variants, is_enum, is_union, repr) = match def {
diff --git a/crates/hir-ty/src/layout/target.rs b/crates/hir-ty/src/layout/target.rs
index 37b831652f..b248031f15 100644
--- a/crates/hir-ty/src/layout/target.rs
+++ b/crates/hir-ty/src/layout/target.rs
@@ -2,35 +2,45 @@
 
 use std::sync::Arc;
 
-use base_db::CrateId;
-use hir_def::layout::{Endian, Size, TargetDataLayout};
+use hir_def::layout::TargetDataLayout;
 
 use crate::db::HirDatabase;
 
-pub fn target_data_layout_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<TargetDataLayout> {
+use hir_def::layout::{AbiAndPrefAlign, AddressSpace, Align, Endian, Integer, Size};
+
+pub fn current_target_data_layout_query(db: &dyn HirDatabase) -> Arc<TargetDataLayout> {
     let crate_graph = db.crate_graph();
-    let target_layout = &crate_graph[krate].target_layout;
-    let cfg_options = &crate_graph[krate].cfg_options;
-    Arc::new(
-        target_layout
-            .as_ref()
-            .and_then(|it| TargetDataLayout::parse_from_llvm_datalayout_string(it).ok())
-            .unwrap_or_else(|| {
-                let endian = match cfg_options.get_cfg_values("target_endian").next() {
-                    Some(x) if x.as_str() == "big" => Endian::Big,
-                    _ => Endian::Little,
-                };
-                let pointer_size = Size::from_bytes(
-                    match cfg_options.get_cfg_values("target_pointer_width").next() {
-                        Some(x) => match x.as_str() {
-                            "16" => 2,
-                            "32" => 4,
-                            _ => 8,
-                        },
-                        _ => 8,
-                    },
-                );
-                TargetDataLayout { endian, pointer_size, ..TargetDataLayout::default() }
-            }),
-    )
+    let cfg_options = &crate_graph[crate_graph.iter().next().unwrap()].cfg_options;
+    let endian = match cfg_options.get_cfg_values("target_endian").next() {
+        Some(x) if x.as_str() == "big" => Endian::Big,
+        _ => Endian::Little,
+    };
+    let pointer_size =
+        Size::from_bytes(match cfg_options.get_cfg_values("target_pointer_width").next() {
+            Some(x) => match x.as_str() {
+                "16" => 2,
+                "32" => 4,
+                _ => 8,
+            },
+            _ => 8,
+        });
+    // FIXME: These values are incorrect for many architectures, at least for aarch64 and riscv64,
+    // use `rustc +nightly -Z unstable-options --print target-spec-json` or something similar instead.
+    Arc::new(TargetDataLayout {
+        endian,
+        i1_align: AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()),
+        i8_align: AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()),
+        i16_align: AbiAndPrefAlign::new(Align::from_bytes(2).unwrap()),
+        i32_align: AbiAndPrefAlign::new(Align::from_bytes(4).unwrap()),
+        i64_align: AbiAndPrefAlign::new(Align::from_bytes(8).unwrap()),
+        i128_align: AbiAndPrefAlign::new(Align::from_bytes(8).unwrap()),
+        f32_align: AbiAndPrefAlign::new(Align::from_bytes(4).unwrap()),
+        f64_align: AbiAndPrefAlign::new(Align::from_bytes(8).unwrap()),
+        pointer_size,
+        pointer_align: AbiAndPrefAlign::new(Align::from_bytes(pointer_size.bytes()).unwrap()),
+        aggregate_align: AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()),
+        vector_align: vec![],
+        instruction_address_space: AddressSpace(0),
+        c_enum_min_size: Integer::I32,
+    })
 }
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 7e0e024526..2933d488a1 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -74,7 +74,7 @@ use once_cell::unsync::Lazy;
 use rustc_hash::FxHashSet;
 use stdx::{impl_from, never};
 use syntax::{
-    ast::{self, Expr, HasAttrs as _, HasDocComments, HasName},
+    ast::{self, HasAttrs as _, HasDocComments, HasName},
     AstNode, AstPtr, SmolStr, SyntaxNodePtr, TextRange, T,
 };
 
@@ -114,20 +114,12 @@ pub use {
         path::{ModPath, PathKind},
         type_ref::{Mutability, TypeRef},
         visibility::Visibility,
-        // FIXME: This is here since it is input of a method in `HirWrite`
-        // and things outside of hir need to implement that trait. We probably
-        // should move whole `hir_ty::display` to this crate so we will become
-        // able to use `ModuleDef` or `Definition` instead of `ModuleDefId`.
-        ModuleDefId,
     },
     hir_expand::{
         name::{known, Name},
         ExpandResult, HirFileId, InFile, MacroFile, Origin,
     },
-    hir_ty::{
-        display::{HirDisplay, HirWrite},
-        PointerCast, Safety,
-    },
+    hir_ty::{display::HirDisplay, PointerCast, Safety},
 };
 
 // These are negative re-exports: pub using these names is forbidden, they
@@ -874,7 +866,7 @@ impl Field {
     }
 
     pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
-        layout_of_ty(db, &self.ty(db).ty, self.parent.module(db).krate().into())
+        layout_of_ty(db, &self.ty(db).ty)
     }
 
     pub fn parent_def(&self, _db: &dyn HirDatabase) -> VariantDef {
@@ -1082,7 +1074,7 @@ impl Variant {
         db.enum_data(self.parent.id).variants[self.id].variant_data.clone()
     }
 
-    pub fn value(self, db: &dyn HirDatabase) -> Option<Expr> {
+    pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> {
         self.source(db)?.value.expr()
     }
 
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 2ed62372ae..569c2bfb9e 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -5,11 +5,14 @@ mod source_to_def;
 use std::{cell::RefCell, fmt, iter, mem, ops};
 
 use base_db::{FileId, FileRange};
+use either::Either;
 use hir_def::{
-    body, macro_id_to_def_id,
+    body,
+    expr::Expr,
+    macro_id_to_def_id,
     resolver::{self, HasResolver, Resolver, TypeNs},
     type_ref::Mutability,
-    AsMacroCall, FunctionId, MacroId, TraitId, VariantId,
+    AsMacroCall, DefWithBodyId, FunctionId, MacroId, TraitId, VariantId,
 };
 use hir_expand::{
     db::AstDatabase,
@@ -438,8 +441,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
     }
 
     pub fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
-        let src = self.imp.find_file(src.syntax()).with_value(src).cloned();
-        T::to_def(&self.imp, src)
+        self.imp.to_def(src)
     }
 
     pub fn to_module_def(&self, file: FileId) -> Option<Module> {
@@ -481,6 +483,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
     pub fn is_unsafe_ident_pat(&self, ident_pat: &ast::IdentPat) -> bool {
         self.imp.is_unsafe_ident_pat(ident_pat)
     }
+
+    /// Returns `true` if the `node` is inside an `unsafe` context.
+    pub fn is_inside_unsafe(&self, expr: &ast::Expr) -> bool {
+        self.imp.is_inside_unsafe(expr)
+    }
 }
 
 impl<'db> SemanticsImpl<'db> {
@@ -1243,6 +1250,11 @@ impl<'db> SemanticsImpl<'db> {
         f(&mut ctx)
     }
 
+    fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
+        let src = self.find_file(src.syntax()).with_value(src).cloned();
+        T::to_def(&self, src)
+    }
+
     fn to_module_def(&self, file: FileId) -> impl Iterator<Item = Module> {
         self.with_ctx(|ctx| ctx.file_to_def(file)).into_iter().map(Module::from)
     }
@@ -1458,6 +1470,56 @@ impl<'db> SemanticsImpl<'db> {
             .map(|ty| ty.original.is_packed(self.db))
             .unwrap_or(false)
     }
+
+    fn is_inside_unsafe(&self, expr: &ast::Expr) -> bool {
+        let item_or_variant = |ancestor: SyntaxNode| {
+            if ast::Item::can_cast(ancestor.kind()) {
+                ast::Item::cast(ancestor).map(Either::Left)
+            } else {
+                ast::Variant::cast(ancestor).map(Either::Right)
+            }
+        };
+        let Some(enclosing_item) = expr.syntax().ancestors().find_map(item_or_variant) else { return false };
+
+        let def = match &enclosing_item {
+            Either::Left(ast::Item::Fn(it)) if it.unsafe_token().is_some() => return true,
+            Either::Left(ast::Item::Fn(it)) => {
+                self.to_def(it).map(<_>::into).map(DefWithBodyId::FunctionId)
+            }
+            Either::Left(ast::Item::Const(it)) => {
+                self.to_def(it).map(<_>::into).map(DefWithBodyId::ConstId)
+            }
+            Either::Left(ast::Item::Static(it)) => {
+                self.to_def(it).map(<_>::into).map(DefWithBodyId::StaticId)
+            }
+            Either::Left(_) => None,
+            Either::Right(it) => self.to_def(it).map(<_>::into).map(DefWithBodyId::VariantId),
+        };
+        let Some(def) = def else { return false };
+        let enclosing_node = enclosing_item.as_ref().either(|i| i.syntax(), |v| v.syntax());
+
+        let (body, source_map) = self.db.body_with_source_map(def);
+
+        let file_id = self.find_file(expr.syntax()).file_id;
+
+        let Some(mut parent) = expr.syntax().parent() else { return false };
+        loop {
+            if &parent == enclosing_node {
+                break false;
+            }
+
+            if let Some(parent) = ast::Expr::cast(parent.clone()) {
+                if let Some(expr_id) = source_map.node_expr(InFile { file_id, value: &parent }) {
+                    if let Expr::Unsafe { .. } = body[expr_id] {
+                        break true;
+                    }
+                }
+            }
+
+            let Some(parent_) = parent.parent() else { break false };
+            parent = parent_;
+        }
+    }
 }
 
 fn macro_call_to_macro_id(
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 9aef78143d..eca76d05fd 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -1,19 +1,15 @@
-use std::{
-    fmt::{self, Write},
-    mem::take,
-};
+use std::fmt;
 
 use either::Either;
-use hir::{known, HasVisibility, HirDisplay, HirWrite, ModuleDef, ModuleDefId, Semantics};
+use hir::{known, HasVisibility, HirDisplay, Semantics};
 use ide_db::{base_db::FileRange, famous_defs::FamousDefs, RootDatabase};
 use itertools::Itertools;
-use stdx::never;
 use syntax::{
     ast::{self, AstNode},
     match_ast, NodeOrToken, SyntaxNode, TextRange, TextSize,
 };
 
-use crate::{navigation_target::TryToNav, FileId};
+use crate::FileId;
 
 mod closing_brace;
 mod implicit_static;
@@ -27,12 +23,12 @@ mod bind_pat;
 
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct InlayHintsConfig {
-    pub location_links: bool,
     pub render_colons: bool,
     pub type_hints: bool,
     pub parameter_hints: bool,
     pub chaining_hints: bool,
     pub adjustment_hints: AdjustmentHints,
+    pub adjustment_hints_hide_outside_unsafe: bool,
     pub closure_return_type_hints: ClosureReturnTypeHints,
     pub binding_mode_hints: bool,
     pub lifetime_elision_hints: LifetimeElisionHints,
@@ -94,7 +90,6 @@ pub enum InlayTooltip {
     HoverOffset(FileId, TextSize),
 }
 
-#[derive(Default)]
 pub struct InlayHintLabel {
     pub parts: Vec<InlayHintLabelPart>,
 }
@@ -178,104 +173,6 @@ impl fmt::Debug for InlayHintLabelPart {
     }
 }
 
-#[derive(Debug)]
-struct InlayHintLabelBuilder<'a> {
-    db: &'a RootDatabase,
-    result: InlayHintLabel,
-    last_part: String,
-    location_link_enabled: bool,
-    location: Option<FileRange>,
-}
-
-impl fmt::Write for InlayHintLabelBuilder<'_> {
-    fn write_str(&mut self, s: &str) -> fmt::Result {
-        self.last_part.write_str(s)
-    }
-}
-
-impl HirWrite for InlayHintLabelBuilder<'_> {
-    fn start_location_link(&mut self, def: ModuleDefId) {
-        if !self.location_link_enabled {
-            return;
-        }
-        if self.location.is_some() {
-            never!("location link is already started");
-        }
-        self.make_new_part();
-        let Some(location) = ModuleDef::from(def).try_to_nav(self.db) else { return };
-        let location =
-            FileRange { file_id: location.file_id, range: location.focus_or_full_range() };
-        self.location = Some(location);
-    }
-
-    fn end_location_link(&mut self) {
-        if !self.location_link_enabled {
-            return;
-        }
-        self.make_new_part();
-    }
-}
-
-impl InlayHintLabelBuilder<'_> {
-    fn make_new_part(&mut self) {
-        self.result.parts.push(InlayHintLabelPart {
-            text: take(&mut self.last_part),
-            linked_location: self.location.take(),
-        });
-    }
-
-    fn finish(mut self) -> InlayHintLabel {
-        self.make_new_part();
-        self.result
-    }
-}
-
-fn label_of_ty(
-    sema: &Semantics<'_, RootDatabase>,
-    desc_pat: &impl AstNode,
-    config: &InlayHintsConfig,
-    ty: hir::Type,
-) -> Option<InlayHintLabel> {
-    fn rec(
-        sema: &Semantics<'_, RootDatabase>,
-        famous_defs: &FamousDefs<'_, '_>,
-        mut max_length: Option<usize>,
-        ty: hir::Type,
-        label_builder: &mut InlayHintLabelBuilder<'_>,
-    ) {
-        let iter_item_type = hint_iterator(sema, &famous_defs, &ty);
-        match iter_item_type {
-            Some(ty) => {
-                const LABEL_START: &str = "impl Iterator<Item = ";
-                const LABEL_END: &str = ">";
-
-                max_length =
-                    max_length.map(|len| len.saturating_sub(LABEL_START.len() + LABEL_END.len()));
-
-                label_builder.write_str(LABEL_START).unwrap();
-                rec(sema, famous_defs, max_length, ty, label_builder);
-                label_builder.write_str(LABEL_END).unwrap();
-            }
-            None => {
-                let _ = ty.display_truncated(sema.db, max_length).write_to(label_builder);
-            }
-        };
-    }
-
-    let krate = sema.scope(desc_pat.syntax())?.krate();
-    let famous_defs = FamousDefs(sema, krate);
-    let mut label_builder = InlayHintLabelBuilder {
-        db: sema.db,
-        last_part: String::new(),
-        location: None,
-        location_link_enabled: config.location_links,
-        result: InlayHintLabel::default(),
-    };
-    rec(sema, &famous_defs, config.max_length, ty, &mut label_builder);
-    let r = label_builder.finish();
-    Some(r)
-}
-
 // Feature: Inlay Hints
 //
 // rust-analyzer shows additional information inline with the source code.
@@ -328,7 +225,7 @@ pub(crate) fn inlay_hints(
 
 fn hints(
     hints: &mut Vec<InlayHint>,
-    FamousDefs(sema, _): &FamousDefs<'_, '_>,
+    famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
     file_id: FileId,
     node: SyntaxNode,
@@ -337,14 +234,14 @@ fn hints(
     match_ast! {
         match node {
             ast::Expr(expr) => {
-                chaining::hints(hints, sema, config, file_id, &expr);
+                chaining::hints(hints, sema, &famous_defs, config, file_id, &expr);
                 adjustment::hints(hints, sema, config, &expr);
                 match expr {
                     ast::Expr::CallExpr(it) => param_name::hints(hints, sema, config, ast::Expr::from(it)),
                     ast::Expr::MethodCallExpr(it) => {
                         param_name::hints(hints, sema, config, ast::Expr::from(it))
                     }
-                    ast::Expr::ClosureExpr(it) => closure_ret::hints(hints, sema, config, file_id, it),
+                    ast::Expr::ClosureExpr(it) => closure_ret::hints(hints, sema, &famous_defs, config, file_id, it),
                     // We could show reborrows for all expressions, but usually that is just noise to the user
                     // and the main point here is to show why "moving" a mutable reference doesn't necessarily move it
                     // ast::Expr::PathExpr(_) => reborrow_hints(hints, sema, config, &expr),
@@ -374,12 +271,13 @@ fn hints(
     };
 }
 
-/// Checks if the type is an Iterator from std::iter and returns its item type.
+/// Checks if the type is an Iterator from std::iter and replaces its hint with an `impl Iterator<Item = Ty>`.
 fn hint_iterator(
     sema: &Semantics<'_, RootDatabase>,
     famous_defs: &FamousDefs<'_, '_>,
+    config: &InlayHintsConfig,
     ty: &hir::Type,
-) -> Option<hir::Type> {
+) -> Option<String> {
     let db = sema.db;
     let strukt = ty.strip_references().as_adt()?;
     let krate = strukt.module(db).krate();
@@ -402,7 +300,21 @@ fn hint_iterator(
             _ => None,
         })?;
         if let Some(ty) = ty.normalize_trait_assoc_type(db, &[], assoc_type_item) {
-            return Some(ty);
+            const LABEL_START: &str = "impl Iterator<Item = ";
+            const LABEL_END: &str = ">";
+
+            let ty_display = hint_iterator(sema, famous_defs, config, &ty)
+                .map(|assoc_type_impl| assoc_type_impl.to_string())
+                .unwrap_or_else(|| {
+                    ty.display_truncated(
+                        db,
+                        config
+                            .max_length
+                            .map(|len| len.saturating_sub(LABEL_START.len() + LABEL_END.len())),
+                    )
+                    .to_string()
+                });
+            return Some(format!("{}{}{}", LABEL_START, ty_display, LABEL_END));
         }
     }
 
@@ -425,7 +337,6 @@ mod tests {
     use super::ClosureReturnTypeHints;
 
     pub(super) const DISABLED_CONFIG: InlayHintsConfig = InlayHintsConfig {
-        location_links: false,
         render_colons: false,
         type_hints: false,
         parameter_hints: false,
@@ -433,6 +344,7 @@ mod tests {
         lifetime_elision_hints: LifetimeElisionHints::Never,
         closure_return_type_hints: ClosureReturnTypeHints::Never,
         adjustment_hints: AdjustmentHints::Never,
+        adjustment_hints_hide_outside_unsafe: false,
         binding_mode_hints: false,
         hide_named_constructor_hints: false,
         hide_closure_initialization_hints: false,
@@ -440,8 +352,6 @@ mod tests {
         max_length: None,
         closing_brace_hints_min_lines: None,
     };
-    pub(super) const DISABLED_CONFIG_WITH_LINKS: InlayHintsConfig =
-        InlayHintsConfig { location_links: true, ..DISABLED_CONFIG };
     pub(super) const TEST_CONFIG: InlayHintsConfig = InlayHintsConfig {
         type_hints: true,
         parameter_hints: true,
@@ -449,7 +359,7 @@ mod tests {
         closure_return_type_hints: ClosureReturnTypeHints::WithBlock,
         binding_mode_hints: true,
         lifetime_elision_hints: LifetimeElisionHints::Always,
-        ..DISABLED_CONFIG_WITH_LINKS
+        ..DISABLED_CONFIG
     };
 
     #[track_caller]
diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs
index b2bec10d05..1c13f31cf2 100644
--- a/crates/ide/src/inlay_hints/adjustment.rs
+++ b/crates/ide/src/inlay_hints/adjustment.rs
@@ -5,7 +5,6 @@
 //! ```
 use hir::{Adjust, AutoBorrow, Mutability, OverloadedDeref, PointerCast, Safety, Semantics};
 use ide_db::RootDatabase;
-
 use syntax::ast::{self, AstNode};
 
 use crate::{AdjustmentHints, InlayHint, InlayHintsConfig, InlayKind};
@@ -16,6 +15,10 @@ pub(super) fn hints(
     config: &InlayHintsConfig,
     expr: &ast::Expr,
 ) -> Option<()> {
+    if config.adjustment_hints_hide_outside_unsafe && !sema.is_inside_unsafe(expr) {
+        return None;
+    }
+
     if config.adjustment_hints == AdjustmentHints::Never {
         return None;
     }
@@ -233,4 +236,96 @@ fn or_else() {
             "#,
         )
     }
+
+    #[test]
+    fn adjustment_hints_unsafe_only() {
+        check_with_config(
+            InlayHintsConfig {
+                adjustment_hints: AdjustmentHints::Always,
+                adjustment_hints_hide_outside_unsafe: true,
+                ..DISABLED_CONFIG
+            },
+            r#"
+unsafe fn enabled() {
+    f(&&());
+    //^^^^&
+    //^^^^*
+    //^^^^*
+}
+
+fn disabled() {
+    f(&&());
+}
+
+fn mixed() {
+    f(&&());
+
+    unsafe {
+        f(&&());
+        //^^^^&
+        //^^^^*
+        //^^^^*
+    }
+}
+
+const _: () = {
+    f(&&());
+
+    unsafe {
+        f(&&());
+        //^^^^&
+        //^^^^*
+        //^^^^*
+    }
+};
+
+static STATIC: () = {
+    f(&&());
+
+    unsafe {
+        f(&&());
+        //^^^^&
+        //^^^^*
+        //^^^^*
+    }
+};
+
+enum E {
+    Disable = { f(&&()); 0 },
+    Enable = unsafe { f(&&()); 1 },
+                      //^^^^&
+                      //^^^^*
+                      //^^^^*
+}
+
+const fn f(_: &()) {}
+            "#,
+        )
+    }
+
+    #[test]
+    fn adjustment_hints_unsafe_only_with_item() {
+        check_with_config(
+            InlayHintsConfig {
+                adjustment_hints: AdjustmentHints::Always,
+                adjustment_hints_hide_outside_unsafe: true,
+                ..DISABLED_CONFIG
+            },
+            r#"
+fn a() {
+    struct Struct;
+    impl Struct {
+        fn by_ref(&self) {}
+    }
+
+    _ = Struct.by_ref();
+
+    _ = unsafe { Struct.by_ref() };
+               //^^^^^^(
+               //^^^^^^&
+               //^^^^^^)
+}
+            "#,
+        );
+    }
 }
diff --git a/crates/ide/src/inlay_hints/bind_pat.rs b/crates/ide/src/inlay_hints/bind_pat.rs
index 7766d49791..754df09df1 100644
--- a/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/crates/ide/src/inlay_hints/bind_pat.rs
@@ -3,8 +3,8 @@
 //! fn f(a: i32, b: i32) -> i32 { a + b }
 //! let _x /* i32 */= f(4, 4);
 //! ```
-use hir::{Semantics, TypeInfo};
-use ide_db::{base_db::FileId, RootDatabase};
+use hir::{HirDisplay, Semantics, TypeInfo};
+use ide_db::{base_db::FileId, famous_defs::FamousDefs, RootDatabase};
 
 use itertools::Itertools;
 use syntax::{
@@ -13,11 +13,10 @@ use syntax::{
 };
 
 use crate::{
-    inlay_hints::closure_has_block_body, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip,
+    inlay_hints::{closure_has_block_body, hint_iterator},
+    InlayHint, InlayHintsConfig, InlayKind, InlayTooltip,
 };
 
-use super::label_of_ty;
-
 pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
     sema: &Semantics<'_, RootDatabase>,
@@ -37,13 +36,22 @@ pub(super) fn hints(
         return None;
     }
 
-    let label = label_of_ty(sema, desc_pat, config, ty)?;
+    let krate = sema.scope(desc_pat.syntax())?.krate();
+    let famous_defs = FamousDefs(sema, krate);
+    let label = hint_iterator(sema, &famous_defs, config, &ty);
 
-    if config.hide_named_constructor_hints
-        && is_named_constructor(sema, pat, &label.to_string()).is_some()
-    {
-        return None;
-    }
+    let label = match label {
+        Some(label) => label,
+        None => {
+            let ty_name = ty.display_truncated(sema.db, config.max_length).to_string();
+            if config.hide_named_constructor_hints
+                && is_named_constructor(sema, pat, &ty_name).is_some()
+            {
+                return None;
+            }
+            ty_name
+        }
+    };
 
     acc.push(InlayHint {
         range: match pat.name() {
@@ -51,7 +59,7 @@ pub(super) fn hints(
             None => pat.syntax().text_range(),
         },
         kind: InlayKind::TypeHint,
-        label,
+        label: label.into(),
         tooltip: pat
             .name()
             .map(|it| it.syntax().text_range())
@@ -194,8 +202,7 @@ mod tests {
     use crate::{fixture, inlay_hints::InlayHintsConfig};
 
     use crate::inlay_hints::tests::{
-        check, check_expect, check_with_config, DISABLED_CONFIG, DISABLED_CONFIG_WITH_LINKS,
-        TEST_CONFIG,
+        check, check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG,
     };
     use crate::ClosureReturnTypeHints;
 
@@ -291,7 +298,7 @@ fn main() {
     fn iterator_hint_regression_issue_12674() {
         // Ensure we don't crash while solving the projection type of iterators.
         check_expect(
-            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS },
+            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG },
             r#"
 //- minicore: iterators
 struct S<T>(T);
@@ -339,31 +346,7 @@ fn main(a: SliceIter<'_, Container>) {
                         range: 484..485,
                         kind: ChainingHint,
                         label: [
-                            "",
-                            InlayHintLabelPart {
-                                text: "SliceIter",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 289..298,
-                                    },
-                                ),
-                            },
-                            "<",
-                            InlayHintLabelPart {
-                                text: "Container",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 238..247,
-                                    },
-                                ),
-                            },
-                            ">",
+                            "SliceIter<Container>",
                         ],
                         tooltip: Some(
                             HoverRanged(
diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs
index efeb2b7925..32421afd39 100644
--- a/crates/ide/src/inlay_hints/chaining.rs
+++ b/crates/ide/src/inlay_hints/chaining.rs
@@ -1,18 +1,19 @@
 //! Implementation of "chaining" inlay hints.
-use hir::Semantics;
-use ide_db::RootDatabase;
+use hir::{HirDisplay, Semantics};
+use ide_db::{famous_defs::FamousDefs, RootDatabase};
 use syntax::{
     ast::{self, AstNode},
     Direction, NodeOrToken, SyntaxKind, T,
 };
 
-use crate::{FileId, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip};
-
-use super::label_of_ty;
+use crate::{
+    inlay_hints::hint_iterator, FileId, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip,
+};
 
 pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
     sema: &Semantics<'_, RootDatabase>,
+    famous_defs: &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
     file_id: FileId,
     expr: &ast::Expr,
@@ -61,7 +62,9 @@ pub(super) fn hints(
             acc.push(InlayHint {
                 range: expr.syntax().text_range(),
                 kind: InlayKind::ChainingHint,
-                label: label_of_ty(sema, desc_expr, config, ty)?,
+                label: hint_iterator(sema, &famous_defs, config, &ty)
+                    .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string())
+                    .into(),
                 tooltip: Some(InlayTooltip::HoverRanged(file_id, expr.syntax().text_range())),
             });
         }
@@ -74,10 +77,7 @@ mod tests {
     use expect_test::expect;
 
     use crate::{
-        inlay_hints::tests::{
-            check_expect, check_with_config, DISABLED_CONFIG, DISABLED_CONFIG_WITH_LINKS,
-            TEST_CONFIG,
-        },
+        inlay_hints::tests::{check_expect, check_with_config, DISABLED_CONFIG, TEST_CONFIG},
         InlayHintsConfig,
     };
 
@@ -89,11 +89,7 @@ mod tests {
     #[test]
     fn chaining_hints_ignore_comments() {
         check_expect(
-            InlayHintsConfig {
-                type_hints: false,
-                chaining_hints: true,
-                ..DISABLED_CONFIG_WITH_LINKS
-            },
+            InlayHintsConfig { type_hints: false, chaining_hints: true, ..DISABLED_CONFIG },
             r#"
 struct A(B);
 impl A { fn into_b(self) -> B { self.0 } }
@@ -114,19 +110,7 @@ fn main() {
                         range: 147..172,
                         kind: ChainingHint,
                         label: [
-                            "",
-                            InlayHintLabelPart {
-                                text: "B",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 63..64,
-                                    },
-                                ),
-                            },
-                            "",
+                            "B",
                         ],
                         tooltip: Some(
                             HoverRanged(
@@ -141,19 +125,7 @@ fn main() {
                         range: 147..154,
                         kind: ChainingHint,
                         label: [
-                            "",
-                            InlayHintLabelPart {
-                                text: "A",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 7..8,
-                                    },
-                                ),
-                            },
-                            "",
+                            "A",
                         ],
                         tooltip: Some(
                             HoverRanged(
@@ -185,69 +157,10 @@ fn main() {
         );
     }
 
-    #[test]
-    fn disabled_location_links() {
-        check_expect(
-            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG },
-            r#"
-    struct A { pub b: B }
-    struct B { pub c: C }
-    struct C(pub bool);
-    struct D;
-
-    impl D {
-        fn foo(&self) -> i32 { 42 }
-    }
-
-    fn main() {
-        let x = A { b: B { c: C(true) } }
-            .b
-            .c
-            .0;
-        let x = D
-            .foo();
-    }"#,
-            expect![[r#"
-                [
-                    InlayHint {
-                        range: 143..190,
-                        kind: ChainingHint,
-                        label: [
-                            "C",
-                        ],
-                        tooltip: Some(
-                            HoverRanged(
-                                FileId(
-                                    0,
-                                ),
-                                143..190,
-                            ),
-                        ),
-                    },
-                    InlayHint {
-                        range: 143..179,
-                        kind: ChainingHint,
-                        label: [
-                            "B",
-                        ],
-                        tooltip: Some(
-                            HoverRanged(
-                                FileId(
-                                    0,
-                                ),
-                                143..179,
-                            ),
-                        ),
-                    },
-                ]
-            "#]],
-        );
-    }
-
     #[test]
     fn struct_access_chaining_hints() {
         check_expect(
-            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS },
+            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG },
             r#"
 struct A { pub b: B }
 struct B { pub c: C }
@@ -272,19 +185,7 @@ fn main() {
                         range: 143..190,
                         kind: ChainingHint,
                         label: [
-                            "",
-                            InlayHintLabelPart {
-                                text: "C",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 51..52,
-                                    },
-                                ),
-                            },
-                            "",
+                            "C",
                         ],
                         tooltip: Some(
                             HoverRanged(
@@ -299,19 +200,7 @@ fn main() {
                         range: 143..179,
                         kind: ChainingHint,
                         label: [
-                            "",
-                            InlayHintLabelPart {
-                                text: "B",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 29..30,
-                                    },
-                                ),
-                            },
-                            "",
+                            "B",
                         ],
                         tooltip: Some(
                             HoverRanged(
@@ -330,7 +219,7 @@ fn main() {
     #[test]
     fn generic_chaining_hints() {
         check_expect(
-            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS },
+            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG },
             r#"
 struct A<T>(T);
 struct B<T>(T);
@@ -356,31 +245,7 @@ fn main() {
                         range: 246..283,
                         kind: ChainingHint,
                         label: [
-                            "",
-                            InlayHintLabelPart {
-                                text: "B",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 23..24,
-                                    },
-                                ),
-                            },
-                            "<",
-                            InlayHintLabelPart {
-                                text: "X",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 55..56,
-                                    },
-                                ),
-                            },
-                            "<i32, bool>>",
+                            "B<X<i32, bool>>",
                         ],
                         tooltip: Some(
                             HoverRanged(
@@ -395,31 +260,7 @@ fn main() {
                         range: 246..265,
                         kind: ChainingHint,
                         label: [
-                            "",
-                            InlayHintLabelPart {
-                                text: "A",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 7..8,
-                                    },
-                                ),
-                            },
-                            "<",
-                            InlayHintLabelPart {
-                                text: "X",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 55..56,
-                                    },
-                                ),
-                            },
-                            "<i32, bool>>",
+                            "A<X<i32, bool>>",
                         ],
                         tooltip: Some(
                             HoverRanged(
@@ -438,7 +279,7 @@ fn main() {
     #[test]
     fn shorten_iterator_chaining_hints() {
         check_expect(
-            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG_WITH_LINKS },
+            InlayHintsConfig { chaining_hints: true, ..DISABLED_CONFIG },
             r#"
 //- minicore: iterators
 use core::iter;
@@ -511,19 +352,7 @@ fn main() {
                         range: 174..189,
                         kind: ChainingHint,
                         label: [
-                            "&mut ",
-                            InlayHintLabelPart {
-                                text: "MyIter",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 24..30,
-                                    },
-                                ),
-                            },
-                            "",
+                            "&mut MyIter",
                         ],
                         tooltip: Some(
                             HoverRanged(
@@ -567,19 +396,7 @@ fn main() {
                         range: 124..130,
                         kind: TypeHint,
                         label: [
-                            "",
-                            InlayHintLabelPart {
-                                text: "Struct",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 7..13,
-                                    },
-                                ),
-                            },
-                            "",
+                            "Struct",
                         ],
                         tooltip: Some(
                             HoverRanged(
@@ -594,19 +411,7 @@ fn main() {
                         range: 145..185,
                         kind: ChainingHint,
                         label: [
-                            "",
-                            InlayHintLabelPart {
-                                text: "Struct",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 7..13,
-                                    },
-                                ),
-                            },
-                            "",
+                            "Struct",
                         ],
                         tooltip: Some(
                             HoverRanged(
@@ -621,19 +426,7 @@ fn main() {
                         range: 145..168,
                         kind: ChainingHint,
                         label: [
-                            "",
-                            InlayHintLabelPart {
-                                text: "Struct",
-                                linked_location: Some(
-                                    FileRange {
-                                        file_id: FileId(
-                                            0,
-                                        ),
-                                        range: 7..13,
-                                    },
-                                ),
-                            },
-                            "",
+                            "Struct",
                         ],
                         tooltip: Some(
                             HoverRanged(
diff --git a/crates/ide/src/inlay_hints/closing_brace.rs b/crates/ide/src/inlay_hints/closing_brace.rs
index e340c64c54..57605b392a 100644
--- a/crates/ide/src/inlay_hints/closing_brace.rs
+++ b/crates/ide/src/inlay_hints/closing_brace.rs
@@ -109,10 +109,7 @@ pub(super) fn hints(
         return None;
     }
 
-    let linked_location = config
-        .location_links
-        .then(|| name_range.map(|range| FileRange { file_id, range }))
-        .flatten();
+    let linked_location = name_range.map(|range| FileRange { file_id, range });
     acc.push(InlayHint {
         range: closing_token.text_range(),
         kind: InlayKind::ClosingBraceHint,
diff --git a/crates/ide/src/inlay_hints/closure_ret.rs b/crates/ide/src/inlay_hints/closure_ret.rs
index 247a4abcc5..de04f3ac75 100644
--- a/crates/ide/src/inlay_hints/closure_ret.rs
+++ b/crates/ide/src/inlay_hints/closure_ret.rs
@@ -1,18 +1,17 @@
 //! Implementation of "closure return type" inlay hints.
-use hir::Semantics;
-use ide_db::{base_db::FileId, RootDatabase};
+use hir::{HirDisplay, Semantics};
+use ide_db::{base_db::FileId, famous_defs::FamousDefs, RootDatabase};
 use syntax::ast::{self, AstNode};
 
 use crate::{
-    inlay_hints::closure_has_block_body, ClosureReturnTypeHints, InlayHint, InlayHintsConfig,
-    InlayKind, InlayTooltip,
+    inlay_hints::{closure_has_block_body, hint_iterator},
+    ClosureReturnTypeHints, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip,
 };
 
-use super::label_of_ty;
-
 pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
     sema: &Semantics<'_, RootDatabase>,
+    famous_defs: &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
     file_id: FileId,
     closure: ast::ClosureExpr,
@@ -43,7 +42,9 @@ pub(super) fn hints(
     acc.push(InlayHint {
         range: param_list.syntax().text_range(),
         kind: InlayKind::ClosureReturnTypeHint,
-        label: label_of_ty(sema, &param_list, config, ty)?,
+        label: hint_iterator(sema, &famous_defs, config, &ty)
+            .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string())
+            .into(),
         tooltip: Some(InlayTooltip::HoverRanged(file_id, param_list.syntax().text_range())),
     });
     Some(())
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 6698bf766a..7402e86f36 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -236,7 +236,6 @@ impl Analysis {
             Ok(Vec::new()),
             false,
             CrateOrigin::CratesIo { repo: None, name: None },
-            None,
         );
         change.change_file(file_id, Some(Arc::new(text)));
         change.set_crate_graph(crate_graph);
diff --git a/crates/ide/src/shuffle_crate_graph.rs b/crates/ide/src/shuffle_crate_graph.rs
index ae539a5d39..2d86627643 100644
--- a/crates/ide/src/shuffle_crate_graph.rs
+++ b/crates/ide/src/shuffle_crate_graph.rs
@@ -36,7 +36,6 @@ pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) {
             data.proc_macro.clone(),
             data.is_proc_macro,
             data.origin.clone(),
-            data.target_layout.clone(),
         );
         map.insert(old_id, new_id);
     }
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index 42b5951c84..4f1946ed48 100644
--- a/crates/ide/src/static_index.rs
+++ b/crates/ide/src/static_index.rs
@@ -106,7 +106,6 @@ impl StaticIndex<'_> {
             .analysis
             .inlay_hints(
                 &InlayHintsConfig {
-                    location_links: true,
                     render_colons: true,
                     type_hints: true,
                     parameter_hints: true,
@@ -114,6 +113,7 @@ impl StaticIndex<'_> {
                     closure_return_type_hints: crate::ClosureReturnTypeHints::WithBlock,
                     lifetime_elision_hints: crate::LifetimeElisionHints::Never,
                     adjustment_hints: crate::AdjustmentHints::Never,
+                    adjustment_hints_hide_outside_unsafe: false,
                     hide_named_constructor_hints: false,
                     hide_closure_initialization_hints: false,
                     param_names_for_lifetime_elision_hints: false,
diff --git a/crates/project-model/src/lib.rs b/crates/project-model/src/lib.rs
index 835f2b3dd0..575581fa54 100644
--- a/crates/project-model/src/lib.rs
+++ b/crates/project-model/src/lib.rs
@@ -25,7 +25,6 @@ mod sysroot;
 mod workspace;
 mod rustc_cfg;
 mod build_scripts;
-mod target_data_layout;
 
 #[cfg(test)]
 mod tests;
diff --git a/crates/project-model/src/rustc_cfg.rs b/crates/project-model/src/rustc_cfg.rs
index 12c8cf70dc..3231361836 100644
--- a/crates/project-model/src/rustc_cfg.rs
+++ b/crates/project-model/src/rustc_cfg.rs
@@ -50,7 +50,7 @@ fn get_rust_cfgs(
         cargo_config.envs(extra_env);
         cargo_config
             .current_dir(cargo_toml.parent())
-            .args(&["rustc", "-Z", "unstable-options", "--print", "cfg"])
+            .args(&["-Z", "unstable-options", "rustc", "--print", "cfg"])
             .env("RUSTC_BOOTSTRAP", "1");
         if let Some(target) = target {
             cargo_config.args(&["--target", target]);
diff --git a/crates/project-model/src/target_data_layout.rs b/crates/project-model/src/target_data_layout.rs
deleted file mode 100644
index b9d7d2338c..0000000000
--- a/crates/project-model/src/target_data_layout.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-//! Runs `rustc --print target-spec-json` to get the target_data_layout.
-use std::process::Command;
-
-use rustc_hash::FxHashMap;
-
-use crate::{utf8_stdout, ManifestPath};
-
-pub(super) fn get(
-    cargo_toml: Option<&ManifestPath>,
-    target: Option<&str>,
-    extra_env: &FxHashMap<String, String>,
-) -> Option<String> {
-    let output = (|| {
-        if let Some(cargo_toml) = cargo_toml {
-            let mut cmd = Command::new(toolchain::rustc());
-            cmd.envs(extra_env);
-            cmd.current_dir(cargo_toml.parent())
-                .args(&["-Z", "unstable-options", "rustc", "--print", "target-spec-json"])
-                .env("RUSTC_BOOTSTRAP", "1");
-            if let Some(target) = target {
-                cmd.args(&["--target", target]);
-            }
-            match utf8_stdout(cmd) {
-                Ok(it) => return Ok(it),
-                Err(e) => tracing::debug!("{e:?}: falling back to querying rustc for cfgs"),
-            }
-        }
-        // using unstable cargo features failed, fall back to using plain rustc
-        let mut cmd = Command::new(toolchain::rustc());
-        cmd.envs(extra_env)
-            .args(&["-Z", "unstable-options", "rustc", "--print", "target-spec-json"])
-            .env("RUSTC_BOOTSTRAP", "1");
-        if let Some(target) = target {
-            cmd.args(&["--target", target]);
-        }
-        utf8_stdout(cmd)
-    })()
-    .ok()?;
-    Some(output.split_once(r#""data-layout": ""#)?.1.split_once('"')?.0.to_owned())
-}
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index 52ac3b6dc0..aa54342e39 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -21,8 +21,8 @@ use crate::{
     cfg_flag::CfgFlag,
     rustc_cfg,
     sysroot::SysrootCrate,
-    target_data_layout, utf8_stdout, CargoConfig, CargoWorkspace, InvocationStrategy, ManifestPath,
-    Package, ProjectJson, ProjectManifest, Sysroot, TargetKind, WorkspaceBuildScripts,
+    utf8_stdout, CargoConfig, CargoWorkspace, InvocationStrategy, ManifestPath, Package,
+    ProjectJson, ProjectManifest, Sysroot, TargetKind, WorkspaceBuildScripts,
 };
 
 /// A set of cfg-overrides per crate.
@@ -79,7 +79,6 @@ pub enum ProjectWorkspace {
         rustc_cfg: Vec<CfgFlag>,
         cfg_overrides: CfgOverrides,
         toolchain: Option<Version>,
-        target_layout: Option<String>,
     },
     /// Project workspace was manually specified using a `rust-project.json` file.
     Json { project: ProjectJson, sysroot: Option<Sysroot>, rustc_cfg: Vec<CfgFlag> },
@@ -109,7 +108,6 @@ impl fmt::Debug for ProjectWorkspace {
                 rustc_cfg,
                 cfg_overrides,
                 toolchain,
-                target_layout: data_layout,
             } => f
                 .debug_struct("Cargo")
                 .field("root", &cargo.workspace_root().file_name())
@@ -122,7 +120,6 @@ impl fmt::Debug for ProjectWorkspace {
                 .field("n_rustc_cfg", &rustc_cfg.len())
                 .field("n_cfg_overrides", &cfg_overrides.len())
                 .field("toolchain", &toolchain)
-                .field("data_layout", &data_layout)
                 .finish(),
             ProjectWorkspace::Json { project, sysroot, rustc_cfg } => {
                 let mut debug_struct = f.debug_struct("Json");
@@ -244,11 +241,6 @@ impl ProjectWorkspace {
                     rustc_cfg::get(Some(&cargo_toml), config.target.as_deref(), &config.extra_env);
 
                 let cfg_overrides = config.cfg_overrides();
-                let data_layout = target_data_layout::get(
-                    Some(&cargo_toml),
-                    config.target.as_deref(),
-                    &config.extra_env,
-                );
                 ProjectWorkspace::Cargo {
                     cargo,
                     build_scripts: WorkspaceBuildScripts::default(),
@@ -257,7 +249,6 @@ impl ProjectWorkspace {
                     rustc_cfg,
                     cfg_overrides,
                     toolchain,
-                    target_layout: data_layout,
                 }
             }
         };
@@ -444,7 +435,6 @@ impl ProjectWorkspace {
                 cfg_overrides: _,
                 build_scripts,
                 toolchain: _,
-                target_layout: _,
             } => {
                 cargo
                     .packages()
@@ -540,7 +530,6 @@ impl ProjectWorkspace {
                 project,
                 sysroot,
                 extra_env,
-                None,
             ),
             ProjectWorkspace::Cargo {
                 cargo,
@@ -550,7 +539,6 @@ impl ProjectWorkspace {
                 cfg_overrides,
                 build_scripts,
                 toolchain: _,
-                target_layout,
             } => cargo_to_crate_graph(
                 load_proc_macro,
                 load,
@@ -560,10 +548,9 @@ impl ProjectWorkspace {
                 rustc_cfg.clone(),
                 cfg_overrides,
                 build_scripts,
-                target_layout.as_deref().map(Arc::from),
             ),
             ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => {
-                detached_files_to_crate_graph(rustc_cfg.clone(), load, files, sysroot, None)
+                detached_files_to_crate_graph(rustc_cfg.clone(), load, files, sysroot)
             }
         };
         if crate_graph.patch_cfg_if() {
@@ -582,18 +569,11 @@ fn project_json_to_crate_graph(
     project: &ProjectJson,
     sysroot: &Option<Sysroot>,
     extra_env: &FxHashMap<String, String>,
-    target_layout: Option<Arc<str>>,
 ) -> CrateGraph {
     let mut crate_graph = CrateGraph::default();
-    let sysroot_deps = sysroot.as_ref().map(|sysroot| {
-        sysroot_to_crate_graph(
-            &mut crate_graph,
-            sysroot,
-            rustc_cfg.clone(),
-            target_layout.clone(),
-            load,
-        )
-    });
+    let sysroot_deps = sysroot
+        .as_ref()
+        .map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load));
 
     let mut cfg_cache: FxHashMap<&str, Vec<CfgFlag>> = FxHashMap::default();
     let crates: NoHashHashMap<CrateId, CrateId> = project
@@ -645,7 +625,6 @@ fn project_json_to_crate_graph(
                     } else {
                         CrateOrigin::CratesIo { repo: None, name: None }
                     },
-                    target_layout.clone(),
                 ),
             )
         })
@@ -686,18 +665,11 @@ fn cargo_to_crate_graph(
     rustc_cfg: Vec<CfgFlag>,
     override_cfg: &CfgOverrides,
     build_scripts: &WorkspaceBuildScripts,
-    target_layout: Option<Arc<str>>,
 ) -> CrateGraph {
     let _p = profile::span("cargo_to_crate_graph");
     let mut crate_graph = CrateGraph::default();
     let (public_deps, libproc_macro) = match sysroot {
-        Some(sysroot) => sysroot_to_crate_graph(
-            &mut crate_graph,
-            sysroot,
-            rustc_cfg.clone(),
-            target_layout.clone(),
-            load,
-        ),
+        Some(sysroot) => sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load),
         None => (SysrootPublicDeps::default(), None),
     };
 
@@ -760,7 +732,6 @@ fn cargo_to_crate_graph(
                     file_id,
                     &cargo[tgt].name,
                     cargo[tgt].is_proc_macro,
-                    target_layout.clone(),
                 );
                 if cargo[tgt].kind == TargetKind::Lib {
                     lib_tgt = Some((crate_id, cargo[tgt].name.clone()));
@@ -840,7 +811,6 @@ fn cargo_to_crate_graph(
                 &cfg_options,
                 override_cfg,
                 build_scripts,
-                target_layout,
             );
         }
     }
@@ -852,18 +822,11 @@ fn detached_files_to_crate_graph(
     load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
     detached_files: &[AbsPathBuf],
     sysroot: &Option<Sysroot>,
-    target_layout: Option<Arc<str>>,
 ) -> CrateGraph {
     let _p = profile::span("detached_files_to_crate_graph");
     let mut crate_graph = CrateGraph::default();
     let (public_deps, _libproc_macro) = match sysroot {
-        Some(sysroot) => sysroot_to_crate_graph(
-            &mut crate_graph,
-            sysroot,
-            rustc_cfg.clone(),
-            target_layout.clone(),
-            load,
-        ),
+        Some(sysroot) => sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load),
         None => (SysrootPublicDeps::default(), None),
     };
 
@@ -896,7 +859,6 @@ fn detached_files_to_crate_graph(
                 repo: None,
                 name: display_name.map(|n| n.canonical_name().to_string()),
             },
-            target_layout.clone(),
         );
 
         public_deps.add_to_crate_graph(&mut crate_graph, detached_file_crate);
@@ -917,7 +879,6 @@ fn handle_rustc_crates(
     cfg_options: &CfgOptions,
     override_cfg: &CfgOverrides,
     build_scripts: &WorkspaceBuildScripts,
-    target_layout: Option<Arc<str>>,
 ) {
     let mut rustc_pkg_crates = FxHashMap::default();
     // The root package of the rustc-dev component is rustc_driver, so we match that
@@ -974,7 +935,6 @@ fn handle_rustc_crates(
                         file_id,
                         &rustc_workspace[tgt].name,
                         rustc_workspace[tgt].is_proc_macro,
-                        target_layout.clone(),
                     );
                     pkg_to_lib_crate.insert(pkg, crate_id);
                     // Add dependencies on core / std / alloc for this crate
@@ -1039,7 +999,6 @@ fn add_target_crate_root(
     file_id: FileId,
     cargo_name: &str,
     is_proc_macro: bool,
-    target_layout: Option<Arc<str>>,
 ) -> CrateId {
     let edition = pkg.edition;
     let mut potential_cfg_options = cfg_options.clone();
@@ -1086,7 +1045,6 @@ fn add_target_crate_root(
         proc_macro,
         is_proc_macro,
         CrateOrigin::CratesIo { repo: pkg.repository.clone(), name: Some(pkg.name.clone()) },
-        target_layout,
     )
 }
 
@@ -1108,7 +1066,6 @@ fn sysroot_to_crate_graph(
     crate_graph: &mut CrateGraph,
     sysroot: &Sysroot,
     rustc_cfg: Vec<CfgFlag>,
-    target_layout: Option<Arc<str>>,
     load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
 ) -> (SysrootPublicDeps, Option<CrateId>) {
     let _p = profile::span("sysroot_to_crate_graph");
@@ -1132,7 +1089,6 @@ fn sysroot_to_crate_graph(
                 Err("no proc macro loaded for sysroot crate".into()),
                 false,
                 CrateOrigin::Lang(LangCrateOrigin::from(&*sysroot[krate].name)),
-                target_layout.clone(),
             );
             Some((krate, crate_id))
         })
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index ec5053e991..7bf595d2a4 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -183,8 +183,6 @@ fn run_server() -> Result<()> {
         }
     }
 
-    config.client_specific_adjustments(&initialize_params.client_info);
-
     let server_capabilities = rust_analyzer::server_capabilities(&config);
 
     let initialize_result = lsp_types::InitializeResult {
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 0bcc91eb41..35d0d8f977 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -20,7 +20,7 @@ use ide_db::{
     SnippetCap,
 };
 use itertools::Itertools;
-use lsp_types::{ClientCapabilities, ClientInfo, MarkupKind};
+use lsp_types::{ClientCapabilities, MarkupKind};
 use project_model::{
     CargoConfig, CargoFeatures, ProjectJson, ProjectJsonData, ProjectManifest, RustcSource,
     UnsetTestCrates,
@@ -329,12 +329,12 @@ config_data! {
         inlayHints_closureReturnTypeHints_enable: ClosureReturnTypeHintsDef  = "\"never\"",
         /// Whether to show inlay hints for type adjustments.
         inlayHints_expressionAdjustmentHints_enable: AdjustmentHintsDef = "\"never\"",
+        /// Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.
+        inlayHints_expressionAdjustmentHints_hideOutsideUnsafe: bool = "false",
         /// Whether to show inlay type hints for elided lifetimes in function signatures.
         inlayHints_lifetimeElisionHints_enable: LifetimeElisionDef = "\"never\"",
         /// Whether to prefer using parameter names as the name for elided lifetime hints if possible.
         inlayHints_lifetimeElisionHints_useParameterNames: bool    = "false",
-        /// Whether to use location links for parts of type mentioned in inlay hints.
-        inlayHints_locationLinks: bool                             = "true",
         /// Maximum length for inlay hints. Set to null to have an unlimited length.
         inlayHints_maxLength: Option<usize>                        = "25",
         /// Whether to show function parameter name inlay hints at the call
@@ -716,19 +716,6 @@ impl Config {
         }
     }
 
-    pub fn client_specific_adjustments(&mut self, client_info: &Option<ClientInfo>) {
-        // FIXME: remove this when we drop support for vscode 1.65 and below
-        if let Some(client) = client_info {
-            if client.name.contains("Code") || client.name.contains("Codium") {
-                if let Some(version) = &client.version {
-                    if version.as_str() < "1.76" {
-                        self.data.inlayHints_locationLinks = false;
-                    }
-                }
-            }
-        }
-    }
-
     pub fn update(&mut self, mut json: serde_json::Value) -> Result<(), ConfigUpdateError> {
         tracing::info!("updating config from JSON: {:#}", json);
         if json.is_null() || json.as_object().map_or(false, |it| it.is_empty()) {
@@ -1211,7 +1198,6 @@ impl Config {
 
     pub fn inlay_hints(&self) -> InlayHintsConfig {
         InlayHintsConfig {
-            location_links: self.data.inlayHints_locationLinks,
             render_colons: self.data.inlayHints_renderColons,
             type_hints: self.data.inlayHints_typeHints_enable,
             parameter_hints: self.data.inlayHints_parameterHints_enable,
@@ -1240,6 +1226,9 @@ impl Config {
                 },
                 AdjustmentHintsDef::Reborrow => ide::AdjustmentHints::ReborrowOnly,
             },
+            adjustment_hints_hide_outside_unsafe: self
+                .data
+                .inlayHints_expressionAdjustmentHints_hideOutsideUnsafe,
             binding_mode_hints: self.data.inlayHints_bindingModeHints_enable,
             param_names_for_lifetime_elision_hints: self
                 .data
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index faf7a2c213..3e7664d7d3 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -226,7 +226,6 @@ impl GlobalState {
 
                     build_scripts: _,
                     toolchain: _,
-                    target_layout: _,
                 } => Some((cargo, sysroot, rustc, rustc_cfg, cfg_overrides)),
                 _ => None,
             };
diff --git a/docs/dev/README.md b/docs/dev/README.md
index cdab6b0992..4ac75b4bbf 100644
--- a/docs/dev/README.md
+++ b/docs/dev/README.md
@@ -200,7 +200,7 @@ Look for `fn benchmark_xxx` tests for a quick way to reproduce performance probl
 
 ## Release Process
 
-Release process is handled by `release`, `dist`, `publish-release-notes` and `promote` xtasks, `release` being the main one.
+Release process is handled by `release`, `dist` and `promote` xtasks, `release` being the main one.
 
 `release` assumes that you have checkouts of `rust-analyzer`, `rust-analyzer.github.io`, and `rust-lang/rust` in the same directory:
 
@@ -231,9 +231,8 @@ Release steps:
    * create a new changelog in `rust-analyzer.github.io`
 3. While the release is in progress, fill in the changelog
 4. Commit & push the changelog
-5. Run `cargo xtask publish-release-notes <CHANGELOG>` -- this will convert the changelog entry in AsciiDoc to Markdown and update the body of GitHub Releases entry.
-6. Tweet
-7. Inside `rust-analyzer`, run `cargo xtask promote` -- this will create a PR to rust-lang/rust updating rust-analyzer's subtree.
+5. Tweet
+6. Inside `rust-analyzer`, run `cargo xtask promote` -- this will create a PR to rust-lang/rust updating rust-analyzer's subtree.
    Self-approve the PR.
 
 If the GitHub Actions release fails because of a transient problem like a timeout, you can re-run the job from the Actions console.
diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc
index 47511aad0f..7cff2cbb6a 100644
--- a/docs/user/generated_config.adoc
+++ b/docs/user/generated_config.adoc
@@ -459,6 +459,11 @@ Whether to show inlay type hints for return types of closures.
 --
 Whether to show inlay hints for type adjustments.
 --
+[[rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe]]rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe (default: `false`)::
++
+--
+Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.
+--
 [[rust-analyzer.inlayHints.lifetimeElisionHints.enable]]rust-analyzer.inlayHints.lifetimeElisionHints.enable (default: `"never"`)::
 +
 --
@@ -469,11 +474,6 @@ Whether to show inlay type hints for elided lifetimes in function signatures.
 --
 Whether to prefer using parameter names as the name for elided lifetime hints if possible.
 --
-[[rust-analyzer.inlayHints.locationLinks]]rust-analyzer.inlayHints.locationLinks (default: `true`)::
-+
---
-Whether to use location links for parts of type mentioned in inlay hints.
---
 [[rust-analyzer.inlayHints.maxLength]]rust-analyzer.inlayHints.maxLength (default: `25`)::
 +
 --
diff --git a/editors/code/package.json b/editors/code/package.json
index 5b09ee6f7d..21d65321d2 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -975,6 +975,11 @@
                         "Only show auto borrow and dereference adjustment hints."
                     ]
                 },
+                "rust-analyzer.inlayHints.expressionAdjustmentHints.hideOutsideUnsafe": {
+                    "markdownDescription": "Whether to hide inlay hints for type adjustments outside of `unsafe` blocks.",
+                    "default": false,
+                    "type": "boolean"
+                },
                 "rust-analyzer.inlayHints.lifetimeElisionHints.enable": {
                     "markdownDescription": "Whether to show inlay type hints for elided lifetimes in function signatures.",
                     "default": "never",
@@ -995,11 +1000,6 @@
                     "default": false,
                     "type": "boolean"
                 },
-                "rust-analyzer.inlayHints.locationLinks": {
-                    "markdownDescription": "Whether to use location links for parts of type mentioned in inlay hints.",
-                    "default": true,
-                    "type": "boolean"
-                },
                 "rust-analyzer.inlayHints.maxLength": {
                     "markdownDescription": "Maximum length for inlay hints. Set to null to have an unlimited length.",
                     "default": 25,
diff --git a/xtask/src/flags.rs b/xtask/src/flags.rs
index 2100479701..0fce488983 100644
--- a/xtask/src/flags.rs
+++ b/xtask/src/flags.rs
@@ -34,13 +34,6 @@ xflags::xflags! {
         cmd dist {
             optional --client-patch-version version: String
         }
-        /// Read a changelog AsciiDoc file and update the GitHub Releases entry in Markdown.
-        cmd publish-release-notes {
-            /// Only run conversion and show the result.
-            optional --dry-run
-            /// Target changelog file.
-            required changelog: String
-        }
         cmd metrics {
             optional --dry-run
         }
@@ -66,7 +59,6 @@ pub enum XtaskCmd {
     Release(Release),
     Promote(Promote),
     Dist(Dist),
-    PublishReleaseNotes(PublishReleaseNotes),
     Metrics(Metrics),
     Bb(Bb),
 }
@@ -98,13 +90,6 @@ pub struct Dist {
     pub client_patch_version: Option<String>,
 }
 
-#[derive(Debug)]
-pub struct PublishReleaseNotes {
-    pub changelog: String,
-
-    pub dry_run: bool,
-}
-
 #[derive(Debug)]
 pub struct Metrics {
     pub dry_run: bool,
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
index 6a45033ada..a37f469adc 100644
--- a/xtask/src/main.rs
+++ b/xtask/src/main.rs
@@ -15,7 +15,6 @@ mod flags;
 mod install;
 mod release;
 mod dist;
-mod publish;
 mod metrics;
 
 use anyhow::bail;
@@ -37,7 +36,6 @@ fn main() -> anyhow::Result<()> {
         flags::XtaskCmd::Release(cmd) => cmd.run(sh),
         flags::XtaskCmd::Promote(cmd) => cmd.run(sh),
         flags::XtaskCmd::Dist(cmd) => cmd.run(sh),
-        flags::XtaskCmd::PublishReleaseNotes(cmd) => cmd.run(sh),
         flags::XtaskCmd::Metrics(cmd) => cmd.run(sh),
         flags::XtaskCmd::Bb(cmd) => {
             {
diff --git a/xtask/src/publish.rs b/xtask/src/publish.rs
deleted file mode 100644
index 79b5f3d2f6..0000000000
--- a/xtask/src/publish.rs
+++ /dev/null
@@ -1,109 +0,0 @@
-mod notes;
-
-use crate::flags;
-use anyhow::{anyhow, bail, Result};
-use std::env;
-use xshell::{cmd, Shell};
-
-impl flags::PublishReleaseNotes {
-    pub(crate) fn run(self, sh: &Shell) -> Result<()> {
-        let asciidoc = sh.read_file(&self.changelog)?;
-        let mut markdown = notes::convert_asciidoc_to_markdown(std::io::Cursor::new(&asciidoc))?;
-        let file_name = check_file_name(self.changelog)?;
-        let tag_name = &file_name[0..10];
-        let original_changelog_url = create_original_changelog_url(&file_name);
-        let additional_paragraph =
-            format!("\nSee also [original changelog]({original_changelog_url}).");
-        markdown.push_str(&additional_paragraph);
-        if self.dry_run {
-            println!("{markdown}");
-        } else {
-            update_release(sh, tag_name, &markdown)?;
-        }
-        Ok(())
-    }
-}
-
-fn check_file_name<P: AsRef<std::path::Path>>(path: P) -> Result<String> {
-    let file_name = path
-        .as_ref()
-        .file_name()
-        .ok_or_else(|| anyhow!("file name is not specified as `changelog`"))?
-        .to_string_lossy();
-
-    let mut chars = file_name.chars();
-    if file_name.len() >= 10
-        && chars.next().unwrap().is_ascii_digit()
-        && chars.next().unwrap().is_ascii_digit()
-        && chars.next().unwrap().is_ascii_digit()
-        && chars.next().unwrap().is_ascii_digit()
-        && chars.next().unwrap() == '-'
-        && chars.next().unwrap().is_ascii_digit()
-        && chars.next().unwrap().is_ascii_digit()
-        && chars.next().unwrap() == '-'
-        && chars.next().unwrap().is_ascii_digit()
-        && chars.next().unwrap().is_ascii_digit()
-    {
-        Ok(file_name.to_string())
-    } else {
-        bail!("unexpected file name format; no date information prefixed")
-    }
-}
-
-fn create_original_changelog_url(file_name: &str) -> String {
-    let year = &file_name[0..4];
-    let month = &file_name[5..7];
-    let day = &file_name[8..10];
-    let mut stem = &file_name[11..];
-    if let Some(stripped) = stem.strip_suffix(".adoc") {
-        stem = stripped;
-    }
-    format!("https://rust-analyzer.github.io/thisweek/{year}/{month}/{day}/{stem}.html")
-}
-
-fn update_release(sh: &Shell, tag_name: &str, release_notes: &str) -> Result<()> {
-    let token = match env::var("GITHUB_TOKEN") {
-        Ok(token) => token,
-        Err(_) => bail!("Please obtain a personal access token from https://github.com/settings/tokens and set the `GITHUB_TOKEN` environment variable."),
-    };
-    let accept = "Accept: application/vnd.github+json";
-    let authorization = format!("Authorization: Bearer {token}");
-    let api_version = "X-GitHub-Api-Version: 2022-11-28";
-    let release_url = "https://api.github.com/repos/rust-lang/rust-analyzer/releases";
-
-    let release_json = cmd!(
-        sh,
-        "curl -sf -H {accept} -H {authorization} -H {api_version} {release_url}/tags/{tag_name}"
-    )
-    .read()?;
-    let release_id = cmd!(sh, "jq .id").stdin(release_json).read()?;
-
-    let mut patch = String::new();
-    write_json::object(&mut patch)
-        .string("tag_name", tag_name)
-        .string("target_commitish", "master")
-        .string("name", tag_name)
-        .string("body", release_notes)
-        .bool("draft", false)
-        .bool("prerelease", false);
-    let _ = cmd!(
-        sh,
-        "curl -sf -X PATCH -H {accept} -H {authorization} -H {api_version} {release_url}/{release_id} -d {patch}"
-    )
-    .read()?;
-
-    Ok(())
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn original_changelog_url_creation() {
-        let input = "2019-07-24-changelog-0.adoc";
-        let actual = create_original_changelog_url(input);
-        let expected = "https://rust-analyzer.github.io/thisweek/2019/07/24/changelog-0.html";
-        assert_eq!(actual, expected);
-    }
-}
diff --git a/xtask/src/publish/notes.rs b/xtask/src/publish/notes.rs
deleted file mode 100644
index c30267295b..0000000000
--- a/xtask/src/publish/notes.rs
+++ /dev/null
@@ -1,631 +0,0 @@
-use anyhow::{anyhow, bail};
-use std::{
-    borrow::Cow,
-    io::{BufRead, Lines},
-    iter::Peekable,
-};
-
-const LISTING_DELIMITER: &str = "----";
-const IMAGE_BLOCK_PREFIX: &str = "image::";
-const VIDEO_BLOCK_PREFIX: &str = "video::";
-
-struct Converter<'a, 'b, R: BufRead> {
-    iter: &'a mut Peekable<Lines<R>>,
-    output: &'b mut String,
-}
-
-impl<'a, 'b, R: BufRead> Converter<'a, 'b, R> {
-    fn new(iter: &'a mut Peekable<Lines<R>>, output: &'b mut String) -> Self {
-        Self { iter, output }
-    }
-
-    fn process(&mut self) -> anyhow::Result<()> {
-        self.process_document_header()?;
-        self.skip_blank_lines()?;
-        self.output.push('\n');
-
-        loop {
-            let line = self.iter.peek().unwrap().as_deref().map_err(|e| anyhow!("{e}"))?;
-            if get_title(line).is_some() {
-                let line = self.iter.next().unwrap().unwrap();
-                let (level, title) = get_title(&line).unwrap();
-                self.write_title(level, title);
-            } else if get_list_item(line).is_some() {
-                self.process_list()?;
-            } else if line.starts_with('[') {
-                self.process_source_code_block(0)?;
-            } else if line.starts_with(LISTING_DELIMITER) {
-                self.process_listing_block(None, 0)?;
-            } else if line.starts_with('.') {
-                self.process_block_with_title(0)?;
-            } else if line.starts_with(IMAGE_BLOCK_PREFIX) {
-                self.process_image_block(None, 0)?;
-            } else if line.starts_with(VIDEO_BLOCK_PREFIX) {
-                self.process_video_block(None, 0)?;
-            } else {
-                self.process_paragraph(0, |line| line.is_empty())?;
-            }
-
-            self.skip_blank_lines()?;
-            if self.iter.peek().is_none() {
-                break;
-            }
-            self.output.push('\n');
-        }
-        Ok(())
-    }
-
-    fn process_document_header(&mut self) -> anyhow::Result<()> {
-        self.process_document_title()?;
-
-        while let Some(line) = self.iter.next() {
-            let line = line?;
-            if line.is_empty() {
-                break;
-            }
-            if !line.starts_with(':') {
-                self.write_line(&line, 0)
-            }
-        }
-
-        Ok(())
-    }
-
-    fn process_document_title(&mut self) -> anyhow::Result<()> {
-        if let Some(Ok(line)) = self.iter.next() {
-            if let Some((level, title)) = get_title(&line) {
-                let title = process_inline_macros(title)?;
-                if level == 1 {
-                    self.write_title(level, &title);
-                    return Ok(());
-                }
-            }
-        }
-        bail!("document title not found")
-    }
-
-    fn process_list(&mut self) -> anyhow::Result<()> {
-        let mut nesting = ListNesting::new();
-        while let Some(line) = self.iter.peek() {
-            let line = line.as_deref().map_err(|e| anyhow!("{e}"))?;
-
-            if get_list_item(line).is_some() {
-                let line = self.iter.next().unwrap()?;
-                let line = process_inline_macros(&line)?;
-                let (marker, item) = get_list_item(&line).unwrap();
-                nesting.set_current(marker);
-                self.write_list_item(item, &nesting);
-                self.process_paragraph(nesting.indent(), |line| {
-                    line.is_empty() || get_list_item(line).is_some() || line == "+"
-                })?;
-            } else if line == "+" {
-                let _ = self.iter.next().unwrap()?;
-                let line = self
-                    .iter
-                    .peek()
-                    .ok_or_else(|| anyhow!("list continuation unexpectedly terminated"))?;
-                let line = line.as_deref().map_err(|e| anyhow!("{e}"))?;
-
-                let indent = nesting.indent();
-                if line.starts_with('[') {
-                    self.write_line("", 0);
-                    self.process_source_code_block(indent)?;
-                } else if line.starts_with(LISTING_DELIMITER) {
-                    self.write_line("", 0);
-                    self.process_listing_block(None, indent)?;
-                } else if line.starts_with('.') {
-                    self.write_line("", 0);
-                    self.process_block_with_title(indent)?;
-                } else if line.starts_with(IMAGE_BLOCK_PREFIX) {
-                    self.write_line("", 0);
-                    self.process_image_block(None, indent)?;
-                } else if line.starts_with(VIDEO_BLOCK_PREFIX) {
-                    self.write_line("", 0);
-                    self.process_video_block(None, indent)?;
-                } else {
-                    self.write_line("", 0);
-                    let current = nesting.current().unwrap();
-                    self.process_paragraph(indent, |line| {
-                        line.is_empty()
-                            || get_list_item(line).filter(|(m, _)| m == current).is_some()
-                            || line == "+"
-                    })?;
-                }
-            } else {
-                break;
-            }
-            self.skip_blank_lines()?;
-        }
-
-        Ok(())
-    }
-
-    fn process_source_code_block(&mut self, level: usize) -> anyhow::Result<()> {
-        if let Some(Ok(line)) = self.iter.next() {
-            if let Some(styles) = line.strip_prefix("[source").and_then(|s| s.strip_suffix(']')) {
-                let mut styles = styles.split(',');
-                if !styles.next().unwrap().is_empty() {
-                    bail!("not a source code block");
-                }
-                let language = styles.next();
-                return self.process_listing_block(language, level);
-            }
-        }
-        bail!("not a source code block")
-    }
-
-    fn process_listing_block(&mut self, style: Option<&str>, level: usize) -> anyhow::Result<()> {
-        if let Some(Ok(line)) = self.iter.next() {
-            if line == LISTING_DELIMITER {
-                self.write_indent(level);
-                self.output.push_str("```");
-                if let Some(style) = style {
-                    self.output.push_str(style);
-                }
-                self.output.push('\n');
-                while let Some(line) = self.iter.next() {
-                    let line = line?;
-                    if line == LISTING_DELIMITER {
-                        self.write_line("```", level);
-                        return Ok(());
-                    } else {
-                        self.write_line(&line, level);
-                    }
-                }
-                bail!("listing block is not terminated")
-            }
-        }
-        bail!("not a listing block")
-    }
-
-    fn process_block_with_title(&mut self, level: usize) -> anyhow::Result<()> {
-        if let Some(Ok(line)) = self.iter.next() {
-            let title =
-                line.strip_prefix('.').ok_or_else(|| anyhow!("extraction of the title failed"))?;
-
-            let line = self
-                .iter
-                .peek()
-                .ok_or_else(|| anyhow!("target block for the title is not found"))?;
-            let line = line.as_deref().map_err(|e| anyhow!("{e}"))?;
-            if line.starts_with(IMAGE_BLOCK_PREFIX) {
-                return self.process_image_block(Some(title), level);
-            } else if line.starts_with(VIDEO_BLOCK_PREFIX) {
-                return self.process_video_block(Some(title), level);
-            } else {
-                bail!("title for that block type is not supported");
-            }
-        }
-        bail!("not a title")
-    }
-
-    fn process_image_block(&mut self, caption: Option<&str>, level: usize) -> anyhow::Result<()> {
-        if let Some(Ok(line)) = self.iter.next() {
-            if let Some((url, attrs)) = parse_media_block(&line, IMAGE_BLOCK_PREFIX) {
-                let alt = if let Some(stripped) =
-                    attrs.strip_prefix('"').and_then(|s| s.strip_suffix('"'))
-                {
-                    stripped
-                } else {
-                    attrs
-                };
-                if let Some(caption) = caption {
-                    self.write_caption_line(caption, level);
-                }
-                self.write_indent(level);
-                self.output.push_str("![");
-                self.output.push_str(alt);
-                self.output.push_str("](");
-                self.output.push_str(url);
-                self.output.push_str(")\n");
-                return Ok(());
-            }
-        }
-        bail!("not a image block")
-    }
-
-    fn process_video_block(&mut self, caption: Option<&str>, level: usize) -> anyhow::Result<()> {
-        if let Some(Ok(line)) = self.iter.next() {
-            if let Some((url, attrs)) = parse_media_block(&line, VIDEO_BLOCK_PREFIX) {
-                let html_attrs = match attrs {
-                    "options=loop" => "controls loop",
-                    r#"options="autoplay,loop""# => "autoplay controls loop",
-                    _ => bail!("unsupported video syntax"),
-                };
-                if let Some(caption) = caption {
-                    self.write_caption_line(caption, level);
-                }
-                self.write_indent(level);
-                self.output.push_str(r#"<video src=""#);
-                self.output.push_str(url);
-                self.output.push_str(r#"" "#);
-                self.output.push_str(html_attrs);
-                self.output.push_str(">Your browser does not support the video tag.</video>\n");
-                return Ok(());
-            }
-        }
-        bail!("not a video block")
-    }
-
-    fn process_paragraph<P>(&mut self, level: usize, predicate: P) -> anyhow::Result<()>
-    where
-        P: Fn(&str) -> bool,
-    {
-        while let Some(line) = self.iter.peek() {
-            let line = line.as_deref().map_err(|e| anyhow!("{e}"))?;
-            if predicate(line) {
-                break;
-            }
-
-            self.write_indent(level);
-            let line = self.iter.next().unwrap()?;
-            let line = line.trim_start();
-            let line = process_inline_macros(line)?;
-            if let Some(stripped) = line.strip_suffix('+') {
-                self.output.push_str(stripped);
-                self.output.push('\\');
-            } else {
-                self.output.push_str(&line);
-            }
-            self.output.push('\n');
-        }
-
-        Ok(())
-    }
-
-    fn skip_blank_lines(&mut self) -> anyhow::Result<()> {
-        while let Some(line) = self.iter.peek() {
-            if !line.as_deref().unwrap().is_empty() {
-                break;
-            }
-            self.iter.next().unwrap()?;
-        }
-        Ok(())
-    }
-
-    fn write_title(&mut self, indent: usize, title: &str) {
-        for _ in 0..indent {
-            self.output.push('#');
-        }
-        self.output.push(' ');
-        self.output.push_str(title);
-        self.output.push('\n');
-    }
-
-    fn write_list_item(&mut self, item: &str, nesting: &ListNesting) {
-        let (marker, indent) = nesting.marker();
-        self.write_indent(indent);
-        self.output.push_str(marker);
-        self.output.push_str(item);
-        self.output.push('\n');
-    }
-
-    fn write_caption_line(&mut self, caption: &str, indent: usize) {
-        self.write_indent(indent);
-        self.output.push('_');
-        self.output.push_str(caption);
-        self.output.push_str("_\\\n");
-    }
-
-    fn write_indent(&mut self, indent: usize) {
-        for _ in 0..indent {
-            self.output.push(' ');
-        }
-    }
-
-    fn write_line(&mut self, line: &str, indent: usize) {
-        self.write_indent(indent);
-        self.output.push_str(line);
-        self.output.push('\n');
-    }
-}
-
-pub(crate) fn convert_asciidoc_to_markdown<R>(input: R) -> anyhow::Result<String>
-where
-    R: BufRead,
-{
-    let mut output = String::new();
-    let mut iter = input.lines().peekable();
-
-    let mut converter = Converter::new(&mut iter, &mut output);
-    converter.process()?;
-
-    Ok(output)
-}
-
-fn get_title(line: &str) -> Option<(usize, &str)> {
-    strip_prefix_symbol(line, '=')
-}
-
-fn get_list_item(line: &str) -> Option<(ListMarker, &str)> {
-    const HYPHEN_MARKER: &str = "- ";
-    if let Some(text) = line.strip_prefix(HYPHEN_MARKER) {
-        Some((ListMarker::Hyphen, text))
-    } else if let Some((count, text)) = strip_prefix_symbol(line, '*') {
-        Some((ListMarker::Asterisk(count), text))
-    } else if let Some((count, text)) = strip_prefix_symbol(line, '.') {
-        Some((ListMarker::Dot(count), text))
-    } else {
-        None
-    }
-}
-
-fn strip_prefix_symbol(line: &str, symbol: char) -> Option<(usize, &str)> {
-    let mut iter = line.chars();
-    if iter.next()? != symbol {
-        return None;
-    }
-    let mut count = 1;
-    loop {
-        match iter.next() {
-            Some(ch) if ch == symbol => {
-                count += 1;
-            }
-            Some(' ') => {
-                break;
-            }
-            _ => return None,
-        }
-    }
-    Some((count, iter.as_str()))
-}
-
-fn parse_media_block<'a>(line: &'a str, prefix: &str) -> Option<(&'a str, &'a str)> {
-    if let Some(line) = line.strip_prefix(prefix) {
-        if let Some((url, rest)) = line.split_once('[') {
-            if let Some(attrs) = rest.strip_suffix(']') {
-                return Some((url, attrs));
-            }
-        }
-    }
-    None
-}
-
-#[derive(Debug)]
-struct ListNesting(Vec<ListMarker>);
-
-impl ListNesting {
-    fn new() -> Self {
-        Self(Vec::<ListMarker>::with_capacity(6))
-    }
-
-    fn current(&mut self) -> Option<&ListMarker> {
-        self.0.last()
-    }
-
-    fn set_current(&mut self, marker: ListMarker) {
-        let Self(markers) = self;
-        if let Some(index) = markers.iter().position(|m| *m == marker) {
-            markers.truncate(index + 1);
-        } else {
-            markers.push(marker);
-        }
-    }
-
-    fn indent(&self) -> usize {
-        self.0.iter().map(|m| m.in_markdown().len()).sum()
-    }
-
-    fn marker(&self) -> (&str, usize) {
-        let Self(markers) = self;
-        let indent = markers.iter().take(markers.len() - 1).map(|m| m.in_markdown().len()).sum();
-        let marker = match markers.last() {
-            None => "",
-            Some(marker) => marker.in_markdown(),
-        };
-        (marker, indent)
-    }
-}
-
-#[derive(Debug, PartialEq, Eq)]
-enum ListMarker {
-    Asterisk(usize),
-    Hyphen,
-    Dot(usize),
-}
-
-impl ListMarker {
-    fn in_markdown(&self) -> &str {
-        match self {
-            ListMarker::Asterisk(_) => "- ",
-            ListMarker::Hyphen => "- ",
-            ListMarker::Dot(_) => "1. ",
-        }
-    }
-}
-
-fn process_inline_macros(line: &str) -> anyhow::Result<Cow<'_, str>> {
-    let mut chars = line.char_indices();
-    loop {
-        let (start, end, a_macro) = match get_next_line_component(&mut chars) {
-            Component::None => break,
-            Component::Text => continue,
-            Component::Macro(s, e, m) => (s, e, m),
-        };
-        let mut src = line.chars();
-        let mut processed = String::new();
-        for _ in 0..start {
-            processed.push(src.next().unwrap());
-        }
-        processed.push_str(a_macro.process()?.as_str());
-        for _ in start..end {
-            let _ = src.next().unwrap();
-        }
-        let mut pos = end;
-
-        loop {
-            let (start, end, a_macro) = match get_next_line_component(&mut chars) {
-                Component::None => break,
-                Component::Text => continue,
-                Component::Macro(s, e, m) => (s, e, m),
-            };
-            for _ in pos..start {
-                processed.push(src.next().unwrap());
-            }
-            processed.push_str(a_macro.process()?.as_str());
-            for _ in start..end {
-                let _ = src.next().unwrap();
-            }
-            pos = end;
-        }
-        for ch in src {
-            processed.push(ch);
-        }
-        return Ok(Cow::Owned(processed));
-    }
-    Ok(Cow::Borrowed(line))
-}
-
-fn get_next_line_component(chars: &mut std::str::CharIndices<'_>) -> Component {
-    let (start, mut macro_name) = match chars.next() {
-        None => return Component::None,
-        Some((_, ch)) if ch == ' ' || !ch.is_ascii() => return Component::Text,
-        Some((pos, ch)) => (pos, String::from(ch)),
-    };
-    loop {
-        match chars.next() {
-            None => return Component::None,
-            Some((_, ch)) if ch == ' ' || !ch.is_ascii() => return Component::Text,
-            Some((_, ':')) => break,
-            Some((_, ch)) => macro_name.push(ch),
-        }
-    }
-
-    let mut macro_target = String::new();
-    loop {
-        match chars.next() {
-            None => return Component::None,
-            Some((_, ' ')) => return Component::Text,
-            Some((_, '[')) => break,
-            Some((_, ch)) => macro_target.push(ch),
-        }
-    }
-
-    let mut attr_value = String::new();
-    let end = loop {
-        match chars.next() {
-            None => return Component::None,
-            Some((pos, ']')) => break pos + 1,
-            Some((_, ch)) => attr_value.push(ch),
-        }
-    };
-
-    Component::Macro(start, end, Macro::new(macro_name, macro_target, attr_value))
-}
-
-enum Component {
-    None,
-    Text,
-    Macro(usize, usize, Macro),
-}
-
-struct Macro {
-    name: String,
-    target: String,
-    attrs: String,
-}
-
-impl Macro {
-    fn new(name: String, target: String, attrs: String) -> Self {
-        Self { name, target, attrs }
-    }
-
-    fn process(&self) -> anyhow::Result<String> {
-        let name = &self.name;
-        let text = match name.as_str() {
-            "https" => {
-                let url = &self.target;
-                let anchor_text = &self.attrs;
-                format!("[{anchor_text}](https:{url})")
-            }
-            "image" => {
-                let url = &self.target;
-                let alt = &self.attrs;
-                format!("![{alt}]({url})")
-            }
-            "kbd" => {
-                let keys = self.attrs.split('+').map(|k| Cow::Owned(format!("<kbd>{k}</kbd>")));
-                keys.collect::<Vec<_>>().join("+")
-            }
-            "pr" => {
-                let pr = &self.target;
-                let url = format!("https://github.com/rust-analyzer/rust-analyzer/pull/{pr}");
-                format!("[`#{pr}`]({url})")
-            }
-            "commit" => {
-                let hash = &self.target;
-                let short = &hash[0..7];
-                let url = format!("https://github.com/rust-analyzer/rust-analyzer/commit/{hash}");
-                format!("[`{short}`]({url})")
-            }
-            "release" => {
-                let date = &self.target;
-                let url = format!("https://github.com/rust-analyzer/rust-analyzer/releases/{date}");
-                format!("[`{date}`]({url})")
-            }
-            _ => bail!("macro not supported: {name}"),
-        };
-        Ok(text)
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use std::fs::read_to_string;
-
-    #[test]
-    fn test_asciidoc_to_markdown_conversion() {
-        let input = read_to_string("test_data/input.adoc").unwrap();
-        let expected = read_to_string("test_data/expected.md").unwrap();
-        let actual = convert_asciidoc_to_markdown(std::io::Cursor::new(&input)).unwrap();
-
-        assert_eq!(actual, expected);
-    }
-
-    macro_rules! test_inline_macro_processing {
-        ($((
-            $name:ident,
-            $input:expr,
-            $expected:expr
-        ),)*) => ($(
-            #[test]
-            fn $name() {
-                let input = $input;
-                let actual = process_inline_macros(&input).unwrap();
-                let expected = $expected;
-                assert_eq!(actual, expected)
-            }
-        )*);
-    }
-
-    test_inline_macro_processing! {
-        (inline_macro_processing_for_empty_line, "", ""),
-        (inline_macro_processing_for_line_with_no_macro, "foo bar", "foo bar"),
-        (
-            inline_macro_processing_for_macro_in_line_start,
-            "kbd::[Ctrl+T] foo",
-            "<kbd>Ctrl</kbd>+<kbd>T</kbd> foo"
-        ),
-        (
-            inline_macro_processing_for_macro_in_line_end,
-            "foo kbd::[Ctrl+T]",
-            "foo <kbd>Ctrl</kbd>+<kbd>T</kbd>"
-        ),
-        (
-            inline_macro_processing_for_macro_in_the_middle_of_line,
-            "foo kbd::[Ctrl+T] foo",
-            "foo <kbd>Ctrl</kbd>+<kbd>T</kbd> foo"
-        ),
-        (
-            inline_macro_processing_for_several_macros,
-            "foo kbd::[Ctrl+T] foo kbd::[Enter] foo",
-            "foo <kbd>Ctrl</kbd>+<kbd>T</kbd> foo <kbd>Enter</kbd> foo"
-        ),
-        (
-            inline_macro_processing_for_several_macros_without_text_in_between,
-            "foo kbd::[Ctrl+T]kbd::[Enter] foo",
-            "foo <kbd>Ctrl</kbd>+<kbd>T</kbd><kbd>Enter</kbd> foo"
-        ),
-    }
-}


Test patch:
diff --git a/crates/hir-ty/src/layout/tests.rs b/crates/hir-ty/src/layout/tests.rs
index ba821235f3..5d97a69501 100644
--- a/crates/hir-ty/src/layout/tests.rs
+++ b/crates/hir-ty/src/layout/tests.rs
@@ -9,22 +9,8 @@ use crate::{test_db::TestDB, Interner, Substitution};
 
 use super::layout_of_ty;
 
-fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Layout, LayoutError> {
-    // using unstable cargo features failed, fall back to using plain rustc
-    let mut cmd = std::process::Command::new("rustc");
-    cmd.args(&["-Z", "unstable-options", "--print", "target-spec-json"])
-        .env("RUSTC_BOOTSTRAP", "1");
-    let output = cmd.output().unwrap();
-    assert!(output.status.success(), "{}", output.status);
-    let stdout = String::from_utf8(output.stdout).unwrap();
-    let target_data_layout =
-        stdout.split_once(r#""data-layout": ""#).unwrap().1.split_once('"').unwrap().0.to_owned();
-
-    let ra_fixture = format!(
-        "{minicore}//- /main.rs crate:test target_data_layout:{target_data_layout}\n{ra_fixture}",
-    );
-
-    let (db, file_id) = TestDB::with_single_file(&ra_fixture);
+fn eval_goal(ra_fixture: &str) -> Result<Layout, LayoutError> {
+    let (db, file_id) = TestDB::with_single_file(ra_fixture);
     let module_id = db.module_for_file(file_id);
     let def_map = module_id.def_map(&db);
     let scope = &def_map[module_id.local_id].scope;
@@ -34,29 +20,31 @@ fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Layout, LayoutError> {
         .find_map(|x| match x {
             hir_def::ModuleDefId::AdtId(x) => {
                 let name = match x {
-                    hir_def::AdtId::StructId(x) => db.struct_data(x).name.to_smol_str(),
-                    hir_def::AdtId::UnionId(x) => db.union_data(x).name.to_smol_str(),
-                    hir_def::AdtId::EnumId(x) => db.enum_data(x).name.to_smol_str(),
+                    hir_def::AdtId::StructId(x) => db.struct_data(x).name.to_string(),
+                    hir_def::AdtId::UnionId(x) => db.union_data(x).name.to_string(),
+                    hir_def::AdtId::EnumId(x) => db.enum_data(x).name.to_string(),
                 };
-                (name == "Goal").then(|| x)
+                if name == "Goal" {
+                    Some(x)
+                } else {
+                    None
+                }
             }
             _ => None,
         })
         .unwrap();
     let goal_ty = TyKind::Adt(AdtId(adt_id), Substitution::empty(Interner)).intern(Interner);
-    layout_of_ty(&db, &goal_ty, module_id.krate())
+    layout_of_ty(&db, &goal_ty)
 }
 
-#[track_caller]
-fn check_size_and_align(ra_fixture: &str, minicore: &str, size: u64, align: u64) {
-    let l = eval_goal(ra_fixture, minicore).unwrap();
+fn check_size_and_align(ra_fixture: &str, size: u64, align: u64) {
+    let l = eval_goal(ra_fixture).unwrap();
     assert_eq!(l.size.bytes(), size);
     assert_eq!(l.align.abi.bytes(), align);
 }
 
-#[track_caller]
 fn check_fail(ra_fixture: &str, e: LayoutError) {
-    let r = eval_goal(ra_fixture, "");
+    let r = eval_goal(ra_fixture);
     assert_eq!(r, Err(e));
 }
 
@@ -66,8 +54,7 @@ macro_rules! size_and_align {
             #[allow(dead_code)]
             $($t)*
             check_size_and_align(
-                stringify!($($t)*),
-                &format!("//- minicore: {}\n", stringify!($($x),*)),
+                &format!("//- minicore: {}\n{}", stringify!($($x),*), stringify!($($t)*)),
                 ::std::mem::size_of::<Goal>() as u64,
                 ::std::mem::align_of::<Goal>() as u64,
             );
@@ -79,7 +66,6 @@ macro_rules! size_and_align {
             $($t)*
             check_size_and_align(
                 stringify!($($t)*),
-                "",
                 ::std::mem::size_of::<Goal>() as u64,
                 ::std::mem::align_of::<Goal>() as u64,
             );
diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs
index adb106e979..a1cb438bdd 100644
--- a/crates/project-model/src/tests.rs
+++ b/crates/project-model/src/tests.rs
@@ -29,7 +29,6 @@ fn load_cargo_with_overrides(file: &str, cfg_overrides: CfgOverrides) -> CrateGr
         rustc_cfg: Vec::new(),
         cfg_overrides,
         toolchain: None,
-        target_layout: None,
     };
     to_crate_graph(project_workspace)
 }
@@ -151,7 +150,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "debug_assertions",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -221,7 +219,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "debug_assertions",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -300,7 +297,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "debug_assertions",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -379,7 +375,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "debug_assertions",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -467,7 +462,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                                 "feature=use_std",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -553,7 +547,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "test",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -625,7 +618,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "test",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -706,7 +698,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "test",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -787,7 +778,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "test",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -875,7 +865,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                                 "feature=use_std",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -952,7 +941,6 @@ fn cargo_hello_world_project_model() {
                                 "test",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -1024,7 +1012,6 @@ fn cargo_hello_world_project_model() {
                                 "test",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -1105,7 +1092,6 @@ fn cargo_hello_world_project_model() {
                                 "test",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -1186,7 +1172,6 @@ fn cargo_hello_world_project_model() {
                                 "test",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -1274,7 +1259,6 @@ fn cargo_hello_world_project_model() {
                                 "feature=use_std",
                             ],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {
                                 "CARGO_PKG_LICENSE": "",
@@ -1343,7 +1327,6 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1388,7 +1371,6 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1423,7 +1405,6 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1458,7 +1439,6 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1493,7 +1473,6 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1538,7 +1517,6 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1573,7 +1551,6 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1681,7 +1658,6 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1716,7 +1692,6 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1751,7 +1726,6 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
@@ -1786,7 +1760,6 @@ fn rust_project_hello_world_project_model() {
                         potential_cfg_options: CfgOptions(
                             [],
                         ),
-                        target_layout: None,
                         env: Env {
                             entries: {},
                         },
diff --git a/crates/test-utils/src/fixture.rs b/crates/test-utils/src/fixture.rs
index 73e72c1880..c824f5af72 100644
--- a/crates/test-utils/src/fixture.rs
+++ b/crates/test-utils/src/fixture.rs
@@ -78,7 +78,6 @@ pub struct Fixture {
     pub edition: Option<String>,
     pub env: FxHashMap<String, String>,
     pub introduce_new_source_root: Option<String>,
-    pub target_data_layout: Option<String>,
 }
 
 pub struct MiniCore {
@@ -182,7 +181,6 @@ impl Fixture {
         let mut cfg_key_values = Vec::new();
         let mut env = FxHashMap::default();
         let mut introduce_new_source_root = None;
-        let mut target_data_layout = None;
         for component in components[1..].iter() {
             let (key, value) = component
                 .split_once(':')
@@ -215,7 +213,6 @@ impl Fixture {
                     }
                 }
                 "new_source_root" => introduce_new_source_root = Some(value.to_string()),
-                "target_data_layout" => target_data_layout = Some(value.to_string()),
                 _ => panic!("bad component: {:?}", component),
             }
         }
@@ -240,7 +237,6 @@ impl Fixture {
             edition,
             env,
             introduce_new_source_root,
-            target_data_layout,
         }
     }
 }
diff --git a/xtask/test_data/expected.md b/xtask/test_data/expected.md
deleted file mode 100644
index 19c940c67b..0000000000
--- a/xtask/test_data/expected.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# Changelog #256
-
-Hello!
-
-Commit: [`0123456`](https://github.com/rust-analyzer/rust-analyzer/commit/0123456789abcdef0123456789abcdef01234567) \
-Release: [`2022-01-01`](https://github.com/rust-analyzer/rust-analyzer/releases/2022-01-01)
-
-## New Features
-
-- **BREAKING** [`#1111`](https://github.com/rust-analyzer/rust-analyzer/pull/1111) shortcut <kbd>ctrl</kbd>+<kbd>r</kbd>
-  - hyphen-prefixed list item
-- nested list item
-  - `foo` -> `foofoo`
-  - `bar` -> `barbar`
-- listing in the secondary level
-  1. install
-  1. add to config
-
-     ```json
-     {"foo":"bar"}
-     ```
-- list item with continuation
-
-  ![](https://example.com/animation.gif)
-
-  ![alt text](https://example.com/animation.gif)
-
-  <video src="https://example.com/movie.mp4" controls loop>Your browser does not support the video tag.</video>
-
-  <video src="https://example.com/movie.mp4" autoplay controls loop>Your browser does not support the video tag.</video>
-
-  _Image_\
-  ![](https://example.com/animation.gif)
-
-  _Video_\
-  <video src="https://example.com/movie.mp4" controls loop>Your browser does not support the video tag.</video>
-
-  ```bash
-  rustup update nightly
-  ```
-
-  ```
-  This is a plain listing.
-  ```
-- single line item followed by empty lines
-- multiline list
-  item followed by empty lines
-- multiline list
-  item with indent
-- multiline list
-  item not followed by empty lines
-- multiline list
-  item followed by different marker
-  - foo
-  - bar
-- multiline list
-  item followed by list continuation
-
-  paragraph
-  paragraph
-
-## Another Section
-
-- foo bar baz
-- list item with an inline image
-  ![](https://example.com/animation.gif)
-
-The highlight of the month is probably [`#1111`](https://github.com/rust-analyzer/rust-analyzer/pull/1111).
-See [online manual](https://example.com/manual) for more information.
-
-```bash
-rustup update nightly
-```
-
-```
-rustup update nightly
-```
-
-```
-This is a plain listing.
-```
diff --git a/xtask/test_data/input.adoc b/xtask/test_data/input.adoc
deleted file mode 100644
index 105bd8df0d..0000000000
--- a/xtask/test_data/input.adoc
+++ /dev/null
@@ -1,90 +0,0 @@
-= Changelog #256
-:sectanchors:
-:page-layout: post
-
-Hello!
-
-Commit: commit:0123456789abcdef0123456789abcdef01234567[] +
-Release: release:2022-01-01[]
-
-== New Features
-
-* **BREAKING** pr:1111[] shortcut kbd:[ctrl+r]
-- hyphen-prefixed list item
-* nested list item
-** `foo` -> `foofoo`
-** `bar` -> `barbar`
-* listing in the secondary level
-. install
-. add to config
-+
-[source,json]
-----
-{"foo":"bar"}
-----
-* list item with continuation
-+
-image::https://example.com/animation.gif[]
-+
-image::https://example.com/animation.gif["alt text"]
-+
-video::https://example.com/movie.mp4[options=loop]
-+
-video::https://example.com/movie.mp4[options="autoplay,loop"]
-+
-.Image
-image::https://example.com/animation.gif[]
-+
-.Video
-video::https://example.com/movie.mp4[options=loop]
-+
-[source,bash]
-----
-rustup update nightly
-----
-+
-----
-This is a plain listing.
-----
-* single line item followed by empty lines
-
-* multiline list
-item followed by empty lines
-
-* multiline list
-  item with indent
-
-* multiline list
-item not followed by empty lines
-* multiline list
-item followed by different marker
-** foo
-** bar
-* multiline list
-item followed by list continuation
-+
-paragraph
-paragraph
-
-== Another Section
-
-* foo bar baz
-* list item with an inline image
-  image:https://example.com/animation.gif[]
-
-The highlight of the month is probably pr:1111[].
-See https://example.com/manual[online manual] for more information.
-
-[source,bash]
-----
-rustup update nightly
-----
-
-[source]
-----
-rustup update nightly
-----
-
-----
-This is a plain listing.
-----