Unnamed repository; edit this file 'description' to name the repository.
Update solver types as required by the upgrade
Chayim Refael Friedman 6 weeks ago
parent c7cbaa7 · commit 2880f88
-rw-r--r--Cargo.lock44
-rw-r--r--Cargo.toml16
-rw-r--r--crates/hir-ty/src/builtin_derive.rs22
-rw-r--r--crates/hir-ty/src/display.rs16
-rw-r--r--crates/hir-ty/src/dyn_compatibility.rs57
-rw-r--r--crates/hir-ty/src/infer.rs10
-rw-r--r--crates/hir-ty/src/infer/closure.rs2
-rw-r--r--crates/hir-ty/src/infer/coerce.rs2
-rw-r--r--crates/hir-ty/src/infer/unify.rs7
-rw-r--r--crates/hir-ty/src/layout/target.rs31
-rw-r--r--crates/hir-ty/src/lib.rs13
-rw-r--r--crates/hir-ty/src/lower.rs10
-rw-r--r--crates/hir-ty/src/lower/path.rs6
-rw-r--r--crates/hir-ty/src/mir/eval.rs6
-rw-r--r--crates/hir-ty/src/next_solver.rs14
-rw-r--r--crates/hir-ty/src/next_solver/consts.rs81
-rw-r--r--crates/hir-ty/src/next_solver/fold.rs26
-rw-r--r--crates/hir-ty/src/next_solver/fulfill.rs2
-rw-r--r--crates/hir-ty/src/next_solver/fulfill/errors.rs1173
-rw-r--r--crates/hir-ty/src/next_solver/infer/canonical/canonicalizer.rs38
-rw-r--r--crates/hir-ty/src/next_solver/infer/canonical/instantiate.rs14
-rw-r--r--crates/hir-ty/src/next_solver/infer/canonical/mod.rs18
-rw-r--r--crates/hir-ty/src/next_solver/infer/mod.rs18
-rw-r--r--crates/hir-ty/src/next_solver/infer/region_constraints/mod.rs4
-rw-r--r--crates/hir-ty/src/next_solver/infer/relate/generalize.rs2
-rw-r--r--crates/hir-ty/src/next_solver/infer/relate/higher_ranked.rs23
-rw-r--r--crates/hir-ty/src/next_solver/infer/relate/lattice.rs4
-rw-r--r--crates/hir-ty/src/next_solver/inspect.rs6
-rw-r--r--crates/hir-ty/src/next_solver/interner.rs213
-rw-r--r--crates/hir-ty/src/next_solver/ir_print.rs2
-rw-r--r--crates/hir-ty/src/next_solver/normalize.rs1
-rw-r--r--crates/hir-ty/src/next_solver/region.rs136
-rw-r--r--crates/hir-ty/src/next_solver/solver.rs9
-rw-r--r--crates/hir-ty/src/next_solver/ty.rs97
-rw-r--r--crates/hir-ty/src/next_solver/util.rs21
-rw-r--r--crates/hir-ty/src/variance.rs2
-rw-r--r--crates/hir/src/lib.rs28
-rw-r--r--crates/hir/src/source_analyzer.rs12
38 files changed, 416 insertions, 1770 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4c6e0e5ed8..94e9507c02 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2048,9 +2048,9 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "ra-ap-rustc_abi"
-version = "0.159.0"
+version = "0.160.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ada9f3d87f035c2234b48ceb43c07f04daa40348bffda88e91e5bc452fca147"
+checksum = "4b917ab47d7036977be4c984321af3e0de089229404d68ea9a286f50aa464697"
dependencies = [
"bitflags 2.9.4",
"ra-ap-rustc_hashes",
@@ -2060,33 +2060,33 @@ dependencies = [
[[package]]
name = "ra-ap-rustc_ast_ir"
-version = "0.159.0"
+version = "0.160.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "113acd7f51ff383eb86ebc8fb12df8a44d418bed0a990bcea363388f737a329a"
+checksum = "021d80bea67458b8c90cc25bfdca6f911ea818a41905e370c1f310cced1dd07e"
[[package]]
name = "ra-ap-rustc_hashes"
-version = "0.159.0"
+version = "0.160.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2002d37e435be69d87d307bd4d9b494a3ac08b30d383c7e4b1b6b3f976fb2675"
+checksum = "8bb89395306ecfc980d252f77a4038d8b8bb578a25c856b545cbeeb3fde8358e"
dependencies = [
"rustc-stable-hash",
]
[[package]]
name = "ra-ap-rustc_index"
-version = "0.159.0"
+version = "0.160.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32e8921cba582b0c93d8e4443cca24aec07f25e87b1483e4fa62113d2d9cfea1"
+checksum = "84219d028a1954c4340ddde11adffe93eb83e476e942718fe926f4d99637cbbe"
dependencies = [
"ra-ap-rustc_index_macros",
]
[[package]]
name = "ra-ap-rustc_index_macros"
-version = "0.159.0"
+version = "0.160.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49574ecf35748cebf67fec53db7e81968b599cc50becceba01b895d1ad40e9ea"
+checksum = "3908fdfa258c663d8ee407e6b4a205b0880e323b533c0df7edceafbd54a02fb6"
dependencies = [
"proc-macro2",
"quote",
@@ -2095,9 +2095,9 @@ dependencies = [
[[package]]
name = "ra-ap-rustc_lexer"
-version = "0.159.0"
+version = "0.160.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33aabb4e87bc6c0dbb721728ad71126fb17fb9262cb9cd215314a10d64c92985"
+checksum = "34b50f19d5856b8e2b36150e89b53a6102ab096e8044e1f55fd6fef977b10d85"
dependencies = [
"memchr",
"unicode-ident",
@@ -2106,9 +2106,9 @@ dependencies = [
[[package]]
name = "ra-ap-rustc_next_trait_solver"
-version = "0.159.0"
+version = "0.160.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7559a4b05b358ec59838d8d2a9a6b6e3c4f7aaf3805c0878b82456d63ad4d05"
+checksum = "76f83dcc451bcee8a99e284a583d5b3d82db5a200107a256a40ef132c4988f1b"
dependencies = [
"derive-where",
"ra-ap-rustc_index",
@@ -2119,9 +2119,9 @@ dependencies = [
[[package]]
name = "ra-ap-rustc_parse_format"
-version = "0.159.0"
+version = "0.160.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5ec9bf15c3fed1ba4e0f9a0ceba36f8fa740e2f606609a68fc42034e0e6b28d"
+checksum = "f31236bdc6cbcae8af42d0b2db2fa8d812a8715b90a2ba5afb1132b37a4d0bbc"
dependencies = [
"ra-ap-rustc_lexer",
"rustc-literal-escaper 0.0.7",
@@ -2129,9 +2129,9 @@ dependencies = [
[[package]]
name = "ra-ap-rustc_pattern_analysis"
-version = "0.159.0"
+version = "0.160.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9088a430b80729958eda4c428acf731644d3b78caa4285ed659ff586b772743"
+checksum = "3fc4edac740e896fba4b3b4d9c423083e3eac49947732561ddfb2377e1f57829"
dependencies = [
"ra-ap-rustc_index",
"rustc-hash 2.1.1",
@@ -2142,9 +2142,9 @@ dependencies = [
[[package]]
name = "ra-ap-rustc_type_ir"
-version = "0.159.0"
+version = "0.160.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0f59b0708ec44c375dad7dc3818a3bd8eb3497a54d5968f5c945ac11c029854"
+checksum = "8efa119afc1bcadd821b27aa94332abf79c48ac0a972cb78932f63004ba4cdd9"
dependencies = [
"arrayvec",
"bitflags 2.9.4",
@@ -2163,9 +2163,9 @@ dependencies = [
[[package]]
name = "ra-ap-rustc_type_ir_macros"
-version = "0.159.0"
+version = "0.160.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4b09efb7749eb0a3fb8fac1ce26618eef8ee5ca0aa36fe01228b853d28113a2"
+checksum = "e6b1dc03abfabc7179393c282892c73a3f0e4bbd5f0b6c87ff42c2b142e68f57"
dependencies = [
"proc-macro2",
"quote",
diff --git a/Cargo.toml b/Cargo.toml
index 40fcb9aed6..4372afa0f5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -86,14 +86,14 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" }
vfs = { path = "./crates/vfs", version = "0.0.0" }
edition = { path = "./crates/edition", version = "0.0.0" }
-ra-ap-rustc_lexer = { version = "0.159", default-features = false }
-ra-ap-rustc_parse_format = { version = "0.159", default-features = false }
-ra-ap-rustc_index = { version = "0.159", default-features = false }
-ra-ap-rustc_abi = { version = "0.159", default-features = false }
-ra-ap-rustc_pattern_analysis = { version = "0.159", default-features = false }
-ra-ap-rustc_ast_ir = { version = "0.159", default-features = false }
-ra-ap-rustc_type_ir = { version = "0.159", default-features = false }
-ra-ap-rustc_next_trait_solver = { version = "0.159", default-features = false }
+ra-ap-rustc_lexer = { version = "0.160", default-features = false }
+ra-ap-rustc_parse_format = { version = "0.160", default-features = false }
+ra-ap-rustc_index = { version = "0.160", default-features = false }
+ra-ap-rustc_abi = { version = "0.160", default-features = false }
+ra-ap-rustc_pattern_analysis = { version = "0.160", default-features = false }
+ra-ap-rustc_ast_ir = { version = "0.160", default-features = false }
+ra-ap-rustc_type_ir = { version = "0.160", default-features = false }
+ra-ap-rustc_next_trait_solver = { version = "0.160", default-features = false }
# local crates that aren't published to crates.io. These should not have versions.
diff --git a/crates/hir-ty/src/builtin_derive.rs b/crates/hir-ty/src/builtin_derive.rs
index eb3922f4b6..6a9b1671e7 100644
--- a/crates/hir-ty/src/builtin_derive.rs
+++ b/crates/hir-ty/src/builtin_derive.rs
@@ -20,8 +20,8 @@ use crate::{
GenericPredicates,
db::HirDatabase,
next_solver::{
- Clause, Clauses, DbInterner, EarlyBinder, GenericArgs, ParamEnv, StoredEarlyBinder,
- StoredTy, TraitRef, Ty, TyKind, fold::fold_tys, generics::Generics,
+ AliasTy, Clause, Clauses, DbInterner, EarlyBinder, GenericArgs, ParamEnv,
+ StoredEarlyBinder, StoredTy, TraitRef, Ty, TyKind, fold::fold_tys, generics::Generics,
},
};
@@ -342,7 +342,7 @@ fn extend_assoc_type_bounds<'db>(
type Result = ();
fn visit_ty(&mut self, t: Ty<'db>) -> Self::Result {
- if let TyKind::Alias(AliasTyKind::Projection, _) = t.kind() {
+ if let TyKind::Alias(AliasTy { kind: AliasTyKind::Projection { .. }, .. }) = t.kind() {
self.assoc_type_bounds.push(
TraitRef::new_from_args(
self.interner,
@@ -546,49 +546,49 @@ struct WithGenerics<'a, T: Trait, const N: usize>(&'a [T; N], T::Assoc);
Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Debug, polarity:Positive), bound_vars: [] })
- Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): Debug, polarity:Positive), bound_vars: [] })
+ Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): Debug, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Clone, polarity:Positive), bound_vars: [] })
- Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): Clone, polarity:Positive), bound_vars: [] })
+ Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): Clone, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Copy, polarity:Positive), bound_vars: [] })
- Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): Copy, polarity:Positive), bound_vars: [] })
+ Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): Copy, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: PartialEq<[#1]>, polarity:Positive), bound_vars: [] })
- Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): PartialEq<[Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. })]>, polarity:Positive), bound_vars: [] })
+ Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): PartialEq<[Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. })]>, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Eq, polarity:Positive), bound_vars: [] })
- Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): Eq, polarity:Positive), bound_vars: [] })
+ Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): Eq, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: PartialOrd<[#1]>, polarity:Positive), bound_vars: [] })
- Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): PartialOrd<[Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. })]>, polarity:Positive), bound_vars: [] })
+ Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): PartialOrd<[Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. })]>, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Ord, polarity:Positive), bound_vars: [] })
- Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): Ord, polarity:Positive), bound_vars: [] })
+ Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): Ord, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
Clause(Binder { value: TraitPredicate(#1: Hash, polarity:Positive), bound_vars: [] })
- Clause(Binder { value: TraitPredicate(Alias(Projection, AliasTy { args: [#1], def_id: TypeAliasId("Assoc"), .. }): Hash, polarity:Positive), bound_vars: [] })
+ Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): Hash, polarity:Positive), bound_vars: [] })
"#]],
);
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 7f1b1ecbd2..1e4c2985cf 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -646,7 +646,7 @@ fn write_projection<'db>(
ClauseKind::TypeOutlives(t) => t.0,
_ => return false,
};
- let TyKind::Alias(AliasTyKind::Projection, a) = ty.kind() else {
+ let TyKind::Alias(a) = ty.kind() else {
return false;
};
a == *alias
@@ -657,7 +657,7 @@ fn write_projection<'db>(
write_bounds_like_dyn_trait_with_prefix(
f,
"impl",
- Either::Left(Ty::new_alias(f.interner, AliasTyKind::Projection, *alias)),
+ Either::Left(Ty::new_alias(f.interner, *alias)),
&bounds,
SizedByDefault::NotSized,
needs_parens_if_multi,
@@ -673,7 +673,7 @@ fn write_projection<'db>(
write!(
f,
">::{}",
- TypeAliasSignature::of(f.db, alias.def_id.expect_type_alias())
+ TypeAliasSignature::of(f.db, alias.kind.def_id().expect_type_alias())
.name
.display(f.db, f.edition())
)?;
@@ -1005,7 +1005,7 @@ fn render_const_scalar_inner<'db>(
TyKind::Pat(_, _) => f.write_str("<pat>"),
TyKind::Error(..)
| TyKind::Placeholder(_)
- | TyKind::Alias(_, _)
+ | TyKind::Alias(..)
| TyKind::Param(_)
| TyKind::Bound(_, _)
| TyKind::Infer(_) => f.write_str("<placeholder-or-unknown-type>"),
@@ -1280,7 +1280,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
hir_fmt_generics(f, parameters.as_slice(), Some(def.def_id().0.into()), None)?;
}
- TyKind::Alias(AliasTyKind::Projection, alias_ty) => {
+ TyKind::Alias(alias_ty @ AliasTy { kind: AliasTyKind::Projection { .. }, .. }) => {
write_projection(f, &alias_ty, trait_bounds_need_parens)?
}
TyKind::Foreign(alias) => {
@@ -1289,8 +1289,8 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
write!(f, "{}", type_alias.name.display(f.db, f.edition()))?;
f.end_location_link();
}
- TyKind::Alias(AliasTyKind::Opaque, alias_ty) => {
- let opaque_ty_id = match alias_ty.def_id {
+ TyKind::Alias(alias_ty @ AliasTy { kind: AliasTyKind::Opaque { def_id }, .. }) => {
+ let opaque_ty_id = match def_id {
SolverDefId::InternedOpaqueTyId(id) => id,
_ => unreachable!(),
};
@@ -1585,7 +1585,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
TyKind::CoroutineWitness(..) => write!(f, "{{coroutine witness}}")?,
TyKind::Pat(_, _) => write!(f, "{{pat}}")?,
TyKind::UnsafeBinder(_) => write!(f, "{{unsafe binder}}")?,
- TyKind::Alias(_, _) => write!(f, "{{alias}}")?,
+ TyKind::Alias(..) => write!(f, "{{alias}}")?,
}
Ok(())
}
diff --git a/crates/hir-ty/src/dyn_compatibility.rs b/crates/hir-ty/src/dyn_compatibility.rs
index e70918f8e1..ba63343d49 100644
--- a/crates/hir-ty/src/dyn_compatibility.rs
+++ b/crates/hir-ty/src/dyn_compatibility.rs
@@ -21,8 +21,9 @@ use crate::{
db::{HirDatabase, InternedOpaqueTyId},
lower::{GenericPredicates, associated_ty_item_bounds},
next_solver::{
- Binder, Clause, Clauses, DbInterner, EarlyBinder, GenericArgs, Goal, ParamEnv, ParamTy,
- SolverDefId, TraitPredicate, TraitRef, Ty, TypingMode, infer::DbInternerInferExt, mk_param,
+ AliasTy, Binder, Clause, Clauses, DbInterner, EarlyBinder, GenericArgs, Goal, ParamEnv,
+ ParamTy, SolverDefId, TraitPredicate, TraitRef, Ty, TypingMode, infer::DbInternerInferExt,
+ mk_param,
},
traits::next_trait_solve_in_ctxt,
};
@@ -239,30 +240,30 @@ fn contains_illegal_self_type_reference<'db, T: rustc_type_ir::TypeVisitable<DbI
match ty.kind() {
rustc_type_ir::TyKind::Param(param) if param.index == 0 => ControlFlow::Break(()),
rustc_type_ir::TyKind::Param(_) => ControlFlow::Continue(()),
- rustc_type_ir::TyKind::Alias(AliasTyKind::Projection, proj) => {
- match self.allow_self_projection {
- AllowSelfProjection::Yes => {
- let trait_ = proj.trait_def_id(interner);
- let trait_ = match trait_ {
- SolverDefId::TraitId(id) => id,
- _ => unreachable!(),
- };
- if self.super_traits.is_none() {
- self.super_traits = Some(
- elaborate::supertrait_def_ids(interner, self.trait_.into())
- .map(|super_trait| super_trait.0)
- .collect(),
- )
- }
- if self.super_traits.as_ref().is_some_and(|s| s.contains(&trait_)) {
- ControlFlow::Continue(())
- } else {
- ty.super_visit_with(self)
- }
+ rustc_type_ir::TyKind::Alias(
+ proj @ AliasTy { kind: AliasTyKind::Projection { .. }, .. },
+ ) => match self.allow_self_projection {
+ AllowSelfProjection::Yes => {
+ let trait_ = proj.trait_def_id(interner);
+ let trait_ = match trait_ {
+ SolverDefId::TraitId(id) => id,
+ _ => unreachable!(),
+ };
+ if self.super_traits.is_none() {
+ self.super_traits = Some(
+ elaborate::supertrait_def_ids(interner, self.trait_.into())
+ .map(|super_trait| super_trait.0)
+ .collect(),
+ )
+ }
+ if self.super_traits.as_ref().is_some_and(|s| s.contains(&trait_)) {
+ ControlFlow::Continue(())
+ } else {
+ ty.super_visit_with(self)
}
- AllowSelfProjection::No => ty.super_visit_with(self),
}
- }
+ AllowSelfProjection::No => ty.super_visit_with(self),
+ },
_ => ty.super_visit_with(self),
}
}
@@ -503,8 +504,12 @@ fn contains_illegal_impl_trait_in_trait<'db>(
&mut self,
ty: <DbInterner<'db> as rustc_type_ir::Interner>::Ty,
) -> Self::Result {
- if let rustc_type_ir::TyKind::Alias(AliasTyKind::Opaque, op) = ty.kind() {
- let id = match op.def_id {
+ if let rustc_type_ir::TyKind::Alias(AliasTy {
+ kind: AliasTyKind::Opaque { def_id },
+ ..
+ }) = ty.kind()
+ {
+ let id = match def_id {
SolverDefId::InternedOpaqueTyId(id) => id,
_ => unreachable!(),
};
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index bd897113bf..70083dbe3e 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -1674,10 +1674,9 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
Some(res_assoc_ty) => {
let alias = Ty::new_alias(
self.interner(),
- AliasTyKind::Projection,
AliasTy::new(
self.interner(),
- res_assoc_ty.into(),
+ AliasTyKind::Projection { def_id: res_assoc_ty.into() },
iter::once(inner_ty.into()).chain(params.iter().copied()),
),
);
@@ -1728,8 +1727,11 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
let args = self.infcx().fill_rest_fresh_args(assoc_type.into(), trait_ref.args);
let alias = Ty::new_alias(
self.interner(),
- AliasTyKind::Projection,
- AliasTy::new_from_args(self.interner(), assoc_type.into(), args),
+ AliasTy::new_from_args(
+ self.interner(),
+ AliasTyKind::Projection { def_id: assoc_type.into() },
+ args,
+ ),
);
ty = self.table.try_structurally_resolve_type(alias);
segments = segments.skip(1);
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 2cb936fec3..bebf39b694 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -364,7 +364,7 @@ impl<'db> InferenceContext<'_, 'db> {
closure_kind: ClosureKind,
) -> (Option<PolyFnSig<'db>>, Option<rustc_type_ir::ClosureKind>) {
match expected_ty.kind() {
- TyKind::Alias(rustc_type_ir::Opaque, AliasTy { def_id, args, .. }) => self
+ TyKind::Alias(AliasTy { kind: rustc_type_ir::Opaque { def_id }, args, .. }) => self
.deduce_closure_signature_from_predicates(
expected_ty,
closure_kind,
diff --git a/crates/hir-ty/src/infer/coerce.rs b/crates/hir-ty/src/infer/coerce.rs
index 47a7049248..f92503003b 100644
--- a/crates/hir-ty/src/infer/coerce.rs
+++ b/crates/hir-ty/src/infer/coerce.rs
@@ -1663,7 +1663,7 @@ fn coerce<'db>(
Const::new_bound(
self.interner,
self.debruijn,
- BoundConst { var: BoundVar::from_usize(i) },
+ BoundConst::new(BoundVar::from_usize(i)),
)
},
)
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs
index d093412b42..35b41f0bbd 100644
--- a/crates/hir-ty/src/infer/unify.rs
+++ b/crates/hir-ty/src/infer/unify.rs
@@ -538,8 +538,11 @@ impl<'db> InferenceTable<'db> {
let proj_args = self.infer_ctxt.fill_rest_fresh_args(output_assoc_type.into(), args);
let projection = Ty::new_alias(
self.interner(),
- rustc_type_ir::AliasTyKind::Projection,
- AliasTy::new_from_args(self.interner(), output_assoc_type.into(), proj_args),
+ AliasTy::new_from_args(
+ self.interner(),
+ rustc_type_ir::Projection { def_id: output_assoc_type.into() },
+ proj_args,
+ ),
);
let pred = Predicate::upcast_from(trait_ref, self.interner());
diff --git a/crates/hir-ty/src/layout/target.rs b/crates/hir-ty/src/layout/target.rs
index b0986c423b..1752b56b0f 100644
--- a/crates/hir-ty/src/layout/target.rs
+++ b/crates/hir-ty/src/layout/target.rs
@@ -2,7 +2,7 @@
use base_db::{Crate, target::TargetLoadError};
use hir_def::layout::TargetDataLayout;
-use rustc_abi::{AddressSpace, AlignFromBytesError, TargetDataLayoutErrors};
+use rustc_abi::{AddressSpace, AlignFromBytesError, TargetDataLayoutError};
use triomphe::Arc;
use crate::db::HirDatabase;
@@ -16,30 +16,29 @@ pub fn target_data_layout_query(
Ok(it) => Ok(Arc::new(it)),
Err(e) => {
Err(match e {
- TargetDataLayoutErrors::InvalidAddressSpace { addr_space, cause, err } => {
+ TargetDataLayoutError::InvalidAddressSpace { addr_space, cause, err } => {
format!(
r#"invalid address space `{addr_space}` for `{cause}` in "data-layout": {err}"#
)
}
- TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => format!(r#"invalid {kind} `{bit}` for `{cause}` in "data-layout": {err}"#),
- TargetDataLayoutErrors::MissingAlignment { cause } => format!(r#"missing alignment for `{cause}` in "data-layout""#),
- TargetDataLayoutErrors::InvalidAlignment { cause, err } => format!(
- r#"invalid alignment for `{cause}` in "data-layout": `{align}` is {err_kind}"#,
- align = err.align(),
- err_kind = match err {
- AlignFromBytesError::NotPowerOfTwo(_) => "not a power of two",
- AlignFromBytesError::TooLarge(_) => "too large",
- }
- ),
- TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
+ TargetDataLayoutError::InvalidBits { kind, bit, cause, err } => format!(r#"invalid {kind} `{bit}` for `{cause}` in "data-layout": {err}"#),
+ TargetDataLayoutError::MissingAlignment { cause } => format!(r#"missing alignment for `{cause}` in "data-layout""#),
+ TargetDataLayoutError::InvalidAlignment { cause, err } => {
+ let (align, err_kind) = match err {
+ AlignFromBytesError::NotPowerOfTwo(align) => (align, "not a power of two"),
+ AlignFromBytesError::TooLarge(align) => (align, "too large"),
+ };
+ format!(r#"invalid alignment for `{cause}` in "data-layout": `{align}` is {err_kind}"#)
+ },
+ TargetDataLayoutError::InconsistentTargetArchitecture { dl, target } => {
format!(r#"inconsistent target specification: "data-layout" claims architecture is {dl}-endian, while "target-endian" is `{target}`"#)
}
- TargetDataLayoutErrors::InconsistentTargetPointerWidth {
+ TargetDataLayoutError::InconsistentTargetPointerWidth {
pointer_size,
target,
} => format!(r#"inconsistent target specification: "data-layout" claims pointers are {pointer_size}-bit, while "target-pointer-width" is `{target}`"#),
- TargetDataLayoutErrors::InvalidBitsSize { err } => err,
- TargetDataLayoutErrors::UnknownPointerSpecification { err } => format!(r#"use of unknown pointer specifier in "data-layout": {err}"#),
+ TargetDataLayoutError::InvalidBitsSize { err } => err,
+ TargetDataLayoutError::UnknownPointerSpecification { err } => format!(r#"use of unknown pointer specifier in "data-layout": {err}"#),
}.into())
}
},
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index 5086be7330..9198e8b424 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/crates/hir-ty/src/lib.rs
@@ -84,7 +84,7 @@ use crate::{
lower::SupertraitsInfo,
next_solver::{
AliasTy, Binder, BoundConst, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, Canonical,
- CanonicalVarKind, CanonicalVars, ClauseKind, Const, ConstKind, DbInterner, FnSig,
+ CanonicalVarKind, CanonicalVarKinds, ClauseKind, Const, ConstKind, DbInterner, FnSig,
GenericArgs, PolyFnSig, Predicate, Region, RegionKind, TraitRef, Ty, TyKind, Tys, abi,
},
};
@@ -435,7 +435,7 @@ where
ConstKind::Error(_) => {
let var = rustc_type_ir::BoundVar::from_usize(self.vars.len());
self.vars.push(CanonicalVarKind::Const(rustc_type_ir::UniverseIndex::ZERO));
- Ok(Const::new_bound(self.interner, self.binder, BoundConst { var }))
+ Ok(Const::new_bound(self.interner, self.binder, BoundConst::new(var)))
}
ConstKind::Infer(_) => error(),
ConstKind::Bound(BoundVarIndexKind::Bound(index), _) if index > self.binder => {
@@ -479,7 +479,7 @@ where
Canonical {
value,
max_universe: rustc_type_ir::UniverseIndex::ZERO,
- variables: CanonicalVars::new_from_slice(&error_replacer.vars),
+ var_kinds: CanonicalVarKinds::new_from_slice(&error_replacer.vars),
}
}
@@ -551,8 +551,11 @@ pub fn callable_sig_from_fn_trait<'db>(
let trait_ref = TraitRef::new_from_args(table.interner(), fn_once_trait.into(), args);
let projection = Ty::new_alias(
table.interner(),
- rustc_type_ir::AliasTyKind::Projection,
- AliasTy::new_from_args(table.interner(), output_assoc_type.into(), args),
+ AliasTy::new_from_args(
+ table.interner(),
+ rustc_type_ir::Projection { def_id: output_assoc_type.into() },
+ args,
+ ),
);
let pred = Predicate::upcast_from(trait_ref, table.interner());
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 71a7db6559..5a6e14a1e5 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -537,8 +537,11 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
let args = GenericArgs::identity_for_item(self.interner, opaque_ty_id);
Ty::new_alias(
self.interner,
- AliasTyKind::Opaque,
- AliasTy::new_from_args(self.interner, opaque_ty_id, args),
+ AliasTy::new_from_args(
+ self.interner,
+ AliasTyKind::Opaque { def_id: opaque_ty_id },
+ args,
+ ),
)
}
ImplTraitLoweringMode::Disallowed => {
@@ -1039,8 +1042,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
let args = GenericArgs::identity_for_item(interner, def_id);
let self_ty = Ty::new_alias(
self.interner,
- rustc_type_ir::AliasTyKind::Opaque,
- AliasTy::new_from_args(interner, def_id, args),
+ AliasTy::new_from_args(interner, rustc_type_ir::Opaque { def_id }, args),
);
let (predicates, assoc_ty_bounds_start) =
self.with_shifted_in(DebruijnIndex::from_u32(1), |ctx| {
diff --git a/crates/hir-ty/src/lower/path.rs b/crates/hir-ty/src/lower/path.rs
index 889f0792d3..4f70732178 100644
--- a/crates/hir-ty/src/lower/path.rs
+++ b/crates/hir-ty/src/lower/path.rs
@@ -214,10 +214,9 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
);
Ty::new_alias(
self.ctx.interner,
- AliasTyKind::Projection,
AliasTy::new_from_args(
self.ctx.interner,
- associated_ty.into(),
+ AliasTyKind::Projection { def_id: associated_ty.into() },
args,
),
)
@@ -949,10 +948,9 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> {
bound,
Ty::new_alias(
self.ctx.interner,
- AliasTyKind::Projection,
AliasTy::new_from_args(
self.ctx.interner,
- associated_ty.into(),
+ AliasTyKind::Projection { def_id: associated_ty.into() },
args,
),
),
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 79b1c5cb7c..17af4ad961 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -46,7 +46,7 @@ use crate::{
layout::{Layout, LayoutError, RustcEnumVariantIdx},
method_resolution::{is_dyn_method, lookup_impl_const},
next_solver::{
- Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, Region,
+ AliasTy, Const, ConstBytes, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, Region,
StoredConst, StoredTy, Ty, TyKind, TypingMode, UnevaluatedConst, ValueConst,
infer::{DbInternerInferExt, InferCtxt, traits::ObligationCause},
obligation_ctxt::ObligationCtxt,
@@ -2340,7 +2340,7 @@ impl<'db> Evaluator<'db> {
}
AdtId::UnionId(_) => (),
},
- TyKind::Alias(AliasTyKind::Projection, _) => {
+ TyKind::Alias(AliasTy { kind: AliasTyKind::Projection { .. }, .. }) => {
let mut ocx = ObligationCtxt::new(&this.infcx);
let ty = ocx
.structurally_normalize_ty(
@@ -2483,7 +2483,7 @@ impl<'db> Evaluator<'db> {
| TyKind::Error(_)
| TyKind::Placeholder(_)
| TyKind::Dynamic(_, _)
- | TyKind::Alias(_, _)
+ | TyKind::Alias(..)
| TyKind::Bound(_, _)
| TyKind::Infer(_)
| TyKind::Pat(_, _)
diff --git a/crates/hir-ty/src/next_solver.rs b/crates/hir-ty/src/next_solver.rs
index 605e31404c..354ad16ffe 100644
--- a/crates/hir-ty/src/next_solver.rs
+++ b/crates/hir-ty/src/next_solver.rs
@@ -101,7 +101,7 @@ pub struct DefaultEmpty<'db> {
pub tys: Tys<'db>,
pub generic_args: GenericArgs<'db>,
pub bound_var_kinds: BoundVarKinds<'db>,
- pub canonical_vars: CanonicalVars<'db>,
+ pub canonical_vars: CanonicalVarKinds<'db>,
pub variances: VariancesOf<'db>,
pub pat_list: PatList<'db>,
pub predefined_opaques: PredefinedOpaques<'db>,
@@ -109,6 +109,7 @@ pub struct DefaultEmpty<'db> {
pub bound_existential_predicates: BoundExistentialPredicates<'db>,
pub clauses: Clauses<'db>,
pub region_assumptions: RegionAssumptions<'db>,
+ pub consts: Consts<'db>,
}
pub struct DefaultAny<'db> {
@@ -167,7 +168,7 @@ pub fn default_types<'a, 'db>(db: &'db dyn HirDatabase) -> &'a DefaultAny<'db> {
ty.as_ref()
};
let create_canonical_vars = |slice| {
- let ty = CanonicalVars::new_from_slice(slice);
+ let ty = CanonicalVarKinds::new_from_slice(slice);
// We need to increase the refcount (forever), so that the types won't be freed.
let ty = ManuallyDrop::new(ty.store());
ty.as_ref()
@@ -220,6 +221,12 @@ pub fn default_types<'a, 'db>(db: &'db dyn HirDatabase) -> &'a DefaultAny<'db> {
let ty = ManuallyDrop::new(ty.store());
ty.as_ref()
};
+ let create_consts = |slice| {
+ let ty = Consts::new_from_slice(slice);
+ // We need to increase the refcount (forever), so that the types won't be freed.
+ let ty = ManuallyDrop::new(ty.store());
+ ty.as_ref()
+ };
let str = create_ty(TyKind::Str);
let statik = create_region(RegionKind::ReStatic);
@@ -270,11 +277,12 @@ pub fn default_types<'a, 'db>(db: &'db dyn HirDatabase) -> &'a DefaultAny<'db> {
bound_existential_predicates: create_bound_existential_predicates(&[]),
clauses: create_clauses(&[]),
region_assumptions: create_region_assumptions(&[]),
+ consts: create_consts(&[]),
},
one_invariant: create_variances_of(&[rustc_type_ir::Variance::Invariant]),
one_covariant: create_variances_of(&[rustc_type_ir::Variance::Covariant]),
coroutine_captures_by_ref_bound_var_kinds: create_bound_var_kinds(&[
- BoundVarKind::Region(BoundRegionKind::ClosureEnv),
+ BoundVariableKind::Region(BoundRegionKind::ClosureEnv),
]),
}
})
diff --git a/crates/hir-ty/src/next_solver/consts.rs b/crates/hir-ty/src/next_solver/consts.rs
index 9643f1ba4c..8ed515b452 100644
--- a/crates/hir-ty/src/next_solver/consts.rs
+++ b/crates/hir-ty/src/next_solver/consts.rs
@@ -10,16 +10,19 @@ use rustc_type_ir::{
BoundVar, BoundVarIndexKind, ConstVid, DebruijnIndex, FlagComputation, Flags,
GenericTypeVisitable, InferConst, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable,
TypeVisitable, TypeVisitableExt, WithCachedTypeInfo,
- inherent::{IntoKind, ParamEnv as _, PlaceholderLike, SliceLike},
+ inherent::{IntoKind, ParamEnv as _, SliceLike},
relate::Relate,
};
use crate::{
MemoryMap,
- next_solver::{ClauseKind, ParamEnv, impl_stored_interned},
+ next_solver::{
+ ClauseKind, ParamEnv, impl_foldable_for_interned_slice, impl_stored_interned,
+ interned_slice,
+ },
};
-use super::{BoundVarKind, DbInterner, ErrorGuaranteed, GenericArgs, Placeholder, Ty};
+use super::{DbInterner, ErrorGuaranteed, GenericArgs, Ty};
pub type ConstKind<'db> = rustc_type_ir::ConstKind<DbInterner<'db>>;
pub type UnevaluatedConst<'db> = rustc_type_ir::UnevaluatedConst<DbInterner<'db>>;
@@ -71,11 +74,15 @@ impl<'db> Const<'db> {
Const::new(interner, ConstKind::Param(param))
}
- pub fn new_placeholder(interner: DbInterner<'db>, placeholder: PlaceholderConst) -> Self {
+ pub fn new_placeholder(interner: DbInterner<'db>, placeholder: PlaceholderConst<'db>) -> Self {
Const::new(interner, ConstKind::Placeholder(placeholder))
}
- pub fn new_bound(interner: DbInterner<'db>, index: DebruijnIndex, bound: BoundConst) -> Self {
+ pub fn new_bound(
+ interner: DbInterner<'db>,
+ index: DebruijnIndex,
+ bound: BoundConst<'db>,
+ ) -> Self {
Const::new(interner, ConstKind::Bound(BoundVarIndexKind::Bound(index), bound))
}
@@ -120,7 +127,7 @@ impl<'db> std::fmt::Debug for Const<'db> {
}
}
-pub type PlaceholderConst = Placeholder<BoundConst>;
+pub type PlaceholderConst<'db> = rustc_type_ir::PlaceholderConst<DbInterner<'db>>;
#[derive(Copy, Clone, Hash, Eq, PartialEq)]
pub struct ParamConst {
@@ -169,6 +176,8 @@ impl ParamConst {
}
}
+pub type ValTreeKind<'db> = rustc_type_ir::ValTreeKind<DbInterner<'db>>;
+
/// A type-level constant value.
///
/// Represents a typed, fully evaluated constant.
@@ -235,6 +244,14 @@ const _: () = {
is_copy::<Valtree<'static>>();
};
+impl<'db> IntoKind for Valtree<'db> {
+ type Kind = ValTreeKind<'db>;
+
+ fn kind(self) -> Self::Kind {
+ todo!()
+ }
+}
+
impl<'db> Valtree<'db> {
#[inline]
pub fn new(bytes: ConstBytes<'db>) -> Self {
@@ -388,25 +405,22 @@ impl<'db> rustc_type_ir::inherent::Const<DbInterner<'db>> for Const<'db> {
Const::new(interner, ConstKind::Infer(InferConst::Var(var)))
}
- fn new_bound(interner: DbInterner<'db>, debruijn: DebruijnIndex, var: BoundConst) -> Self {
+ fn new_bound(interner: DbInterner<'db>, debruijn: DebruijnIndex, var: BoundConst<'db>) -> Self {
Const::new(interner, ConstKind::Bound(BoundVarIndexKind::Bound(debruijn), var))
}
fn new_anon_bound(interner: DbInterner<'db>, debruijn: DebruijnIndex, var: BoundVar) -> Self {
Const::new(
interner,
- ConstKind::Bound(BoundVarIndexKind::Bound(debruijn), BoundConst { var }),
+ ConstKind::Bound(BoundVarIndexKind::Bound(debruijn), BoundConst::new(var)),
)
}
fn new_canonical_bound(interner: DbInterner<'db>, var: BoundVar) -> Self {
- Const::new(interner, ConstKind::Bound(BoundVarIndexKind::Canonical, BoundConst { var }))
+ Const::new(interner, ConstKind::Bound(BoundVarIndexKind::Canonical, BoundConst::new(var)))
}
- fn new_placeholder(
- interner: DbInterner<'db>,
- param: <DbInterner<'db> as rustc_type_ir::Interner>::PlaceholderConst,
- ) -> Self {
+ fn new_placeholder(interner: DbInterner<'db>, param: PlaceholderConst<'db>) -> Self {
Const::new(interner, ConstKind::Placeholder(param))
}
@@ -426,43 +440,7 @@ impl<'db> rustc_type_ir::inherent::Const<DbInterner<'db>> for Const<'db> {
}
}
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub struct BoundConst {
- pub var: BoundVar,
-}
-
-impl<'db> rustc_type_ir::inherent::BoundVarLike<DbInterner<'db>> for BoundConst {
- fn var(self) -> BoundVar {
- self.var
- }
-
- fn assert_eq(self, var: BoundVarKind) {
- var.expect_const()
- }
-}
-
-impl<'db> PlaceholderLike<DbInterner<'db>> for PlaceholderConst {
- type Bound = BoundConst;
-
- fn universe(self) -> rustc_type_ir::UniverseIndex {
- self.universe
- }
-
- fn var(self) -> rustc_type_ir::BoundVar {
- self.bound.var
- }
-
- fn with_updated_universe(self, ui: rustc_type_ir::UniverseIndex) -> Self {
- Placeholder { universe: ui, bound: self.bound }
- }
-
- fn new(ui: rustc_type_ir::UniverseIndex, var: BoundConst) -> Self {
- Placeholder { universe: ui, bound: var }
- }
- fn new_anon(ui: rustc_type_ir::UniverseIndex, var: rustc_type_ir::BoundVar) -> Self {
- Placeholder { universe: ui, bound: BoundConst { var } }
- }
-}
+pub type BoundConst<'db> = rustc_type_ir::BoundConst<DbInterner<'db>>;
impl<'db> Relate<DbInterner<'db>> for ExprConst {
fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>(
@@ -483,3 +461,6 @@ impl<'db> rustc_type_ir::inherent::ExprConst<DbInterner<'db>> for ExprConst {
GenericArgs::default()
}
}
+
+interned_slice!(ConstsStorage, Consts, StoredConsts, consts, Const<'db>, Const<'static>);
+impl_foldable_for_interned_slice!(Consts);
diff --git a/crates/hir-ty/src/next_solver/fold.rs b/crates/hir-ty/src/next_solver/fold.rs
index 7836419e8b..af823aa005 100644
--- a/crates/hir-ty/src/next_solver/fold.rs
+++ b/crates/hir-ty/src/next_solver/fold.rs
@@ -17,28 +17,28 @@ use super::{
/// gets mapped to the same result. `BoundVarReplacer` caches by using
/// a `DelayedMap` which does not cache the first few types it encounters.
pub trait BoundVarReplacerDelegate<'db> {
- fn replace_region(&mut self, br: BoundRegion) -> Region<'db>;
- fn replace_ty(&mut self, bt: BoundTy) -> Ty<'db>;
- fn replace_const(&mut self, bv: BoundConst) -> Const<'db>;
+ fn replace_region(&mut self, br: BoundRegion<'db>) -> Region<'db>;
+ fn replace_ty(&mut self, bt: BoundTy<'db>) -> Ty<'db>;
+ fn replace_const(&mut self, bv: BoundConst<'db>) -> Const<'db>;
}
/// A simple delegate taking 3 mutable functions. The used functions must
/// always return the same result for each bound variable, no matter how
/// frequently they are called.
pub struct FnMutDelegate<'db, 'a> {
- pub regions: &'a mut (dyn FnMut(BoundRegion) -> Region<'db> + 'a),
- pub types: &'a mut (dyn FnMut(BoundTy) -> Ty<'db> + 'a),
- pub consts: &'a mut (dyn FnMut(BoundConst) -> Const<'db> + 'a),
+ pub regions: &'a mut (dyn FnMut(BoundRegion<'db>) -> Region<'db> + 'a),
+ pub types: &'a mut (dyn FnMut(BoundTy<'db>) -> Ty<'db> + 'a),
+ pub consts: &'a mut (dyn FnMut(BoundConst<'db>) -> Const<'db> + 'a),
}
impl<'db, 'a> BoundVarReplacerDelegate<'db> for FnMutDelegate<'db, 'a> {
- fn replace_region(&mut self, br: BoundRegion) -> Region<'db> {
+ fn replace_region(&mut self, br: BoundRegion<'db>) -> Region<'db> {
(self.regions)(br)
}
- fn replace_ty(&mut self, bt: BoundTy) -> Ty<'db> {
+ fn replace_ty(&mut self, bt: BoundTy<'db>) -> Ty<'db> {
(self.types)(bt)
}
- fn replace_const(&mut self, bv: BoundConst) -> Const<'db> {
+ fn replace_const(&mut self, bv: BoundConst<'db>) -> Const<'db> {
(self.consts)(bv)
}
}
@@ -177,13 +177,13 @@ impl<'db> DbInterner<'db> {
self,
value: Binder<'db, T>,
mut fld_r: F,
- ) -> (T, FxIndexMap<BoundRegion, Region<'db>>)
+ ) -> (T, FxIndexMap<BoundRegion<'db>, Region<'db>>)
where
- F: FnMut(BoundRegion) -> Region<'db>,
+ F: FnMut(BoundRegion<'db>) -> Region<'db>,
T: TypeFoldable<DbInterner<'db>>,
{
let mut region_map = FxIndexMap::default();
- let real_fld_r = |br: BoundRegion| *region_map.entry(br).or_insert_with(|| fld_r(br));
+ let real_fld_r = |br: BoundRegion<'db>| *region_map.entry(br).or_insert_with(|| fld_r(br));
let value = self.instantiate_bound_regions_uncached(value, real_fld_r);
(value, region_map)
}
@@ -194,7 +194,7 @@ impl<'db> DbInterner<'db> {
mut replace_regions: F,
) -> T
where
- F: FnMut(BoundRegion) -> Region<'db>,
+ F: FnMut(BoundRegion<'db>) -> Region<'db>,
T: TypeFoldable<DbInterner<'db>>,
{
let value = value.skip_binder();
diff --git a/crates/hir-ty/src/next_solver/fulfill.rs b/crates/hir-ty/src/next_solver/fulfill.rs
index a8bff44a02..6739795a00 100644
--- a/crates/hir-ty/src/next_solver/fulfill.rs
+++ b/crates/hir-ty/src/next_solver/fulfill.rs
@@ -1,7 +1,5 @@
//! Fulfill loop for next-solver.
-mod errors;
-
use std::ops::ControlFlow;
use rustc_hash::FxHashSet;
diff --git a/crates/hir-ty/src/next_solver/fulfill/errors.rs b/crates/hir-ty/src/next_solver/fulfill/errors.rs
deleted file mode 100644
index 0e8218b33a..0000000000
--- a/crates/hir-ty/src/next_solver/fulfill/errors.rs
+++ /dev/null
@@ -1,1173 +0,0 @@
-//! Trait solving error diagnosis and reporting.
-//!
-//! This code isn't used by rust-analyzer (it should, but then it'll probably be better to re-port it from rustc).
-//! It's only there because without it, debugging trait solver errors is a nightmare.
-
-use std::{fmt::Debug, ops::ControlFlow};
-
-use rustc_next_trait_solver::solve::{GoalEvaluation, SolverDelegateEvalExt};
-use rustc_type_ir::{
- AliasRelationDirection, AliasTermKind, HostEffectPredicate, Interner, PredicatePolarity,
- error::ExpectedFound,
- inherent::{IntoKind, Span as _},
- lang_items::SolverTraitLangItem,
- solve::{Certainty, GoalSource, MaybeCause, NoSolution},
-};
-use tracing::{instrument, trace};
-
-use crate::next_solver::{
- AliasTerm, Binder, ClauseKind, Const, ConstKind, DbInterner, PolyTraitPredicate, PredicateKind,
- SolverContext, Span, Term, TraitPredicate, Ty, TyKind, TypeError,
- fulfill::NextSolverError,
- infer::{
- InferCtxt,
- select::SelectionError,
- traits::{Obligation, ObligationCause, PredicateObligation, PredicateObligations},
- },
- inspect::{self, ProofTreeVisitor},
- normalize::deeply_normalize_for_diagnostics,
-};
-
-#[derive(Debug)]
-pub struct FulfillmentError<'db> {
- pub obligation: PredicateObligation<'db>,
- pub code: FulfillmentErrorCode<'db>,
- /// Diagnostics only: the 'root' obligation which resulted in
- /// the failure to process `obligation`. This is the obligation
- /// that was initially passed to `register_predicate_obligation`
- pub root_obligation: PredicateObligation<'db>,
-}
-
-impl<'db> FulfillmentError<'db> {
- pub fn new(
- obligation: PredicateObligation<'db>,
- code: FulfillmentErrorCode<'db>,
- root_obligation: PredicateObligation<'db>,
- ) -> FulfillmentError<'db> {
- FulfillmentError { obligation, code, root_obligation }
- }
-
- pub fn is_true_error(&self) -> bool {
- match self.code {
- FulfillmentErrorCode::Select(_)
- | FulfillmentErrorCode::Project(_)
- | FulfillmentErrorCode::Subtype(_, _)
- | FulfillmentErrorCode::ConstEquate(_, _) => true,
- FulfillmentErrorCode::Cycle(_) | FulfillmentErrorCode::Ambiguity { overflow: _ } => {
- false
- }
- }
- }
-}
-
-#[derive(Debug, Clone)]
-pub enum FulfillmentErrorCode<'db> {
- /// Inherently impossible to fulfill; this trait is implemented if and only
- /// if it is already implemented.
- Cycle(PredicateObligations<'db>),
- Select(SelectionError<'db>),
- Project(MismatchedProjectionTypes<'db>),
- Subtype(ExpectedFound<Ty<'db>>, TypeError<'db>), // always comes from a SubtypePredicate
- ConstEquate(ExpectedFound<Const<'db>>, TypeError<'db>),
- Ambiguity {
- /// Overflow is only `Some(suggest_recursion_limit)` when using the next generation
- /// trait solver `-Znext-solver`. With the old solver overflow is eagerly handled by
- /// emitting a fatal error instead.
- overflow: Option<bool>,
- },
-}
-
-#[derive(Debug, Clone)]
-pub struct MismatchedProjectionTypes<'db> {
- pub err: TypeError<'db>,
-}
-
-pub(super) fn fulfillment_error_for_no_solution<'db>(
- infcx: &InferCtxt<'db>,
- root_obligation: PredicateObligation<'db>,
-) -> FulfillmentError<'db> {
- let obligation = find_best_leaf_obligation(infcx, &root_obligation, false);
-
- let code = match obligation.predicate.kind().skip_binder() {
- PredicateKind::Clause(ClauseKind::Projection(_)) => {
- FulfillmentErrorCode::Project(
- // FIXME: This could be a `Sorts` if the term is a type
- MismatchedProjectionTypes { err: TypeError::Mismatch },
- )
- }
- PredicateKind::Clause(ClauseKind::ConstArgHasType(ct, expected_ty)) => {
- let ct_ty = match ct.kind() {
- ConstKind::Unevaluated(uv) => {
- infcx.interner.type_of(uv.def.into()).instantiate(infcx.interner, uv.args)
- }
- ConstKind::Param(param_ct) => param_ct.find_const_ty_from_env(obligation.param_env),
- ConstKind::Value(cv) => cv.ty,
- kind => panic!(
- "ConstArgHasWrongType failed but we don't know how to compute type for {kind:?}"
- ),
- };
- FulfillmentErrorCode::Select(SelectionError::ConstArgHasWrongType {
- ct,
- ct_ty,
- expected_ty,
- })
- }
- PredicateKind::NormalizesTo(..) => {
- FulfillmentErrorCode::Project(MismatchedProjectionTypes { err: TypeError::Mismatch })
- }
- PredicateKind::AliasRelate(_, _, _) => {
- FulfillmentErrorCode::Project(MismatchedProjectionTypes { err: TypeError::Mismatch })
- }
- PredicateKind::Subtype(pred) => {
- let (a, b) = infcx.enter_forall_and_leak_universe(
- obligation.predicate.kind().rebind((pred.a, pred.b)),
- );
- let expected_found = ExpectedFound::new(a, b);
- FulfillmentErrorCode::Subtype(expected_found, TypeError::Sorts(expected_found))
- }
- PredicateKind::Coerce(pred) => {
- let (a, b) = infcx.enter_forall_and_leak_universe(
- obligation.predicate.kind().rebind((pred.a, pred.b)),
- );
- let expected_found = ExpectedFound::new(b, a);
- FulfillmentErrorCode::Subtype(expected_found, TypeError::Sorts(expected_found))
- }
- PredicateKind::Clause(_) | PredicateKind::DynCompatible(_) | PredicateKind::Ambiguous => {
- FulfillmentErrorCode::Select(SelectionError::Unimplemented)
- }
- PredicateKind::ConstEquate(..) => {
- panic!("unexpected goal: {obligation:?}")
- }
- };
-
- FulfillmentError { obligation, code, root_obligation }
-}
-
-pub(super) fn fulfillment_error_for_stalled<'db>(
- infcx: &InferCtxt<'db>,
- root_obligation: PredicateObligation<'db>,
-) -> FulfillmentError<'db> {
- let (code, refine_obligation) = infcx.probe(|_| {
- match <&SolverContext<'db>>::from(infcx).evaluate_root_goal(
- root_obligation.as_goal(),
- Span::dummy(),
- None,
- ) {
- Ok(GoalEvaluation {
- certainty: Certainty::Maybe { cause: MaybeCause::Ambiguity, .. },
- ..
- }) => (FulfillmentErrorCode::Ambiguity { overflow: None }, true),
- Ok(GoalEvaluation {
- certainty:
- Certainty::Maybe {
- cause:
- MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
- ..
- },
- ..
- }) => (
- FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) },
- // Don't look into overflows because we treat overflows weirdly anyways.
- // We discard the inference constraints from overflowing goals, so
- // recomputing the goal again during `find_best_leaf_obligation` may apply
- // inference guidance that makes other goals go from ambig -> pass, for example.
- //
- // FIXME: We should probably just look into overflows here.
- false,
- ),
- Ok(GoalEvaluation { certainty: Certainty::Yes, .. }) => {
- panic!(
- "did not expect successful goal when collecting ambiguity errors for `{:?}`",
- infcx.resolve_vars_if_possible(root_obligation.predicate),
- )
- }
- Err(_) => {
- panic!(
- "did not expect selection error when collecting ambiguity errors for `{:?}`",
- infcx.resolve_vars_if_possible(root_obligation.predicate),
- )
- }
- }
- });
-
- FulfillmentError {
- obligation: if refine_obligation {
- find_best_leaf_obligation(infcx, &root_obligation, true)
- } else {
- root_obligation.clone()
- },
- code,
- root_obligation,
- }
-}
-
-pub(super) fn fulfillment_error_for_overflow<'db>(
- infcx: &InferCtxt<'db>,
- root_obligation: PredicateObligation<'db>,
-) -> FulfillmentError<'db> {
- FulfillmentError {
- obligation: find_best_leaf_obligation(infcx, &root_obligation, true),
- code: FulfillmentErrorCode::Ambiguity { overflow: Some(true) },
- root_obligation,
- }
-}
-
-#[instrument(level = "debug", skip(infcx), ret)]
-fn find_best_leaf_obligation<'db>(
- infcx: &InferCtxt<'db>,
- obligation: &PredicateObligation<'db>,
- consider_ambiguities: bool,
-) -> PredicateObligation<'db> {
- let obligation = infcx.resolve_vars_if_possible(obligation.clone());
- // FIXME: we use a probe here as the `BestObligation` visitor does not
- // check whether it uses candidates which get shadowed by where-bounds.
- //
- // We should probably fix the visitor to not do so instead, as this also
- // means the leaf obligation may be incorrect.
- let obligation = infcx
- .fudge_inference_if_ok(|| {
- infcx
- .visit_proof_tree(
- obligation.as_goal(),
- &mut BestObligation { obligation: obligation.clone(), consider_ambiguities },
- )
- .break_value()
- .ok_or(())
- })
- .unwrap_or(obligation);
- deeply_normalize_for_diagnostics(infcx, obligation.param_env, obligation)
-}
-
-struct BestObligation<'db> {
- obligation: PredicateObligation<'db>,
- consider_ambiguities: bool,
-}
-
-impl<'db> BestObligation<'db> {
- fn with_derived_obligation(
- &mut self,
- derived_obligation: PredicateObligation<'db>,
- and_then: impl FnOnce(&mut Self) -> <Self as ProofTreeVisitor<'db>>::Result,
- ) -> <Self as ProofTreeVisitor<'db>>::Result {
- let old_obligation = std::mem::replace(&mut self.obligation, derived_obligation);
- let res = and_then(self);
- self.obligation = old_obligation;
- res
- }
-
- /// Filter out the candidates that aren't interesting to visit for the
- /// purposes of reporting errors. For ambiguities, we only consider
- /// candidates that may hold. For errors, we only consider candidates that
- /// *don't* hold and which have impl-where clauses that also don't hold.
- fn non_trivial_candidates<'a>(
- &self,
- goal: &'a inspect::InspectGoal<'a, 'db>,
- ) -> Vec<inspect::InspectCandidate<'a, 'db>> {
- let mut candidates = goal.candidates();
- match self.consider_ambiguities {
- true => {
- // If we have an ambiguous obligation, we must consider *all* candidates
- // that hold, or else we may guide inference causing other goals to go
- // from ambig -> pass/fail.
- candidates.retain(|candidate| candidate.result().is_ok());
- }
- false => {
- // We always handle rigid alias candidates separately as we may not add them for
- // aliases whose trait bound doesn't hold.
- candidates.retain(|c| !matches!(c.kind(), inspect::ProbeKind::RigidAlias { .. }));
- // If we have >1 candidate, one may still be due to "boring" reasons, like
- // an alias-relate that failed to hold when deeply evaluated. We really
- // don't care about reasons like this.
- if candidates.len() > 1 {
- candidates.retain(|candidate| {
- goal.infcx().probe(|_| {
- candidate.instantiate_nested_goals().iter().any(|nested_goal| {
- matches!(
- nested_goal.source(),
- GoalSource::ImplWhereBound
- | GoalSource::AliasBoundConstCondition
- | GoalSource::AliasWellFormed
- ) && nested_goal.result().is_err()
- })
- })
- });
- }
- }
- }
-
- candidates
- }
-
- /// HACK: We walk the nested obligations for a well-formed arg manually,
- /// since there's nontrivial logic in `wf.rs` to set up an obligation cause.
- /// Ideally we'd be able to track this better.
- fn visit_well_formed_goal(
- &mut self,
- candidate: &inspect::InspectCandidate<'_, 'db>,
- term: Term<'db>,
- ) -> ControlFlow<PredicateObligation<'db>> {
- let infcx = candidate.goal().infcx();
- let param_env = candidate.goal().goal().param_env;
-
- for obligation in wf::unnormalized_obligations(infcx, param_env, term).into_iter().flatten()
- {
- let nested_goal = candidate
- .instantiate_proof_tree_for_nested_goal(GoalSource::Misc, obligation.as_goal());
- // Skip nested goals that aren't the *reason* for our goal's failure.
- match (self.consider_ambiguities, nested_goal.result()) {
- (true, Ok(Certainty::Maybe { cause: MaybeCause::Ambiguity, .. }))
- | (false, Err(_)) => {}
- _ => continue,
- }
-
- self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?;
- }
-
- ControlFlow::Break(self.obligation.clone())
- }
-
- /// If a normalization of an associated item or a trait goal fails without trying any
- /// candidates it's likely that normalizing its self type failed. We manually detect
- /// such cases here.
- fn detect_error_in_self_ty_normalization(
- &mut self,
- goal: &inspect::InspectGoal<'_, 'db>,
- self_ty: Ty<'db>,
- ) -> ControlFlow<PredicateObligation<'db>> {
- assert!(!self.consider_ambiguities);
- let interner = goal.infcx().interner;
- if let TyKind::Alias(..) = self_ty.kind() {
- let infer_term = goal.infcx().next_ty_var();
- let pred = PredicateKind::AliasRelate(
- self_ty.into(),
- infer_term.into(),
- AliasRelationDirection::Equate,
- );
- let obligation = Obligation::new(
- interner,
- self.obligation.cause.clone(),
- goal.goal().param_env,
- pred,
- );
- self.with_derived_obligation(obligation, |this| {
- goal.infcx().visit_proof_tree_at_depth(
- goal.goal().with(interner, pred),
- goal.depth() + 1,
- this,
- )
- })
- } else {
- ControlFlow::Continue(())
- }
- }
-
- /// When a higher-ranked projection goal fails, check that the corresponding
- /// higher-ranked trait goal holds or not. This is because the process of
- /// instantiating and then re-canonicalizing the binder of the projection goal
- /// forces us to be unable to see that the leak check failed in the nested
- /// `NormalizesTo` goal, so we don't fall back to the rigid projection check
- /// that should catch when a projection goal fails due to an unsatisfied trait
- /// goal.
- fn detect_trait_error_in_higher_ranked_projection(
- &mut self,
- goal: &inspect::InspectGoal<'_, 'db>,
- ) -> ControlFlow<PredicateObligation<'db>> {
- let interner = goal.infcx().interner;
- if let Some(projection_clause) = goal.goal().predicate.as_projection_clause()
- && !projection_clause.bound_vars().is_empty()
- {
- let pred = projection_clause.map_bound(|proj| proj.projection_term.trait_ref(interner));
- let obligation = Obligation::new(
- interner,
- self.obligation.cause.clone(),
- goal.goal().param_env,
- deeply_normalize_for_diagnostics(goal.infcx(), goal.goal().param_env, pred),
- );
- self.with_derived_obligation(obligation, |this| {
- goal.infcx().visit_proof_tree_at_depth(
- goal.goal().with(interner, pred),
- goal.depth() + 1,
- this,
- )
- })
- } else {
- ControlFlow::Continue(())
- }
- }
-
- /// It is likely that `NormalizesTo` failed without any applicable candidates
- /// because the alias is not well-formed.
- ///
- /// As we only enter `RigidAlias` candidates if the trait bound of the associated type
- /// holds, we discard these candidates in `non_trivial_candidates` and always manually
- /// check this here.
- fn detect_non_well_formed_assoc_item(
- &mut self,
- goal: &inspect::InspectGoal<'_, 'db>,
- alias: AliasTerm<'db>,
- ) -> ControlFlow<PredicateObligation<'db>> {
- let interner = goal.infcx().interner;
- let obligation = Obligation::new(
- interner,
- self.obligation.cause.clone(),
- goal.goal().param_env,
- alias.trait_ref(interner),
- );
- self.with_derived_obligation(obligation, |this| {
- goal.infcx().visit_proof_tree_at_depth(
- goal.goal().with(interner, alias.trait_ref(interner)),
- goal.depth() + 1,
- this,
- )
- })
- }
-
- /// If we have no candidates, then it's likely that there is a
- /// non-well-formed alias in the goal.
- fn detect_error_from_empty_candidates(
- &mut self,
- goal: &inspect::InspectGoal<'_, 'db>,
- ) -> ControlFlow<PredicateObligation<'db>> {
- let interner = goal.infcx().interner;
- let pred_kind = goal.goal().predicate.kind();
-
- match pred_kind.no_bound_vars() {
- Some(PredicateKind::Clause(ClauseKind::Trait(pred))) => {
- self.detect_error_in_self_ty_normalization(goal, pred.self_ty())?;
- }
- Some(PredicateKind::NormalizesTo(pred)) => {
- if let AliasTermKind::ProjectionTy | AliasTermKind::ProjectionConst =
- pred.alias.kind(interner)
- {
- self.detect_error_in_self_ty_normalization(goal, pred.alias.self_ty())?;
- self.detect_non_well_formed_assoc_item(goal, pred.alias)?;
- }
- }
- Some(_) | None => {}
- }
-
- ControlFlow::Break(self.obligation.clone())
- }
-}
-
-impl<'db> ProofTreeVisitor<'db> for BestObligation<'db> {
- type Result = ControlFlow<PredicateObligation<'db>>;
-
- #[instrument(level = "trace", skip(self, goal), fields(goal = ?goal.goal()))]
- fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'db>) -> Self::Result {
- let interner = goal.infcx().interner;
- // Skip goals that aren't the *reason* for our goal's failure.
- match (self.consider_ambiguities, goal.result()) {
- (true, Ok(Certainty::Maybe { cause: MaybeCause::Ambiguity, .. })) | (false, Err(_)) => {
- }
- _ => return ControlFlow::Continue(()),
- }
-
- let pred = goal.goal().predicate;
-
- let candidates = self.non_trivial_candidates(goal);
- let candidate = match candidates.as_slice() {
- [candidate] => candidate,
- [] => return self.detect_error_from_empty_candidates(goal),
- _ => return ControlFlow::Break(self.obligation.clone()),
- };
-
- // // Don't walk into impls that have `do_not_recommend`.
- // if let inspect::ProbeKind::TraitCandidate {
- // source: CandidateSource::Impl(impl_def_id),
- // result: _,
- // } = candidate.kind()
- // && interner.do_not_recommend_impl(impl_def_id)
- // {
- // trace!("#[do_not_recommend] -> exit");
- // return ControlFlow::Break(self.obligation.clone());
- // }
-
- // FIXME: Also, what about considering >1 layer up the stack? May be necessary
- // for normalizes-to.
- let child_mode = match pred.kind().skip_binder() {
- PredicateKind::Clause(ClauseKind::Trait(trait_pred)) => {
- ChildMode::Trait(pred.kind().rebind(trait_pred))
- }
- PredicateKind::Clause(ClauseKind::HostEffect(host_pred)) => {
- ChildMode::Host(pred.kind().rebind(host_pred))
- }
- PredicateKind::NormalizesTo(normalizes_to)
- if matches!(
- normalizes_to.alias.kind(interner),
- AliasTermKind::ProjectionTy | AliasTermKind::ProjectionConst
- ) =>
- {
- ChildMode::Trait(pred.kind().rebind(TraitPredicate {
- trait_ref: normalizes_to.alias.trait_ref(interner),
- polarity: PredicatePolarity::Positive,
- }))
- }
- PredicateKind::Clause(ClauseKind::WellFormed(term)) => {
- return self.visit_well_formed_goal(candidate, term);
- }
- _ => ChildMode::PassThrough,
- };
-
- let nested_goals = candidate.instantiate_nested_goals();
-
- // If the candidate requires some `T: FnPtr` bound which does not hold should not be treated as
- // an actual candidate, instead we should treat them as if the impl was never considered to
- // have potentially applied. As if `impl<A, R> Trait for for<..> fn(..A) -> R` was written
- // instead of `impl<T: FnPtr> Trait for T`.
- //
- // We do this as a separate loop so that we do not choose to tell the user about some nested
- // goal before we encounter a `T: FnPtr` nested goal.
- for nested_goal in &nested_goals {
- if let Some(poly_trait_pred) = nested_goal.goal().predicate.as_trait_clause()
- && interner
- .is_trait_lang_item(poly_trait_pred.def_id(), SolverTraitLangItem::FnPtrTrait)
- && let Err(NoSolution) = nested_goal.result()
- {
- return ControlFlow::Break(self.obligation.clone());
- }
- }
-
- for nested_goal in nested_goals {
- trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result()));
-
- let nested_pred = nested_goal.goal().predicate;
-
- let make_obligation = || Obligation {
- cause: ObligationCause::dummy(),
- param_env: nested_goal.goal().param_env,
- predicate: nested_pred,
- recursion_depth: self.obligation.recursion_depth + 1,
- };
-
- let obligation = match (child_mode, nested_goal.source()) {
- (
- ChildMode::Trait(_) | ChildMode::Host(_),
- GoalSource::Misc | GoalSource::TypeRelating | GoalSource::NormalizeGoal(_),
- ) => {
- continue;
- }
- (ChildMode::Trait(_parent_trait_pred), GoalSource::ImplWhereBound) => {
- make_obligation()
- }
- (
- ChildMode::Host(_parent_host_pred),
- GoalSource::ImplWhereBound | GoalSource::AliasBoundConstCondition,
- ) => make_obligation(),
- (ChildMode::PassThrough, _)
- | (_, GoalSource::AliasWellFormed | GoalSource::AliasBoundConstCondition) => {
- make_obligation()
- }
- };
-
- self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?;
- }
-
- // alias-relate may fail because the lhs or rhs can't be normalized,
- // and therefore is treated as rigid.
- if let Some(PredicateKind::AliasRelate(lhs, rhs, _)) = pred.kind().no_bound_vars() {
- goal.infcx().visit_proof_tree_at_depth(
- goal.goal().with(interner, ClauseKind::WellFormed(lhs)),
- goal.depth() + 1,
- self,
- )?;
- goal.infcx().visit_proof_tree_at_depth(
- goal.goal().with(interner, ClauseKind::WellFormed(rhs)),
- goal.depth() + 1,
- self,
- )?;
- }
-
- self.detect_trait_error_in_higher_ranked_projection(goal)?;
-
- ControlFlow::Break(self.obligation.clone())
- }
-}
-
-#[derive(Debug, Copy, Clone)]
-enum ChildMode<'db> {
- // Try to derive an `ObligationCause::{ImplDerived,BuiltinDerived}`,
- // and skip all `GoalSource::Misc`, which represent useless obligations
- // such as alias-eq which may not hold.
- Trait(PolyTraitPredicate<'db>),
- // Try to derive an `ObligationCause::{ImplDerived,BuiltinDerived}`,
- // and skip all `GoalSource::Misc`, which represent useless obligations
- // such as alias-eq which may not hold.
- Host(Binder<'db, HostEffectPredicate<DbInterner<'db>>>),
- // Skip trying to derive an `ObligationCause` from this obligation, and
- // report *all* sub-obligations as if they came directly from the parent
- // obligation.
- PassThrough,
-}
-
-impl<'db> NextSolverError<'db> {
- pub fn to_debuggable_error(&self, infcx: &InferCtxt<'db>) -> FulfillmentError<'db> {
- match self {
- NextSolverError::TrueError(obligation) => {
- fulfillment_error_for_no_solution(infcx, obligation.clone())
- }
- NextSolverError::Ambiguity(obligation) => {
- fulfillment_error_for_stalled(infcx, obligation.clone())
- }
- NextSolverError::Overflow(obligation) => {
- fulfillment_error_for_overflow(infcx, obligation.clone())
- }
- }
- }
-}
-
-mod wf {
- use hir_def::signatures::ImplSignature;
- use hir_def::{GeneralConstId, ItemContainerId};
- use rustc_type_ir::inherent::{
- AdtDef, BoundExistentialPredicates, GenericArgs as _, IntoKind, SliceLike, Term as _,
- Ty as _,
- };
- use rustc_type_ir::lang_items::SolverTraitLangItem;
- use rustc_type_ir::{
- Interner, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
- };
- use tracing::{debug, instrument};
-
- use crate::next_solver::infer::InferCtxt;
- use crate::next_solver::infer::traits::{Obligation, ObligationCause, PredicateObligations};
- use crate::next_solver::{
- Binder, ClauseKind, Const, ConstKind, Ctor, DbInterner, ExistentialPredicate, GenericArgs,
- ParamEnv, Predicate, PredicateKind, Region, SolverDefId, Term, TraitRef, Ty, TyKind,
- };
-
- /// Compute the predicates that are required for a type to be well-formed.
- ///
- /// This is only intended to be used in the new solver, since it does not
- /// take into account recursion depth or proper error-reporting spans.
- pub(crate) fn unnormalized_obligations<'db>(
- infcx: &InferCtxt<'db>,
- param_env: ParamEnv<'db>,
- term: Term<'db>,
- ) -> Option<PredicateObligations<'db>> {
- debug_assert_eq!(term, infcx.resolve_vars_if_possible(term));
-
- // However, if `arg` IS an unresolved inference variable, returns `None`,
- // because we are not able to make any progress at all. This is to prevent
- // cycles where we say "?0 is WF if ?0 is WF".
- if term.is_infer() {
- return None;
- }
-
- let mut wf =
- WfPredicates { infcx, param_env, out: PredicateObligations::new(), recursion_depth: 0 };
- wf.add_wf_preds_for_term(term);
- Some(wf.out)
- }
-
- struct WfPredicates<'a, 'db> {
- infcx: &'a InferCtxt<'db>,
- param_env: ParamEnv<'db>,
- out: PredicateObligations<'db>,
- recursion_depth: usize,
- }
-
- impl<'a, 'db> WfPredicates<'a, 'db> {
- fn interner(&self) -> DbInterner<'db> {
- self.infcx.interner
- }
-
- fn require_sized(&mut self, subty: Ty<'db>) {
- if !subty.has_escaping_bound_vars() {
- let cause = ObligationCause::new();
- let trait_ref = TraitRef::new(
- self.interner(),
- self.interner().require_trait_lang_item(SolverTraitLangItem::Sized),
- [subty],
- );
- self.out.push(Obligation::with_depth(
- self.interner(),
- cause,
- self.recursion_depth,
- self.param_env,
- Binder::dummy(trait_ref),
- ));
- }
- }
-
- /// Pushes all the predicates needed to validate that `term` is WF into `out`.
- #[instrument(level = "debug", skip(self))]
- fn add_wf_preds_for_term(&mut self, term: Term<'db>) {
- term.visit_with(self);
- debug!(?self.out);
- }
-
- #[instrument(level = "debug", skip(self))]
- fn nominal_obligations(
- &mut self,
- def_id: SolverDefId,
- args: GenericArgs<'db>,
- ) -> PredicateObligations<'db> {
- // PERF: `Sized`'s predicates include `MetaSized`, but both are compiler implemented marker
- // traits, so `MetaSized` will always be WF if `Sized` is WF and vice-versa. Determining
- // the nominal obligations of `Sized` would in-effect just elaborate `MetaSized` and make
- // the compiler do a bunch of work needlessly.
- if let SolverDefId::TraitId(def_id) = def_id
- && self.interner().is_trait_lang_item(def_id.into(), SolverTraitLangItem::Sized)
- {
- return Default::default();
- }
-
- self.interner()
- .predicates_of(def_id)
- .iter_instantiated(self.interner(), args)
- .map(|pred| {
- let cause = ObligationCause::new();
- Obligation::with_depth(
- self.interner(),
- cause,
- self.recursion_depth,
- self.param_env,
- pred,
- )
- })
- .filter(|pred| !pred.has_escaping_bound_vars())
- .collect()
- }
-
- fn add_wf_preds_for_dyn_ty(
- &mut self,
- _ty: Ty<'db>,
- data: &[Binder<'db, ExistentialPredicate<'db>>],
- region: Region<'db>,
- ) {
- // Imagine a type like this:
- //
- // trait Foo { }
- // trait Bar<'c> : 'c { }
- //
- // &'b (Foo+'c+Bar<'d>)
- // ^
- //
- // In this case, the following relationships must hold:
- //
- // 'b <= 'c
- // 'd <= 'c
- //
- // The first conditions is due to the normal region pointer
- // rules, which say that a reference cannot outlive its
- // referent.
- //
- // The final condition may be a bit surprising. In particular,
- // you may expect that it would have been `'c <= 'd`, since
- // usually lifetimes of outer things are conservative
- // approximations for inner things. However, it works somewhat
- // differently with trait objects: here the idea is that if the
- // user specifies a region bound (`'c`, in this case) it is the
- // "master bound" that *implies* that bounds from other traits are
- // all met. (Remember that *all bounds* in a type like
- // `Foo+Bar+Zed` must be met, not just one, hence if we write
- // `Foo<'x>+Bar<'y>`, we know that the type outlives *both* 'x and
- // 'y.)
- //
- // Note: in fact we only permit builtin traits, not `Bar<'d>`, I
- // am looking forward to the future here.
- if !data.has_escaping_bound_vars() && !region.has_escaping_bound_vars() {
- let implicit_bounds = object_region_bounds(self.interner(), data);
-
- let explicit_bound = region;
-
- self.out.reserve(implicit_bounds.len());
- for implicit_bound in implicit_bounds {
- let cause = ObligationCause::new();
- let outlives = Binder::dummy(rustc_type_ir::OutlivesPredicate(
- explicit_bound,
- implicit_bound,
- ));
- self.out.push(Obligation::with_depth(
- self.interner(),
- cause,
- self.recursion_depth,
- self.param_env,
- outlives,
- ));
- }
-
- // We don't add any wf predicates corresponding to the trait ref's generic arguments
- // which allows code like this to compile:
- // ```rust
- // trait Trait<T: Sized> {}
- // fn foo(_: &dyn Trait<[u32]>) {}
- // ```
- }
- }
- }
-
- impl<'a, 'db> TypeVisitor<DbInterner<'db>> for WfPredicates<'a, 'db> {
- type Result = ();
-
- fn visit_ty(&mut self, t: Ty<'db>) -> Self::Result {
- debug!("wf bounds for t={:?} t.kind={:#?}", t, t.kind());
-
- let tcx = self.interner();
-
- match t.kind() {
- TyKind::Bool
- | TyKind::Char
- | TyKind::Int(..)
- | TyKind::Uint(..)
- | TyKind::Float(..)
- | TyKind::Error(_)
- | TyKind::Str
- | TyKind::CoroutineWitness(..)
- | TyKind::Never
- | TyKind::Param(_)
- | TyKind::Bound(..)
- | TyKind::Placeholder(..)
- | TyKind::Foreign(..) => {
- // WfScalar, WfParameter, etc
- }
-
- // Can only infer to `TyKind::Int(_) | TyKind::Uint(_)`.
- TyKind::Infer(rustc_type_ir::IntVar(_)) => {}
-
- // Can only infer to `TyKind::Float(_)`.
- TyKind::Infer(rustc_type_ir::FloatVar(_)) => {}
-
- TyKind::Slice(subty) => {
- self.require_sized(subty);
- }
-
- TyKind::Array(subty, len) => {
- self.require_sized(subty);
- // Note that the len being WF is implicitly checked while visiting.
- // Here we just check that it's of type usize.
- let cause = ObligationCause::new();
- self.out.push(Obligation::with_depth(
- tcx,
- cause,
- self.recursion_depth,
- self.param_env,
- Binder::dummy(PredicateKind::Clause(ClauseKind::ConstArgHasType(
- len,
- Ty::new_unit(self.interner()),
- ))),
- ));
- }
-
- TyKind::Pat(base_ty, _pat) => {
- self.require_sized(base_ty);
- }
-
- TyKind::Tuple(tys) => {
- if let Some((_last, rest)) = tys.split_last() {
- for &elem in rest {
- self.require_sized(elem);
- }
- }
- }
-
- TyKind::RawPtr(_, _) => {
- // Simple cases that are WF if their type args are WF.
- }
-
- TyKind::Alias(
- rustc_type_ir::Projection | rustc_type_ir::Opaque | rustc_type_ir::Free,
- data,
- ) => {
- let obligations = self.nominal_obligations(data.def_id, data.args);
- self.out.extend(obligations);
- }
- TyKind::Alias(rustc_type_ir::Inherent, _data) => {
- return;
- }
-
- TyKind::Adt(def, args) => {
- // WfNominalType
- let obligations = self.nominal_obligations(def.def_id().0.into(), args);
- self.out.extend(obligations);
- }
-
- TyKind::FnDef(did, args) => {
- // HACK: Check the return type of function definitions for
- // well-formedness to mostly fix #84533. This is still not
- // perfect and there may be ways to abuse the fact that we
- // ignore requirements with escaping bound vars. That's a
- // more general issue however.
- let fn_sig = tcx.fn_sig(did).instantiate(tcx, args);
- fn_sig.output().skip_binder().visit_with(self);
-
- let did = match did.0 {
- hir_def::CallableDefId::FunctionId(id) => id.into(),
- hir_def::CallableDefId::StructId(id) => SolverDefId::Ctor(Ctor::Struct(id)),
- hir_def::CallableDefId::EnumVariantId(id) => {
- SolverDefId::Ctor(Ctor::Enum(id))
- }
- };
- let obligations = self.nominal_obligations(did, args);
- self.out.extend(obligations);
- }
-
- TyKind::Ref(r, rty, _) => {
- // WfReference
- if !r.has_escaping_bound_vars() && !rty.has_escaping_bound_vars() {
- let cause = ObligationCause::new();
- self.out.push(Obligation::with_depth(
- tcx,
- cause,
- self.recursion_depth,
- self.param_env,
- Binder::dummy(PredicateKind::Clause(ClauseKind::TypeOutlives(
- rustc_type_ir::OutlivesPredicate(rty, r),
- ))),
- ));
- }
- }
-
- TyKind::Coroutine(did, args, ..) => {
- // Walk ALL the types in the coroutine: this will
- // include the upvar types as well as the yield
- // type. Note that this is mildly distinct from
- // the closure case, where we have to be careful
- // about the signature of the closure. We don't
- // have the problem of implied bounds here since
- // coroutines don't take arguments.
- let obligations = self.nominal_obligations(did.0.into(), args);
- self.out.extend(obligations);
- }
-
- TyKind::Closure(did, args) => {
- // Note that we cannot skip the generic types
- // types. Normally, within the fn
- // body where they are created, the generics will
- // always be WF, and outside of that fn body we
- // are not directly inspecting closure types
- // anyway, except via auto trait matching (which
- // only inspects the upvar types).
- // But when a closure is part of a type-alias-impl-trait
- // then the function that created the defining site may
- // have had more bounds available than the type alias
- // specifies. This may cause us to have a closure in the
- // hidden type that is not actually well formed and
- // can cause compiler crashes when the user abuses unsafe
- // code to procure such a closure.
- // See tests/ui/type-alias-impl-trait/wf_check_closures.rs
- let obligations = self.nominal_obligations(did.0.into(), args);
- self.out.extend(obligations);
- // Only check the upvar types for WF, not the rest
- // of the types within. This is needed because we
- // capture the signature and it may not be WF
- // without the implied bounds. Consider a closure
- // like `|x: &'a T|` -- it may be that `T: 'a` is
- // not known to hold in the creator's context (and
- // indeed the closure may not be invoked by its
- // creator, but rather turned to someone who *can*
- // verify that).
- //
- // The special treatment of closures here really
- // ought not to be necessary either; the problem
- // is related to #25860 -- there is no way for us
- // to express a fn type complete with the implied
- // bounds that it is assuming. I think in reality
- // the WF rules around fn are a bit messed up, and
- // that is the rot problem: `fn(&'a T)` should
- // probably always be WF, because it should be
- // shorthand for something like `where(T: 'a) {
- // fn(&'a T) }`, as discussed in #25860.
- let upvars = args.as_closure().tupled_upvars_ty();
- return upvars.visit_with(self);
- }
-
- TyKind::CoroutineClosure(did, args) => {
- // See the above comments. The same apply to coroutine-closures.
- let obligations = self.nominal_obligations(did.0.into(), args);
- self.out.extend(obligations);
- let upvars = args.as_coroutine_closure().tupled_upvars_ty();
- return upvars.visit_with(self);
- }
-
- TyKind::FnPtr(..) => {
- // Let the visitor iterate into the argument/return
- // types appearing in the fn signature.
- }
- TyKind::UnsafeBinder(_ty) => {}
-
- TyKind::Dynamic(data, r) => {
- // WfObject
- //
- // Here, we defer WF checking due to higher-ranked
- // regions. This is perhaps not ideal.
- self.add_wf_preds_for_dyn_ty(t, data.as_slice(), r);
-
- // FIXME(#27579) RFC also considers adding trait
- // obligations that don't refer to Self and
- // checking those
- if let Some(principal) = data.principal_def_id() {
- self.out.push(Obligation::with_depth(
- tcx,
- ObligationCause::new(),
- self.recursion_depth,
- self.param_env,
- Binder::dummy(PredicateKind::DynCompatible(principal)),
- ));
- }
- }
-
- // Inference variables are the complicated case, since we don't
- // know what type they are. We do two things:
- //
- // 1. Check if they have been resolved, and if so proceed with
- // THAT type.
- // 2. If not, we've at least simplified things (e.g., we went
- // from `Vec?0>: WF` to `?0: WF`), so we can
- // register a pending obligation and keep
- // moving. (Goal is that an "inductive hypothesis"
- // is satisfied to ensure termination.)
- // See also the comment on `fn obligations`, describing cycle
- // prevention, which happens before this can be reached.
- TyKind::Infer(_) => {
- let cause = ObligationCause::new();
- self.out.push(Obligation::with_depth(
- tcx,
- cause,
- self.recursion_depth,
- self.param_env,
- Binder::dummy(PredicateKind::Clause(ClauseKind::WellFormed(t.into()))),
- ));
- }
- }
-
- t.super_visit_with(self)
- }
-
- fn visit_const(&mut self, c: Const<'db>) -> Self::Result {
- let tcx = self.interner();
-
- match c.kind() {
- ConstKind::Unevaluated(uv) => {
- if !c.has_escaping_bound_vars() {
- let predicate =
- Binder::dummy(PredicateKind::Clause(ClauseKind::ConstEvaluatable(c)));
- let cause = ObligationCause::new();
- self.out.push(Obligation::with_depth(
- tcx,
- cause,
- self.recursion_depth,
- self.param_env,
- predicate,
- ));
-
- if let GeneralConstId::ConstId(uv_def) = uv.def.0
- && let ItemContainerId::ImplId(impl_) =
- uv_def.loc(self.interner().db).container
- && ImplSignature::of(self.interner().db, impl_).target_trait.is_none()
- {
- return; // Subtree is handled by above function
- } else {
- let obligations = self.nominal_obligations(uv.def.into(), uv.args);
- self.out.extend(obligations);
- }
- }
- }
- ConstKind::Infer(_) => {
- let cause = ObligationCause::new();
-
- self.out.push(Obligation::with_depth(
- tcx,
- cause,
- self.recursion_depth,
- self.param_env,
- Binder::dummy(PredicateKind::Clause(ClauseKind::WellFormed(c.into()))),
- ));
- }
- ConstKind::Expr(_) => {
- // FIXME(generic_const_exprs): this doesn't verify that given `Expr(N + 1)` the
- // trait bound `typeof(N): Add<typeof(1)>` holds. This is currently unnecessary
- // as `ConstKind::Expr` is only produced via normalization of `ConstKind::Unevaluated`
- // which means that the `DefId` would have been typeck'd elsewhere. However in
- // the future we may allow directly lowering to `ConstKind::Expr` in which case
- // we would not be proving bounds we should.
-
- let predicate =
- Binder::dummy(PredicateKind::Clause(ClauseKind::ConstEvaluatable(c)));
- let cause = ObligationCause::new();
- self.out.push(Obligation::with_depth(
- tcx,
- cause,
- self.recursion_depth,
- self.param_env,
- predicate,
- ));
- }
-
- ConstKind::Error(_)
- | ConstKind::Param(_)
- | ConstKind::Bound(..)
- | ConstKind::Placeholder(..) => {
- // These variants are trivially WF, so nothing to do here.
- }
- ConstKind::Value(..) => {
- // FIXME: Enforce that values are structurally-matchable.
- }
- }
-
- c.super_visit_with(self)
- }
-
- fn visit_predicate(&mut self, _p: Predicate<'db>) -> Self::Result {
- panic!("predicate should not be checked for well-formedness");
- }
- }
-
- /// Given an object type like `SomeTrait + Send`, computes the lifetime
- /// bounds that must hold on the elided self type. These are derived
- /// from the declarations of `SomeTrait`, `Send`, and friends -- if
- /// they declare `trait SomeTrait : 'static`, for example, then
- /// `'static` would appear in the list.
- ///
- /// N.B., in some cases, particularly around higher-ranked bounds,
- /// this function returns a kind of conservative approximation.
- /// That is, all regions returned by this function are definitely
- /// required, but there may be other region bounds that are not
- /// returned, as well as requirements like `for<'a> T: 'a`.
- ///
- /// Requires that trait definitions have been processed so that we can
- /// elaborate predicates and walk supertraits.
- pub(crate) fn object_region_bounds<'db>(
- interner: DbInterner<'db>,
- existential_predicates: &[Binder<'db, ExistentialPredicate<'db>>],
- ) -> Vec<Region<'db>> {
- let erased_self_ty = Ty::new_unit(interner);
-
- let predicates = existential_predicates
- .iter()
- .map(|predicate| predicate.with_self_ty(interner, erased_self_ty));
-
- rustc_type_ir::elaborate::elaborate(interner, predicates)
- .filter_map(|pred| {
- debug!(?pred);
- match pred.kind().skip_binder() {
- ClauseKind::TypeOutlives(rustc_type_ir::OutlivesPredicate(ref t, ref r)) => {
- // Search for a bound of the form `erased_self_ty
- // : 'a`, but be wary of something like `for<'a>
- // erased_self_ty : 'a` (we interpret a
- // higher-ranked bound like that as 'static,
- // though at present the code in `fulfill.rs`
- // considers such bounds to be unsatisfiable, so
- // it's kind of a moot point since you could never
- // construct such an object, but this seems
- // correct even if that code changes).
- if t == &erased_self_ty && !r.has_escaping_bound_vars() {
- Some(*r)
- } else {
- None
- }
- }
- ClauseKind::Trait(_)
- | ClauseKind::HostEffect(..)
- | ClauseKind::RegionOutlives(_)
- | ClauseKind::Projection(_)
- | ClauseKind::ConstArgHasType(_, _)
- | ClauseKind::WellFormed(_)
- | ClauseKind::UnstableFeature(_)
- | ClauseKind::ConstEvaluatable(_) => None,
- }
- })
- .collect()
- }
-}
diff --git a/crates/hir-ty/src/next_solver/infer/canonical/canonicalizer.rs b/crates/hir-ty/src/next_solver/infer/canonical/canonicalizer.rs
index ccd9359010..33e4c175d0 100644
--- a/crates/hir-ty/src/next_solver/infer/canonical/canonicalizer.rs
+++ b/crates/hir-ty/src/next_solver/infer/canonical/canonicalizer.rs
@@ -16,11 +16,11 @@ use rustc_type_ir::{
use smallvec::SmallVec;
use tracing::debug;
-use crate::next_solver::infer::InferCtxt;
use crate::next_solver::{
- Binder, Canonical, CanonicalVarKind, CanonicalVars, Const, ConstKind, DbInterner, GenericArg,
- Placeholder, Region, Ty, TyKind,
+ Binder, Canonical, CanonicalVarKind, CanonicalVarKinds, Const, ConstKind, DbInterner,
+ GenericArg, PlaceholderConst, PlaceholderRegion, Region, Ty, TyKind,
};
+use crate::next_solver::{PlaceholderType, infer::InferCtxt};
/// When we canonicalize a value to form a query, we wind up replacing
/// various parts of it with canonical variables. This struct stores
@@ -498,7 +498,7 @@ impl<'cx, 'db> Canonicalizer<'cx, 'db> {
{
let base = Canonical {
max_universe: UniverseIndex::ROOT,
- variables: CanonicalVars::empty(tcx),
+ var_kinds: CanonicalVarKinds::empty(tcx),
value: (),
};
Canonicalizer::canonicalize_with_base(
@@ -539,7 +539,7 @@ impl<'cx, 'db> Canonicalizer<'cx, 'db> {
tcx,
canonicalize_mode: canonicalize_region_mode,
needs_canonical_flags,
- variables: SmallVec::from_slice(base.variables.as_slice()),
+ variables: SmallVec::from_slice(base.var_kinds.as_slice()),
query_state,
indices: FxHashMap::default(),
sub_root_lookup_table: Default::default(),
@@ -562,7 +562,7 @@ impl<'cx, 'db> Canonicalizer<'cx, 'db> {
debug_assert!(!out_value.has_infer() && !out_value.has_placeholders());
let canonical_variables =
- CanonicalVars::new_from_slice(&canonicalizer.universe_canonicalized_variables());
+ CanonicalVarKinds::new_from_slice(&canonicalizer.universe_canonicalized_variables());
let max_universe = canonical_variables
.iter()
@@ -570,7 +570,7 @@ impl<'cx, 'db> Canonicalizer<'cx, 'db> {
.max()
.unwrap_or(UniverseIndex::ROOT);
- Canonical { max_universe, variables: canonical_variables, value: (base.value, out_value) }
+ Canonical { max_universe, var_kinds: canonical_variables, value: (base.value, out_value) }
}
/// Creates a canonical variable replacing `kind` from the input,
@@ -670,22 +670,22 @@ impl<'cx, 'db> Canonicalizer<'cx, 'db> {
CanonicalVarKind::Region(u) => CanonicalVarKind::Region(reverse_universe_map[&u]),
CanonicalVarKind::Const(u) => CanonicalVarKind::Const(reverse_universe_map[&u]),
CanonicalVarKind::PlaceholderTy(placeholder) => {
- CanonicalVarKind::PlaceholderTy(Placeholder {
- universe: reverse_universe_map[&placeholder.universe],
- ..placeholder
- })
+ CanonicalVarKind::PlaceholderTy(PlaceholderType::new(
+ reverse_universe_map[&placeholder.universe],
+ placeholder.bound,
+ ))
}
CanonicalVarKind::PlaceholderRegion(placeholder) => {
- CanonicalVarKind::PlaceholderRegion(Placeholder {
- universe: reverse_universe_map[&placeholder.universe],
- ..placeholder
- })
+ CanonicalVarKind::PlaceholderRegion(PlaceholderRegion::new(
+ reverse_universe_map[&placeholder.universe],
+ placeholder.bound,
+ ))
}
CanonicalVarKind::PlaceholderConst(placeholder) => {
- CanonicalVarKind::PlaceholderConst(Placeholder {
- universe: reverse_universe_map[&placeholder.universe],
- ..placeholder
- })
+ CanonicalVarKind::PlaceholderConst(PlaceholderConst::new(
+ reverse_universe_map[&placeholder.universe],
+ placeholder.bound,
+ ))
}
})
.collect()
diff --git a/crates/hir-ty/src/next_solver/infer/canonical/instantiate.rs b/crates/hir-ty/src/next_solver/infer/canonical/instantiate.rs
index 61d1e97746..1738552a8e 100644
--- a/crates/hir-ty/src/next_solver/infer/canonical/instantiate.rs
+++ b/crates/hir-ty/src/next_solver/infer/canonical/instantiate.rs
@@ -69,7 +69,7 @@ impl<'db, V> CanonicalExt<'db, V> for Canonical<'db, V> {
where
T: TypeFoldable<DbInterner<'db>>,
{
- assert_eq!(self.variables.len(), var_values.len());
+ assert_eq!(self.var_kinds.len(), var_values.len());
let value = projection_fn(&self.value);
instantiate_value(tcx, var_values, value)
}
@@ -90,15 +90,15 @@ where
value
} else {
let delegate = FnMutDelegate {
- regions: &mut |br: BoundRegion| match var_values[br.var].kind() {
+ regions: &mut |br: BoundRegion<'db>| match var_values[br.var].kind() {
GenericArgKind::Lifetime(l) => l,
r => panic!("{br:?} is a region but value is {r:?}"),
},
- types: &mut |bound_ty: BoundTy| match var_values[bound_ty.var].kind() {
+ types: &mut |bound_ty: BoundTy<'db>| match var_values[bound_ty.var].kind() {
GenericArgKind::Type(ty) => ty,
r => panic!("{bound_ty:?} is a type but value is {r:?}"),
},
- consts: &mut |bound_ct: BoundConst| match var_values[bound_ct.var].kind() {
+ consts: &mut |bound_ct: BoundConst<'db>| match var_values[bound_ct.var].kind() {
GenericArgKind::Const(ct) => ct,
c => panic!("{bound_ct:?} is a const but value is {c:?}"),
},
@@ -356,7 +356,7 @@ impl<'db> InferCtxt<'db> {
// result, then we can type the corresponding value from the
// input. See the example above.
let mut opt_values: IndexVec<BoundVar, Option<GenericArg<'db>>> =
- IndexVec::from_elem_n(None, query_response.variables.len());
+ IndexVec::from_elem_n(None, query_response.var_kinds.len());
for (original_value, result_value) in iter::zip(&original_values.var_values, result_values)
{
@@ -368,7 +368,7 @@ impl<'db> InferCtxt<'db> {
// more involved. They are also a lot rarer than region variables.
if let TyKind::Bound(index_kind, b) = result_value.kind()
&& !matches!(
- query_response.variables.as_slice()[b.var.as_usize()],
+ query_response.var_kinds.as_slice()[b.var.as_usize()],
CanonicalVarKind::Ty { .. }
)
{
@@ -398,7 +398,7 @@ impl<'db> InferCtxt<'db> {
// given variable in the loop above, use that. Otherwise, use
// a fresh inference variable.
let interner = self.interner;
- let variables = query_response.variables;
+ let variables = query_response.var_kinds;
let var_values =
CanonicalVarValues::instantiate(interner, variables, |var_values, kind| {
if kind.universe() != UniverseIndex::ROOT {
diff --git a/crates/hir-ty/src/next_solver/infer/canonical/mod.rs b/crates/hir-ty/src/next_solver/infer/canonical/mod.rs
index a0420a5a00..1fefc0f265 100644
--- a/crates/hir-ty/src/next_solver/infer/canonical/mod.rs
+++ b/crates/hir-ty/src/next_solver/infer/canonical/mod.rs
@@ -23,7 +23,7 @@
use crate::next_solver::{
ArgOutlivesPredicate, Canonical, CanonicalVarValues, Const, DbInterner, GenericArg,
- OpaqueTypeKey, PlaceholderConst, PlaceholderRegion, PlaceholderTy, Region, Ty, TyKind,
+ OpaqueTypeKey, PlaceholderConst, PlaceholderRegion, PlaceholderType, Region, Ty, TyKind,
infer::InferCtxt,
};
use instantiate::CanonicalExt;
@@ -70,7 +70,7 @@ impl<'db> InferCtxt<'db> {
let var_values = CanonicalVarValues::instantiate(
self.interner,
- canonical.variables,
+ canonical.var_kinds,
|var_values, info| self.instantiate_canonical_var(info, var_values, |ui| universes[ui]),
);
let result = canonical.instantiate(self.interner, &var_values);
@@ -110,9 +110,9 @@ impl<'db> InferCtxt<'db> {
CanonicalVarKind::Float => self.next_float_var().into(),
- CanonicalVarKind::PlaceholderTy(PlaceholderTy { universe, bound }) => {
+ CanonicalVarKind::PlaceholderTy(PlaceholderType { universe, bound, .. }) => {
let universe_mapped = universe_map(universe);
- let placeholder_mapped = PlaceholderTy { universe: universe_mapped, bound };
+ let placeholder_mapped = PlaceholderType::new(universe_mapped, bound);
Ty::new_placeholder(self.interner, placeholder_mapped).into()
}
@@ -120,18 +120,16 @@ impl<'db> InferCtxt<'db> {
self.next_region_var_in_universe(universe_map(ui)).into()
}
- CanonicalVarKind::PlaceholderRegion(PlaceholderRegion { universe, bound }) => {
+ CanonicalVarKind::PlaceholderRegion(PlaceholderRegion { universe, bound, .. }) => {
let universe_mapped = universe_map(universe);
- let placeholder_mapped: crate::next_solver::Placeholder<
- crate::next_solver::BoundRegion,
- > = PlaceholderRegion { universe: universe_mapped, bound };
+ let placeholder_mapped = PlaceholderRegion::new(universe_mapped, bound);
Region::new_placeholder(self.interner, placeholder_mapped).into()
}
CanonicalVarKind::Const(ui) => self.next_const_var_in_universe(universe_map(ui)).into(),
- CanonicalVarKind::PlaceholderConst(PlaceholderConst { universe, bound }) => {
+ CanonicalVarKind::PlaceholderConst(PlaceholderConst { universe, bound, .. }) => {
let universe_mapped = universe_map(universe);
- let placeholder_mapped = PlaceholderConst { universe: universe_mapped, bound };
+ let placeholder_mapped = PlaceholderConst::new(universe_mapped, bound);
Const::new_placeholder(self.interner, placeholder_mapped).into()
}
}
diff --git a/crates/hir-ty/src/next_solver/infer/mod.rs b/crates/hir-ty/src/next_solver/infer/mod.rs
index 21baacb116..a6957c66ff 100644
--- a/crates/hir-ty/src/next_solver/infer/mod.rs
+++ b/crates/hir-ty/src/next_solver/infer/mod.rs
@@ -30,7 +30,7 @@ use unify_key::{ConstVariableOrigin, ConstVariableValue, ConstVidKey};
pub use crate::next_solver::infer::traits::ObligationInspector;
use crate::next_solver::{
- ArgOutlivesPredicate, BoundConst, BoundRegion, BoundTy, BoundVarKind, Goal, Predicate,
+ ArgOutlivesPredicate, BoundConst, BoundRegion, BoundTy, BoundVariableKind, Goal, Predicate,
SolverContext,
fold::BoundVarReplacerDelegate,
infer::{at::ToTrace, select::EvaluationResult, traits::PredicateObligation},
@@ -53,7 +53,7 @@ mod outlives;
pub mod region_constraints;
pub mod relate;
pub mod resolve;
-pub(crate) mod select;
+pub mod select;
pub(crate) mod snapshot;
pub(crate) mod traits;
mod type_variable;
@@ -366,7 +366,7 @@ impl<'db> InferCtxtBuilder<'db> {
where
T: TypeFoldable<DbInterner<'db>>,
{
- let infcx = self.build(input.typing_mode);
+ let infcx = self.build(input.typing_mode.0);
let (value, args) = infcx.instantiate_canonical(&input.canonical);
(infcx, value, args)
}
@@ -1098,9 +1098,9 @@ impl<'db> InferCtxt<'db> {
for bound_var_kind in bound_vars {
let arg: GenericArg<'db> = match bound_var_kind {
- BoundVarKind::Ty(_) => self.next_ty_var().into(),
- BoundVarKind::Region(_) => self.next_region_var().into(),
- BoundVarKind::Const => self.next_const_var().into(),
+ BoundVariableKind::Ty(_) => self.next_ty_var().into(),
+ BoundVariableKind::Region(_) => self.next_region_var().into(),
+ BoundVariableKind::Const => self.next_const_var().into(),
};
args.push(arg);
}
@@ -1110,13 +1110,13 @@ impl<'db> InferCtxt<'db> {
}
impl<'db> BoundVarReplacerDelegate<'db> for ToFreshVars<'db> {
- fn replace_region(&mut self, br: BoundRegion) -> Region<'db> {
+ fn replace_region(&mut self, br: BoundRegion<'db>) -> Region<'db> {
self.args[br.var.index()].expect_region()
}
- fn replace_ty(&mut self, bt: BoundTy) -> Ty<'db> {
+ fn replace_ty(&mut self, bt: BoundTy<'db>) -> Ty<'db> {
self.args[bt.var.index()].expect_ty()
}
- fn replace_const(&mut self, bv: BoundConst) -> Const<'db> {
+ fn replace_const(&mut self, bv: BoundConst<'db>) -> Const<'db> {
self.args[bv.var.index()].expect_const()
}
}
diff --git a/crates/hir-ty/src/next_solver/infer/region_constraints/mod.rs b/crates/hir-ty/src/next_solver/infer/region_constraints/mod.rs
index ae5930d55c..7bb39519f5 100644
--- a/crates/hir-ty/src/next_solver/infer/region_constraints/mod.rs
+++ b/crates/hir-ty/src/next_solver/infer/region_constraints/mod.rs
@@ -17,7 +17,7 @@ use super::MemberConstraint;
use super::unify_key::RegionVidKey;
use crate::next_solver::infer::snapshot::undo_log::{InferCtxtUndoLogs, Snapshot};
use crate::next_solver::infer::unify_key::RegionVariableValue;
-use crate::next_solver::{AliasTy, Binder, DbInterner, ParamTy, PlaceholderTy, Region, Ty};
+use crate::next_solver::{AliasTy, Binder, DbInterner, ParamTy, PlaceholderType, Region, Ty};
#[derive(Debug, Clone, Default)]
pub struct RegionConstraintStorage<'db> {
@@ -122,7 +122,7 @@ pub struct Verify<'db> {
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum GenericKind<'db> {
Param(ParamTy),
- Placeholder(PlaceholderTy),
+ Placeholder(PlaceholderType<'db>),
Alias(AliasTy<'db>),
}
diff --git a/crates/hir-ty/src/next_solver/infer/relate/generalize.rs b/crates/hir-ty/src/next_solver/infer/relate/generalize.rs
index 0f7ae99fa4..d621dd4906 100644
--- a/crates/hir-ty/src/next_solver/infer/relate/generalize.rs
+++ b/crates/hir-ty/src/next_solver/infer/relate/generalize.rs
@@ -531,7 +531,7 @@ impl<'db> TypeRelation<DbInterner<'db>> for Generalizer<'_, 'db> {
}
}
- TyKind::Alias(_, data) => match self.structurally_relate_aliases {
+ TyKind::Alias(data) => match self.structurally_relate_aliases {
StructurallyRelateAliases::No => self.generalize_alias_ty(data),
StructurallyRelateAliases::Yes => relate::structurally_relate_tys(self, t, t),
},
diff --git a/crates/hir-ty/src/next_solver/infer/relate/higher_ranked.rs b/crates/hir-ty/src/next_solver/infer/relate/higher_ranked.rs
index c523751e03..cfa864406c 100644
--- a/crates/hir-ty/src/next_solver/infer/relate/higher_ranked.rs
+++ b/crates/hir-ty/src/next_solver/infer/relate/higher_ranked.rs
@@ -8,7 +8,7 @@ use crate::next_solver::fold::FnMutDelegate;
use crate::next_solver::infer::InferCtxt;
use crate::next_solver::{
Binder, BoundConst, BoundRegion, BoundTy, Const, DbInterner, PlaceholderConst,
- PlaceholderRegion, PlaceholderTy, Region, Ty,
+ PlaceholderRegion, PlaceholderType, Region, Ty,
};
impl<'db> InferCtxt<'db> {
@@ -35,23 +35,14 @@ impl<'db> InferCtxt<'db> {
let next_universe = self.create_next_universe();
let delegate = FnMutDelegate {
- regions: &mut |br: BoundRegion| {
- Region::new_placeholder(
- self.interner,
- PlaceholderRegion { universe: next_universe, bound: br },
- )
+ regions: &mut |br: BoundRegion<'db>| {
+ Region::new_placeholder(self.interner, PlaceholderRegion::new(next_universe, br))
},
- types: &mut |bound_ty: BoundTy| {
- Ty::new_placeholder(
- self.interner,
- PlaceholderTy { universe: next_universe, bound: bound_ty },
- )
+ types: &mut |bound_ty: BoundTy<'db>| {
+ Ty::new_placeholder(self.interner, PlaceholderType::new(next_universe, bound_ty))
},
- consts: &mut |bound: BoundConst| {
- Const::new_placeholder(
- self.interner,
- PlaceholderConst { universe: next_universe, bound },
- )
+ consts: &mut |bound: BoundConst<'db>| {
+ Const::new_placeholder(self.interner, PlaceholderConst::new(next_universe, bound))
},
};
diff --git a/crates/hir-ty/src/next_solver/infer/relate/lattice.rs b/crates/hir-ty/src/next_solver/infer/relate/lattice.rs
index 1abe6a93f4..3522827a9e 100644
--- a/crates/hir-ty/src/next_solver/infer/relate/lattice.rs
+++ b/crates/hir-ty/src/next_solver/infer/relate/lattice.rs
@@ -165,8 +165,8 @@ impl<'db> TypeRelation<DbInterner<'db>> for LatticeOp<'_, 'db> {
}
(
- TyKind::Alias(rustc_type_ir::Opaque, AliasTy { def_id: a_def_id, .. }),
- TyKind::Alias(rustc_type_ir::Opaque, AliasTy { def_id: b_def_id, .. }),
+ TyKind::Alias(AliasTy { kind: rustc_type_ir::Opaque { def_id: a_def_id }, .. }),
+ TyKind::Alias(AliasTy { kind: rustc_type_ir::Opaque { def_id: b_def_id }, .. }),
) if a_def_id == b_def_id => super_combine_tys(infcx, self, a, b),
_ => super_combine_tys(infcx, self, a, b),
diff --git a/crates/hir-ty/src/next_solver/inspect.rs b/crates/hir-ty/src/next_solver/inspect.rs
index 5286977549..f30589d91b 100644
--- a/crates/hir-ty/src/next_solver/inspect.rs
+++ b/crates/hir-ty/src/next_solver/inspect.rs
@@ -1,5 +1,3 @@
-pub(crate) use rustc_next_trait_solver::solve::inspect::*;
-
use rustc_ast_ir::try_visit;
use rustc_next_trait_solver::{
canonical::instantiate_canonical_state,
@@ -329,10 +327,6 @@ impl<'a, 'db> InspectGoal<'a, 'db> {
self.result
}
- pub(crate) fn source(&self) -> GoalSource {
- self.source
- }
-
pub(crate) fn depth(&self) -> usize {
self.depth
}
diff --git a/crates/hir-ty/src/next_solver/interner.rs b/crates/hir-ty/src/next_solver/interner.rs
index 4f30fc7a89..9a94d1a865 100644
--- a/crates/hir-ty/src/next_solver/interner.rs
+++ b/crates/hir-ty/src/next_solver/interner.rs
@@ -25,9 +25,9 @@ use rustc_abi::{ReprFlags, ReprOptions};
use rustc_hash::FxHashSet;
use rustc_index::bit_set::DenseBitSet;
use rustc_type_ir::{
- AliasTermKind, AliasTyKind, BoundVar, CoroutineWitnessTypes, DebruijnIndex, EarlyBinder,
- FlagComputation, Flags, GenericArgKind, GenericTypeVisitable, ImplPolarity, InferTy, Interner,
- TraitRef, TypeFlags, TypeVisitableExt, UniverseIndex, Upcast, Variance,
+ AliasTermKind, AliasTy, AliasTyKind, BoundVar, CoroutineWitnessTypes, DebruijnIndex,
+ EarlyBinder, FlagComputation, Flags, GenericArgKind, GenericTypeVisitable, ImplPolarity,
+ InferTy, Interner, TraitRef, TypeFlags, TypeVisitableExt, Upcast, Variance,
elaborate::elaborate,
error::TypeError,
fast_reject,
@@ -43,9 +43,9 @@ use crate::{
method_resolution::TraitImpls,
next_solver::{
AdtIdWrapper, AnyImplId, BoundConst, CallableIdWrapper, CanonicalVarKind, ClosureIdWrapper,
- CoroutineClosureIdWrapper, CoroutineIdWrapper, Ctor, FnSig, FxIndexMap,
- GeneralConstIdWrapper, OpaqueTypeKey, RegionAssumptions, SimplifiedType, SolverContext,
- SolverDefIds, TraitIdWrapper, TypeAliasIdWrapper, UnevaluatedConst,
+ Consts, CoroutineClosureIdWrapper, CoroutineIdWrapper, Ctor, FnSig, FxIndexMap,
+ GeneralConstIdWrapper, LateParamRegion, OpaqueTypeKey, RegionAssumptions, SimplifiedType,
+ SolverContext, SolverDefIds, TraitIdWrapper, TypeAliasIdWrapper, UnevaluatedConst,
util::{explicit_item_bounds, explicit_item_self_bounds},
},
};
@@ -53,14 +53,11 @@ use crate::{
use super::{
Binder, BoundExistentialPredicates, BoundTy, BoundTyKind, Clause, ClauseKind, Clauses, Const,
ErrorGuaranteed, ExprConst, ExternalConstraints, GenericArg, GenericArgs, ParamConst, ParamEnv,
- ParamTy, PlaceholderConst, PlaceholderTy, PredefinedOpaques, Predicate, SolverDefId, Term, Ty,
- TyKind, Tys, Valtree, ValueConst,
+ ParamTy, PredefinedOpaques, Predicate, SolverDefId, Term, Ty, TyKind, Tys, Valtree, ValueConst,
abi::Safety,
fold::{BoundVarReplacer, BoundVarReplacerDelegate, FnMutDelegate},
generics::{Generics, generics},
- region::{
- BoundRegion, BoundRegionKind, EarlyParamRegion, LateParamRegion, PlaceholderRegion, Region,
- },
+ region::{BoundRegion, BoundRegionKind, EarlyParamRegion, Region},
util::sizedness_constraint_for_ty,
};
@@ -390,43 +387,15 @@ interned_slice!(
BoundVarKinds,
StoredBoundVarKinds,
bound_var_kinds,
- BoundVarKind,
- BoundVarKind,
+ BoundVariableKind<'db>,
+ BoundVariableKind<'static>,
);
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum BoundVarKind {
- Ty(BoundTyKind),
- Region(BoundRegionKind),
- Const,
-}
-
-impl BoundVarKind {
- pub fn expect_region(self) -> BoundRegionKind {
- match self {
- BoundVarKind::Region(lt) => lt,
- _ => panic!("expected a region, but found another kind"),
- }
- }
-
- pub fn expect_ty(self) -> BoundTyKind {
- match self {
- BoundVarKind::Ty(ty) => ty,
- _ => panic!("expected a type, but found another kind"),
- }
- }
-
- pub fn expect_const(self) {
- match self {
- BoundVarKind::Const => (),
- _ => panic!("expected a const, but found another kind"),
- }
- }
-}
+pub type BoundVariableKind<'db> = rustc_type_ir::BoundVariableKind<DbInterner<'db>>;
interned_slice!(
CanonicalVarsStorage,
- CanonicalVars,
+ CanonicalVarKinds,
StoredCanonicalVars,
canonical_vars,
CanonicalVarKind<'db>,
@@ -438,22 +407,6 @@ pub struct DepNodeIndex;
#[derive(Debug)]
pub struct Tracked<T: fmt::Debug + Clone>(T);
-#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
-pub struct Placeholder<T> {
- pub universe: UniverseIndex,
- pub bound: T,
-}
-
-impl<T: std::fmt::Debug> std::fmt::Debug for Placeholder<T> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
- if self.universe == UniverseIndex::ROOT {
- write!(f, "!{:?}", self.bound)
- } else {
- write!(f, "!{}_{:?}", self.universe.index(), self.bound)
- }
- }
-}
-
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct AllocId;
@@ -773,6 +726,19 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
fn is_manually_drop(self) -> bool {
self.inner().flags.is_manually_drop
}
+
+ fn is_packed(self) -> bool {
+ self.repr().packed()
+ }
+
+ fn field_representing_type_info(
+ self,
+ _interner: DbInterner<'db>,
+ _args: GenericArgs<'db>,
+ ) -> Option<rustc_type_ir::FieldInfo<DbInterner<'db>>> {
+ // FIXME
+ None
+ }
}
impl fmt::Debug for AdtDef {
@@ -806,11 +772,16 @@ impl<'db> inherent::Features<DbInterner<'db>> for Features {
false
}
- fn associated_const_equality(self) -> bool {
+ fn feature_bound_holds_in_crate(self, _symbol: Symbol) -> bool {
false
}
+}
+
+#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, GenericTypeVisitable)]
+pub struct Symbol;
- fn feature_bound_holds_in_crate(self, _symbol: ()) -> bool {
+impl<'db> inherent::Symbol<DbInterner<'db>> for Symbol {
+ fn is_kw_underscore_lifetime(self) -> bool {
false
}
}
@@ -1036,7 +1007,6 @@ impl<'db> Interner for DbInterner<'db> {
type Term = Term<'db>;
type BoundVarKinds = BoundVarKinds<'db>;
- type BoundVarKind = BoundVarKind;
type PredefinedOpaques = PredefinedOpaques<'db>;
@@ -1047,13 +1017,13 @@ impl<'db> Interner for DbInterner<'db> {
PredefinedOpaques::new_from_slice(data)
}
- type CanonicalVarKinds = CanonicalVars<'db>;
+ type CanonicalVarKinds = CanonicalVarKinds<'db>;
fn mk_canonical_var_kinds(
self,
kinds: &[rustc_type_ir::CanonicalVarKind<Self>],
) -> Self::CanonicalVarKinds {
- CanonicalVars::new_from_slice(kinds)
+ CanonicalVarKinds::new_from_slice(kinds)
}
type ExternalConstraints = ExternalConstraints<'db>;
@@ -1073,9 +1043,7 @@ impl<'db> Interner for DbInterner<'db> {
type Tys = Tys<'db>;
type FnInputTys = &'db [Ty<'db>];
type ParamTy = ParamTy;
- type BoundTy = BoundTy;
- type PlaceholderTy = PlaceholderTy;
- type Symbol = ();
+ type Symbol = Symbol;
type ErrorGuaranteed = ErrorGuaranteed;
type BoundExistentialPredicates = BoundExistentialPredicates<'db>;
@@ -1086,18 +1054,16 @@ impl<'db> Interner for DbInterner<'db> {
type Abi = FnAbi;
type Const = Const<'db>;
- type PlaceholderConst = PlaceholderConst;
type ParamConst = ParamConst;
- type BoundConst = BoundConst;
type ValueConst = ValueConst<'db>;
type ValTree = Valtree<'db>;
+ type Consts = Consts<'db>;
+ type ScalarInt = ();
type ExprConst = ExprConst;
type Region = Region<'db>;
type EarlyParamRegion = EarlyParamRegion;
- type LateParamRegion = LateParamRegion;
- type BoundRegion = BoundRegion;
- type PlaceholderRegion = PlaceholderRegion;
+ type LateParamRegion = LateParamRegion<'db>;
type RegionAssumptions = RegionAssumptions<'db>;
@@ -1231,22 +1197,6 @@ impl<'db> Interner for DbInterner<'db> {
AdtDef::new(def_id.0, self)
}
- fn alias_ty_kind(self, alias: rustc_type_ir::AliasTy<Self>) -> AliasTyKind {
- match alias.def_id {
- SolverDefId::InternedOpaqueTyId(_) => AliasTyKind::Opaque,
- SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
- ItemContainerId::ImplId(impl_)
- if ImplSignature::of(self.db, impl_).target_trait.is_none() =>
- {
- AliasTyKind::Inherent
- }
- ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => AliasTyKind::Projection,
- _ => AliasTyKind::Free,
- },
- _ => unimplemented!("Unexpected alias: {:?}", alias.def_id),
- }
- }
-
fn alias_term_kind(
self,
alias: rustc_type_ir::AliasTerm<Self>,
@@ -1346,7 +1296,7 @@ impl<'db> Interner for DbInterner<'db> {
50
}
- fn features(self) -> Self::Features {
+ fn features(self) -> Features {
Features
}
@@ -1476,7 +1426,9 @@ impl<'db> Interner for DbInterner<'db> {
fn is_ty_assoc_of_self(ty: Ty<'_>) -> bool {
// FIXME: Is this correct wrt. combined kind of assoc type bounds, i.e. `where Self::Assoc: Trait<Assoc2: Trait>`
// wrt. `Assoc2`, which we should exclude?
- if let TyKind::Alias(AliasTyKind::Projection, alias) = ty.kind() {
+ if let TyKind::Alias(alias @ AliasTy { kind: AliasTyKind::Projection { .. }, .. }) =
+ ty.kind()
+ {
is_ty_assoc_of_self(alias.self_ty())
} else {
is_ty_self(ty)
@@ -1540,6 +1492,8 @@ impl<'db> Interner for DbInterner<'db> {
SolverLangItem::DynMetadata => {
return lang_items.DynMetadata.expect("Lang item required but not found.").into();
}
+ SolverLangItem::FieldBase => unimplemented!(),
+ SolverLangItem::FieldType => unimplemented!(),
};
lang_item.expect("Lang item required but not found.").into()
}
@@ -1580,6 +1534,7 @@ impl<'db> Interner for DbInterner<'db> {
unimplemented!()
}
SolverTraitLangItem::TrivialClone => lang_items.TrivialClone,
+ SolverTraitLangItem::Field => unimplemented!(),
};
lang_item.expect("Lang item required but not found.").into()
}
@@ -1607,6 +1562,7 @@ impl<'db> Interner for DbInterner<'db> {
AsyncIterator,
BikeshedGuaranteedNoDrop,
FusedIterator,
+ Field,
AsyncFnOnceOutput, // This is incorrectly marked as `SolverTraitLangItem`, and is not used by the solver.
}
@@ -1652,6 +1608,8 @@ impl<'db> Interner for DbInterner<'db> {
ignore = {
AsyncFnKindUpvars,
DynMetadata,
+ FieldBase,
+ FieldType,
}
Metadata,
@@ -1676,6 +1634,8 @@ impl<'db> Interner for DbInterner<'db> {
CallRefFuture,
CallOnceFuture,
AsyncFnOnceOutput,
+ FieldBase,
+ FieldType,
}
DynMetadata,
@@ -1694,6 +1654,7 @@ impl<'db> Interner for DbInterner<'db> {
AsyncIterator,
BikeshedGuaranteedNoDrop,
FusedIterator,
+ Field,
AsyncFnOnceOutput, // This is incorrectly marked as `SolverTraitLangItem`, and is not used by the solver.
}
@@ -1871,7 +1832,7 @@ impl<'db> Interner for DbInterner<'db> {
//
// Impls which apply to an alias after normalization are handled by
// `assemble_candidates_after_normalizing_self_ty`.
- TyKind::Alias(_, _) | TyKind::Placeholder(..) | TyKind::Error(_) => (),
+ TyKind::Alias(..) | TyKind::Placeholder(..) | TyKind::Error(_) => (),
// FIXME: These should ideally not exist as a self type. It would be nice for
// the builtin auto trait impls of coroutines to instead directly recurse
@@ -1964,12 +1925,6 @@ impl<'db> Interner for DbInterner<'db> {
trait_data.flags.contains(TraitFlags::FUNDAMENTAL)
}
- fn trait_may_be_implemented_via_object(self, _trait_def_id: Self::TraitId) -> bool {
- // FIXME(next-solver): should check the `TraitFlags` for
- // the `#[rustc_do_not_implement_via_object]` flag
- true
- }
-
fn is_impl_trait_in_trait(self, _def_id: Self::DefId) -> bool {
// FIXME(next-solver)
false
@@ -2068,32 +2023,33 @@ impl<'db> Interner for DbInterner<'db> {
) -> rustc_type_ir::Binder<Self, T> {
struct Anonymize<'a, 'db> {
interner: DbInterner<'db>,
- map: &'a mut FxIndexMap<BoundVar, BoundVarKind>,
+ map: &'a mut FxIndexMap<BoundVar, BoundVariableKind<'db>>,
}
impl<'db> BoundVarReplacerDelegate<'db> for Anonymize<'_, 'db> {
- fn replace_region(&mut self, br: BoundRegion) -> Region<'db> {
+ fn replace_region(&mut self, br: BoundRegion<'db>) -> Region<'db> {
let entry = self.map.entry(br.var);
let index = entry.index();
let var = BoundVar::from_usize(index);
- let kind = (*entry.or_insert_with(|| BoundVarKind::Region(BoundRegionKind::Anon)))
- .expect_region();
+ let kind = (*entry
+ .or_insert_with(|| BoundVariableKind::Region(BoundRegionKind::Anon)))
+ .expect_region();
let br = BoundRegion { var, kind };
Region::new_bound(self.interner, DebruijnIndex::ZERO, br)
}
- fn replace_ty(&mut self, bt: BoundTy) -> Ty<'db> {
+ fn replace_ty(&mut self, bt: BoundTy<'db>) -> Ty<'db> {
let entry = self.map.entry(bt.var);
let index = entry.index();
let var = BoundVar::from_usize(index);
- let kind =
- (*entry.or_insert_with(|| BoundVarKind::Ty(BoundTyKind::Anon))).expect_ty();
+ let kind = (*entry.or_insert_with(|| BoundVariableKind::Ty(BoundTyKind::Anon)))
+ .expect_ty();
Ty::new_bound(self.interner, DebruijnIndex::ZERO, BoundTy { var, kind })
}
- fn replace_const(&mut self, bv: BoundConst) -> Const<'db> {
+ fn replace_const(&mut self, bv: BoundConst<'db>) -> Const<'db> {
let entry = self.map.entry(bv.var);
let index = entry.index();
let var = BoundVar::from_usize(index);
- let () = (*entry.or_insert_with(|| BoundVarKind::Const)).expect_const();
- Const::new_bound(self.interner, DebruijnIndex::ZERO, BoundConst { var })
+ let () = (*entry.or_insert_with(|| BoundVariableKind::Const)).expect_const();
+ Const::new_bound(self.interner, DebruijnIndex::ZERO, BoundConst::new(var))
}
}
@@ -2273,6 +2229,34 @@ impl<'db> Interner for DbInterner<'db> {
UnevaluatedConst { def: GeneralConstIdWrapper(id), args: GenericArgs::empty(self) },
))
}
+
+ fn anon_const_kind(self, _def_id: Self::DefId) -> rustc_type_ir::AnonConstKind {
+ // FIXME
+ rustc_type_ir::AnonConstKind::GCE
+ }
+
+ fn alias_ty_kind_from_def_id(self, def_id: Self::DefId) -> AliasTyKind<DbInterner<'db>> {
+ match def_id {
+ SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
+ ItemContainerId::ExternBlockId(_) | ItemContainerId::ModuleId(_) => {
+ AliasTyKind::Free { def_id }
+ }
+ ItemContainerId::ImplId(_) => AliasTyKind::Inherent { def_id },
+ ItemContainerId::TraitId(_) => AliasTyKind::Projection { def_id },
+ },
+ SolverDefId::InternedOpaqueTyId(_) => AliasTyKind::Opaque { def_id },
+ _ => unreachable!(),
+ }
+ }
+
+ fn closure_is_const(self, _def_id: Self::ClosureId) -> bool {
+ // FIXME
+ false
+ }
+
+ fn item_name(self, _item_index: Self::DefId) -> Self::Symbol {
+ Symbol
+ }
}
fn is_ty_self(ty: Ty<'_>) -> bool {
@@ -2302,14 +2286,14 @@ impl<'db> DbInterner<'db> {
self.replace_escaping_bound_vars_uncached(
value,
FnMutDelegate {
- regions: &mut |r: BoundRegion| {
+ regions: &mut |r: BoundRegion<'db>| {
Region::new_bound(
self,
DebruijnIndex::ZERO,
BoundRegion { var: shift_bv(r.var), kind: r.kind },
)
},
- types: &mut |t: BoundTy| {
+ types: &mut |t: BoundTy<'db>| {
Ty::new_bound(
self,
DebruijnIndex::ZERO,
@@ -2317,7 +2301,7 @@ impl<'db> DbInterner<'db> {
)
},
consts: &mut |c| {
- Const::new_bound(self, DebruijnIndex::ZERO, BoundConst { var: shift_bv(c.var) })
+ Const::new_bound(self, DebruijnIndex::ZERO, BoundConst::new(shift_bv(c.var)))
},
},
)
@@ -2430,17 +2414,8 @@ TrivialTypeTraversalImpls! {
Span,
ParamConst,
ParamTy,
- BoundRegion,
- Placeholder<BoundRegion>,
- Placeholder<BoundTy>,
- Placeholder<BoundVar>,
- Placeholder<BoundConst>,
- BoundVarKind,
EarlyParamRegion,
- LateParamRegion,
AdtDef,
- BoundTy,
- BoundConst,
}
mod tls_db {
diff --git a/crates/hir-ty/src/next_solver/ir_print.rs b/crates/hir-ty/src/next_solver/ir_print.rs
index e0732b3473..5dd372a367 100644
--- a/crates/hir-ty/src/next_solver/ir_print.rs
+++ b/crates/hir-ty/src/next_solver/ir_print.rs
@@ -12,7 +12,7 @@ impl<'db> IrPrint<ty::AliasTy<Self>> for DbInterner<'db> {
}
fn print_debug(t: &ty::AliasTy<Self>, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- crate::with_attached_db(|db| match t.def_id {
+ crate::with_attached_db(|db| match t.kind.def_id() {
SolverDefId::TypeAliasId(id) => fmt.write_str(&format!(
"AliasTy({:?}[{:?}])",
TypeAliasSignature::of(db, id).name.as_str(),
diff --git a/crates/hir-ty/src/next_solver/normalize.rs b/crates/hir-ty/src/next_solver/normalize.rs
index bd678b3e78..5d8f3fe519 100644
--- a/crates/hir-ty/src/next_solver/normalize.rs
+++ b/crates/hir-ty/src/next_solver/normalize.rs
@@ -229,6 +229,7 @@ impl<'db> FallibleTypeFolder<DbInterner<'db>> for NormalizationFolder<'_, 'db> {
}
// Deeply normalize a value and return it
+#[expect(dead_code, reason = "rustc has this")]
pub(crate) fn deeply_normalize_for_diagnostics<'db, T: TypeFoldable<DbInterner<'db>>>(
infcx: &InferCtxt<'db>,
param_env: ParamEnv<'db>,
diff --git a/crates/hir-ty/src/next_solver/region.rs b/crates/hir-ty/src/next_solver/region.rs
index dc2441f76e..3f0aebac2d 100644
--- a/crates/hir-ty/src/next_solver/region.rs
+++ b/crates/hir-ty/src/next_solver/region.rs
@@ -1,12 +1,12 @@
//! Things related to regions.
use hir_def::LifetimeParamId;
-use intern::{Interned, InternedRef, Symbol, impl_internable};
+use intern::{Interned, InternedRef, impl_internable};
use macros::GenericTypeVisitable;
use rustc_type_ir::{
- BoundVar, BoundVarIndexKind, DebruijnIndex, Flags, GenericTypeVisitable, INNERMOST, RegionVid,
- TypeFlags, TypeFoldable, TypeVisitable,
- inherent::{IntoKind, PlaceholderLike, SliceLike},
+ BoundVarIndexKind, DebruijnIndex, Flags, GenericTypeVisitable, INNERMOST, RegionVid, TypeFlags,
+ TypeFoldable, TypeVisitable,
+ inherent::{IntoKind, SliceLike},
relate::Relate,
};
@@ -15,10 +15,7 @@ use crate::next_solver::{
interned_slice,
};
-use super::{
- SolverDefId,
- interner::{BoundVarKind, DbInterner, Placeholder},
-};
+use super::{SolverDefId, interner::DbInterner};
pub type RegionKind<'db> = rustc_type_ir::RegionKind<DbInterner<'db>>;
@@ -57,7 +54,7 @@ impl<'db> Region<'db> {
Region::new(interner, RegionKind::ReEarlyParam(early_bound_region))
}
- pub fn new_placeholder(interner: DbInterner<'db>, placeholder: PlaceholderRegion) -> Self {
+ pub fn new_placeholder(interner: DbInterner<'db>, placeholder: PlaceholderRegion<'db>) -> Self {
Region::new(interner, RegionKind::RePlaceholder(placeholder))
}
@@ -72,7 +69,7 @@ impl<'db> Region<'db> {
pub fn new_bound(
interner: DbInterner<'db>,
index: DebruijnIndex,
- bound: BoundRegion,
+ bound: BoundRegion<'db>,
) -> Region<'db> {
Region::new(interner, RegionKind::ReBound(BoundVarIndexKind::Bound(index), bound))
}
@@ -147,7 +144,7 @@ impl<'db> Region<'db> {
}
}
-pub type PlaceholderRegion = Placeholder<BoundRegion>;
+pub type PlaceholderRegion<'db> = rustc_type_ir::PlaceholderRegion<DbInterner<'db>>;
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct EarlyParamRegion {
@@ -156,7 +153,7 @@ pub struct EarlyParamRegion {
pub index: u32,
}
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, GenericTypeVisitable)]
/// The parameter representation of late-bound function parameters, "some region
/// at least as big as the scope `fr.scope`".
///
@@ -165,50 +162,19 @@ pub struct EarlyParamRegion {
/// between others we use the `DefId` of the parameter. For this reason the `bound_region` field
/// should basically always be `BoundRegionKind::Named` as otherwise there is no way of telling
/// different parameters apart.
-pub struct LateParamRegion {
+pub struct LateParamRegion<'db> {
pub scope: SolverDefId,
- pub bound_region: BoundRegionKind,
+ pub bound_region: BoundRegionKind<'db>,
}
-impl std::fmt::Debug for LateParamRegion {
+impl std::fmt::Debug for LateParamRegion<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "ReLateParam({:?}, {:?})", self.scope, self.bound_region)
}
}
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub enum BoundRegionKind {
- /// An anonymous region parameter for a given fn (&T)
- Anon,
-
- /// Named region parameters for functions (a in &'a T)
- ///
- /// The `DefId` is needed to distinguish free regions in
- /// the event of shadowing.
- Named(SolverDefId),
-
- /// Anonymous region for the implicit env pointer parameter
- /// to a closure
- ClosureEnv,
-}
-
-impl std::fmt::Debug for BoundRegionKind {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- match *self {
- BoundRegionKind::Anon => write!(f, "BrAnon"),
- BoundRegionKind::Named(did) => {
- write!(f, "BrNamed({did:?})")
- }
- BoundRegionKind::ClosureEnv => write!(f, "BrEnv"),
- }
- }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub struct BoundRegion {
- pub var: BoundVar,
- pub kind: BoundRegionKind,
-}
+pub type BoundRegion<'db> = rustc_type_ir::BoundRegion<DbInterner<'db>>;
+pub type BoundRegionKind<'db> = rustc_type_ir::BoundRegionKind<DbInterner<'db>>;
impl rustc_type_ir::inherent::ParamLike for EarlyParamRegion {
fn index(self) -> u32 {
@@ -223,45 +189,6 @@ impl std::fmt::Debug for EarlyParamRegion {
}
}
-impl<'db> rustc_type_ir::inherent::BoundVarLike<DbInterner<'db>> for BoundRegion {
- fn var(self) -> BoundVar {
- self.var
- }
-
- fn assert_eq(self, var: BoundVarKind) {
- assert_eq!(self.kind, var.expect_region())
- }
-}
-
-impl core::fmt::Debug for BoundRegion {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- match &self.kind {
- BoundRegionKind::Anon => write!(f, "{:?}", self.var),
- BoundRegionKind::ClosureEnv => write!(f, "{:?}.Env", self.var),
- BoundRegionKind::Named(def) => {
- write!(f, "{:?}.Named({:?})", self.var, def)
- }
- }
- }
-}
-
-impl BoundRegionKind {
- pub fn is_named(&self) -> bool {
- matches!(self, BoundRegionKind::Named(_))
- }
-
- pub fn get_name(&self) -> Option<Symbol> {
- None
- }
-
- pub fn get_id(&self) -> Option<SolverDefId> {
- match self {
- BoundRegionKind::Named(id) => Some(*id),
- _ => None,
- }
- }
-}
-
impl std::fmt::Debug for Region<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.kind().fmt(f)
@@ -323,15 +250,15 @@ impl<'db> Flags for Region<'db> {
impl<'db> rustc_type_ir::inherent::Region<DbInterner<'db>> for Region<'db> {
fn new_bound(
interner: DbInterner<'db>,
- debruijn: rustc_type_ir::DebruijnIndex,
- var: BoundRegion,
+ debruijn: DebruijnIndex,
+ var: BoundRegion<'db>,
) -> Self {
Region::new(interner, RegionKind::ReBound(BoundVarIndexKind::Bound(debruijn), var))
}
fn new_anon_bound(
interner: DbInterner<'db>,
- debruijn: rustc_type_ir::DebruijnIndex,
+ debruijn: DebruijnIndex,
var: rustc_type_ir::BoundVar,
) -> Self {
Region::new(
@@ -357,38 +284,11 @@ impl<'db> rustc_type_ir::inherent::Region<DbInterner<'db>> for Region<'db> {
interner.default_types().regions.statik
}
- fn new_placeholder(
- interner: DbInterner<'db>,
- var: <DbInterner<'db> as rustc_type_ir::Interner>::PlaceholderRegion,
- ) -> Self {
+ fn new_placeholder(interner: DbInterner<'db>, var: PlaceholderRegion<'db>) -> Self {
Region::new(interner, RegionKind::RePlaceholder(var))
}
}
-impl<'db> PlaceholderLike<DbInterner<'db>> for PlaceholderRegion {
- type Bound = BoundRegion;
-
- fn universe(self) -> rustc_type_ir::UniverseIndex {
- self.universe
- }
-
- fn var(self) -> rustc_type_ir::BoundVar {
- self.bound.var
- }
-
- fn with_updated_universe(self, ui: rustc_type_ir::UniverseIndex) -> Self {
- Placeholder { universe: ui, bound: self.bound }
- }
-
- fn new(ui: rustc_type_ir::UniverseIndex, bound: Self::Bound) -> Self {
- Placeholder { universe: ui, bound }
- }
-
- fn new_anon(ui: rustc_type_ir::UniverseIndex, var: rustc_type_ir::BoundVar) -> Self {
- Placeholder { universe: ui, bound: BoundRegion { var, kind: BoundRegionKind::Anon } }
- }
-}
-
impl<'db, V: super::WorldExposer> GenericTypeVisitable<V> for Region<'db> {
fn generic_visit_with(&self, visitor: &mut V) {
if visitor.on_interned(self.interned).is_continue() {
diff --git a/crates/hir-ty/src/next_solver/solver.rs b/crates/hir-ty/src/next_solver/solver.rs
index 848bb110af..a9e7de1613 100644
--- a/crates/hir-ty/src/next_solver/solver.rs
+++ b/crates/hir-ty/src/next_solver/solver.rs
@@ -155,10 +155,11 @@ impl<'db> SolverDelegate for SolverContext<'db> {
fold_tys(interner, clause, |ty| match ty.kind() {
// Replace all other mentions of the same opaque type with the hidden type,
// as the bounds must hold on the hidden type after all.
- TyKind::Alias(
- AliasTyKind::Opaque,
- AliasTy { def_id: def_id2, args: args2, .. },
- ) if def_id == def_id2 && args == args2 => hidden_ty,
+ TyKind::Alias(AliasTy {
+ kind: AliasTyKind::Opaque { def_id: def_id2 },
+ args: args2,
+ ..
+ }) if def_id == def_id2 && args == args2 => hidden_ty,
_ => ty,
})
};
diff --git a/crates/hir-ty/src/next_solver/ty.rs b/crates/hir-ty/src/next_solver/ty.rs
index dccb8c7936..3811bddb38 100644
--- a/crates/hir-ty/src/next_solver/ty.rs
+++ b/crates/hir-ty/src/next_solver/ty.rs
@@ -17,8 +17,8 @@ use rustc_type_ir::{
IntVid, Interner, TyVid, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor, UintTy, Upcast, WithCachedTypeInfo,
inherent::{
- AdtDef as _, BoundExistentialPredicates, BoundVarLike, Const as _, GenericArgs as _,
- IntoKind, ParamLike, PlaceholderLike, Safety as _, SliceLike, Ty as _,
+ AdtDef as _, BoundExistentialPredicates, Const as _, GenericArgs as _, IntoKind, ParamLike,
+ Safety as _, SliceLike, Ty as _,
},
relate::Relate,
solve::SizedTraitKind,
@@ -40,7 +40,7 @@ use crate::{
};
use super::{
- BoundVarKind, DbInterner, GenericArgs, Placeholder, SolverDefId,
+ DbInterner, GenericArgs, SolverDefId,
util::{FloatExt, IntegerExt},
};
@@ -97,7 +97,7 @@ impl<'db> Ty<'db> {
Ty::new(interner, TyKind::Param(ParamTy { id, index }))
}
- pub fn new_placeholder(interner: DbInterner<'db>, placeholder: PlaceholderTy) -> Self {
+ pub fn new_placeholder(interner: DbInterner<'db>, placeholder: PlaceholderType<'db>) -> Self {
Ty::new(interner, TyKind::Placeholder(placeholder))
}
@@ -177,7 +177,10 @@ impl<'db> Ty<'db> {
def_id: SolverDefId,
args: GenericArgs<'db>,
) -> Self {
- Ty::new_alias(interner, AliasTyKind::Opaque, AliasTy::new_from_args(interner, def_id, args))
+ Ty::new_alias(
+ interner,
+ AliasTy::new_from_args(interner, AliasTyKind::Opaque { def_id }, args),
+ )
}
/// Returns the `Size` for primitive types (bool, uint, int, char, float).
@@ -681,12 +684,11 @@ impl<'db> Ty<'db> {
let interner = DbInterner::new_no_crate(db);
match self.kind() {
- TyKind::Alias(AliasTyKind::Opaque, opaque_ty) => Some(
- opaque_ty
- .def_id
+ TyKind::Alias(AliasTy { kind: AliasTyKind::Opaque { def_id }, args, .. }) => Some(
+ def_id
.expect_opaque_ty()
.predicates(db)
- .iter_instantiated_copied(interner, opaque_ty.args.as_slice())
+ .iter_instantiated_copied(interner, args.as_slice())
.collect(),
),
TyKind::Param(param) => {
@@ -743,9 +745,7 @@ impl<'db> Ty<'db> {
true
}
(TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2,
- (TyKind::Alias(_, alias, ..), TyKind::Alias(_, alias2)) => {
- alias.def_id == alias2.def_id
- }
+ (TyKind::Alias(alias), TyKind::Alias(alias2)) => alias.kind == alias2.kind,
(TyKind::Foreign(ty_id, ..), TyKind::Foreign(ty_id2, ..)) => ty_id == ty_id2,
(TyKind::Closure(id1, _), TyKind::Closure(id2, _)) => id1 == id2,
(TyKind::Ref(.., mutability), TyKind::Ref(.., mutability2))
@@ -858,7 +858,7 @@ impl<'db> TypeSuperVisitable<DbInterner<'db>> for Ty<'db> {
TyKind::CoroutineWitness(_did, ref args) => args.visit_with(visitor),
TyKind::Closure(_did, ref args) => args.visit_with(visitor),
TyKind::CoroutineClosure(_did, ref args) => args.visit_with(visitor),
- TyKind::Alias(_, ref data) => data.visit_with(visitor),
+ TyKind::Alias(ref data) => data.visit_with(visitor),
TyKind::Pat(ty, pat) => {
try_visit!(ty.visit_with(visitor));
@@ -925,7 +925,7 @@ impl<'db> TypeSuperFoldable<DbInterner<'db>> for Ty<'db> {
TyKind::CoroutineClosure(did, args) => {
TyKind::CoroutineClosure(did, args.try_fold_with(folder)?)
}
- TyKind::Alias(kind, data) => TyKind::Alias(kind, data.try_fold_with(folder)?),
+ TyKind::Alias(data) => TyKind::Alias(data.try_fold_with(folder)?),
TyKind::Pat(ty, pat) => {
TyKind::Pat(ty.try_fold_with(folder)?, pat.try_fold_with(folder)?)
}
@@ -974,7 +974,7 @@ impl<'db> TypeSuperFoldable<DbInterner<'db>> for Ty<'db> {
TyKind::CoroutineClosure(did, args) => {
TyKind::CoroutineClosure(did, args.fold_with(folder))
}
- TyKind::Alias(kind, data) => TyKind::Alias(kind, data.fold_with(folder)),
+ TyKind::Alias(data) => TyKind::Alias(data.fold_with(folder)),
TyKind::Pat(ty, pat) => TyKind::Pat(ty.fold_with(folder), pat.fold_with(folder)),
TyKind::Bool
@@ -1045,11 +1045,11 @@ impl<'db> rustc_type_ir::inherent::Ty<DbInterner<'db>> for Ty<'db> {
Ty::new(interner, TyKind::Param(param))
}
- fn new_placeholder(interner: DbInterner<'db>, param: PlaceholderTy) -> Self {
+ fn new_placeholder(interner: DbInterner<'db>, param: PlaceholderType<'db>) -> Self {
Ty::new(interner, TyKind::Placeholder(param))
}
- fn new_bound(interner: DbInterner<'db>, debruijn: DebruijnIndex, var: BoundTy) -> Self {
+ fn new_bound(interner: DbInterner<'db>, debruijn: DebruijnIndex, var: BoundTy<'db>) -> Self {
Ty::new(interner, TyKind::Bound(BoundVarIndexKind::Bound(debruijn), var))
}
@@ -1070,8 +1070,8 @@ impl<'db> rustc_type_ir::inherent::Ty<DbInterner<'db>> for Ty<'db> {
)
}
- fn new_alias(interner: DbInterner<'db>, kind: AliasTyKind, alias_ty: AliasTy<'db>) -> Self {
- Ty::new(interner, TyKind::Alias(kind, alias_ty))
+ fn new_alias(interner: DbInterner<'db>, alias_ty: AliasTy<'db>) -> Self {
+ Ty::new(interner, TyKind::Alias(alias_ty))
}
fn new_error(interner: DbInterner<'db>, guar: ErrorGuaranteed) -> Self {
@@ -1352,7 +1352,7 @@ impl<'db> rustc_type_ir::inherent::Tys<DbInterner<'db>> for Tys<'db> {
}
}
-pub type PlaceholderTy = Placeholder<BoundTy>;
+pub type PlaceholderType<'db> = rustc_type_ir::PlaceholderType<DbInterner<'db>>;
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct ParamTy {
@@ -1375,27 +1375,8 @@ impl std::fmt::Debug for ParamTy {
}
}
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub struct BoundTy {
- pub var: BoundVar,
- // FIXME: This is for diagnostics in rustc, do we really need it?
- pub kind: BoundTyKind,
-}
-
-impl std::fmt::Debug for BoundTy {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- match self.kind {
- BoundTyKind::Anon => write!(f, "{:?}", self.var),
- BoundTyKind::Param(def_id) => write!(f, "{def_id:?}"),
- }
- }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
-pub enum BoundTyKind {
- Anon,
- Param(SolverDefId),
-}
+pub type BoundTy<'db> = rustc_type_ir::BoundTy<DbInterner<'db>>;
+pub type BoundTyKind<'db> = rustc_type_ir::BoundTyKind<DbInterner<'db>>;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct ErrorGuaranteed;
@@ -1431,40 +1412,6 @@ impl ParamLike for ParamTy {
}
}
-impl<'db> BoundVarLike<DbInterner<'db>> for BoundTy {
- fn var(self) -> BoundVar {
- self.var
- }
-
- fn assert_eq(self, var: BoundVarKind) {
- assert_eq!(self.kind, var.expect_ty())
- }
-}
-
-impl<'db> PlaceholderLike<DbInterner<'db>> for PlaceholderTy {
- type Bound = BoundTy;
-
- fn universe(self) -> rustc_type_ir::UniverseIndex {
- self.universe
- }
-
- fn var(self) -> BoundVar {
- self.bound.var
- }
-
- fn with_updated_universe(self, ui: rustc_type_ir::UniverseIndex) -> Self {
- Placeholder { universe: ui, bound: self.bound }
- }
-
- fn new(ui: rustc_type_ir::UniverseIndex, bound: BoundTy) -> Self {
- Placeholder { universe: ui, bound }
- }
-
- fn new_anon(ui: rustc_type_ir::UniverseIndex, var: rustc_type_ir::BoundVar) -> Self {
- Placeholder { universe: ui, bound: BoundTy { var, kind: BoundTyKind::Anon } }
- }
-}
-
impl<'db> DbInterner<'db> {
/// Given a closure signature, returns an equivalent fn signature. Detuples
/// and so forth -- so e.g., if we have a sig with `Fn<(u32, i32)>` then
diff --git a/crates/hir-ty/src/next_solver/util.rs b/crates/hir-ty/src/next_solver/util.rs
index c175062bda..858233cb2c 100644
--- a/crates/hir-ty/src/next_solver/util.rs
+++ b/crates/hir-ty/src/next_solver/util.rs
@@ -15,7 +15,7 @@ use rustc_type_ir::{
use crate::{
next_solver::{
- BoundConst, FxIndexMap, ParamEnv, Placeholder, PlaceholderConst, PlaceholderRegion,
+ BoundConst, FxIndexMap, ParamEnv, PlaceholderConst, PlaceholderRegion, PlaceholderType,
PolyTraitRef,
infer::{
InferCtxt,
@@ -446,9 +446,10 @@ pub fn apply_args_to_binder<'db, T: TypeFoldable<DbInterner<'db>>>(
args: GenericArgs<'db>,
interner: DbInterner<'db>,
) -> T {
- let types = &mut |ty: BoundTy| args.as_slice()[ty.var.index()].expect_ty();
- let regions = &mut |region: BoundRegion| args.as_slice()[region.var.index()].expect_region();
- let consts = &mut |const_: BoundConst| args.as_slice()[const_.var.index()].expect_const();
+ let types = &mut |ty: BoundTy<'db>| args.as_slice()[ty.var.index()].expect_ty();
+ let regions =
+ &mut |region: BoundRegion<'db>| args.as_slice()[region.var.index()].expect_region();
+ let consts = &mut |const_: BoundConst<'db>| args.as_slice()[const_.var.index()].expect_const();
let mut instantiate = BoundVarReplacer::new(interner, FnMutDelegate { types, regions, consts });
b.skip_binder().fold_with(&mut instantiate)
}
@@ -497,9 +498,9 @@ impl<'db> TypeVisitor<DbInterner<'db>> for ContainsTypeErrors {
/// The inverse of [`BoundVarReplacer`]: replaces placeholders with the bound vars from which they came.
pub struct PlaceholderReplacer<'a, 'db> {
infcx: &'a InferCtxt<'db>,
- mapped_regions: FxIndexMap<PlaceholderRegion, BoundRegion>,
- mapped_types: FxIndexMap<Placeholder<BoundTy>, BoundTy>,
- mapped_consts: FxIndexMap<PlaceholderConst, BoundConst>,
+ mapped_regions: FxIndexMap<PlaceholderRegion<'db>, BoundRegion<'db>>,
+ mapped_types: FxIndexMap<PlaceholderType<'db>, BoundTy<'db>>,
+ mapped_consts: FxIndexMap<PlaceholderConst<'db>, BoundConst<'db>>,
universe_indices: &'a [Option<UniverseIndex>],
current_index: DebruijnIndex,
}
@@ -507,9 +508,9 @@ pub struct PlaceholderReplacer<'a, 'db> {
impl<'a, 'db> PlaceholderReplacer<'a, 'db> {
pub fn replace_placeholders<T: TypeFoldable<DbInterner<'db>>>(
infcx: &'a InferCtxt<'db>,
- mapped_regions: FxIndexMap<PlaceholderRegion, BoundRegion>,
- mapped_types: FxIndexMap<Placeholder<BoundTy>, BoundTy>,
- mapped_consts: FxIndexMap<PlaceholderConst, BoundConst>,
+ mapped_regions: FxIndexMap<PlaceholderRegion<'db>, BoundRegion<'db>>,
+ mapped_types: FxIndexMap<PlaceholderType<'db>, BoundTy<'db>>,
+ mapped_consts: FxIndexMap<PlaceholderConst<'db>, BoundConst<'db>>,
universe_indices: &'a [Option<UniverseIndex>],
value: T,
) -> T {
diff --git a/crates/hir-ty/src/variance.rs b/crates/hir-ty/src/variance.rs
index 1945b04bb3..a88457e3c7 100644
--- a/crates/hir-ty/src/variance.rs
+++ b/crates/hir-ty/src/variance.rs
@@ -216,7 +216,7 @@ impl<'db> Context<'db> {
TyKind::Adt(def, args) => {
self.add_constraints_from_args(def.def_id().0.into(), args, variance);
}
- TyKind::Alias(_, alias) => {
+ TyKind::Alias(alias) => {
// FIXME: Probably not correct wrt. opaques.
self.add_constraints_from_invariant_args(alias.args);
}
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 53240259e0..e102572148 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -5736,8 +5736,11 @@ impl<'db> Type<'db> {
// FIXME: We don't handle GATs yet.
let projection = Ty::new_alias(
interner,
- AliasTyKind::Projection,
- AliasTy::new_from_args(interner, alias.id.into(), args),
+ AliasTy::new_from_args(
+ interner,
+ AliasTyKind::Projection { def_id: alias.id.into() },
+ args,
+ ),
);
let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis);
@@ -6353,8 +6356,12 @@ impl<'db> Type<'db> {
}
pub fn as_associated_type_parent_trait(&self, db: &'db dyn HirDatabase) -> Option<Trait> {
- let TyKind::Alias(AliasTyKind::Projection, alias) = self.ty.kind() else { return None };
- match alias.def_id.expect_type_alias().loc(db).container {
+ let TyKind::Alias(AliasTy { kind: AliasTyKind::Projection { def_id }, .. }) =
+ self.ty.kind()
+ else {
+ return None;
+ };
+ match def_id.expect_type_alias().loc(db).container {
ItemContainerId::TraitId(id) => Some(Trait { id }),
_ => None,
}
@@ -6670,8 +6677,8 @@ impl Layout {
let offset = stride.bytes() * tail;
self.0.size.bytes().checked_sub(offset)?.checked_sub(tail_field_size)
}),
- layout::FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
- let tail = memory_index.last_index()?;
+ layout::FieldsShape::Arbitrary { ref offsets, ref in_memory_order } => {
+ let tail = in_memory_order[in_memory_order.len().checked_sub(1)? as u32];
let tail_field_size = field_size(tail.0.into_raw().into_u32() as usize)?;
let offset = offsets.get(tail)?.bytes();
self.0.size.bytes().checked_sub(offset)?.checked_sub(tail_field_size)
@@ -6691,10 +6698,11 @@ impl Layout {
let size = field_size(0)?;
stride.bytes().checked_sub(size)
}
- layout::FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
- let mut reverse_index = vec![None; memory_index.len()];
- for (src, (mem, offset)) in memory_index.iter().zip(offsets.iter()).enumerate() {
- reverse_index[*mem as usize] = Some((src, offset.bytes()));
+ layout::FieldsShape::Arbitrary { ref offsets, ref in_memory_order } => {
+ let mut reverse_index = vec![None; in_memory_order.len()];
+ for (mem, src) in in_memory_order.iter().enumerate() {
+ reverse_index[mem] =
+ Some((src.0.into_raw().into_u32() as usize, offsets[*src].bytes()));
}
if reverse_index.iter().any(|it| it.is_none()) {
stdx::never!();
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 1a34fa9134..6c43f80ce8 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -37,7 +37,7 @@ use hir_ty::{
lang_items::lang_items_for_bin_op,
method_resolution::{self, CandidateId},
next_solver::{
- DbInterner, ErrorGuaranteed, GenericArgs, ParamEnv, Ty, TyKind, TypingMode,
+ AliasTy, DbInterner, ErrorGuaranteed, GenericArgs, ParamEnv, Ty, TyKind, TypingMode,
infer::DbInternerInferExt,
},
traits::structurally_normalize_ty,
@@ -1293,10 +1293,14 @@ impl<'db> SourceAnalyzer<'db> {
PathResolution::Def(ModuleDef::Adt(adt_id.into())),
)
}
- TyKind::Alias(AliasTyKind::Projection, alias) => {
- let assoc_id = alias.def_id.expect_type_alias();
+ TyKind::Alias(AliasTy {
+ kind: AliasTyKind::Projection { def_id },
+ args,
+ ..
+ }) => {
+ let assoc_id = def_id.expect_type_alias();
(
- GenericSubstitution::new(assoc_id.into(), alias.args, env),
+ GenericSubstitution::new(assoc_id.into(), args, env),
PathResolution::Def(ModuleDef::TypeAlias(assoc_id.into())),
)
}