Skip to content

Commit f2c0406

Browse files
committed
Trying to fix rust-analyzer's placeholder crimes
1 parent a4fdea7 commit f2c0406

File tree

6 files changed

+159
-68
lines changed

6 files changed

+159
-68
lines changed

crates/hir-ty/src/display.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use chalk_ir::{BoundVar, Safety, TyKind};
1212
use either::Either;
1313
use hir_def::{
1414
GeneralConstId, GenericDefId, HasModule, ImportPathConfig, LocalFieldId, Lookup, ModuleDefId,
15-
ModuleId, TraitId,
15+
ModuleId, TraitId, TypeOrConstParamId,
1616
db::DefDatabase,
1717
expr_store::{ExpressionStore, path::Path},
1818
find_path::{self, PrefixKind},
@@ -1612,9 +1612,28 @@ impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
16121612
}
16131613
}
16141614
TyKind::Placeholder(idx) => {
1615-
let placeholder_index = chalk_ir::PlaceholderIndex {
1616-
idx: idx.bound.var.as_usize(),
1617-
ui: chalk_ir::UniverseIndex { counter: idx.universe.as_usize() },
1615+
let placeholder_index = match idx.bound.kind {
1616+
crate::next_solver::BoundTyKind::Anon => chalk_ir::PlaceholderIndex {
1617+
idx: idx.bound.var.as_usize(),
1618+
ui: chalk_ir::UniverseIndex { counter: idx.universe.as_usize() },
1619+
},
1620+
crate::next_solver::BoundTyKind::Param(solver_def_id) => {
1621+
let Some(def) =
1622+
crate::next_solver::mapping::solver_def_id_to_generic_def_id_opt(
1623+
interner.db,
1624+
solver_def_id,
1625+
)
1626+
else {
1627+
unreachable!()
1628+
};
1629+
crate::mapping::to_placeholder_idx(
1630+
interner.db,
1631+
TypeOrConstParamId {
1632+
parent: def,
1633+
local_id: crate::Idx::from_raw(idx.bound.var.as_u32().into()),
1634+
},
1635+
)
1636+
}
16181637
};
16191638
let id = from_placeholder_idx(db, placeholder_index);
16201639
let generics = generics(db, id.parent);

crates/hir-ty/src/infer/closure.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,10 @@ impl InferenceContext<'_> {
568568
let supplied_sig = self.supplied_sig_of_closure(body, ret_type, arg_types, closure_kind);
569569

570570
let snapshot = self.table.snapshot();
571-
if !self.table.unify::<_, crate::next_solver::GenericArgs<'_>>(&expected_sig.substitution.0, &supplied_sig.expected_sig.substitution.0) {
571+
if !self.table.unify::<_, crate::next_solver::GenericArgs<'_>>(
572+
&expected_sig.substitution.0,
573+
&supplied_sig.expected_sig.substitution.0,
574+
) {
572575
self.table.rollback_to(snapshot);
573576
}
574577

@@ -878,7 +881,9 @@ impl CapturedItemWithoutTy {
878881
idx: chalk_ir::PlaceholderIndex,
879882
outer_binder: DebruijnIndex,
880883
) -> std::result::Result<Ty, Self::Error> {
884+
dbg!(&idx);
881885
let x = from_placeholder_idx(self.db, idx);
886+
dbg!(&x);
882887
let Some(idx) = self.generics.type_or_const_param_idx(x) else {
883888
return Err(());
884889
};

crates/hir-ty/src/infer/path.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@ use hir_expand::name::Name;
1010
use stdx::never;
1111

1212
use crate::{
13-
builder::ParamKind, consteval, error_lifetime, generics::generics, infer::diagnostics::InferenceTyLoweringContext as TyLoweringContext, method_resolution::{self, VisibleFromModule}, next_solver::mapping::ChalkToNextSolver, to_chalk_trait_id, InferenceDiagnostic, Interner, LifetimeElisionKind, Substitution, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, ValueTyDefId
13+
InferenceDiagnostic, Interner, LifetimeElisionKind, Substitution, TraitRef, TraitRefExt, Ty,
14+
TyBuilder, TyExt, TyKind, ValueTyDefId,
15+
builder::ParamKind,
16+
consteval, error_lifetime,
17+
generics::generics,
18+
infer::diagnostics::InferenceTyLoweringContext as TyLoweringContext,
19+
method_resolution::{self, VisibleFromModule},
20+
next_solver::mapping::ChalkToNextSolver,
21+
to_chalk_trait_id,
1422
};
1523

1624
use super::{ExprOrPatId, InferenceContext, InferenceTyDiagnosticSource};

crates/hir-ty/src/next_solver/infer/canonical/canonicalizer.rs

Lines changed: 38 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1-
21
use rustc_hash::FxHashMap;
32
use rustc_index::Idx;
4-
use rustc_type_ir::inherent::{Const as _, IntoKind as _, Region as _, SliceLike, Ty as _};
53
use rustc_type_ir::InferTy::{self, FloatVar, IntVar, TyVar};
6-
use rustc_type_ir::{BoundVar, CanonicalQueryInput, CanonicalTyVarKind, DebruijnIndex, Flags, InferConst, RegionKind, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, UniverseIndex};
4+
use rustc_type_ir::inherent::{Const as _, IntoKind as _, Region as _, SliceLike, Ty as _};
5+
use rustc_type_ir::{
6+
BoundVar, CanonicalQueryInput, CanonicalTyVarKind, DebruijnIndex, Flags, InferConst,
7+
RegionKind, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
8+
UniverseIndex,
9+
};
710
use smallvec::SmallVec;
811
use tracing::debug;
912

1013
use crate::next_solver::infer::InferCtxt;
11-
use crate::next_solver::{Binder, BoundRegion, BoundRegionKind, BoundTy, Canonical, CanonicalVarKind, CanonicalVars, Const, ConstKind, DbInterner, GenericArg, ParamEnvAnd, Placeholder, Region, Ty, TyKind};
14+
use crate::next_solver::{
15+
Binder, BoundRegion, BoundRegionKind, BoundTy, Canonical, CanonicalVarKind, CanonicalVars,
16+
Const, ConstKind, DbInterner, GenericArg, ParamEnvAnd, Placeholder, Region, Ty, TyKind,
17+
};
1218

1319
/// When we canonicalize a value to form a query, we wind up replacing
1420
/// various parts of it with canonical variables. This struct stores
@@ -180,12 +186,14 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
180186
};
181187

182188
match r.kind() {
183-
RegionKind::ReLateParam(_) | RegionKind::ReErased | RegionKind::ReStatic | RegionKind::ReEarlyParam(..) | RegionKind::ReError(..) => r,
189+
RegionKind::ReLateParam(_)
190+
| RegionKind::ReErased
191+
| RegionKind::ReStatic
192+
| RegionKind::ReEarlyParam(..)
193+
| RegionKind::ReError(..) => r,
184194

185-
RegionKind::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region(
186-
CanonicalVarKind::PlaceholderRegion(placeholder),
187-
r,
188-
),
195+
RegionKind::RePlaceholder(placeholder) => canonicalizer
196+
.canonical_var_for_region(CanonicalVarKind::PlaceholderRegion(placeholder), r),
189197

190198
RegionKind::ReVar(vid) => {
191199
let universe = infcx
@@ -194,10 +202,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
194202
.unwrap_region_constraints()
195203
.probe_value(vid)
196204
.unwrap_err();
197-
canonicalizer.canonical_var_for_region(
198-
CanonicalVarKind::Region(universe),
199-
r,
200-
)
205+
canonicalizer.canonical_var_for_region(CanonicalVarKind::Region(universe), r)
201206
}
202207

203208
_ => {
@@ -384,36 +389,29 @@ impl<'cx, 'db> TypeFolder<DbInterner<'db>> for Canonicalizer<'cx, 'db> {
384389
if nt != t {
385390
self.fold_ty(nt)
386391
} else {
387-
self.canonicalize_ty_var(
388-
CanonicalVarKind::Ty(CanonicalTyVarKind::Int),
389-
t,
390-
)
392+
self.canonicalize_ty_var(CanonicalVarKind::Ty(CanonicalTyVarKind::Int), t)
391393
}
392394
}
393395
TyKind::Infer(FloatVar(vid)) => {
394396
let nt = self.infcx.unwrap().opportunistic_resolve_float_var(vid);
395397
if nt != t {
396398
self.fold_ty(nt)
397399
} else {
398-
self.canonicalize_ty_var(
399-
CanonicalVarKind::Ty(CanonicalTyVarKind::Float),
400-
t,
401-
)
400+
self.canonicalize_ty_var(CanonicalVarKind::Ty(CanonicalTyVarKind::Float), t)
402401
}
403402
}
404403

405-
TyKind::Infer(InferTy::FreshTy(_) | InferTy::FreshIntTy(_) | InferTy::FreshFloatTy(_)) => {
404+
TyKind::Infer(
405+
InferTy::FreshTy(_) | InferTy::FreshIntTy(_) | InferTy::FreshFloatTy(_),
406+
) => {
406407
panic!("encountered a fresh type during canonicalization")
407408
}
408409

409410
TyKind::Placeholder(mut placeholder) => {
410411
if !self.canonicalize_mode.preserve_universes() {
411412
placeholder.universe = UniverseIndex::ROOT;
412413
}
413-
self.canonicalize_ty_var(
414-
CanonicalVarKind::PlaceholderTy(placeholder),
415-
t,
416-
)
414+
self.canonicalize_ty_var(CanonicalVarKind::PlaceholderTy(placeholder), t)
417415
}
418416

419417
TyKind::Bound(debruijn, _) => {
@@ -485,10 +483,7 @@ impl<'cx, 'db> TypeFolder<DbInterner<'db>> for Canonicalizer<'cx, 'db> {
485483
// FIXME: perf problem described in #55921.
486484
ui = UniverseIndex::ROOT;
487485
}
488-
return self.canonicalize_const_var(
489-
CanonicalVarKind::Const(ui),
490-
ct,
491-
);
486+
return self.canonicalize_const_var(CanonicalVarKind::Const(ui), ct);
492487
}
493488
}
494489
}
@@ -503,10 +498,8 @@ impl<'cx, 'db> TypeFolder<DbInterner<'db>> for Canonicalizer<'cx, 'db> {
503498
}
504499
}
505500
ConstKind::Placeholder(placeholder) => {
506-
return self.canonicalize_const_var(
507-
CanonicalVarKind::PlaceholderConst(placeholder),
508-
ct,
509-
);
501+
return self
502+
.canonicalize_const_var(CanonicalVarKind::PlaceholderConst(placeholder), ct);
510503
}
511504
_ => {}
512505
}
@@ -596,7 +589,8 @@ impl<'cx, 'db> Canonicalizer<'cx, 'db> {
596589
// anymore.
597590
debug_assert!(!out_value.has_infer() && !out_value.has_placeholders());
598591

599-
let canonical_variables = CanonicalVars::new_from_iter(tcx, canonicalizer.universe_canonicalized_variables());
592+
let canonical_variables =
593+
CanonicalVars::new_from_iter(tcx, canonicalizer.universe_canonicalized_variables());
600594

601595
let max_universe = canonical_variables
602596
.iter()
@@ -690,15 +684,11 @@ impl<'cx, 'db> Canonicalizer<'cx, 'db> {
690684
self.variables
691685
.iter()
692686
.map(|v| match *v {
693-
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => {
694-
*v
695-
}
687+
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => *v,
696688
CanonicalVarKind::Ty(CanonicalTyVarKind::General(u)) => {
697689
CanonicalVarKind::Ty(CanonicalTyVarKind::General(reverse_universe_map[&u]))
698690
}
699-
CanonicalVarKind::Region(u) => {
700-
CanonicalVarKind::Region(reverse_universe_map[&u])
701-
}
691+
CanonicalVarKind::Region(u) => CanonicalVarKind::Region(reverse_universe_map[&u]),
702692
CanonicalVarKind::Const(u) => CanonicalVarKind::Const(reverse_universe_map[&u]),
703693
CanonicalVarKind::PlaceholderTy(placeholder) => {
704694
CanonicalVarKind::PlaceholderTy(Placeholder {
@@ -735,14 +725,8 @@ impl<'cx, 'db> Canonicalizer<'cx, 'db> {
735725
///
736726
/// (This works because unification never fails -- and hence trait
737727
/// selection is never affected -- due to a universe mismatch.)
738-
fn canonical_var_for_region_in_root_universe(
739-
&mut self,
740-
r: Region<'db>,
741-
) -> Region<'db> {
742-
self.canonical_var_for_region(
743-
CanonicalVarKind::Region(UniverseIndex::ROOT),
744-
r,
745-
)
728+
fn canonical_var_for_region_in_root_universe(&mut self, r: Region<'db>) -> Region<'db> {
729+
self.canonical_var_for_region(CanonicalVarKind::Region(UniverseIndex::ROOT), r)
746730
}
747731

748732
/// Creates a canonical variable (with the given `info`)
@@ -764,7 +748,11 @@ impl<'cx, 'db> Canonicalizer<'cx, 'db> {
764748
fn canonicalize_ty_var(&mut self, info: CanonicalVarKind<'db>, ty_var: Ty<'db>) -> Ty<'db> {
765749
debug_assert!(!self.infcx.is_some_and(|infcx| ty_var != infcx.shallow_resolve(ty_var)));
766750
let var = self.canonical_var(info, ty_var.into());
767-
Ty::new_bound(self.tcx, self.binder_index, BoundTy { kind: crate::next_solver::BoundTyKind::Anon, var })
751+
Ty::new_bound(
752+
self.tcx,
753+
self.binder_index,
754+
BoundTy { kind: crate::next_solver::BoundTyKind::Anon, var },
755+
)
768756
}
769757

770758
/// Given a type variable `const_var` of the given kind, first check

crates/hir-ty/src/next_solver/mapping.rs

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use chalk_ir::{
66
WellFormed, cast::Cast, fold::Shift, interner::HasInterner,
77
};
88
use hir_def::{
9-
CallableDefId, ConstParamId, FunctionId, GeneralConstId, LifetimeParamId, TypeAliasId,
10-
TypeOrConstParamId, TypeParamId, signatures::TraitFlags,
9+
CallableDefId, ConstParamId, FunctionId, GeneralConstId, GenericDefId, LifetimeParamId,
10+
TypeAliasId, TypeOrConstParamId, TypeParamId, signatures::TraitFlags,
1111
};
1212
use intern::sym;
1313
use rustc_type_ir::{
@@ -276,10 +276,23 @@ impl<'db> ChalkToNextSolver<'db, Ty<'db>> for chalk_ir::Ty<Interner> {
276276
),
277277
chalk_ir::TyKind::Error => rustc_type_ir::TyKind::Error(ErrorGuaranteed),
278278
chalk_ir::TyKind::Placeholder(placeholder_index) => {
279-
rustc_type_ir::TyKind::Placeholder(PlaceholderTy::new_anon(
280-
placeholder_index.ui.to_nextsolver(interner),
281-
rustc_type_ir::BoundVar::from_usize(placeholder_index.idx),
282-
))
279+
if placeholder_index.idx < 128 {
280+
dbg!(placeholder_index.idx);
281+
rustc_type_ir::TyKind::Placeholder(PlaceholderTy::new_anon(
282+
placeholder_index.ui.to_nextsolver(interner),
283+
rustc_type_ir::BoundVar::from_usize(placeholder_index.idx),
284+
))
285+
} else {
286+
let id =
287+
crate::mapping::from_placeholder_idx(interner.db, *placeholder_index);
288+
rustc_type_ir::TyKind::Placeholder(PlaceholderTy::new(
289+
placeholder_index.ui.to_nextsolver(interner),
290+
BoundTy {
291+
var: BoundVar::from_u32(id.local_id.into_raw().into_u32()),
292+
kind: BoundTyKind::Param(id.parent.into()),
293+
},
294+
))
295+
}
283296
}
284297
chalk_ir::TyKind::Dyn(dyn_ty) => {
285298
// exists<type> { for<...> ^1.0: ... }
@@ -559,8 +572,27 @@ impl<'db> ChalkToNextSolver<'db, Ty<'db>> for chalk_ir::Ty<Interner> {
559572

560573
rustc_type_ir::TyKind::Placeholder(placeholder) => {
561574
let ui = chalk_ir::UniverseIndex { counter: placeholder.universe.as_usize() };
562-
let placeholder_index =
563-
chalk_ir::PlaceholderIndex { idx: placeholder.bound.var.as_usize(), ui };
575+
let placeholder_index = match placeholder.bound.kind {
576+
BoundTyKind::Anon => {
577+
chalk_ir::PlaceholderIndex { idx: placeholder.bound.var.as_usize(), ui }
578+
}
579+
BoundTyKind::Param(solver_def_id) => {
580+
let Some(def) =
581+
solver_def_id_to_generic_def_id_opt(interner.db, solver_def_id)
582+
else {
583+
unreachable!()
584+
};
585+
crate::mapping::to_placeholder_idx(
586+
interner.db,
587+
TypeOrConstParamId {
588+
parent: def,
589+
local_id: crate::Idx::from_raw(
590+
placeholder.bound.var.as_u32().into(),
591+
),
592+
},
593+
)
594+
}
595+
};
564596
TyKind::Placeholder(placeholder_index)
565597
}
566598

@@ -1986,8 +2018,24 @@ pub(crate) fn convert_ty_for_result<'db>(interner: DbInterner<'db>, ty: Ty<'db>)
19862018

19872019
rustc_type_ir::TyKind::Placeholder(placeholder) => {
19882020
let ui = chalk_ir::UniverseIndex { counter: placeholder.universe.as_usize() };
1989-
let placeholder_index =
1990-
chalk_ir::PlaceholderIndex { idx: placeholder.bound.var.as_usize(), ui };
2021+
let placeholder_index = match placeholder.bound.kind {
2022+
BoundTyKind::Anon => {
2023+
chalk_ir::PlaceholderIndex { idx: placeholder.bound.var.as_usize(), ui }
2024+
}
2025+
BoundTyKind::Param(solver_def_id) => {
2026+
let Some(def) = solver_def_id_to_generic_def_id_opt(interner.db, solver_def_id)
2027+
else {
2028+
unreachable!()
2029+
};
2030+
crate::mapping::to_placeholder_idx(
2031+
interner.db,
2032+
TypeOrConstParamId {
2033+
parent: def,
2034+
local_id: crate::Idx::from_raw(placeholder.bound.var.as_u32().into()),
2035+
},
2036+
)
2037+
}
2038+
};
19912039
TyKind::Placeholder(placeholder_index)
19922040
}
19932041

@@ -2298,3 +2346,27 @@ impl InferenceVarExt for InferenceVar {
22982346
InferenceVar::from(vid.as_u32())
22992347
}
23002348
}
2349+
2350+
pub fn solver_def_id_to_generic_def_id_opt(
2351+
db: &dyn HirDatabase,
2352+
id: SolverDefId,
2353+
) -> Option<GenericDefId> {
2354+
match id {
2355+
SolverDefId::AdtId(it) => Some(it.into()),
2356+
SolverDefId::ConstId(it) => Some(it.into()),
2357+
SolverDefId::FunctionId(it) => Some(it.into()),
2358+
SolverDefId::ImplId(it) => Some(it.into()),
2359+
SolverDefId::StaticId(it) => Some(it.into()),
2360+
SolverDefId::TraitId(it) => Some(it.into()),
2361+
SolverDefId::TypeAliasId(it) => Some(it.into()),
2362+
SolverDefId::Ctor(crate::next_solver::Ctor::Struct(it)) => Some(it.into()),
2363+
SolverDefId::Ctor(crate::next_solver::Ctor::Enum(it)) => Some(it.loc(db).parent.into()),
2364+
SolverDefId::InternedOpaqueTyId(it) => match it.loc(db) {
2365+
crate::ImplTraitId::ReturnTypeImplTrait(it, _) => Some(it.into()),
2366+
crate::ImplTraitId::TypeAliasImplTrait(it, _) => Some(it.into()),
2367+
crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => None,
2368+
},
2369+
SolverDefId::InternedClosureId(_) => None,
2370+
SolverDefId::InternedCoroutineId(_) => None,
2371+
}
2372+
}

crates/hir-ty/src/next_solver/solver.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ use crate::{
1313
TraitRefExt,
1414
db::HirDatabase,
1515
next_solver::{
16-
ClauseKind, CoercePredicate, PredicateKind, SubtypePredicate,
17-
mapping::ChalkToNextSolver,
16+
ClauseKind, CoercePredicate, PredicateKind, SubtypePredicate, mapping::ChalkToNextSolver,
1817
util::sizedness_fast_path,
1918
},
2019
};

0 commit comments

Comments
 (0)