Merge pull request #20563 from ChayimFriedman2/ns-projection-dyn-auto-trait

fix: When mapping next-solver's `dyn` type, add `Self` (aka. bound var ^1.0) to auto traits' substitutions
diff --git a/Cargo.lock b/Cargo.lock
index f72e698..b008aa1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2738,9 +2738,9 @@
 
 [[package]]
 name = "tracing-subscriber"
-version = "0.3.19"
+version = "0.3.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
+checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5"
 dependencies = [
  "sharded-slab",
  "thread_local",
diff --git a/Cargo.toml b/Cargo.toml
index bb8444e..05ee190 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -163,7 +163,7 @@
 text-size = "1.1.1"
 tracing = "0.1.41"
 tracing-tree = "0.4.0"
-tracing-subscriber = { version = "0.3.19", default-features = false, features = [
+tracing-subscriber = { version = "0.3.20", default-features = false, features = [
     "registry",
     "fmt",
     "local-time",
diff --git a/crates/hir-ty/src/infer/cast.rs b/crates/hir-ty/src/infer/cast.rs
index 09b983a..4336496 100644
--- a/crates/hir-ty/src/infer/cast.rs
+++ b/crates/hir-ty/src/infer/cast.rs
@@ -6,7 +6,9 @@
 
 use crate::{
     Adjustment, Binders, DynTy, InferenceDiagnostic, Interner, PlaceholderIndex,
-    QuantifiedWhereClauses, Ty, TyExt, TyKind, TypeFlags, WhereClause, from_chalk_trait_id,
+    QuantifiedWhereClauses, Ty, TyExt, TyKind, TypeFlags, WhereClause,
+    db::HirDatabase,
+    from_chalk_trait_id,
     infer::{coerce::CoerceNever, unify::InferenceTable},
 };
 
@@ -30,7 +32,7 @@
 }
 
 impl CastTy {
-    pub(crate) fn from_ty(table: &mut InferenceTable<'_>, t: &Ty) -> Option<Self> {
+    pub(crate) fn from_ty(db: &dyn HirDatabase, t: &Ty) -> Option<Self> {
         match t.kind(Interner) {
             TyKind::Scalar(Scalar::Bool) => Some(Self::Int(Int::Bool)),
             TyKind::Scalar(Scalar::Char) => Some(Self::Int(Int::Char)),
@@ -43,8 +45,8 @@
                 let (AdtId::EnumId(id), _) = t.as_adt()? else {
                     return None;
                 };
-                let enum_data = id.enum_variants(table.db);
-                if enum_data.is_payload_free(table.db) { Some(Self::Int(Int::CEnum)) } else { None }
+                let enum_data = id.enum_variants(db);
+                if enum_data.is_payload_free(db) { Some(Self::Int(Int::CEnum)) } else { None }
             }
             TyKind::Raw(m, ty) => Some(Self::Ptr(ty.clone(), *m)),
             TyKind::Function(_) => Some(Self::FnPtr),
@@ -142,58 +144,50 @@
     where
         F: FnMut(ExprId, Vec<Adjustment>),
     {
-        let (t_from, t_cast) =
-            match (CastTy::from_ty(table, &self.expr_ty), CastTy::from_ty(table, &self.cast_ty)) {
-                (Some(t_from), Some(t_cast)) => (t_from, t_cast),
-                (None, Some(t_cast)) => match self.expr_ty.kind(Interner) {
-                    TyKind::FnDef(..) => {
-                        let sig = self.expr_ty.callable_sig(table.db).expect("FnDef had no sig");
-                        let sig = table.eagerly_normalize_and_resolve_shallow_in(sig);
-                        let fn_ptr = TyKind::Function(sig.to_fn_ptr()).intern(Interner);
-                        if let Ok((adj, _)) = table.coerce(&self.expr_ty, &fn_ptr, CoerceNever::Yes)
-                        {
-                            apply_adjustments(self.source_expr, adj);
-                        } else {
-                            return Err(CastError::IllegalCast);
-                        }
-
-                        (CastTy::FnPtr, t_cast)
+        let (t_from, t_cast) = match (
+            CastTy::from_ty(table.db, &self.expr_ty),
+            CastTy::from_ty(table.db, &self.cast_ty),
+        ) {
+            (Some(t_from), Some(t_cast)) => (t_from, t_cast),
+            (None, Some(t_cast)) => match self.expr_ty.kind(Interner) {
+                TyKind::FnDef(..) => {
+                    let sig = self.expr_ty.callable_sig(table.db).expect("FnDef had no sig");
+                    let sig = table.eagerly_normalize_and_resolve_shallow_in(sig);
+                    let fn_ptr = TyKind::Function(sig.to_fn_ptr()).intern(Interner);
+                    if let Ok((adj, _)) = table.coerce(&self.expr_ty, &fn_ptr, CoerceNever::Yes) {
+                        apply_adjustments(self.source_expr, adj);
+                    } else {
+                        return Err(CastError::IllegalCast);
                     }
-                    TyKind::Ref(mutbl, _, inner_ty) => {
-                        return match t_cast {
-                            CastTy::Int(_) | CastTy::Float => match inner_ty.kind(Interner) {
-                                TyKind::Scalar(
-                                    Scalar::Int(_) | Scalar::Uint(_) | Scalar::Float(_),
-                                )
-                                | TyKind::InferenceVar(
-                                    _,
-                                    TyVariableKind::Integer | TyVariableKind::Float,
-                                ) => Err(CastError::NeedDeref),
 
-                                _ => Err(CastError::NeedViaPtr),
-                            },
-                            // array-ptr-cast
-                            CastTy::Ptr(t, m) => {
-                                let t = table.eagerly_normalize_and_resolve_shallow_in(t);
-                                if !table.is_sized(&t) {
-                                    return Err(CastError::IllegalCast);
-                                }
-                                self.check_ref_cast(
-                                    table,
-                                    inner_ty,
-                                    *mutbl,
-                                    &t,
-                                    m,
-                                    apply_adjustments,
-                                )
+                    (CastTy::FnPtr, t_cast)
+                }
+                TyKind::Ref(mutbl, _, inner_ty) => {
+                    return match t_cast {
+                        CastTy::Int(_) | CastTy::Float => match inner_ty.kind(Interner) {
+                            TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_) | Scalar::Float(_))
+                            | TyKind::InferenceVar(
+                                _,
+                                TyVariableKind::Integer | TyVariableKind::Float,
+                            ) => Err(CastError::NeedDeref),
+
+                            _ => Err(CastError::NeedViaPtr),
+                        },
+                        // array-ptr-cast
+                        CastTy::Ptr(t, m) => {
+                            let t = table.eagerly_normalize_and_resolve_shallow_in(t);
+                            if !table.is_sized(&t) {
+                                return Err(CastError::IllegalCast);
                             }
-                            _ => Err(CastError::NonScalar),
-                        };
-                    }
-                    _ => return Err(CastError::NonScalar),
-                },
+                            self.check_ref_cast(table, inner_ty, *mutbl, &t, m, apply_adjustments)
+                        }
+                        _ => Err(CastError::NonScalar),
+                    };
+                }
                 _ => return Err(CastError::NonScalar),
-            };
+            },
+            _ => return Err(CastError::NonScalar),
+        };
 
         // rustc checks whether the `expr_ty` is foreign adt with `non_exhaustive` sym
 
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index 7fbd496..45a1131 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -31,7 +31,7 @@
     display::{DisplayTarget, HirDisplay, hir_display_with_store},
     error_lifetime,
     generics::generics,
-    infer::{CaptureKind, CapturedItem, TypeMismatch, cast::CastTy, unify::InferenceTable},
+    infer::{CaptureKind, CapturedItem, TypeMismatch, cast::CastTy},
     inhabitedness::is_ty_uninhabited_from,
     layout::LayoutError,
     mapping::ToChalk,
@@ -950,8 +950,7 @@
                     let cast_kind = if source_ty.as_reference().is_some() {
                         CastKind::PointerCoercion(PointerCast::ArrayToPointer)
                     } else {
-                        let mut table = InferenceTable::new(self.db, self.env.clone());
-                        cast_kind(&mut table, &source_ty, &target_ty)?
+                        cast_kind(self.db, &source_ty, &target_ty)?
                     };
 
                     Rvalue::Cast(cast_kind, it, target_ty)
@@ -2019,9 +2018,9 @@
     }
 }
 
-fn cast_kind(table: &mut InferenceTable<'_>, source_ty: &Ty, target_ty: &Ty) -> Result<CastKind> {
-    let from = CastTy::from_ty(table, source_ty);
-    let cast = CastTy::from_ty(table, target_ty);
+fn cast_kind(db: &dyn HirDatabase, source_ty: &Ty, target_ty: &Ty) -> Result<CastKind> {
+    let from = CastTy::from_ty(db, source_ty);
+    let cast = CastTy::from_ty(db, target_ty);
     Ok(match (from, cast) {
         (Some(CastTy::Ptr(..) | CastTy::FnPtr), Some(CastTy::Int(_))) => {
             CastKind::PointerExposeAddress
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index b17186f..d685f16 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -333,7 +333,7 @@
         }
 
         if self.run_all_ide_things {
-            self.run_ide_things(host.analysis(), file_ids.clone());
+            self.run_ide_things(host.analysis(), file_ids.clone(), db, &vfs, verbosity);
         }
 
         if self.run_term_search {
@@ -393,15 +393,27 @@
     }
 
     fn run_const_eval(&self, db: &RootDatabase, bodies: &[DefWithBody], verbosity: Verbosity) {
+        let len = bodies
+            .iter()
+            .filter(|body| matches!(body, DefWithBody::Const(_) | DefWithBody::Static(_)))
+            .count();
+        let mut bar = match verbosity {
+            Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(),
+            _ if self.parallel || self.output.is_some() => ProgressReport::hidden(),
+            _ => ProgressReport::new(len),
+        };
+
         let mut sw = self.stop_watch();
         let mut all = 0;
         let mut fail = 0;
         for &b in bodies {
+            bar.set_message(move || format!("const eval: {}", full_name(db, b, b.module(db))));
             let res = match b {
                 DefWithBody::Const(c) => c.eval(db),
                 DefWithBody::Static(s) => s.eval(db),
                 _ => continue,
             };
+            bar.inc(1);
             all += 1;
             let Err(error) = res else {
                 continue;
@@ -409,10 +421,11 @@
             if verbosity.is_spammy() {
                 let full_name =
                     full_name_of_item(db, b.module(db), b.name(db).unwrap_or(Name::missing()));
-                println!("Const eval for {full_name} failed due {error:?}");
+                bar.println(format!("Const eval for {full_name} failed due {error:?}"));
             }
             fail += 1;
         }
+        bar.finish_and_clear();
         let const_eval_time = sw.elapsed();
         eprintln!("{:<20} {}", "Const evaluation:", const_eval_time);
         eprintln!("Failed const evals: {fail} ({}%)", percentage(fail, all));
@@ -662,6 +675,10 @@
         let mut all = 0;
         let mut fail = 0;
         for &body_id in bodies {
+            bar.set_message(move || {
+                format!("mir lowering: {}", full_name(db, body_id, body_id.module(db)))
+            });
+            bar.inc(1);
             if matches!(body_id, DefWithBody::Variant(_)) {
                 continue;
             }
@@ -1089,12 +1106,29 @@
         report_metric("body lowering time", body_lowering_time.time.as_millis() as u64, "ms");
     }
 
-    fn run_ide_things(&self, analysis: Analysis, mut file_ids: Vec<EditionedFileId>) {
+    fn run_ide_things(
+        &self,
+        analysis: Analysis,
+        mut file_ids: Vec<EditionedFileId>,
+        db: &RootDatabase,
+        vfs: &Vfs,
+        verbosity: Verbosity,
+    ) {
+        let len = file_ids.len();
+        let create_bar = || match verbosity {
+            Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(),
+            _ if self.parallel || self.output.is_some() => ProgressReport::hidden(),
+            _ => ProgressReport::new(len),
+        };
+
         file_ids.sort();
         file_ids.dedup();
         let mut sw = self.stop_watch();
 
+        let mut bar = create_bar();
         for &file_id in &file_ids {
+            let msg = format!("diagnostics: {}", vfs.file_path(file_id.file_id(db)));
+            bar.set_message(move || msg.clone());
             _ = analysis.full_diagnostics(
                 &DiagnosticsConfig {
                     enabled: true,
@@ -1121,8 +1155,14 @@
                 ide::AssistResolveStrategy::All,
                 analysis.editioned_file_id_to_vfs(file_id),
             );
+            bar.inc(1);
         }
+        bar.finish_and_clear();
+
+        let mut bar = create_bar();
         for &file_id in &file_ids {
+            let msg = format!("inlay hints: {}", vfs.file_path(file_id.file_id(db)));
+            bar.set_message(move || msg.clone());
             _ = analysis.inlay_hints(
                 &InlayHintsConfig {
                     render_colons: false,
@@ -1158,8 +1198,14 @@
                 analysis.editioned_file_id_to_vfs(file_id),
                 None,
             );
+            bar.inc(1);
         }
+        bar.finish_and_clear();
+
+        let mut bar = create_bar();
         for &file_id in &file_ids {
+            let msg = format!("annotations: {}", vfs.file_path(file_id.file_id(db)));
+            bar.set_message(move || msg.clone());
             analysis
                 .annotations(
                     &AnnotationConfig {
@@ -1178,7 +1224,10 @@
                 .for_each(|annotation| {
                     _ = analysis.resolve_annotation(annotation);
                 });
+            bar.inc(1);
         }
+        bar.finish_and_clear();
+
         let ide_time = sw.elapsed();
         eprintln!("{:<20} {} ({} files)", "IDE:", ide_time, file_ids.len());
     }