Repository: rust-lang/rust-analyzer
Pull request #15281 (2023-07-14 15:30:44)

editor/code: Break down CI steps to know what is failing easily
This do the thing I mentioned in https://github.com/rust-lang/rust-analyzer/pull/15265#issuecomment-1634424385

This aims to improve CI status check more readable.

I tried to use [`jobs.<job_id>.if`](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idif) to make the configuration
more shortly once.

But it could not fire the `end-success` or `end-failure` status if some jobs in the workflow were skipped. This causes an integration problem with bors.

By their reasons, this patch still uses `jobs.<job_id>.steps[*].if`.

---

To do this change, we reorganize npm-script.

| previous           | after                                  |
|--------------------|----------------------------------------|
| `npm run lint`     | `npm run lint && npm run format:check` |
| `npm run fix`      | `npm run lint:fix && npm run format`   |

The previous `npm run fix` sometimes does not complete fix automatically because ESLint's autofix doees not follow prettier's formatting. So we need to run `npm run lint:fix && npm run format` by this order.

tetsuharuohzeki: @lnicola How do you think about this?

I did not do same thing for Rust's CI job because [their step has a dependency that affects to CI job performance](https://github.com/rust-lang/rust-analyzer/blob/8e5f944317cfefc8fb17b57ff7b7ccc7326f4642/.github/workflows/ci.yaml#L78-L95). I would not like to touch them in this PR to avoid to make this PR more complex.
lnicola: To be honest, I'm not a fan of this. It's a bunch more complex, and I'm not sure it's worth it over a good comment or message printed in the workflow.
lnicola: Yeah, that's closer to what I meant.
tetsuharuohzeki: @lnicola 

Thanks. I updated my changeset.
lnicola: @tetsuharuohzeki did you see my comments on https://github.com/rust-lang/rust-analyzer/commit/19f6f5061d99d22ea336c1313d853f3a5e08a437?
tetsuharuohzeki: > @tetsuharuohzeki did you see my comments on https://github.com/rust-lang/rust-analyzer/commit/19f6f5061d99d22ea336c1313d853f3a5e08a437?

Sorry, I missed it.

> Is it worth adding this since it's used only in one place? On one hand, it makes sense for someone who doesn't know what tsc is, on the other it's an extra thing to read through.

I think this alias (mom run type check) is useful when  upgrading TypeScript to fix an error said by TypeScript compiler as just like `cargo check`. Thus I added it.
tetsuharuohzeki: By this commit https://github.com/rust-lang/rust-analyzer/commit/6a97fc60f1d58e130813a0d61e826fedea2d0c4c I break down CI step more `npm run pretest` steps into `npm run lint` and `npm run typecheck`

Patch:
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 31bb7eed8d..9f246098e7 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -161,10 +161,21 @@ jobs:
       #      if: runner.os == 'Linux'
       #      working-directory: ./editors/code
 
+      # If this steps fails, your code's type integrity might be wrong at some places at TypeScript level.
+      - run: npm run typecheck
+        working-directory: ./editors/code
+        if: needs.changes.outputs.typescript == 'true'
+
+      # You may fix the code automatically by running `npm run lint:fix` if this steps fails.
       - run: npm run lint
         working-directory: ./editors/code
         if: needs.changes.outputs.typescript == 'true'
 
+      # To fix this steps, please run `npm run format`.
+      - run: npm run format:check
+        working-directory: ./editors/code
+        if: needs.changes.outputs.typescript == 'true'
+
       - name: Run VS Code tests (Linux)
         if: matrix.os == 'ubuntu-latest' && needs.changes.outputs.typescript == 'true'
         env:
@@ -179,10 +190,6 @@ jobs:
         run: npm test
         working-directory: ./editors/code
 
-      - run: npm run pretest
-        working-directory: ./editors/code
-        if: needs.changes.outputs.typescript == 'true'
-
       - run: npm run package --scripts-prepend-node-path
         working-directory: ./editors/code
         if: needs.changes.outputs.typescript == 'true'
diff --git a/Cargo.toml b/Cargo.toml
index f6a50bfa6b..24889fc142 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,7 +4,7 @@ exclude = ["crates/proc-macro-test/imp"]
 resolver = "2"
 
 [workspace.package]
-rust-version = "1.70"
+rust-version = "1.66"
 edition = "2021"
 license = "MIT OR Apache-2.0"
 authors = ["rust-analyzer team"]
diff --git a/crates/base-db/src/fixture.rs b/crates/base-db/src/fixture.rs
index 323ee4260e..6bfdf402c4 100644
--- a/crates/base-db/src/fixture.rs
+++ b/crates/base-db/src/fixture.rs
@@ -26,7 +26,7 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static {
         let fixture = ChangeFixture::parse(ra_fixture);
         let mut db = Self::default();
         fixture.change.apply(&mut db);
-        assert_eq!(fixture.files.len(), 1, "Multiple file found in the fixture");
+        assert_eq!(fixture.files.len(), 1);
         (db, fixture.files[0])
     }
 
diff --git a/crates/hir-expand/src/builtin_derive_macro.rs b/crates/hir-expand/src/builtin_derive_macro.rs
index ecc8b407a9..c8c3cebb88 100644
--- a/crates/hir-expand/src/builtin_derive_macro.rs
+++ b/crates/hir-expand/src/builtin_derive_macro.rs
@@ -624,14 +624,9 @@ fn hash_expand(
                 }
             },
         );
