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());
}