-        let check_discriminant = if matches!(&adt.shape, AdtShape::Enum { .. }) {
-            quote! { #krate::mem::discriminant(self).hash(ra_expand_state); }
-        } else {
-            quote! {}
-        };
         quote! {
             fn hash<H: #krate::hash::Hasher>(&self, ra_expand_state: &mut H) {
-                #check_discriminant
+                #krate::mem::discriminant(self).hash(ra_expand_state);
                 match self {
                     ##arms
                 }
@@ -747,6 +742,9 @@ fn ord_expand(
             // FIXME: Return expand error here
             return quote!();
         }
+        let left = quote!(#krate::intrinsics::discriminant_value(self));
+        let right = quote!(#krate::intrinsics::discriminant_value(other));
+
         let (self_patterns, other_patterns) = self_and_other_patterns(adt, &adt.name);
         let arms = izip!(self_patterns, other_patterns, adt.shape.field_names()).map(
             |(pat1, pat2, fields)| {
@@ -761,17 +759,17 @@ fn ord_expand(
             },
         );
         let fat_arrow = fat_arrow();
-        let mut body = quote! {
-            match (self, other) {
-                ##arms
-                _unused #fat_arrow #krate::cmp::Ordering::Equal
-            }
-        };
-        if matches!(&adt.shape, AdtShape::Enum { .. }) {
-            let left = quote!(#krate::intrinsics::discriminant_value(self));
-            let right = quote!(#krate::intrinsics::discriminant_value(other));
-            body = compare(krate, left, right, body);
-        }
+        let body = compare(
+            krate,
+            left,
+            right,
+            quote! {
+                match (self, other) {
+                    ##arms
+                    _unused #fat_arrow #krate::cmp::Ordering::Equal
+                }
+            },
+        );
         quote! {
             fn cmp(&self, other: &Self) -> #krate::cmp::Ordering {
                 #body
diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs
index f4fbace19e..50eabc867b 100644
--- a/crates/hir-ty/src/chalk_db.rs
+++ b/crates/hir-ty/src/chalk_db.rs
@@ -60,37 +60,9 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
         // FIXME: keep track of these
         Arc::new(rust_ir::AdtRepr { c: false, packed: false, int: None })
     }
-    fn discriminant_type(&self, ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
-        if let chalk_ir::TyKind::Adt(id, _) = ty.kind(Interner) {
-            if let hir_def::AdtId::EnumId(e) = id.0 {
-                let enum_data = self.db.enum_data(e);
-                let ty = enum_data.repr.unwrap_or_default().discr_type();
-                return chalk_ir::TyKind::Scalar(match ty {
-                    hir_def::layout::IntegerType::Pointer(is_signed) => match is_signed {
-                        true => chalk_ir::Scalar::Int(chalk_ir::IntTy::Isize),
-                        false => chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize),
-                    },
-                    hir_def::layout::IntegerType::Fixed(size, is_signed) => match is_signed {
-                        true => chalk_ir::Scalar::Int(match size {
-                            hir_def::layout::Integer::I8 => chalk_ir::IntTy::I8,
-                            hir_def::layout::Integer::I16 => chalk_ir::IntTy::I16,
-                            hir_def::layout::Integer::I32 => chalk_ir::IntTy::I32,
-                            hir_def::layout::Integer::I64 => chalk_ir::IntTy::I64,
-                            hir_def::layout::Integer::I128 => chalk_ir::IntTy::I128,
-                        }),
-                        false => chalk_ir::Scalar::Uint(match size {
-                            hir_def::layout::Integer::I8 => chalk_ir::UintTy::U8,
-                            hir_def::layout::Integer::I16 => chalk_ir::UintTy::U16,
-                            hir_def::layout::Integer::I32 => chalk_ir::UintTy::U32,
-                            hir_def::layout::Integer::I64 => chalk_ir::UintTy::U64,
-                            hir_def::layout::Integer::I128 => chalk_ir::UintTy::U128,
-                        }),
-                    },
-                })
-                .intern(Interner);
-            }
-        }
-        chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U8)).intern(Interner)
+    fn discriminant_type(&self, _ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
+        // FIXME: keep track of this
+        chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U32)).intern(Interner)
     }
     fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
         self.db.impl_datum(self.krate, impl_id)
diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs
index 1c0f7b08da..4de90d40a7 100644
--- a/crates/hir-ty/src/consteval.rs
+++ b/crates/hir-ty/src/consteval.rs
@@ -16,8 +16,7 @@ use triomphe::Arc;
 use crate::{
     db::HirDatabase, infer::InferenceContext, lower::ParamLoweringMode,
     mir::monomorphize_mir_body_bad, to_placeholder_idx, utils::Generics, Const, ConstData,
-    ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, Substitution, TraitEnvironment, Ty,
-    TyBuilder,
+    ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, Substitution, Ty, TyBuilder,
 };
 
 use super::mir::{interpret_mir, lower_to_mir, pad16, MirEvalError, MirLowerError};
@@ -136,7 +135,7 @@ pub fn intern_const_ref(
     ty: Ty,
     krate: CrateId,
 ) -> Const {
-    let layout = db.layout_of_ty(ty.clone(), Arc::new(TraitEnvironment::empty(krate)));
+    let layout = db.layout_of_ty(ty.clone(), krate);
     let bytes = match value {
         LiteralConstRef::Int(i) => {
             // FIXME: We should handle failure of layout better.
@@ -174,7 +173,7 @@ pub fn try_const_usize(db: &dyn HirDatabase, c: &Const) -> Option<u128> {
         chalk_ir::ConstValue::Concrete(c) => match &c.interned {
             ConstScalar::Bytes(it, _) => Some(u128::from_le_bytes(pad16(&it, false))),
             ConstScalar::UnevaluatedConst(c, subst) => {
-                let ec = db.const_eval(*c, subst.clone(), None).ok()?;
+                let ec = db.const_eval(*c, subst.clone()).ok()?;
                 try_const_usize(db, &ec)
             }
             _ => None,
@@ -187,7 +186,6 @@ pub(crate) fn const_eval_recover(
     _: &[String],
     _: &GeneralConstId,
     _: &Substitution,
-    _: &Option<Arc<TraitEnvironment>>,
 ) -> Result<Const, ConstEvalError> {
     Err(ConstEvalError::MirLowerError(MirLowerError::Loop))
 }
@@ -212,7 +210,6 @@ pub(crate) fn const_eval_query(
     db: &dyn HirDatabase,
     def: GeneralConstId,
     subst: Substitution,
-    trait_env: Option<Arc<TraitEnvironment>>,
 ) -> Result<Const, ConstEvalError> {
     let body = match def {
         GeneralConstId::ConstId(c) => {
@@ -231,7 +228,7 @@ pub(crate) fn const_eval_query(
         }
         GeneralConstId::InTypeConstId(c) => db.mir_body(c.into())?,
     };
-    let c = interpret_mir(db, body, false, trait_env).0?;
+    let c = interpret_mir(db, body, false).0?;
     Ok(c)
 }
 
@@ -244,7 +241,7 @@ pub(crate) fn const_eval_static_query(
         Substitution::empty(Interner),
         db.trait_environment_for_body(def.into()),
     )?;
-    let c = interpret_mir(db, body, false, None).0?;
+    let c = interpret_mir(db, body, false).0?;
     Ok(c)
 }
 
@@ -271,7 +268,7 @@ pub(crate) fn const_eval_discriminant_variant(
         Substitution::empty(Interner),
         db.trait_environment_for_body(def),
     )?;
-    let c = interpret_mir(db, mir_body, false, None).0?;
+    let c = interpret_mir(db, mir_body, false).0?;
     let c = try_const_usize(db, &c).unwrap() as i128;
     Ok(c)
 }
@@ -296,7 +293,7 @@ pub(crate) fn eval_to_const(
     }
     let infer = ctx.clone().resolve_all();
     if let Ok(mir_body) = lower_to_mir(ctx.db, ctx.owner, &ctx.body, &infer, expr) {
-        if let Ok(result) = interpret_mir(db, Arc::new(mir_body), true, None).0 {
+        if let Ok(result) = interpret_mir(db, Arc::new(mir_body), true).0 {
             return result;
         }
     }
diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs
index 9c96b5ab8d..14b719ea41 100644
--- a/crates/hir-ty/src/db.rs
+++ b/crates/hir-ty/src/db.rs
@@ -77,12 +77,8 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
 
     #[salsa::invoke(crate::consteval::const_eval_query)]
     #[salsa::cycle(crate::consteval::const_eval_recover)]
-    fn const_eval(
-        &self,
-        def: GeneralConstId,
-        subst: Substitution,
-        trait_env: Option<Arc<crate::TraitEnvironment>>,
-    ) -> Result<Const, ConstEvalError>;
+    fn const_eval(&self, def: GeneralConstId, subst: Substitution)
+        -> Result<Const, ConstEvalError>;
 
     #[salsa::invoke(crate::consteval::const_eval_static_query)]
     #[salsa::cycle(crate::consteval::const_eval_static_recover)]
@@ -104,16 +100,12 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
         &self,
         def: AdtId,
         subst: Substitution,
-        env: Arc<crate::TraitEnvironment>,
+        krate: CrateId,
     ) -> Result<Arc<Layout>, LayoutError>;
 
     #[salsa::invoke(crate::layout::layout_of_ty_query)]
     #[salsa::cycle(crate::layout::layout_of_ty_recover)]
-    fn layout_of_ty(
-        &self,
-        ty: Ty,
-        env: Arc<crate::TraitEnvironment>,
-    ) -> Result<Arc<Layout>, LayoutError>;
+    fn layout_of_ty(&self, ty: Ty, krate: CrateId) -> Result<Arc<Layout>, LayoutError>;
 
     #[salsa::invoke(crate::layout::target_data_layout_query)]
     fn target_data_layout(&self, krate: CrateId) -> Option<Arc<TargetDataLayout>>;
diff --git a/crates/hir-ty/src/diagnostics/decl_check.rs b/crates/hir-ty/src/diagnostics/decl_check.rs
index 5aaa2bcc7c..73c8ad3dd5 100644
--- a/crates/hir-ty/src/diagnostics/decl_check.rs
+++ b/crates/hir-ty/src/diagnostics/decl_check.rs
@@ -14,12 +14,13 @@ mod case_conv;
 
 use std::fmt;
 
+use base_db::CrateId;
 use hir_def::{
     data::adt::VariantData,
     hir::{Pat, PatId},
     src::HasSource,
-    AdtId, AttrDefId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, ItemContainerId,
-    Lookup, ModuleDefId, StaticId, StructId,
+    AdtId, AttrDefId, ConstId, EnumId, FunctionId, ItemContainerId, Lookup, ModuleDefId, StaticId,
+    StructId,
 };
 use hir_expand::{
     name::{AsName, Name},
@@ -43,9 +44,13 @@ mod allow {
     pub(super) const NON_CAMEL_CASE_TYPES: &str = "non_camel_case_types";
 }
 
-pub fn incorrect_case(db: &dyn HirDatabase, owner: ModuleDefId) -> Vec<IncorrectCase> {
+pub fn incorrect_case(
+    db: &dyn HirDatabase,
+    krate: CrateId,
+    owner: ModuleDefId,
+) -> Vec<IncorrectCase> {
     let _p = profile::span("validate_module_item");
-    let mut validator = DeclValidator::new(db);
+    let mut validator = DeclValidator::new(db, krate);
     validator.validate_item(owner);
     validator.sink
 }
@@ -115,6 +120,7 @@ pub struct IncorrectCase {
 
 pub(super) struct DeclValidator<'a> {
     db: &'a dyn HirDatabase,
+    krate: CrateId,
     pub(super) sink: Vec<IncorrectCase>,
 }
 
@@ -126,8 +132,8 @@ struct Replacement {
 }
 
 impl<'a> DeclValidator<'a> {
-    pub(super) fn new(db: &'a dyn HirDatabase) -> DeclValidator<'a> {
-        DeclValidator { db, sink: Vec::new() }
+    pub(super) fn new(db: &'a dyn HirDatabase, krate: CrateId) -> DeclValidator<'a> {
+        DeclValidator { db, krate, sink: Vec::new() }
     }
 
     pub(super) fn validate_item(&mut self, item: ModuleDefId) {
@@ -189,7 +195,8 @@ impl<'a> DeclValidator<'a> {
                 AttrDefId::TypeAliasId(_) => None,
                 AttrDefId::GenericParamId(_) => None,
             }
-            .is_some_and(|mid| self.allowed(mid, allow_name, true))
+            .map(|mid| self.allowed(mid, allow_name, true))
+            .unwrap_or(false)
     }
 
     fn validate_func(&mut self, func: FunctionId) {
@@ -199,7 +206,17 @@ impl<'a> DeclValidator<'a> {
             return;
         }
 
-        self.validate_body_inner_items(func.into());
+        let body = self.db.body(func.into());
+
+        // Recursively validate inner scope items, such as static variables and constants.
+        for (_, block_def_map) in body.blocks(self.db.upcast()) {
+            for (_, module) in block_def_map.modules() {
+                for def_id in module.scope.declarations() {
+                    let mut validator = DeclValidator::new(self.db, self.krate);
+                    validator.validate_item(def_id);
+                }
+            }
+        }
 
         // Check whether non-snake case identifiers are allowed for this function.
         if self.allowed(func.into(), allow::NON_SNAKE_CASE, false) {
@@ -214,8 +231,6 @@ impl<'a> DeclValidator<'a> {
             expected_case: CaseType::LowerSnakeCase,
         });
 
-        let body = self.db.body(func.into());
-
         // Check the patterns inside the function body.
         // This includes function parameters.
         let pats_replacements = body
@@ -481,11 +496,6 @@ impl<'a> DeclValidator<'a> {
     fn validate_enum(&mut self, enum_id: EnumId) {
         let data = self.db.enum_data(enum_id);
 
-        for (local_id, _) in data.variants.iter() {
-            let variant_id = EnumVariantId { parent: enum_id, local_id };
-            self.validate_body_inner_items(variant_id.into());
-        }
-
         // Check whether non-camel case names are allowed for this enum.
         if self.allowed(enum_id.into(), allow::NON_CAMEL_CASE_TYPES, false) {
             return;
@@ -502,11 +512,13 @@ impl<'a> DeclValidator<'a> {
         // Check the field names.
         let enum_fields_replacements = data
             .variants
-            .values()
-            .filter_map(|variant| {
+            .iter()
+            .filter_map(|(_, variant)| {
                 Some(Replacement {
                     current_name: variant.name.clone(),
-                    suggested_text: to_camel_case(&variant.name.to_smol_str())?,
+                    suggested_text: to_camel_case(
+                        &variant.name.display(self.db.upcast()).to_string(),
+                    )?,
                     expected_case: CaseType::UpperCamelCase,
                 })
             })
@@ -610,8 +622,6 @@ impl<'a> DeclValidator<'a> {
     fn validate_const(&mut self, const_id: ConstId) {
         let data = self.db.const_data(const_id);
 
-        self.validate_body_inner_items(const_id.into());
-
         if self.allowed(const_id.into(), allow::NON_UPPER_CASE_GLOBAL, false) {
             return;
         }
@@ -621,7 +631,7 @@ impl<'a> DeclValidator<'a> {
             None => return,
         };
 
-        let const_name = name.to_smol_str();
+        let const_name = name.display(self.db.upcast()).to_string();
         let replacement = if let Some(new_name) = to_upper_snake_case(&const_name) {
             Replacement {
                 current_name: name.clone(),
@@ -660,15 +670,13 @@ impl<'a> DeclValidator<'a> {
             return;
         }
 
-        self.validate_body_inner_items(static_id.into());
-
         if self.allowed(static_id.into(), allow::NON_UPPER_CASE_GLOBAL, false) {
             return;
         }
 
         let name = &data.name;
 
-        let static_name = name.to_smol_str();
+        let static_name = name.display(self.db.upcast()).to_string();
         let replacement = if let Some(new_name) = to_upper_snake_case(&static_name) {
             Replacement {
                 current_name: name.clone(),
@@ -699,17 +707,4 @@ impl<'a> DeclValidator<'a> {
 
         self.sink.push(diagnostic);
     }
-
-    // FIXME: We don't currently validate names within `DefWithBodyId::InTypeConstId`.
-    /// Recursively validates inner scope items, such as static variables and constants.
-    fn validate_body_inner_items(&mut self, body_id: DefWithBodyId) {
-        let body = self.db.body(body_id);
-        for (_, block_def_map) in body.blocks(self.db.upcast()) {
-            for (_, module) in block_def_map.modules() {
-                for def_id in module.scope.declarations() {
-                    self.validate_item(def_id);
-                }
-            }
-        }
-    }
 }
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 96787959e1..8cffdef289 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -29,7 +29,6 @@ use itertools::Itertools;
 use la_arena::ArenaMap;
 use smallvec::SmallVec;
 use stdx::never;
-use triomphe::Arc;
 
 use crate::{
     consteval::try_const_usize,
@@ -44,7 +43,7 @@ use crate::{
     AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Const, ConstScalar, ConstValue,
     DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData, LifetimeOutlives,
     MemoryMap, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Scalar,
-    Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyExt, WhereClause,
+    Substitution, TraitRef, TraitRefExt, Ty, TyExt, WhereClause,
 };
 
 pub trait HirWrite: fmt::Write {
@@ -455,9 +454,7 @@ fn render_const_scalar(
 ) -> Result<(), HirDisplayError> {
     // FIXME: We need to get krate from the final callers of the hir display
     // infrastructure and have it here as a field on `f`.
-    let trait_env = Arc::new(TraitEnvironment::empty(
-        *f.db.crate_graph().crates_in_topological_order().last().unwrap(),
-    ));
+    let krate = *f.db.crate_graph().crates_in_topological_order().last().unwrap();
     match ty.kind(Interner) {
         TyKind::Scalar(s) => match s {
             Scalar::Bool => write!(f, "{}", if b[0] == 0 { false } else { true }),
@@ -500,7 +497,7 @@ fn render_const_scalar(
             TyKind::Slice(ty) => {
                 let addr = usize::from_le_bytes(b[0..b.len() / 2].try_into().unwrap());
                 let count = usize::from_le_bytes(b[b.len() / 2..].try_into().unwrap());
-                let Ok(layout) = f.db.layout_of_ty(ty.clone(), trait_env) else {
+                let Ok(layout) = f.db.layout_of_ty(ty.clone(), krate) else {
                     return f.write_str("<layout-error>");
                 };
                 let size_one = layout.size.bytes_usize();
@@ -526,7 +523,7 @@ fn render_const_scalar(
                 let Ok(t) = memory_map.vtable.ty(ty_id) else {
                     return f.write_str("<ty-missing-in-vtable-map>");
                 };
-                let Ok(layout) = f.db.layout_of_ty(t.clone(), trait_env) else {
+                let Ok(layout) = f.db.layout_of_ty(t.clone(), krate) else {
                     return f.write_str("<layout-error>");
                 };
                 let size = layout.size.bytes_usize();
@@ -558,7 +555,7 @@ fn render_const_scalar(
                         return f.write_str("<layout-error>");
                     }
                 });
-                let Ok(layout) = f.db.layout_of_ty(t.clone(), trait_env) else {
+                let Ok(layout) = f.db.layout_of_ty(t.clone(), krate) else {
                     return f.write_str("<layout-error>");
                 };
                 let size = layout.size.bytes_usize();
@@ -570,7 +567,7 @@ fn render_const_scalar(
             }
         },
         TyKind::Tuple(_, subst) => {
-            let Ok(layout) = f.db.layout_of_ty(ty.clone(), trait_env.clone()) else {
+            let Ok(layout) = f.db.layout_of_ty(ty.clone(), krate) else {
                 return f.write_str("<layout-error>");
             };
             f.write_str("(")?;
@@ -583,7 +580,7 @@ fn render_const_scalar(
                 }
                 let ty = ty.assert_ty_ref(Interner); // Tuple only has type argument
                 let offset = layout.fields.offset(id).bytes_usize();
-                let Ok(layout) = f.db.layout_of_ty(ty.clone(), trait_env.clone()) else {
+                let Ok(layout) = f.db.layout_of_ty(ty.clone(), krate) else {
                     f.write_str("<layout-error>")?;
                     continue;
                 };
@@ -593,7 +590,7 @@ fn render_const_scalar(
             f.write_str(")")
         }
         TyKind::Adt(adt, subst) => {
-            let Ok(layout) = f.db.layout_of_adt(adt.0, subst.clone(), trait_env.clone()) else {
+            let Ok(layout) = f.db.layout_of_adt(adt.0, subst.clone(), krate) else {
                 return f.write_str("<layout-error>");
             };
             match adt.0 {
@@ -605,7 +602,7 @@ fn render_const_scalar(
                         &data.variant_data,
                         f,
                         &field_types,
-                        f.db.trait_environment(adt.0.into()),
+                        adt.0.module(f.db.upcast()).krate(),
                         &layout,
                         subst,
                         b,
@@ -617,7 +614,7 @@ fn render_const_scalar(
                 }
                 hir_def::AdtId::EnumId(e) => {
                     let Some((var_id, var_layout)) =
-                        detect_variant_from_bytes(&layout, f.db, trait_env.clone(), b, e)
+                        detect_variant_from_bytes(&layout, f.db, krate, b, e)
                     else {
                         return f.write_str("<failed-to-detect-variant>");
                     };
@@ -629,7 +626,7 @@ fn render_const_scalar(
                         &data.variant_data,
                         f,
                         &field_types,
-                        f.db.trait_environment(adt.0.into()),
+                        adt.0.module(f.db.upcast()).krate(),
                         &var_layout,
                         subst,
                         b,
@@ -648,7 +645,7 @@ fn render_const_scalar(
             let Some(len) = try_const_usize(f.db, len) else {
                 return f.write_str("<unknown-array-len>");
             };
-            let Ok(layout) = f.db.layout_of_ty(ty.clone(), trait_env) else {
+            let Ok(layout) = f.db.layout_of_ty(ty.clone(), krate) else {
                 return f.write_str("<layout-error>");
             };
             let size_one = layout.size.bytes_usize();
@@ -687,7 +684,7 @@ fn render_variant_after_name(
     data: &VariantData,
     f: &mut HirFormatter<'_>,
     field_types: &ArenaMap<LocalFieldId, Binders<Ty>>,
-    trait_env: Arc<TraitEnvironment>,
+    krate: CrateId,
     layout: &Layout,
     subst: &Substitution,
     b: &[u8],
@@ -698,7 +695,7 @@ fn render_variant_after_name(
             let render_field = |f: &mut HirFormatter<'_>, id: LocalFieldId| {
                 let offset = layout.fields.offset(u32::from(id.into_raw()) as usize).bytes_usize();
                 let ty = field_types[id].clone().substitute(Interner, subst);
-                let Ok(layout) = f.db.layout_of_ty(ty.clone(), trait_env.clone()) else {
+                let Ok(layout) = f.db.layout_of_ty(ty.clone(), krate) else {
                     return f.write_str("<layout-error>");
                 };
                 let size = layout.size.bytes_usize();
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 72e6443beb..4b14345aa3 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -1665,7 +1665,6 @@ impl InferenceContext<'_> {
                 // the parameter to coerce to the expected type (for example in
                 // `coerce_unsize_expected_type_4`).
                 let param_ty = self.normalize_associated_types_in(param_ty);
-                let expected_ty = self.normalize_associated_types_in(expected_ty);
                 let expected = Expectation::rvalue_hint(self, expected_ty);
                 // infer with the expected type we have...
                 let ty = self.infer_expr_inner(arg, &expected);
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs
index 0fb71135b4..385f39f537 100644
--- a/crates/hir-ty/src/infer/unify.rs
+++ b/crates/hir-ty/src/infer/unify.rs
@@ -252,8 +252,7 @@ impl<'a> InferenceTable<'a> {
                             // and registering an obligation. But it needs chalk support, so we handle the most basic
                             // case (a non associated const without generic parameters) manually.
                             if subst.len(Interner) == 0 {
-                                if let Ok(eval) =
-                                    self.db.const_eval((*c_id).into(), subst.clone(), None)
+                                if let Ok(eval) = self.db.const_eval((*c_id).into(), subst.clone())
                                 {
                                     eval
                                 } else {
@@ -786,7 +785,7 @@ impl<'a> InferenceTable<'a> {
                 crate::ConstScalar::Unknown => self.new_const_var(data.ty.clone()),
                 // try to evaluate unevaluated const. Replace with new var if const eval failed.
                 crate::ConstScalar::UnevaluatedConst(id, subst) => {
-                    if let Ok(eval) = self.db.const_eval(*id, subst.clone(), None) {
+                    if let Ok(eval) = self.db.const_eval(*id, subst.clone()) {
                         eval
                     } else {
                         self.new_const_var(data.ty.clone())
diff --git a/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs
index ffc7a6f2eb..72e2bcc555 100644
--- a/crates/hir-ty/src/layout.rs
+++ b/crates/hir-ty/src/layout.rs
@@ -1,5 +1,6 @@
 //! Compute the binary representation of a type
 
+use base_db::CrateId;
 use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy};
 use hir_def::{
     layout::{
@@ -60,6 +61,7 @@ pub enum LayoutError {
 }
 
 struct LayoutCx<'a> {
+    krate: CrateId,
     target: &'a TargetDataLayout,
 }
 
@@ -80,7 +82,7 @@ fn layout_of_simd_ty(
     db: &dyn HirDatabase,
     id: StructId,
     subst: &Substitution,
-    env: Arc<TraitEnvironment>,
+    krate: CrateId,
     dl: &TargetDataLayout,
 ) -> Result<Arc<Layout>, LayoutError> {
     let fields = db.field_types(id.into());
@@ -109,7 +111,7 @@ fn layout_of_simd_ty(
     // * the homogeneous field type and the number of fields.
     let (e_ty, e_len, is_array) = if let TyKind::Array(e_ty, _) = f0_ty.kind(Interner) {
         // Extract the number of elements from the layout of the array field:
-        let FieldsShape::Array { count, .. } = db.layout_of_ty(f0_ty.clone(), env.clone())?.fields else {
+        let FieldsShape::Array { count, .. } = db.layout_of_ty(f0_ty.clone(), krate)?.fields else {
             user_error!("Array with non array layout");
         };
 
@@ -120,7 +122,7 @@ fn layout_of_simd_ty(
     };
 
     // Compute the ABI of the element type:
-    let e_ly = db.layout_of_ty(e_ty, env.clone())?;
+    let e_ly = db.layout_of_ty(e_ty, krate)?;
     let Abi::Scalar(e_abi) = e_ly.abi else {
         user_error!("simd type with inner non scalar type");
     };
@@ -150,25 +152,25 @@ fn layout_of_simd_ty(
 pub fn layout_of_ty_query(
     db: &dyn HirDatabase,
     ty: Ty,
-    trait_env: Arc<TraitEnvironment>,
+    krate: CrateId,
 ) -> Result<Arc<Layout>, LayoutError> {
-    let krate = trait_env.krate;
     let Some(target) = db.target_data_layout(krate) else {
         return Err(LayoutError::TargetLayoutNotAvailable);
     };
-    let cx = LayoutCx { target: &target };
+    let cx = LayoutCx { krate, target: &target };
     let dl = &*cx.current_data_layout();
-    let ty = normalize(db, trait_env.clone(), ty.clone());
+    let trait_env = Arc::new(TraitEnvironment::empty(krate));
+    let ty = normalize(db, trait_env, ty.clone());
     let result = match ty.kind(Interner) {
         TyKind::Adt(AdtId(def), subst) => {
             if let hir_def::AdtId::StructId(s) = def {
                 let data = db.struct_data(*s);
                 let repr = data.repr.unwrap_or_default();
                 if repr.simd() {
-                    return layout_of_simd_ty(db, *s, subst, trait_env.clone(), &target);
+                    return layout_of_simd_ty(db, *s, subst, krate, &target);
                 }
             };
-            return db.layout_of_adt(*def, subst.clone(), trait_env.clone());
+            return db.layout_of_adt(*def, subst.clone(), krate);
         }
         TyKind::Scalar(s) => match s {
             chalk_ir::Scalar::Bool => Layout::scalar(
@@ -226,7 +228,7 @@ pub fn layout_of_ty_query(
 
             let fields = tys
                 .iter(Interner)
-                .map(|k| db.layout_of_ty(k.assert_ty_ref(Interner).clone(), trait_env.clone()))
+                .map(|k| db.layout_of_ty(k.assert_ty_ref(Interner).clone(), krate))
                 .collect::<Result<Vec<_>, _>>()?;
             let fields = fields.iter().map(|it| &**it).collect::<Vec<_>>();
             let fields = fields.iter().collect::<Vec<_>>();
@@ -236,7 +238,7 @@ pub fn layout_of_ty_query(
             let count = try_const_usize(db, &count).ok_or(LayoutError::UserError(
                 "unevaluated or mistyped const generic parameter".to_string(),
             ))? as u64;
-            let element = db.layout_of_ty(element.clone(), trait_env.clone())?;
+            let element = db.layout_of_ty(element.clone(), krate)?;
             let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow)?;
 
             let abi = if count != 0 && matches!(element.abi, Abi::Uninhabited) {
@@ -257,7 +259,7 @@ pub fn layout_of_ty_query(
             }
         }
         TyKind::Slice(element) => {
-            let element = db.layout_of_ty(element.clone(), trait_env.clone())?;
+            let element = db.layout_of_ty(element.clone(), krate)?;
             Layout {
                 variants: Variants::Single { index: struct_variant_idx() },
                 fields: FieldsShape::Array { stride: element.size, count: 0 },
@@ -333,7 +335,7 @@ pub fn layout_of_ty_query(
             match impl_trait_id {
                 crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
                     let infer = db.infer(func.into());
-                    return db.layout_of_ty(infer.type_of_rpit[idx].clone(), trait_env.clone());
+                    return db.layout_of_ty(infer.type_of_rpit[idx].clone(), krate);
                 }
                 crate::ImplTraitId::AsyncBlockTypeImplTrait(_, _) => {
                     return Err(LayoutError::NotImplemented)
@@ -349,7 +351,7 @@ pub fn layout_of_ty_query(
                 .map(|it| {
                     db.layout_of_ty(
                         it.ty.clone().substitute(Interner, ClosureSubst(subst).parent_subst()),
-                        trait_env.clone(),
+                        krate,
                     )
                 })
                 .collect::<Result<Vec<_>, _>>()?;
@@ -375,7 +377,7 @@ pub fn layout_of_ty_recover(
     _: &dyn HirDatabase,
     _: &[String],
     _: &Ty,
-    _: &Arc<TraitEnvironment>,
+    _: &CrateId,
 ) -> Result<Arc<Layout>, LayoutError> {
     user_error!("infinite sized recursive type");
 }
diff --git a/crates/hir-ty/src/layout/adt.rs b/crates/hir-ty/src/layout/adt.rs
index 1c92e80f33..19d5e98e73 100644
--- a/crates/hir-ty/src/layout/adt.rs
+++ b/crates/hir-ty/src/layout/adt.rs
@@ -2,6 +2,7 @@
 
 use std::{cmp, ops::Bound};
 
+use base_db::CrateId;
 use hir_def::{
     data::adt::VariantData,
     layout::{Integer, LayoutCalculator, ReprOptions, TargetDataLayout},
@@ -15,7 +16,7 @@ use crate::{
     db::HirDatabase,
     lang_items::is_unsafe_cell,
     layout::{field_ty, Layout, LayoutError, RustcEnumVariantIdx},
-    Substitution, TraitEnvironment,
+    Substitution,
 };
 
 use super::LayoutCx;
@@ -28,18 +29,17 @@ pub fn layout_of_adt_query(
     db: &dyn HirDatabase,
     def: AdtId,
     subst: Substitution,
-    trait_env: Arc<TraitEnvironment>,
+    krate: CrateId,
 ) -> Result<Arc<Layout>, LayoutError> {
-    let krate = trait_env.krate;
     let Some(target) = db.target_data_layout(krate) else {
         return Err(LayoutError::TargetLayoutNotAvailable);
     };
-    let cx = LayoutCx { target: &target };
+    let cx = LayoutCx { krate, target: &target };
     let dl = cx.current_data_layout();
     let handle_variant = |def: VariantId, var: &VariantData| {
         var.fields()
             .iter()
-            .map(|(fd, _)| db.layout_of_ty(field_ty(db, def, fd, &subst), trait_env.clone()))
+            .map(|(fd, _)| db.layout_of_ty(field_ty(db, def, fd, &subst), cx.krate))
             .collect::<Result<Vec<_>, _>>()
     };
     let (variants, repr) = match def {
@@ -134,7 +134,7 @@ pub fn layout_of_adt_recover(
     _: &[String],
     _: &AdtId,
     _: &Substitution,
-    _: &Arc<TraitEnvironment>,
+    _: &CrateId,
 ) -> Result<Arc<Layout>, LayoutError> {
     user_error!("infinite sized recursive type");
 }
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index f3a5f69b2a..5e1040bc6a 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -665,21 +665,13 @@ pub fn is_dyn_method(
     };
     let self_ty = trait_ref.self_type_parameter(Interner);
     if let TyKind::Dyn(d) = self_ty.kind(Interner) {
-        let is_my_trait_in_bounds = d
-            .bounds
-            .skip_binders()
-            .as_slice(Interner)
-            .iter()
-            .map(|it| it.skip_binders())
-            .flat_map(|it| match it {
-                WhereClause::Implemented(tr) => {
-                    all_super_traits(db.upcast(), from_chalk_trait_id(tr.trait_id))
-                }
-                _ => smallvec![],
-            })
-            // rustc doesn't accept `impl Foo<2> for dyn Foo<5>`, so if the trait id is equal, no matter
-            // what the generics are, we are sure that the method is come from the vtable.
-            .any(|x| x == trait_id);
+        let is_my_trait_in_bounds =
+            d.bounds.skip_binders().as_slice(Interner).iter().any(|it| match it.skip_binders() {
+                // rustc doesn't accept `impl Foo<2> for dyn Foo<5>`, so if the trait id is equal, no matter
+                // what the generics are, we are sure that the method is come from the vtable.
+                WhereClause::Implemented(tr) => tr.trait_id == trait_ref.trait_id,
+                _ => false,
+            });
         if is_my_trait_in_bounds {
             return Some(fn_params);
         }
@@ -1512,7 +1504,7 @@ fn autoderef_method_receiver(
     ty: Ty,
 ) -> Vec<(Canonical<Ty>, ReceiverAdjustments)> {
     let mut deref_chain: Vec<_> = Vec::new();
-    let mut autoderef = autoderef::Autoderef::new(table, ty, false);
+    let mut autoderef = autoderef::Autoderef::new(table, ty, true);
     while let Some((ty, derefs)) = autoderef.next() {
         deref_chain.push((
             autoderef.table.canonicalize(ty).value,
diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs
index 922e49d281..dc846fc394 100644
--- a/crates/hir-ty/src/mir.rs
+++ b/crates/hir-ty/src/mir.rs
@@ -3,14 +3,9 @@
 use std::{fmt::Display, iter};
 
 use crate::{
-    consteval::usize_const,
-    db::HirDatabase,
-    display::HirDisplay,
-    infer::{normalize, PointerCast},
-    lang_items::is_box,
-    mapping::ToChalk,
-    CallableDefId, ClosureId, Const, ConstScalar, InferenceResult, Interner, MemoryMap,
-    Substitution, TraitEnvironment, Ty, TyKind,
+    consteval::usize_const, db::HirDatabase, display::HirDisplay, infer::PointerCast,
+    lang_items::is_box, mapping::ToChalk, CallableDefId, ClosureId, Const, ConstScalar,
+    InferenceResult, Interner, MemoryMap, Substitution, Ty, TyKind,
 };
 use base_db::CrateId;
 use chalk_ir::Mutability;
@@ -39,7 +34,6 @@ pub use monomorphization::{
 };
 use smallvec::{smallvec, SmallVec};
 use stdx::{impl_from, never};
-use triomphe::Arc;
 
 use super::consteval::{intern_const_scalar, try_const_usize};
 
@@ -137,21 +131,13 @@ pub enum ProjectionElem<V, T> {
 impl<V, T> ProjectionElem<V, T> {
     pub fn projected_ty(
         &self,
-        mut base: Ty,
+        base: Ty,
         db: &dyn HirDatabase,
         closure_field: impl FnOnce(ClosureId, &Substitution, usize) -> Ty,
         krate: CrateId,
     ) -> Ty {
-        if matches!(base.kind(Interner), TyKind::Alias(_) | TyKind::AssociatedType(..)) {
-            base = normalize(
-                db,
-                // FIXME: we should get this from caller
-                Arc::new(TraitEnvironment::empty(krate)),
-                base,
-            );
-        }
         match self {
-            ProjectionElem::Deref => match &base.kind(Interner) {
+            ProjectionElem::Deref => match &base.data(Interner).kind {
                 TyKind::Raw(_, inner) | TyKind::Ref(_, _, inner) => inner.clone(),
                 TyKind::Adt(adt, subst) if is_box(db, adt.0) => {
                     subst.at(Interner, 0).assert_ty_ref(Interner).clone()
@@ -161,7 +147,7 @@ impl<V, T> ProjectionElem<V, T> {
                     return TyKind::Error.intern(Interner);
                 }
             },
-            ProjectionElem::Field(f) => match &base.kind(Interner) {
+            ProjectionElem::Field(f) => match &base.data(Interner).kind {
                 TyKind::Adt(_, subst) => {
                     db.field_types(f.parent)[f.local_id].clone().substitute(Interner, subst)
                 }
@@ -170,7 +156,7 @@ impl<V, T> ProjectionElem<V, T> {
                     return TyKind::Error.intern(Interner);
                 }
             },
-            ProjectionElem::TupleOrClosureField(f) => match &base.kind(Interner) {
+            ProjectionElem::TupleOrClosureField(f) => match &base.data(Interner).kind {
                 TyKind::Tuple(_, subst) => subst
                     .as_slice(Interner)
                     .get(*f)
@@ -187,7 +173,7 @@ impl<V, T> ProjectionElem<V, T> {
                 }
             },
             ProjectionElem::ConstantIndex { .. } | ProjectionElem::Index(_) => {
-                match &base.kind(Interner) {
+                match &base.data(Interner).kind {
                     TyKind::Array(inner, _) | TyKind::Slice(inner) => inner.clone(),
                     _ => {
                         never!("Overloaded index is not a projection");
@@ -195,7 +181,7 @@ impl<V, T> ProjectionElem<V, T> {
                     }
                 }
             }
-            &ProjectionElem::Subslice { from, to } => match &base.kind(Interner) {
+            &ProjectionElem::Subslice { from, to } => match &base.data(Interner).kind {
                 TyKind::Array(inner, c) => {
                     let next_c = usize_const(
                         db,
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 7bd2756c14..47c9354768 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -29,7 +29,7 @@ use crate::{
     infer::PointerCast,
     layout::{Layout, LayoutError, RustcEnumVariantIdx},
     mapping::from_chalk,
-    method_resolution::{is_dyn_method, lookup_impl_const},
+    method_resolution::is_dyn_method,
     name, static_lifetime,
     traits::FnTrait,
     utils::{detect_variant_from_bytes, ClosureSubst},
@@ -484,10 +484,9 @@ pub fn interpret_mir(
     // a zero size, hoping that they are all outside of our current body. Even without a fix for #7434, we can
     // (and probably should) do better here, for example by excluding bindings outside of the target expression.
     assert_placeholder_ty_is_unused: bool,
-    trait_env: Option<Arc<TraitEnvironment>>,
 ) -> (Result<Const>, String, String) {
     let ty = body.locals[return_slot()].ty.clone();
-    let mut evaluator = Evaluator::new(db, body.owner, assert_placeholder_ty_is_unused, trait_env);
+    let mut evaluator = Evaluator::new(db, body.owner, assert_placeholder_ty_is_unused);
     let it: Result<Const> = (|| {
         if evaluator.ptr_size() != std::mem::size_of::<usize>() {
             not_supported!("targets with different pointer size from host");
@@ -513,9 +512,9 @@ impl Evaluator<'_> {
         db: &'a dyn HirDatabase,
         owner: DefWithBodyId,
         assert_placeholder_ty_is_unused: bool,
-        trait_env: Option<Arc<TraitEnvironment>>,
     ) -> Evaluator<'a> {
         let crate_id = owner.module(db.upcast()).krate();
+        let trait_env = db.trait_environment_for_body(owner);
         Evaluator {
             stack: vec![0],
             heap: vec![0],
@@ -525,7 +524,7 @@ impl Evaluator<'_> {
             static_locations: HashMap::default(),
             db,
             random_state: oorandom::Rand64::new(0),
-            trait_env: trait_env.unwrap_or_else(|| db.trait_environment_for_body(owner)),
+            trait_env,
             crate_id,
             stdout: vec![],
             stderr: vec![],
@@ -635,7 +634,7 @@ impl Evaluator<'_> {
                     addr = addr.offset(ty_size * offset);
                 }
                 &ProjectionElem::Subslice { from, to } => {
-                    let inner_ty = match &ty.kind(Interner) {
+                    let inner_ty = match &ty.data(Interner).kind {
                         TyKind::Array(inner, _) | TyKind::Slice(inner) => inner.clone(),
                         _ => TyKind::Error.intern(Interner),
                     };
@@ -695,14 +694,14 @@ impl Evaluator<'_> {
         }
         let r = self
             .db
-            .layout_of_ty(ty.clone(), self.trait_env.clone())
+            .layout_of_ty(ty.clone(), self.crate_id)
             .map_err(|e| MirEvalError::LayoutError(e, ty.clone()))?;
         self.layout_cache.borrow_mut().insert(ty.clone(), r.clone());
         Ok(r)
     }
 
     fn layout_adt(&self, adt: AdtId, subst: Substitution) -> Result<Arc<Layout>> {
-        self.db.layout_of_adt(adt, subst.clone(), self.trait_env.clone()).map_err(|e| {
+        self.db.layout_of_adt(adt, subst.clone(), self.crate_id).map_err(|e| {
             MirEvalError::LayoutError(e, TyKind::Adt(chalk_ir::AdtId(adt), subst).intern(Interner))
         })
     }
@@ -794,7 +793,7 @@ impl Evaluator<'_> {
                                 .iter()
                                 .map(|it| self.operand_ty_and_eval(it, &mut locals))
                                 .collect::<Result<Vec<_>>>()?;
-                            let stack_frame = match &fn_ty.kind(Interner) {
+                            let stack_frame = match &fn_ty.data(Interner).kind {
                                 TyKind::Function(_) => {
                                     let bytes = self.eval_operand(func, &mut locals)?;
                                     self.exec_fn_pointer(
@@ -1256,7 +1255,7 @@ impl Evaluator<'_> {
                     PointerCast::ReifyFnPointer | PointerCast::ClosureFnPointer(_) => {
                         let current_ty = self.operand_ty(operand, locals)?;
                         if let TyKind::FnDef(_, _) | TyKind::Closure(_, _) =
-                            &current_ty.kind(Interner)
+                            &current_ty.data(Interner).kind
                         {
                             let id = self.vtable_map.id(current_ty);
                             let ptr_size = self.ptr_size();
@@ -1409,8 +1408,8 @@ impl Evaluator<'_> {
         addr: Interval,
     ) -> Result<IntervalOrOwned> {
         use IntervalOrOwned::*;
-        Ok(match &target_ty.kind(Interner) {
-            TyKind::Slice(_) => match &current_ty.kind(Interner) {
+        Ok(match &target_ty.data(Interner).kind {
+            TyKind::Slice(_) => match &current_ty.data(Interner).kind {
                 TyKind::Array(_, size) => {
                     let len = match try_const_usize(self.db, size) {
                         None => {
@@ -1436,7 +1435,7 @@ impl Evaluator<'_> {
                 r.extend(vtable.to_le_bytes().into_iter());
                 Owned(r)
             }
-            TyKind::Adt(id, target_subst) => match &current_ty.kind(Interner) {
+            TyKind::Adt(id, target_subst) => match &current_ty.data(Interner).kind {
                 TyKind::Adt(current_id, current_subst) => {
                     if id != current_id {
                         not_supported!("unsizing struct with different type");
@@ -1572,54 +1571,35 @@ impl Evaluator<'_> {
         let chalk_ir::ConstValue::Concrete(c) = &konst.data(Interner).value else {
             not_supported!("evaluating non concrete constant");
         };
-        let result_owner;
-        let (v, memory_map) = match &c.interned {
-            ConstScalar::Bytes(v, mm) => (v, mm),
-            ConstScalar::UnevaluatedConst(const_id, subst) => 'b: {
-                let mut const_id = *const_id;
-                let mut subst = subst.clone();
-                if let hir_def::GeneralConstId::ConstId(c) = const_id {
-                    let (c, s) = lookup_impl_const(self.db, self.trait_env.clone(), c, subst);
-                    const_id = hir_def::GeneralConstId::ConstId(c);
-                    subst = s;
-                }
-                result_owner = self
-                    .db
-                    .const_eval(const_id.into(), subst, Some(self.trait_env.clone()))
-                    .map_err(|e| {
-                        let name = const_id.name(self.db.upcast());
-                        MirEvalError::ConstEvalError(name, Box::new(e))
-                    })?;
-                if let chalk_ir::ConstValue::Concrete(c) = &result_owner.data(Interner).value {
-                    if let ConstScalar::Bytes(v, mm) = &c.interned {
-                        break 'b (v, mm);
+        Ok(match &c.interned {
+            ConstScalar::Bytes(v, memory_map) => {
+                let mut v: Cow<'_, [u8]> = Cow::Borrowed(v);
+                let patch_map = memory_map.transform_addresses(|b, align| {
+                    let addr = self.heap_allocate(b.len(), align)?;
+                    self.write_memory(addr, b)?;
+                    Ok(addr.to_usize())
+                })?;
+                let (size, align) = self.size_align_of(ty, locals)?.unwrap_or((v.len(), 1));
+                if size != v.len() {
+                    // Handle self enum
+                    if size == 16 && v.len() < 16 {
+                        v = Cow::Owned(pad16(&v, false).to_vec());
+                    } else if size < 16 && v.len() == 16 {
+                        v = Cow::Owned(v[0..size].to_vec());
+                    } else {
+                        return Err(MirEvalError::InvalidConst(konst.clone()));
                     }
                 }
-                not_supported!("unevaluatable constant");
+                let addr = self.heap_allocate(size, align)?;
+                self.write_memory(addr, &v)?;
+                self.patch_addresses(&patch_map, &memory_map.vtable, addr, ty, locals)?;
+                Interval::new(addr, size)
             }
-            ConstScalar::Unknown => not_supported!("evaluating unknown const"),
-        };
-        let mut v: Cow<'_, [u8]> = Cow::Borrowed(v);
-        let patch_map = memory_map.transform_addresses(|b, align| {
-            let addr = self.heap_allocate(b.len(), align)?;
-            self.write_memory(addr, b)?;
-            Ok(addr.to_usize())
-        })?;
-        let (size, align) = self.size_align_of(ty, locals)?.unwrap_or((v.len(), 1));
-        if size != v.len() {
-            // Handle self enum
-            if size == 16 && v.len() < 16 {
-                v = Cow::Owned(pad16(&v, false).to_vec());
-            } else if size < 16 && v.len() == 16 {
-                v = Cow::Owned(v[0..size].to_vec());
-            } else {
-                return Err(MirEvalError::InvalidConst(konst.clone()));
+            ConstScalar::UnevaluatedConst(..) => {
+                not_supported!("unevaluated const present in monomorphized mir");
             }
-        }
-        let addr = self.heap_allocate(size, align)?;
-        self.write_memory(addr, &v)?;
-        self.patch_addresses(&patch_map, &memory_map.vtable, addr, ty, locals)?;
-        Ok(Interval::new(addr, size))
+            ConstScalar::Unknown => not_supported!("evaluating unknown const"),
+        })
     }
 
     fn eval_place(&mut self, p: &Place, locals: &Locals) -> Result<Interval> {
@@ -1822,13 +1802,9 @@ impl Evaluator<'_> {
                     }
                     AdtId::EnumId(e) => {
                         let layout = this.layout(ty)?;
-                        if let Some((v, l)) = detect_variant_from_bytes(
-                            &layout,
-                            this.db,
-                            this.trait_env.clone(),
-                            bytes,
-                            e,
-                        ) {
+                        if let Some((v, l)) =
+                            detect_variant_from_bytes(&layout, this.db, this.crate_id, bytes, e)
+                        {
                             let data = &this.db.enum_data(e).variants[v].variant_data;
                             let field_types = this
                                 .db
@@ -1939,7 +1915,7 @@ impl Evaluator<'_> {
     ) -> Result<Option<StackFrame>> {
         let id = from_bytes!(usize, bytes.get(self)?);
         let next_ty = self.vtable_map.ty(id)?.clone();
-        match &next_ty.kind(Interner) {
+        match &next_ty.data(Interner).kind {
             TyKind::FnDef(def, generic_args) => {
                 self.exec_fn_def(*def, generic_args, destination, args, &locals, target_bb, span)
             }
@@ -2190,7 +2166,7 @@ impl Evaluator<'_> {
             let size = self.size_of_sized(&func_ty, locals, "self type of fn trait")?;
             func_data = Interval { addr: Address::from_bytes(func_data.get(self)?)?, size };
         }
-        match &func_ty.kind(Interner) {
+        match &func_ty.data(Interner).kind {
             TyKind::FnDef(def, subst) => {
                 return self.exec_fn_def(
                     *def,
@@ -2417,7 +2393,7 @@ pub fn render_const_using_debug_impl(
     owner: ConstId,
     c: &Const,
 ) -> Result<String> {
-    let mut evaluator = Evaluator::new(db, owner.into(), false, None);
+    let mut evaluator = Evaluator::new(db, owner.into(), false);
     let locals = &Locals {
         ptr: ArenaMap::new(),
         body: db
diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs
index 9ad6087cad..cedc453803 100644
--- a/crates/hir-ty/src/mir/eval/shim.rs
+++ b/crates/hir-ty/src/mir/eval/shim.rs
@@ -380,17 +380,6 @@ impl Evaluator<'_> {
                 let id = from_bytes!(i64, id.get(self)?);
                 self.exec_syscall(id, rest, destination, locals, span)
             }
-            "sched_getaffinity" => {
-                let [_pid, _set_size, set] = args else {
-                    return Err(MirEvalError::TypeError("libc::write args are not provided"));
-                };
-                let set = Address::from_bytes(set.get(self)?)?;
-                // Only enable core 0 (we are single threaded anyway), which is bitset 0x0000001
-                self.write_memory(set, &[1])?;
-                // return 0 as success
-                self.write_memory_using_ref(destination.addr, destination.size)?.fill(0);
-                Ok(())
-            }
             _ => not_supported!("unknown external function {as_str}"),
         }
     }
@@ -613,26 +602,6 @@ impl Evaluator<'_> {
                     destination.write_from_bytes(self, &align.to_le_bytes())
                 }
             }
-            "type_name" => {
-                let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
-                else {
-                    return Err(MirEvalError::TypeError("type_name generic arg is not provided"));
-                };
-                let Ok(ty_name) = ty.display_source_code(
-                    self.db,
-                    locals.body.owner.module(self.db.upcast()),
-                    true,
-                ) else {
-                    not_supported!("fail in generating type_name using source code display");
-                };
-                let len = ty_name.len();
-                let addr = self.heap_allocate(len, 1)?;
-                self.write_memory(addr, ty_name.as_bytes())?;
-                destination.slice(0..self.ptr_size()).write_from_bytes(self, &addr.to_bytes())?;
-                destination
-                    .slice(self.ptr_size()..2 * self.ptr_size())
-                    .write_from_bytes(self, &len.to_le_bytes())
-            }
             "needs_drop" => {
                 let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
                 else {
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index e443c58f22..3610858790 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -633,7 +633,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                     );
                 }
                 let callee_ty = self.expr_ty_after_adjustments(*callee);
-                match &callee_ty.kind(Interner) {
+                match &callee_ty.data(Interner).kind {
                     chalk_ir::TyKind::FnDef(..) => {
                         let func = Operand::from_bytes(vec![], callee_ty.clone());
                         self.lower_call_and_args(
@@ -1229,7 +1229,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
             }
             Expr::Array(l) => match l {
                 Array::ElementList { elements, .. } => {
-                    let elem_ty = match &self.expr_ty_without_adjust(expr_id).kind(Interner) {
+                    let elem_ty = match &self.expr_ty_without_adjust(expr_id).data(Interner).kind {
                         TyKind::Array(ty, _) => ty.clone(),
                         _ => {
                             return Err(MirLowerError::TypeError(
@@ -1260,7 +1260,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
                     else {
                         return Ok(None);
                     };
-                    let len = match &self.expr_ty_without_adjust(expr_id).kind(Interner) {
+                    let len = match &self.expr_ty_without_adjust(expr_id).data(Interner).kind {
                         TyKind::Array(_, len) => len.clone(),
                         _ => {
                             return Err(MirLowerError::TypeError(
@@ -1341,7 +1341,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
     fn lower_literal_to_operand(&mut self, ty: Ty, l: &Literal) -> Result<Operand> {
         let size = self
             .db
-            .layout_of_ty(ty.clone(), self.db.trait_environment_for_body(self.owner))?
+            .layout_of_ty(ty.clone(), self.owner.module(self.db.upcast()).krate())?
             .size
             .bytes_usize();
         let bytes = match l {
@@ -1418,7 +1418,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
         } else {
             let name = const_id.name(self.db.upcast());
             self.db
-                .const_eval(const_id.into(), subst, None)
+                .const_eval(const_id.into(), subst)
                 .map_err(|e| MirLowerError::ConstEvalError(name, Box::new(e)))?
         };
         Ok(Operand::Constant(c))
diff --git a/crates/hir-ty/src/mir/monomorphization.rs b/crates/hir-ty/src/mir/monomorphization.rs
index c565228d91..e4574c77e2 100644
--- a/crates/hir-ty/src/mir/monomorphization.rs
+++ b/crates/hir-ty/src/mir/monomorphization.rs
@@ -13,14 +13,15 @@ use chalk_ir::{
     fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable},
     ConstData, DebruijnIndex,
 };
-use hir_def::DefWithBodyId;
+use hir_def::{DefWithBodyId, GeneralConstId};
 use triomphe::Arc;
 
 use crate::{
-    consteval::{intern_const_scalar, unknown_const},
+    consteval::unknown_const,
     db::HirDatabase,
     from_placeholder_idx,
     infer::normalize,
+    method_resolution::lookup_impl_const,
     utils::{generics, Generics},
     ClosureId, Const, Interner, ProjectionTy, Substitution, TraitEnvironment, Ty, TyKind,
 };
@@ -192,12 +193,25 @@ impl Filler<'_> {
                     | chalk_ir::ConstValue::Placeholder(_) => {}
                     chalk_ir::ConstValue::Concrete(cc) => match &cc.interned {
                         crate::ConstScalar::UnevaluatedConst(const_id, subst) => {
+                            let mut const_id = *const_id;
                             let mut subst = subst.clone();
                             self.fill_subst(&mut subst)?;
-                            *c = intern_const_scalar(
-                                crate::ConstScalar::UnevaluatedConst(*const_id, subst),
-                                c.data(Interner).ty.clone(),
-                            );
+                            if let GeneralConstId::ConstId(c) = const_id {
+                                let (c, s) = lookup_impl_const(
+                                    self.db,
+                                    self.db.trait_environment_for_body(self.owner),
+                                    c,
+                                    subst,
+                                );
+                                const_id = GeneralConstId::ConstId(c);
+                                subst = s;
+                            }
+                            let result =
+                                self.db.const_eval(const_id.into(), subst).map_err(|e| {
+                                    let name = const_id.name(self.db.upcast());
+                                    MirLowerError::ConstEvalError(name, Box::new(e))
+                                })?;
+                            *c = result;
                         }
                         crate::ConstScalar::Bytes(_, _) | crate::ConstScalar::Unknown => (),
                     },
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs
index 75b8b9afa7..0c38fe5d6a 100644
--- a/crates/hir-ty/src/utils.rs
+++ b/crates/hir-ty/src/utils.rs
@@ -28,15 +28,14 @@ use intern::Interned;
 use rustc_hash::FxHashSet;
 use smallvec::{smallvec, SmallVec};
 use stdx::never;
-use triomphe::Arc;
 
 use crate::{
     consteval::unknown_const,
     db::HirDatabase,
     layout::{Layout, TagEncoding},
     mir::pad16,
-    ChalkTraitId, Const, ConstScalar, GenericArg, Interner, Substitution, TraitEnvironment,
-    TraitRef, TraitRefExt, Ty, WhereClause,
+    ChalkTraitId, Const, ConstScalar, GenericArg, Interner, Substitution, TraitRef, TraitRefExt,
+    Ty, WhereClause,
 };
 
 pub(crate) fn fn_traits(
@@ -418,7 +417,7 @@ impl FallibleTypeFolder<Interner> for UnevaluatedConstEvaluatorFolder<'_> {
     ) -> Result<Const, Self::Error> {
         if let chalk_ir::ConstValue::Concrete(c) = &constant.data(Interner).value {
             if let ConstScalar::UnevaluatedConst(id, subst) = &c.interned {
-                if let Ok(eval) = self.db.const_eval(*id, subst.clone(), None) {
+                if let Ok(eval) = self.db.const_eval(*id, subst.clone()) {
                     return Ok(eval);
                 } else {
                     return Ok(unknown_const(constant.data(Interner).ty.clone()));
@@ -432,11 +431,10 @@ impl FallibleTypeFolder<Interner> for UnevaluatedConstEvaluatorFolder<'_> {
 pub(crate) fn detect_variant_from_bytes<'a>(
     layout: &'a Layout,
     db: &dyn HirDatabase,
-    trait_env: Arc<TraitEnvironment>,
+    krate: CrateId,
     b: &[u8],
     e: EnumId,
 ) -> Option<(LocalEnumVariantId, &'a Layout)> {
-    let krate = trait_env.krate;
     let (var_id, var_layout) = match &layout.variants {
         hir_def::layout::Variants::Single { index } => (index.0, &*layout),
         hir_def::layout::Variants::Multiple { tag, tag_encoding, variants, .. } => {
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index b094bb7a06..f8d9398ae2 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -378,6 +378,11 @@ impl ModuleDef {
             ModuleDef::BuiltinType(_) | ModuleDef::Macro(_) => return Vec::new(),
         };
 
+        let module = match self.module(db) {
+            Some(it) => it,
+            None => return Vec::new(),
+        };
+
         let mut acc = Vec::new();
 
         match self.as_def_with_body() {
@@ -385,7 +390,7 @@ impl ModuleDef {
                 def.diagnostics(db, &mut acc);
             }
             None => {
-                for diag in hir_ty::diagnostics::incorrect_case(db, id) {
+                for diag in hir_ty::diagnostics::incorrect_case(db, module.id.krate(), id) {
                     acc.push(diag.into())
                 }
             }
@@ -960,15 +965,8 @@ impl Field {
     }
 
     pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
-        db.layout_of_ty(
-            self.ty(db).ty.clone(),
-            db.trait_environment(match hir_def::VariantId::from(self.parent) {
-                hir_def::VariantId::EnumVariantId(id) => GenericDefId::EnumVariantId(id),
-                hir_def::VariantId::StructId(id) => GenericDefId::AdtId(id.into()),
-                hir_def::VariantId::UnionId(id) => GenericDefId::AdtId(id.into()),
-            }),
-        )
-        .map(|layout| Layout(layout, db.target_data_layout(self.krate(db).into()).unwrap()))
+        db.layout_of_ty(self.ty(db).ty.clone(), self.parent.module(db).krate().into())
+            .map(|layout| Layout(layout, db.target_data_layout(self.krate(db).into()).unwrap()))
     }
 
     pub fn parent_def(&self, _db: &dyn HirDatabase) -> VariantDef {
@@ -1248,12 +1246,8 @@ impl Adt {
             return Err(LayoutError::HasPlaceholder);
         }
         let krate = self.krate(db).id;
-        db.layout_of_adt(
-            self.into(),
-            Substitution::empty(Interner),
-            db.trait_environment(self.into()),
-        )
-        .map(|layout| Layout(layout, db.target_data_layout(krate).unwrap()))
+        db.layout_of_adt(self.into(), Substitution::empty(Interner), krate)
+            .map(|layout| Layout(layout, db.target_data_layout(krate).unwrap()))
     }
 
     /// Turns this ADT into a type. Any type parameters of the ADT will be
@@ -1826,7 +1820,7 @@ impl DefWithBody {
             // FIXME: don't ignore diagnostics for in type const
             DefWithBody::InTypeConst(_) => return,
         };
-        for diag in hir_ty::diagnostics::incorrect_case(db, def.into()) {
+        for diag in hir_ty::diagnostics::incorrect_case(db, krate, def.into()) {
             acc.push(diag.into())
         }
     }
@@ -1993,7 +1987,7 @@ impl Function {
                 return r;
             }
         };
-        let (result, stdout, stderr) = interpret_mir(db, body, false, None);
+        let (result, stdout, stderr) = interpret_mir(db, body, false);
         let mut text = match result {
             Ok(_) => "pass".to_string(),
             Err(e) => {
@@ -2162,7 +2156,7 @@ impl Const {
     }
 
     pub fn render_eval(self, db: &dyn HirDatabase) -> Result<String, ConstEvalError> {
-        let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?;
+        let c = db.const_eval(self.id.into(), Substitution::empty(Interner))?;
         let data = &c.data(Interner);
         if let TyKind::Scalar(s) = data.ty.kind(Interner) {
             if matches!(s, Scalar::Int(_) | Scalar::Uint(_)) {
@@ -4328,7 +4322,7 @@ impl Type {
     }
 
     pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
-        db.layout_of_ty(self.ty.clone(), self.env.clone())
+        db.layout_of_ty(self.ty.clone(), self.env.krate)
             .map(|layout| Layout(layout, db.target_data_layout(self.env.krate).unwrap()))
     }
 }
diff --git a/crates/ide-assists/src/handlers/change_visibility.rs b/crates/ide-assists/src/handlers/change_visibility.rs
index e6179ab8b1..2b1d8f6f01 100644
--- a/crates/ide-assists/src/handlers/change_visibility.rs
+++ b/crates/ide-assists/src/handlers/change_visibility.rs
@@ -2,10 +2,9 @@ use syntax::{
     ast::{self, HasName, HasVisibility},
     AstNode,
     SyntaxKind::{
-        self, ASSOC_ITEM_LIST, CONST, ENUM, FN, MACRO_DEF, MODULE, SOURCE_FILE, STATIC, STRUCT,
-        TRAIT, TYPE_ALIAS, USE, VISIBILITY,
+        CONST, ENUM, FN, MACRO_DEF, MODULE, STATIC, STRUCT, TRAIT, TYPE_ALIAS, USE, VISIBILITY,
     },
-    SyntaxNode, T,
+    T,
 };
 
 use crate::{utils::vis_offset, AssistContext, AssistId, AssistKind, Assists};
@@ -47,11 +46,13 @@ fn add_vis(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
 
     let (offset, target) = if let Some(keyword) = item_keyword {
         let parent = keyword.parent()?;
-
-        if !can_add(&parent) {
+        let def_kws =
+            vec![CONST, STATIC, TYPE_ALIAS, FN, MODULE, STRUCT, ENUM, TRAIT, USE, MACRO_DEF];
+        // Parent is not a definition, can't add visibility
+        if !def_kws.iter().any(|&def_kw| def_kw == parent.kind()) {
             return None;
         }
-        // Already has visibility, do nothing
+        // Already have visibility, do nothing
         if parent.children().any(|child| child.kind() == VISIBILITY) {
             return None;
         }
@@ -85,29 +86,6 @@ fn add_vis(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
     )
 }
 
-fn can_add(node: &SyntaxNode) -> bool {
-    const LEGAL: &[SyntaxKind] =
-        &[CONST, STATIC, TYPE_ALIAS, FN, MODULE, STRUCT, ENUM, TRAIT, USE, MACRO_DEF];
-
-    LEGAL.contains(&node.kind()) && {
-        let Some(p) = node.parent() else {
-            return false;
-        };
-
-        if p.kind() == ASSOC_ITEM_LIST {
-            p.parent()
-                .and_then(|it| ast::Impl::cast(it))
-                // inherent impls i.e 'non-trait impls' have a non-local
-                // effect, thus can have visibility even when nested.
-                // so filter them out
-                .filter(|imp| imp.for_token().is_none())
-                .is_some()
-        } else {
-            matches!(p.kind(), SOURCE_FILE | MODULE)
-        }
-    }
-}
-
 fn change_vis(acc: &mut Assists, vis: ast::Visibility) -> Option<()> {
     if vis.syntax().text() == "pub" {
         let target = vis.syntax().text_range();
@@ -151,16 +129,6 @@ mod tests {
         check_assist(change_visibility, "unsafe f$0n foo() {}", "pub(crate) unsafe fn foo() {}");
         check_assist(change_visibility, "$0macro foo() {}", "pub(crate) macro foo() {}");
         check_assist(change_visibility, "$0use foo;", "pub(crate) use foo;");
-        check_assist(
-            change_visibility,
-            "impl Foo { f$0n foo() {} }",
-            "impl Foo { pub(crate) fn foo() {} }",
-        );
-        check_assist(
-            change_visibility,
-            "fn bar() { impl Foo { f$0n foo() {} } }",
-            "fn bar() { impl Foo { pub(crate) fn foo() {} } }",
-        );
     }
 
     #[test]
@@ -245,33 +213,4 @@ mod tests {
         check_assist_target(change_visibility, "pub(crate)$0 fn foo() {}", "pub(crate)");
         check_assist_target(change_visibility, "struct S { $0field: u32 }", "field");
     }
-
-    #[test]
-    fn not_applicable_for_items_within_traits() {
-        check_assist_not_applicable(change_visibility, "trait Foo { f$0n run() {} }");
-        check_assist_not_applicable(change_visibility, "trait Foo { con$0st FOO: u8 = 69; }");
-        check_assist_not_applicable(change_visibility, "impl Foo for Bar { f$0n quox() {} }");
-    }
-
-    #[test]
-    fn not_applicable_for_items_within_fns() {
-        check_assist_not_applicable(change_visibility, "fn foo() { f$0n inner() {} }");
-        check_assist_not_applicable(change_visibility, "fn foo() { unsafe f$0n inner() {} }");
-        check_assist_not_applicable(change_visibility, "fn foo() { const f$0n inner() {} }");
-        check_assist_not_applicable(change_visibility, "fn foo() { con$0st FOO: u8 = 69; }");
-        check_assist_not_applicable(change_visibility, "fn foo() { en$0um Foo {} }");
-        check_assist_not_applicable(change_visibility, "fn foo() { stru$0ct Foo {} }");
-        check_assist_not_applicable(change_visibility, "fn foo() { mo$0d foo {} }");
-        check_assist_not_applicable(change_visibility, "fn foo() { $0use foo; }");
-        check_assist_not_applicable(change_visibility, "fn foo() { $0type Foo = Bar<T>; }");
-        check_assist_not_applicable(change_visibility, "fn foo() { tr$0ait Foo {} }");
-        check_assist_not_applicable(
-            change_visibility,
-            "fn foo() { impl Trait for Bar { f$0n bar() {} } }",
-        );
-        check_assist_not_applicable(
-            change_visibility,
-            "fn foo() { impl Trait for Bar { con$0st FOO: u8 = 69; } }",
-        );
-    }
 }
diff --git a/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/crates/ide-diagnostics/src/handlers/incorrect_case.rs
index 235062bf53..92fd4f71ca 100644
--- a/crates/ide-diagnostics/src/handlers/incorrect_case.rs
+++ b/crates/ide-diagnostics/src/handlers/incorrect_case.rs
@@ -545,100 +545,4 @@ pub static SomeStatic: u8 = 10;
     "#,
         );
     }
-
-    #[test]
-    fn fn_inner_items() {
-        check_diagnostics(
-            r#"
-fn main() {
-    const foo: bool = true;
-        //^^^ 💡 warn: Constant `foo` should have UPPER_SNAKE_CASE name, e.g. `FOO`
-    static bar: bool = true;
-         //^^^ 💡 warn: Static variable `bar` should have UPPER_SNAKE_CASE name, e.g. `BAR`
-    fn BAZ() {
-     //^^^ 💡 warn: Function `BAZ` should have snake_case name, e.g. `baz`
-        const foo: bool = true;
-            //^^^ 💡 warn: Constant `foo` should have UPPER_SNAKE_CASE name, e.g. `FOO`
-        static bar: bool = true;
-             //^^^ 💡 warn: Static variable `bar` should have UPPER_SNAKE_CASE name, e.g. `BAR`
-        fn BAZ() {
-         //^^^ 💡 warn: Function `BAZ` should have snake_case name, e.g. `baz`
-            let INNER_INNER = 42;
-              //^^^^^^^^^^^ 💡 warn: Variable `INNER_INNER` should have snake_case name, e.g. `inner_inner`
-        }
-
-        let INNER_LOCAL = 42;
-          //^^^^^^^^^^^ 💡 warn: Variable `INNER_LOCAL` should have snake_case name, e.g. `inner_local`
-    }
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn const_body_inner_items() {
-        check_diagnostics(
-            r#"
-const _: () = {
-    static bar: bool = true;
-         //^^^ 💡 warn: Static variable `bar` should have UPPER_SNAKE_CASE name, e.g. `BAR`
-    fn BAZ() {}
-     //^^^ 💡 warn: Function `BAZ` should have snake_case name, e.g. `baz`
-
-    const foo: () = {
-        //^^^ 💡 warn: Constant `foo` should have UPPER_SNAKE_CASE name, e.g. `FOO`
-        const foo: bool = true;
-            //^^^ 💡 warn: Constant `foo` should have UPPER_SNAKE_CASE name, e.g. `FOO`
-        static bar: bool = true;
-             //^^^ 💡 warn: Static variable `bar` should have UPPER_SNAKE_CASE name, e.g. `BAR`
-        fn BAZ() {}
-         //^^^ 💡 warn: Function `BAZ` should have snake_case name, e.g. `baz`
-    };
-};
-"#,
-        );
-    }
-
-    #[test]
-    fn static_body_inner_items() {
-        check_diagnostics(
-            r#"
-static FOO: () = {
-    const foo: bool = true;
-        //^^^ 💡 warn: Constant `foo` should have UPPER_SNAKE_CASE name, e.g. `FOO`
-    fn BAZ() {}
-     //^^^ 💡 warn: Function `BAZ` should have snake_case name, e.g. `baz`
-
-    static bar: () = {
-         //^^^ 💡 warn: Static variable `bar` should have UPPER_SNAKE_CASE name, e.g. `BAR`
-        const foo: bool = true;
-            //^^^ 💡 warn: Constant `foo` should have UPPER_SNAKE_CASE name, e.g. `FOO`
-        static bar: bool = true;
-             //^^^ 💡 warn: Static variable `bar` should have UPPER_SNAKE_CASE name, e.g. `BAR`
-        fn BAZ() {}
-         //^^^ 💡 warn: Function `BAZ` should have snake_case name, e.g. `baz`
-    };
-};
-"#,
-        );
-    }
-
-    #[test]
-    fn enum_variant_body_inner_item() {
-        check_diagnostics(
-            r#"
-enum E {
-    A = {
-        const foo: bool = true;
-            //^^^ 💡 warn: Constant `foo` should have UPPER_SNAKE_CASE name, e.g. `FOO`
-        static bar: bool = true;
-             //^^^ 💡 warn: Static variable `bar` should have UPPER_SNAKE_CASE name, e.g. `BAR`
-        fn BAZ() {}
-         //^^^ 💡 warn: Function `BAZ` should have snake_case name, e.g. `baz`
-        42
-    },
-}
-"#,
-        );
-    }
 }
diff --git a/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/crates/ide-diagnostics/src/handlers/mutability_errors.rs
index e0c3bedce4..935f12a396 100644
--- a/crates/ide-diagnostics/src/handlers/mutability_errors.rs
+++ b/crates/ide-diagnostics/src/handlers/mutability_errors.rs
@@ -1084,33 +1084,6 @@ fn f() {
         );
     }
 
-    #[test]
-    fn regression_15143() {
-        check_diagnostics(
-            r#"
-        trait Tr {
-            type Ty;
-        }
-
-        struct A;
-
-        impl Tr for A {
-            type Ty = (u32, i64);
-        }
-
-        struct B<T: Tr> {
-            f: <T as Tr>::Ty,
-        }
-
-        fn main(b: B<A>) {
-            let f = b.f.0;
-            f = 5;
-          //^^^^^ 💡 error: cannot mutate immutable variable `f`
-        }
-            "#,
-        );
-    }
-
     #[test]
     fn allow_unused_mut_for_identifiers_starting_with_underline() {
         check_diagnostics(
diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs
index b621a8dda7..774383d50d 100644
--- a/crates/ide/src/inlay_hints/chaining.rs
+++ b/crates/ide/src/inlay_hints/chaining.rs
@@ -474,7 +474,7 @@ fn main() {
                                         file_id: FileId(
                                             1,
                                         ),
-                                        range: 9289..9297,
+                                        range: 9288..9296,
                                     },
                                 ),
                                 tooltip: "",
@@ -487,7 +487,7 @@ fn main() {
                                         file_id: FileId(
                                             1,
                                         ),
-                                        range: 9321..9325,
+                                        range: 9320..9324,
                                     },
                                 ),
                                 tooltip: "",
@@ -511,7 +511,7 @@ fn main() {
                                         file_id: FileId(
                                             1,
                                         ),
-                                        range: 9289..9297,
+                                        range: 9288..9296,
                                     },
                                 ),
                                 tooltip: "",
@@ -524,7 +524,7 @@ fn main() {
                                         file_id: FileId(
                                             1,
                                         ),
-                                        range: 9321..9325,
+                                        range: 9320..9324,
                                     },
                                 ),
                                 tooltip: "",
@@ -548,7 +548,7 @@ fn main() {
                                         file_id: FileId(
                                             1,
                                         ),
-                                        range: 9289..9297,
+                                        range: 9288..9296,
                                     },
                                 ),
                                 tooltip: "",
@@ -561,7 +561,7 @@ fn main() {
                                         file_id: FileId(
                                             1,
                                         ),
-                                        range: 9321..9325,
+                                        range: 9320..9324,
                                     },
                                 ),
                                 tooltip: "",
diff --git a/crates/ide/src/interpret_function.rs b/crates/ide/src/interpret_function.rs
index d06ffd5357..cbcbb4b09d 100644
--- a/crates/ide/src/interpret_function.rs
+++ b/crates/ide/src/interpret_function.rs
@@ -34,15 +34,13 @@ fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<Strin
         _ => return None,
     };
     let span_formatter = |file_id, text_range: TextRange| {
+        let line_col = db.line_index(file_id).line_col(text_range.start());
         let path = &db
             .source_root(db.file_source_root(file_id))
             .path_for_file(&file_id)
             .map(|x| x.to_string());
         let path = path.as_deref().unwrap_or("<unknown file>");
-        match db.line_index(file_id).try_line_col(text_range.start()) {
-            Some(line_col) => format!("file://{path}#{}:{}", line_col.line + 1, line_col.col),
-            None => format!("file://{path} range {:?}", text_range),
-        }
+        format!("file://{path}#{}:{}", line_col.line + 1, line_col.col)
     };
     Some(def.eval(db, span_formatter))
 }
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index a868419821..1814e0e54c 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -211,54 +211,70 @@ impl BlockLike {
 const VISIBILITY_FIRST: TokenSet = TokenSet::new(&[T![pub], T![crate]]);
 
 fn opt_visibility(p: &mut Parser<'_>, in_tuple_field: bool) -> bool {
-    if !p.at(T![pub]) {
-        return false;
-    }
-
-    let m = p.start();
-    p.bump(T![pub]);
-    if p.at(T!['(']) {
-        match p.nth(1) {
-            // test crate_visibility
-            // pub(crate) struct S;
-            // pub(self) struct S;
-            // pub(super) struct S;
-
-            // test_err crate_visibility_empty_recover
-            // pub() struct S;
-
-            // test pub_parens_typepath
-            // struct B(pub (super::A));
-            // struct B(pub (crate::A,));
-            T![crate] | T![self] | T![super] | T![ident] | T![')'] if p.nth(2) != T![:] => {
-                // If we are in a tuple struct, then the parens following `pub`
-                // might be an tuple field, not part of the visibility. So in that
-                // case we don't want to consume an identifier.
-
-                // test pub_tuple_field
-                // struct MyStruct(pub (u32, u32));
-                // struct MyStruct(pub (u32));
-                // struct MyStruct(pub ());
-                if !(in_tuple_field && matches!(p.nth(1), T![ident] | T![')'])) {
-                    p.bump(T!['(']);
-                    paths::use_path(p);
-                    p.expect(T![')']);
+    match p.current() {
+        T![pub] => {
+            let m = p.start();
+            p.bump(T![pub]);
+            if p.at(T!['(']) {
+                match p.nth(1) {
+                    // test crate_visibility
+                    // pub(crate) struct S;
+                    // pub(self) struct S;
+                    // pub(super) struct S;
+
+                    // test_err crate_visibility_empty_recover
+                    // pub() struct S;
+
+                    // test pub_parens_typepath
+                    // struct B(pub (super::A));
+                    // struct B(pub (crate::A,));
+                    T![crate] | T![self] | T![super] | T![ident] | T![')'] if p.nth(2) != T![:] => {
+                        // If we are in a tuple struct, then the parens following `pub`
+                        // might be an tuple field, not part of the visibility. So in that
+                        // case we don't want to consume an identifier.
+
+                        // test pub_tuple_field
+                        // struct MyStruct(pub (u32, u32));
+                        // struct MyStruct(pub (u32));
+                        // struct MyStruct(pub ());
+                        if !(in_tuple_field && matches!(p.nth(1), T![ident] | T![')'])) {
+                            p.bump(T!['(']);
+                            paths::use_path(p);
+                            p.expect(T![')']);
+                        }
+                    }
+                    // test crate_visibility_in
+                    // pub(in super::A) struct S;
+                    // pub(in crate) struct S;
+                    T![in] => {
+                        p.bump(T!['(']);
+                        p.bump(T![in]);
+                        paths::use_path(p);
+                        p.expect(T![')']);
+                    }
+                    _ => {}
                 }
             }
-            // test crate_visibility_in
-            // pub(in super::A) struct S;
-            // pub(in crate) struct S;
-            T![in] => {
-                p.bump(T!['(']);
-                p.bump(T![in]);
-                paths::use_path(p);
-                p.expect(T![')']);
+            m.complete(p, VISIBILITY);
+            true
+        }
+        // test crate_keyword_vis
+        // crate fn main() { }
+        // struct S { crate field: u32 }
+        // struct T(crate u32);
+        T![crate] => {
+            if p.nth_at(1, T![::]) {
+                // test crate_keyword_path
+                // fn foo() { crate::foo(); }
+                return false;
             }
-            _ => {}
+            let m = p.start();
+            p.bump(T![crate]);
+            m.complete(p, VISIBILITY);
+            true
         }
+        _ => false,
     }
-    m.complete(p, VISIBILITY);
-    true
 }
 
 fn opt_rename(p: &mut Parser<'_>) {
diff --git a/crates/proc-macro-api/src/version.rs b/crates/proc-macro-api/src/version.rs
index 48efbf589c..13f67a0128 100644
--- a/crates/proc-macro-api/src/version.rs
+++ b/crates/proc-macro-api/src/version.rs
@@ -135,12 +135,7 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
         }
     };
 
-    let mut uncompressed: Box<dyn Read> = if &snappy_portion[0..4] == b"rust" {
-        // Not compressed.
-        Box::new(snappy_portion)
-    } else {
-        Box::new(SnapDecoder::new(snappy_portion))
-    };
+    let mut snappy_decoder = SnapDecoder::new(snappy_portion);
 
     // the bytes before version string bytes, so this basically is:
     // 8 bytes for [b'r',b'u',b's',b't',0,0,0,5]
@@ -149,11 +144,11 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
     // so 13 bytes in total, and we should check the 13th byte
     // to know the length
     let mut bytes_before_version = [0u8; 13];
-    uncompressed.read_exact(&mut bytes_before_version)?;
+    snappy_decoder.read_exact(&mut bytes_before_version)?;
     let length = bytes_before_version[12];
 
     let mut version_string_utf8 = vec![0u8; length as usize];
-    uncompressed.read_exact(&mut version_string_utf8)?;
+    snappy_decoder.read_exact(&mut version_string_utf8)?;
     let version_string = String::from_utf8(version_string_utf8);
     version_string.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
 }
diff --git a/crates/proc-macro-srv/src/server.rs b/crates/proc-macro-srv/src/server.rs
index 1980d4c78b..6fd8de5934 100644
--- a/crates/proc-macro-srv/src/server.rs
+++ b/crates/proc-macro-srv/src/server.rs
@@ -8,7 +8,10 @@
 //!
 //! FIXME: No span and source file information is implemented yet
 
-use proc_macro::bridge::{self, server};
+use proc_macro::{
+    bridge::{self, server},
+    LineColumn,
+};
 
 mod token_stream;
 pub use token_stream::TokenStream;
@@ -301,6 +304,14 @@ impl server::Span for RustAnalyzer {
         // FIXME handle span
         Range { start: 0, end: 0 }
     }
+    fn start(&mut self, _span: Self::Span) -> LineColumn {
+        // FIXME handle span
+        LineColumn { line: 0, column: 0 }
+    }
+    fn end(&mut self, _span: Self::Span) -> LineColumn {
+        // FIXME handle span
+        LineColumn { line: 0, column: 0 }
+    }
     fn join(&mut self, first: Self::Span, _second: Self::Span) -> Option<Self::Span> {
         // Just return the first span again, because some macros will unwrap the result.
         Some(first)
@@ -319,23 +330,13 @@ impl server::Span for RustAnalyzer {
         tt::TokenId::unspecified()
     }
 
-    fn end(&mut self, _self_: Self::Span) -> Self::Span {
+    fn after(&mut self, _self_: Self::Span) -> Self::Span {
         tt::TokenId::unspecified()
     }
 
-    fn start(&mut self, _self_: Self::Span) -> Self::Span {
+    fn before(&mut self, _self_: Self::Span) -> Self::Span {
         tt::TokenId::unspecified()
     }
-
-    fn line(&mut self, _span: Self::Span) -> usize {
-        // FIXME handle line
-        0
-    }
-
-    fn column(&mut self, _span: Self::Span) -> usize {
-        // FIXME handle column
-        0
-    }
 }
 
 impl server::Symbol for RustAnalyzer {
diff --git a/crates/project-model/src/cargo_workspace.rs b/crates/project-model/src/cargo_workspace.rs
index e47808a2cc..e1117ac464 100644
--- a/crates/project-model/src/cargo_workspace.rs
+++ b/crates/project-model/src/cargo_workspace.rs
@@ -145,7 +145,7 @@ pub struct PackageDependency {
     pub kind: DepKind,
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)]
 pub enum DepKind {
     /// Available to the library, binary, and dev targets in the package (but not the build script).
     Normal,
@@ -156,20 +156,23 @@ pub enum DepKind {
 }
 
 impl DepKind {
-    fn iter(list: &[cargo_metadata::DepKindInfo]) -> impl Iterator<Item = Self> {
-        let mut dep_kinds = [None; 3];
+    fn iter(list: &[cargo_metadata::DepKindInfo]) -> impl Iterator<Item = Self> + '_ {
+        let mut dep_kinds = Vec::new();
         if list.is_empty() {
-            dep_kinds[0] = Some(Self::Normal);
+            dep_kinds.push(Self::Normal);
         }
         for info in list {
-            match info.kind {
-                cargo_metadata::DependencyKind::Normal => dep_kinds[0] = Some(Self::Normal),
-                cargo_metadata::DependencyKind::Development => dep_kinds[1] = Some(Self::Dev),
-                cargo_metadata::DependencyKind::Build => dep_kinds[2] = Some(Self::Build),
+            let kind = match info.kind {
+                cargo_metadata::DependencyKind::Normal => Self::Normal,
+                cargo_metadata::DependencyKind::Development => Self::Dev,
+                cargo_metadata::DependencyKind::Build => Self::Build,
                 cargo_metadata::DependencyKind::Unknown => continue,
-            }
+            };
+            dep_kinds.push(kind);
         }
-        dep_kinds.into_iter().flatten()
+        dep_kinds.sort_unstable();
+        dep_kinds.dedup();
+        dep_kinds.into_iter()
     }
 }
 
diff --git a/crates/project-model/src/rustc_cfg.rs b/crates/project-model/src/rustc_cfg.rs
index 8392718b22..7ec6948eff 100644
--- a/crates/project-model/src/rustc_cfg.rs
+++ b/crates/project-model/src/rustc_cfg.rs
@@ -22,9 +22,6 @@ pub(crate) fn get(
         }
     }
 
-    // Add miri cfg, which is useful for mir eval in stdlib
-    res.push(CfgFlag::Atom("miri".into()));
-
     match get_rust_cfgs(cargo_toml, target, extra_env) {
         Ok(rustc_cfgs) => {
             tracing::debug!(
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index 33d7b5ed87..8d68bf160a 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -8,7 +8,7 @@ use std::{
 
 use hir::{
     db::{DefDatabase, ExpandDatabase, HirDatabase},
-    Adt, AssocItem, Crate, DefWithBody, HasSource, HirDisplay, ModuleDef, Name,
+    Adt, AssocItem, Crate, DefWithBody, HasCrate, HasSource, HirDisplay, ModuleDef, Name,
 };
 use hir_def::{
     body::{BodySourceMap, SyntheticSyntax},
@@ -277,7 +277,7 @@ impl flags::AnalysisStats {
             let Err(e) = db.layout_of_adt(
                 hir_def::AdtId::from(a).into(),
                 Substitution::empty(Interner),
-                db.trait_environment(a.into()),
+                a.krate(db).into(),
             ) else {
                 continue;
             };
diff --git a/crates/rust-analyzer/src/cli/flags.rs b/crates/rust-analyzer/src/cli/flags.rs
index 13b7f039bb..31be535fc2 100644
--- a/crates/rust-analyzer/src/cli/flags.rs
+++ b/crates/rust-analyzer/src/cli/flags.rs
@@ -12,7 +12,7 @@ xflags::xflags! {
     /// LSP server for the Rust programming language.
     ///
     /// Subcommands and their flags do not provide any stability guarantees and may be removed or
-    /// changed without notice. Top-level flags that are not marked as [Unstable] provide
+    /// changed without notice. Top-level flags that are not are marked as [Unstable] provide
     /// backwards-compatibility and may be relied on.
     cmd rust-analyzer {
         /// Verbosity level, can be repeated multiple times.
@@ -113,7 +113,7 @@ xflags::xflags! {
         }
 
         cmd ssr {
-            /// A structured search replace rule (`$a.foo($b) ==>> bar($a, $b)`)
+            /// A structured search replace rule (`$a.foo($b) ==> bar($a, $b)`)
             repeated rule: SsrRule
         }
 
diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc
index 2cf985adab..31035c4b72 100644
--- a/docs/user/manual.adoc
+++ b/docs/user/manual.adoc
@@ -449,24 +449,27 @@ You'll need to close and reopen all .rs and Cargo files, or to restart the IDE,
 Support for the language server protocol is built into Kate through the LSP plugin, which is included by default.
 It is preconfigured to use rust-analyzer for Rust sources since Kate 21.12.
 
-To change rust-analyzer config options, start from the following example and put it into Kate's "User Server Settings" tab (located under the LSP Client settings):
+Earlier versions allow you to use rust-analyzer through a simple settings change.
+In the LSP Client settings of Kate, copy the content of the third tab "default parameters" to the second tab "server configuration".
+Then in the configuration replace:
 [source,json]
 ----
-{
-    "servers": {
         "rust": {
-            "initializationOptions": {
-                "cachePriming": {
-                    "enable": false
-                },
-                "check": {
-                    "allTargets": false
-                },
-                "checkOnSave": false
-            }
-        }
-    }
-}
+            "command": ["rls"],
+            "rootIndicationFileNames": ["Cargo.lock", "Cargo.toml"],
+            "url": "https://github.com/rust-lang/rls",
+            "highlightingModeRegex": "^Rust$"
+        },
+----
+With
+[source,json]
+----
+        "rust": {
+            "command": ["rust-analyzer"],
+            "rootIndicationFileNames": ["Cargo.lock", "Cargo.toml"],
+            "url": "https://github.com/rust-lang/rust-analyzer",
+            "highlightingModeRegex": "^Rust$"
+        },
 ----
 Then click on apply, and restart the LSP server for your rust project.
 
diff --git a/editors/code/package.json b/editors/code/package.json
index ffb5dd9079..31c483beb6 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -35,9 +35,12 @@
         "build-base": "esbuild ./src/main.ts --bundle --outfile=out/main.js --external:vscode --format=cjs --platform=node --target=node16",
         "build": "npm run build-base -- --sourcemap",
         "watch": "npm run build-base -- --sourcemap --watch",
-        "lint": "prettier --check . && eslint -c .eslintrc.js --ext ts ./src ./tests",
-        "fix": "prettier --write . && eslint -c .eslintrc.js --ext ts ./src ./tests --fix",
-        "pretest": "tsc && npm run build",
+        "format": "prettier --write .",
+        "format:check": "prettier --check .",
+        "lint": "eslint -c .eslintrc.js --ext ts ./src ./tests",
+        "lint:fix": "npm run lint -- --fix",
+        "typecheck": "tsc",
+        "pretest": "npm run typecheck && npm run build",
         "test": "node ./out/tests/runTests.js"
     },
     "dependencies": {
diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts
index e817d680ea..f3d6238d51 100644
--- a/editors/code/src/debug.ts
+++ b/editors/code/src/debug.ts
@@ -66,12 +66,6 @@ export async function startDebugSession(ctx: Ctx, runnable: ra.Runnable): Promis
     return vscode.debug.startDebugging(undefined, debugConfig);
 }
 
-function createCommandLink(extensionId: string): string {
-    // do not remove the second quotes inside
-    // encodeURIComponent or it won't work
-    return `extension.open?${encodeURIComponent(`"${extensionId}"`)}`;
-}
-
 async function getDebugConfiguration(
     ctx: Ctx,
     runnable: ra.Runnable,
@@ -96,12 +90,9 @@ async function getDebugConfiguration(
     }
 
     if (!debugEngine) {
-        const commandCodeLLDB: string = createCommandLink("vadimcn.vscode-lldb");
-        const commandCpp: string = createCommandLink("ms-vscode.cpptools");
-
         await vscode.window.showErrorMessage(
-            `Install [CodeLLDB](command:${commandCodeLLDB} "Open CodeLLDB")` +
-                ` or [C/C++](command:${commandCpp} "Open C/C++") extension for debugging.`,
+            `Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)` +
+                ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`,
         );
         return;
     }
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index 7a34617e25..b4b294c309 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.1.0"
 publish = false
 license = "MIT OR Apache-2.0"
 edition = "2021"
-rust-version.workspace = true
+rust-version = "1.65"
 
 [dependencies]
 anyhow = "1.0.62"


Test patch:
diff --git a/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs b/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs
index abd84c6a46..145cf8ddd4 100644
--- a/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs
+++ b/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs
@@ -416,44 +416,6 @@ fn test_hash_expand() {
 //- minicore: derive, hash
 use core::hash::Hash;
 
-#[derive(Hash)]
-struct Foo {
-    x: i32,
-    y: u64,
-    z: (i32, u64),
-}
-"#,
-        expect![[r#"
-use core::hash::Hash;
-
-#[derive(Hash)]
-struct Foo {
-    x: i32,
-    y: u64,
-    z: (i32, u64),
-}
-
-impl < > core::hash::Hash for Foo< > where {
-    fn hash<H: core::hash::Hasher>(&self , ra_expand_state: &mut H) {
-        match self {
-            Foo {
-                x: x, y: y, z: z,
-            }
-            => {
-                x.hash(ra_expand_state);
-                y.hash(ra_expand_state);
-                z.hash(ra_expand_state);
-            }
-            ,
-        }
-    }
-}"#]],
-    );
-    check(
-        r#"
-//- minicore: derive, hash
-use core::hash::Hash;
-
 #[derive(Hash)]
 enum Command {
     Move { x: i32, y: i32 },
diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs
index 98ebe55724..e32ae8b268 100644
--- a/crates/hir-ty/src/consteval/tests.rs
+++ b/crates/hir-ty/src/consteval/tests.rs
@@ -5,7 +5,7 @@ use test_utils::skip_slow_tests;
 
 use crate::{
     consteval::try_const_usize, db::HirDatabase, mir::pad16, test_db::TestDB, Const, ConstScalar,
-    Interner, MemoryMap,
+    Interner,
 };
 
 use super::{
@@ -37,7 +37,7 @@ fn check_fail(ra_fixture: &str, error: impl FnOnce(ConstEvalError) -> bool) {
 
 #[track_caller]
 fn check_number(ra_fixture: &str, answer: i128) {
-    check_answer(ra_fixture, |b, _| {
+    check_answer(ra_fixture, |b| {
         assert_eq!(
             b,
             &answer.to_le_bytes()[0..b.len()],
@@ -48,26 +48,8 @@ fn check_number(ra_fixture: &str, answer: i128) {
 }
 
 #[track_caller]
-fn check_str(ra_fixture: &str, answer: &str) {
-    check_answer(ra_fixture, |b, mm| {
-        let addr = usize::from_le_bytes(b[0..b.len() / 2].try_into().unwrap());
-        let size = usize::from_le_bytes(b[b.len() / 2..].try_into().unwrap());
-        let Some(bytes) = mm.get(addr, size) else {
-            panic!("string data missed in the memory map");
-        };
-        assert_eq!(
-            bytes,
-            answer.as_bytes(),
-            "Bytes differ. In string form: actual = {}, expected = {answer}",
-            String::from_utf8_lossy(bytes)
-        );
-    });
-}
-
-#[track_caller]
-fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8], &MemoryMap)) {
-    let (db, file_ids) = TestDB::with_many_files(ra_fixture);
-    let file_id = *file_ids.last().unwrap();
+fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8])) {
+    let (db, file_id) = TestDB::with_single_file(ra_fixture);
     let r = match eval_goal(&db, file_id) {
         Ok(t) => t,
         Err(e) => {
@@ -77,8 +59,8 @@ fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8], &MemoryMap)) {
     };
     match &r.data(Interner).value {
         chalk_ir::ConstValue::Concrete(c) => match &c.interned {
-            ConstScalar::Bytes(b, mm) => {
-                check(b, mm);
+            ConstScalar::Bytes(b, _) => {
+                check(b);
             }
             x => panic!("Expected number but found {:?}", x),
         },
@@ -114,7 +96,7 @@ fn eval_goal(db: &TestDB, file_id: FileId) -> Result<Const, ConstEvalError> {
             _ => None,
         })
         .expect("No const named GOAL found in the test");
-    db.const_eval(const_id.into(), Substitution::empty(Interner), None)
+    db.const_eval(const_id.into(), Substitution::empty(Interner))
 }
 
 #[test]
@@ -243,7 +225,7 @@ const GOAL: usize = {
     transmute(&x)
 }
         "#,
-        |b, _| assert_eq!(b[0] % 8, 0),
+        |b| assert_eq!(b[0] % 8, 0),
     );
     check_answer(
         r#"
@@ -252,7 +234,7 @@ use core::mem::transmute;
 static X: i64 = 12;
 const GOAL: usize = transmute(&X);
         "#,
-        |b, _| assert_eq!(b[0] % 8, 0),
+        |b| assert_eq!(b[0] % 8, 0),
     );
 }
 
@@ -1941,33 +1923,6 @@ fn dyn_trait() {
         "#,
         900,
     );
-    check_number(
-        r#"
-    //- minicore: coerce_unsized, index, slice
-    trait A {
-        fn x(&self) -> i32;
-    }
-
-    trait B: A {}
-
-    impl A for i32 {
-        fn x(&self) -> i32 {
-            5
-        }
-    }
-
-    impl B for i32 {
-
-    }
-
-    const fn f(x: &dyn B) -> i32 {
-        x.x()
-    }
-
-    const GOAL: i32 = f(&2i32);
-        "#,
-        5,
-    );
 }
 
 #[test]
@@ -2113,17 +2068,6 @@ fn array_and_index() {
     );
 }
 
-#[test]
-fn string() {
-    check_str(
-        r#"
-    //- minicore: coerce_unsized, index, slice
-    const GOAL: &str = "hello";
-        "#,
-        "hello",
-    );
-}
-
 #[test]
 fn byte_string() {
     check_number(
@@ -2500,47 +2444,6 @@ fn const_trait_assoc() {
     "#,
         32,
     );
-    check_number(
-        r#"
-    //- /a/lib.rs crate:a
-    pub trait ToConst {
-        const VAL: usize;
-    }
-    pub const fn to_const<T: ToConst>() -> usize {
-        T::VAL
-    }
-    //- /main.rs crate:main deps:a
-    use a::{ToConst, to_const};
-    struct U0;
-    impl ToConst for U0 {
-        const VAL: usize = 5;
-    }
-    const GOAL: usize = to_const::<U0>();
-    "#,
-        5,
-    );
-    check_number(
-        r#"
-    //- minicore: size_of
-    //- /a/lib.rs crate:a
-    use core::mem::size_of;
-    pub struct S<T>(T);
-    impl<T> S<T> {
-        pub const X: usize = core::mem::size_of::<T>();
-    }
-    //- /main.rs crate:main deps:a
-    use a::{S};
-    trait Tr {
-        type Ty;
-    }
-    impl Tr for i32 {
-        type Ty = u64;
-    }
-    struct K<T: Tr>(<T as Tr>::Ty);
-    const GOAL: usize = S::<K<i32>>::X;
-    "#,
-        8,
-    );
     check_number(
         r#"
     struct S<T>(*mut T);
diff --git a/crates/hir-ty/src/consteval/tests/intrinsics.rs b/crates/hir-ty/src/consteval/tests/intrinsics.rs
index 9253e31d77..30e87661ab 100644
--- a/crates/hir-ty/src/consteval/tests/intrinsics.rs
+++ b/crates/hir-ty/src/consteval/tests/intrinsics.rs
@@ -149,36 +149,6 @@ fn min_align_of_val() {
     );
 }
 
-#[test]
-fn type_name() {
-    check_str(
-        r#"
-        extern "rust-intrinsic" {
-            pub fn type_name<T: ?Sized>() -> &'static str;
-        }
-
-        const GOAL: &str = type_name::<i32>();
-        "#,
-        "i32",
-    );
-    check_str(
-        r#"
-        extern "rust-intrinsic" {
-            pub fn type_name<T: ?Sized>() -> &'static str;
-        }
-
-        mod mod1 {
-            pub mod mod2 {
-                pub struct Ty;
-            }
-        }
-
-        const GOAL: &str = type_name::<mod1::mod2::Ty>();
-        "#,
-        "mod1::mod2::Ty",
-    );
-}
-
 #[test]
 fn transmute() {
     check_number(
diff --git a/crates/hir-ty/src/layout/tests.rs b/crates/hir-ty/src/layout/tests.rs
index 333ad473a8..2b74f1a1a1 100644
--- a/crates/hir-ty/src/layout/tests.rs
+++ b/crates/hir-ty/src/layout/tests.rs
@@ -26,7 +26,7 @@ fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutErro
     );
 
     let (db, file_ids) = TestDB::with_many_files(&ra_fixture);
-    let adt_or_type_alias_id = file_ids
+    let (adt_or_type_alias_id, module_id) = file_ids
         .into_iter()
         .find_map(|file_id| {
             let module_id = db.module_for_file(file_id);
@@ -47,7 +47,7 @@ fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutErro
                 }
                 _ => None,
             })?;
-            Some(adt_or_type_alias_id)
+            Some((adt_or_type_alias_id, module_id))
         })
         .unwrap();
     let goal_ty = match adt_or_type_alias_id {
@@ -58,13 +58,7 @@ fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutErro
             db.ty(ty_id.into()).substitute(Interner, &Substitution::empty(Interner))
         }
     };
-    db.layout_of_ty(
-        goal_ty,
-        db.trait_environment(match adt_or_type_alias_id {
-            Either::Left(adt) => hir_def::GenericDefId::AdtId(adt),
-            Either::Right(ty) => hir_def::GenericDefId::TypeAliasId(ty),
-        }),
-    )
+    db.layout_of_ty(goal_ty, module_id.krate())
 }
 
 /// A version of `eval_goal` for types that can not be expressed in ADTs, like closures and `impl Trait`
@@ -78,7 +72,7 @@ fn eval_expr(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutErro
     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;
-    let function_id = scope
+    let adt_id = scope
         .declarations()
         .find_map(|x| match x {
             hir_def::ModuleDefId::FunctionId(x) => {
@@ -88,11 +82,11 @@ fn eval_expr(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutErro
             _ => None,
         })
         .unwrap();
-    let hir_body = db.body(function_id.into());
+    let hir_body = db.body(adt_id.into());
     let b = hir_body.bindings.iter().find(|x| x.1.name.to_smol_str() == "goal").unwrap().0;
-    let infer = db.infer(function_id.into());
+    let infer = db.infer(adt_id.into());
     let goal_ty = infer.type_of_binding[b].clone();
-    db.layout_of_ty(goal_ty, db.trait_environment(function_id.into()))
+    db.layout_of_ty(goal_ty, module_id.krate())
 }
 
 #[track_caller]
@@ -470,41 +464,3 @@ fn enums_with_discriminants() {
         }
     }
 }
-
-#[test]
-fn core_mem_discriminant() {
-    size_and_align! {
-        minicore: discriminant;
-        struct S(i32, u64);
-        struct Goal(core::mem::Discriminant<S>);
-    }
-    size_and_align! {
-        minicore: discriminant;
-        #[repr(u32)]
-        enum S {
-            A,
-            B,
-            C,
-        }
-        struct Goal(core::mem::Discriminant<S>);
-    }
-    size_and_align! {
-        minicore: discriminant;
-        enum S {
-            A(i32),
-            B(i64),
-            C(u8),
-        }
-        struct Goal(core::mem::Discriminant<S>);
-    }
-    size_and_align! {
-        minicore: discriminant;
-        #[repr(C, u16)]
-        enum S {
-            A(i32),
-            B(i64) = 200,
-            C = 1000,
-        }
-        struct Goal(core::mem::Discriminant<S>);
-    }
-}
diff --git a/crates/hir-ty/src/mir/eval/tests.rs b/crates/hir-ty/src/mir/eval/tests.rs
index 93f4b69914..03c083bac4 100644
--- a/crates/hir-ty/src/mir/eval/tests.rs
+++ b/crates/hir-ty/src/mir/eval/tests.rs
@@ -30,7 +30,7 @@ fn eval_main(db: &TestDB, file_id: FileId) -> Result<(String, String), MirEvalEr
             db.trait_environment(func_id.into()),
         )
         .map_err(|e| MirEvalError::MirLowerError(func_id.into(), e))?;
-    let (result, stdout, stderr) = interpret_mir(db, body, false, None);
+    let (result, stdout, stderr) = interpret_mir(db, body, false);
     result?;
     Ok((stdout, stderr))
 }
diff --git a/crates/hir-ty/src/tests/method_resolution.rs b/crates/hir-ty/src/tests/method_resolution.rs
index c837fae3fe..a8e146b096 100644
--- a/crates/hir-ty/src/tests/method_resolution.rs
+++ b/crates/hir-ty/src/tests/method_resolution.rs
@@ -1236,27 +1236,6 @@ fn main() {
     );
 }
 
-#[test]
-fn inherent_method_ref_self_deref_raw() {
-    check_types(
-        r#"
-struct Val;
-
-impl Val {
-    pub fn method(&self) -> u32 {
-        0
-    }
-}
-
-fn main() {
-    let foo: *const Val;
-    foo.method();
- // ^^^^^^^^^^^^ {unknown}
-}
-"#,
-    );
-}
-
 #[test]
 fn trait_method_deref_raw() {
     check_types(
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 542df8b346..5f5cd79451 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -4434,47 +4434,3 @@ fn test(v: S<i32>) {
 "#,
     );
 }
-
-#[test]
-fn associated_type_in_argument() {
-    check(
-        r#"
-    trait A {
-        fn m(&self) -> i32;
-    }
-
-    fn x<T: B>(k: &<T as B>::Ty) {
-        k.m();
-    }
-
-    struct X;
-    struct Y;
-
-    impl A for X {
-        fn m(&self) -> i32 {
-            8
-        }
-    }
-
-    impl A for Y {
-        fn m(&self) -> i32 {
-            32
-        }
-    }
-
-    trait B {
-        type Ty: A;
-    }
-
-    impl B for u16 {
-        type Ty = X;
-    }
-
-    fn ttt() {
-        let inp = Y;
-        x::<u16>(&inp);
-               //^^^^ expected &X, got &Y
-    }
-    "#,
-    );
-}
diff --git a/crates/parser/src/tests/prefix_entries.rs b/crates/parser/src/tests/prefix_entries.rs
index 2f3c7febc0..11f9c34abd 100644
--- a/crates/parser/src/tests/prefix_entries.rs
+++ b/crates/parser/src/tests/prefix_entries.rs
@@ -6,6 +6,7 @@ fn vis() {
     check(PrefixEntryPoint::Vis, "fn foo() {}", "");
     check(PrefixEntryPoint::Vis, "pub(fn foo() {}", "pub");
     check(PrefixEntryPoint::Vis, "pub(crate fn foo() {}", "pub(crate");
+    check(PrefixEntryPoint::Vis, "crate fn foo() {}", "crate");
 }
 
 #[test]
diff --git a/crates/parser/test_data/parser/inline/ok/0040_crate_keyword_vis.rast b/crates/parser/test_data/parser/inline/ok/0040_crate_keyword_vis.rast
new file mode 100644
index 0000000000..07b0210e44
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/0040_crate_keyword_vis.rast
@@ -0,0 +1,63 @@
+SOURCE_FILE
+  FN
+    VISIBILITY
+      CRATE_KW "crate"
+    WHITESPACE " "
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE " "
+        R_CURLY "}"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S"
+    WHITESPACE " "
+    RECORD_FIELD_LIST
+      L_CURLY "{"
+      WHITESPACE " "
+      RECORD_FIELD
+        VISIBILITY
+          CRATE_KW "crate"
+        WHITESPACE " "
+        NAME
+          IDENT "field"
+        COLON ":"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+      WHITESPACE " "
+      R_CURLY "}"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "T"
+    TUPLE_FIELD_LIST
+      L_PAREN "("
+      TUPLE_FIELD
+        VISIBILITY
+          CRATE_KW "crate"
+        WHITESPACE " "
+        PATH_TYPE
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "u32"
+      R_PAREN ")"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/0040_crate_keyword_vis.rs b/crates/parser/test_data/parser/inline/ok/0040_crate_keyword_vis.rs
new file mode 100644
index 0000000000..e2b5f2161d
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/0040_crate_keyword_vis.rs
@@ -0,0 +1,3 @@
+crate fn main() { }
+struct S { crate field: u32 }
+struct T(crate u32);
diff --git a/crates/parser/test_data/parser/inline/ok/0125_crate_keyword_path.rast b/crates/parser/test_data/parser/inline/ok/0125_crate_keyword_path.rast
new file mode 100644
index 0000000000..8d9b61630a
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/0125_crate_keyword_path.rast
@@ -0,0 +1,33 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE " "
+        EXPR_STMT
+          CALL_EXPR
+            PATH_EXPR
+              PATH
+                PATH
+                  PATH_SEGMENT
+                    NAME_REF
+                      CRATE_KW "crate"
+                COLON2 "::"
+                PATH_SEGMENT
+                  NAME_REF
+                    IDENT "foo"
+            ARG_LIST
+              L_PAREN "("
+              R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE " "
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/0125_crate_keyword_path.rs b/crates/parser/test_data/parser/inline/ok/0125_crate_keyword_path.rs
new file mode 100644
index 0000000000..0f454d121d
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/0125_crate_keyword_path.rs
@@ -0,0 +1,1 @@
+fn foo() { crate::foo(); }
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index c765f42447..ebde017686 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -364,11 +364,6 @@ pub mod mem {
         pub fn size_of<T>() -> usize;
     }
     // endregion:size_of
-
-    // region:discriminant
-    use crate::marker::DiscriminantKind;
-    pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant);
-    // endregion:discriminant
 }
 
 pub mod ptr {