Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/lower_nextsolver.rs')
-rw-r--r--crates/hir-ty/src/lower_nextsolver.rs142
1 files changed, 73 insertions, 69 deletions
diff --git a/crates/hir-ty/src/lower_nextsolver.rs b/crates/hir-ty/src/lower_nextsolver.rs
index abca6b6bb9..aced46bf80 100644
--- a/crates/hir-ty/src/lower_nextsolver.rs
+++ b/crates/hir-ty/src/lower_nextsolver.rs
@@ -17,17 +17,20 @@ use std::{
use base_db::Crate;
use either::Either;
-use hir_def::hir::generics::GenericParamDataRef;
-use hir_def::item_tree::FieldsShape;
use hir_def::{
- AdtId, AssocItemId, CallableDefId, ConstParamId, DefWithBodyId, EnumVariantId, FunctionId,
- GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup,
- StructId, TraitId, TypeAliasId, TypeOrConstParamId, VariantId,
+ AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumVariantId,
+ FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
+ LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId,
+ TypeParamId, VariantId,
expr_store::{
ExpressionStore,
path::{GenericArg, Path},
},
- hir::generics::{TypeOrConstParamData, WherePredicate},
+ hir::generics::{
+ GenericParamDataRef, TypeOrConstParamData, TypeParamData, TypeParamProvenance,
+ WherePredicate,
+ },
+ item_tree::FieldsShape,
lang_item::LangItem,
resolver::{HasResolver, LifetimeNs, Resolver, TypeNs},
signatures::{FunctionSignature, TraitFlags, TypeAliasFlags},
@@ -36,7 +39,6 @@ use hir_def::{
TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId,
},
};
-use hir_def::{ConstId, LifetimeParamId, StaticId, TypeParamId};
use hir_expand::name::Name;
use intern::{Symbol, sym};
use la_arena::{Arena, ArenaMap, Idx};
@@ -48,20 +50,17 @@ use rustc_type_ir::{
AliasTyKind, ConstKind, DebruijnIndex, ExistentialPredicate, ExistentialProjection,
ExistentialTraitRef, FnSig, OutlivesPredicate,
TyKind::{self},
- TypeVisitableExt,
+ TypeFoldable, TypeFolder, TypeVisitableExt, Upcast,
inherent::{GenericArg as _, GenericArgs as _, IntoKind as _, Region as _, SliceLike, Ty as _},
};
-use rustc_type_ir::{TypeFoldable, TypeFolder, Upcast};
use salsa::plumbing::AsId;
use smallvec::{SmallVec, smallvec};
use stdx::never;
use triomphe::Arc;
-use crate::ValueTyDefId;
-use crate::next_solver::ParamConst;
use crate::{
FnAbi, ImplTraitId, Interner, ParamKind, TraitEnvironment, TyDefId, TyLoweringDiagnostic,
- TyLoweringDiagnosticKind,
+ TyLoweringDiagnosticKind, ValueTyDefId,
consteval::{intern_const_ref, path_to_const, unknown_const_as_generic},
db::HirDatabase,
generics::{Generics, generics, trait_self_param_idx},
@@ -69,8 +68,8 @@ use crate::{
next_solver::{
AdtDef, AliasTy, Binder, BoundExistentialPredicates, BoundRegionKind, BoundTyKind,
BoundVarKind, BoundVarKinds, Clause, Clauses, Const, DbInterner, EarlyBinder,
- EarlyParamRegion, ErrorGuaranteed, GenericArgs, ParamEnv, PolyFnSig, Predicate, Region,
- SolverDefId, TraitPredicate, TraitRef, Ty, Tys,
+ EarlyParamRegion, ErrorGuaranteed, GenericArgs, ParamConst, ParamEnv, PolyFnSig, Predicate,
+ Region, SolverDefId, TraitPredicate, TraitRef, Ty, Tys,
abi::Safety,
mapping::{ChalkToNextSolver, convert_ty_for_result},
},
@@ -187,8 +186,9 @@ pub struct TyLoweringContext<'db, 'a> {
pub(crate) unsized_types: FxHashSet<Ty<'db>>,
pub(crate) diagnostics: Vec<TyLoweringDiagnostic>,
lifetime_elision: LifetimeElisionKind<'db>,
- /// We disallow referencing generic parameters that have an index greater than or equal to this number.
- disallow_params_after: u32,
+ /// When lowering the defaults for generic params, this contains the index of the currently lowered param.
+ /// We disallow referring to later params, or to ADT's `Self`.
+ lowering_param_default: Option<u32>,
}
impl<'db, 'a> TyLoweringContext<'db, 'a> {
@@ -213,7 +213,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
unsized_types: FxHashSet::default(),
diagnostics: Vec::new(),
lifetime_elision,
- disallow_params_after: u32::MAX,
+ lowering_param_default: None,
}
}
@@ -249,8 +249,8 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
self
}
- pub(crate) fn disallow_params_after(&mut self, after: u32) {
- self.disallow_params_after = after;
+ pub(crate) fn lowering_param_default(&mut self, index: u32) {
+ self.lowering_param_default = Some(index);
}
pub(crate) fn push_diagnostic(&mut self, type_ref: TypeRefId, kind: TyLoweringDiagnosticKind) {
@@ -333,8 +333,13 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
self.generics.get_or_init(|| generics(self.db, self.def))
}
+ fn param_index_is_disallowed(&self, index: u32) -> bool {
+ self.lowering_param_default
+ .is_some_and(|disallow_params_after| index >= disallow_params_after)
+ }
+
fn type_param(&mut self, id: TypeParamId, index: u32, name: Symbol) -> Ty<'db> {
- if index >= self.disallow_params_after {
+ if self.param_index_is_disallowed(index) {
// FIXME: Report an error.
Ty::new_error(self.interner, ErrorGuaranteed)
} else {
@@ -343,7 +348,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
}
fn const_param(&mut self, id: ConstParamId, index: u32) -> Const<'db> {
- if index >= self.disallow_params_after {
+ if self.param_index_is_disallowed(index) {
// FIXME: Report an error.
Const::error(self.interner)
} else {
@@ -352,7 +357,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
}
fn region_param(&mut self, id: LifetimeParamId, index: u32) -> Region<'db> {
- if index >= self.disallow_params_after {
+ if self.param_index_is_disallowed(index) {
// FIXME: Report an error.
Region::error(self.interner)
} else {
@@ -394,7 +399,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
type_data
.name
.as_ref()
- .map_or_else(|| sym::MISSING_NAME.clone(), |d| d.symbol().clone()),
+ .map_or_else(|| sym::MISSING_NAME, |d| d.symbol().clone()),
)
}
&TypeRef::RawPtr(inner, mutability) => {
@@ -1603,8 +1608,6 @@ where
for pred in maybe_parent_generics.where_predicates() {
tracing::debug!(?pred);
if filter(maybe_parent_generics.def()) {
- // We deliberately use `generics` and not `maybe_parent_generics` here. This is not a mistake!
- // If we use the parent generics
predicates.extend(ctx.lower_where_predicate(
pred,
false,
@@ -1619,49 +1622,53 @@ where
let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate());
if let Some(sized_trait) = sized_trait {
- let (mut generics, mut def_id) =
- (crate::next_solver::generics::generics(db, def.into()), def);
- loop {
- if filter(def_id) {
- let self_idx = trait_self_param_idx(db, def_id);
- for (idx, p) in generics.own_params.iter().enumerate() {
- if let Some(self_idx) = self_idx
- && p.index() as usize == self_idx
- {
- continue;
- }
- let GenericParamId::TypeParamId(param_id) = p.id else {
- continue;
- };
- let idx = idx as u32 + generics.parent_count as u32;
- let param_ty = Ty::new_param(interner, param_id, idx, p.name.clone());
- if explicitly_unsized_tys.contains(&param_ty) {
- continue;
- }
- let trait_ref = TraitRef::new_from_args(
- interner,
- sized_trait.into(),
- GenericArgs::new_from_iter(interner, [param_ty.into()]),
- );
- let clause = Clause(Predicate::new(
- interner,
- Binder::dummy(rustc_type_ir::PredicateKind::Clause(
- rustc_type_ir::ClauseKind::Trait(TraitPredicate {
- trait_ref,
- polarity: rustc_type_ir::PredicatePolarity::Positive,
- }),
- )),
- ));
- predicates.push(clause);
- }
+ let mut add_sized_clause = |param_idx, param_id, param_data| {
+ let (
+ GenericParamId::TypeParamId(param_id),
+ GenericParamDataRef::TypeParamData(param_data),
+ ) = (param_id, param_data)
+ else {
+ return;
+ };
+
+ if param_data.provenance == TypeParamProvenance::TraitSelf {
+ return;
}
- if let Some(g) = generics.parent {
- generics = crate::next_solver::generics::generics(db, g.into());
- def_id = g;
- } else {
- break;
+ let param_name = param_data
+ .name
+ .as_ref()
+ .map_or_else(|| sym::MISSING_NAME, |name| name.symbol().clone());
+ let param_ty = Ty::new_param(interner, param_id, param_idx, param_name);
+ if explicitly_unsized_tys.contains(&param_ty) {
+ return;
}
+ let trait_ref = TraitRef::new_from_args(
+ interner,
+ sized_trait.into(),
+ GenericArgs::new_from_iter(interner, [param_ty.into()]),
+ );
+ let clause = Clause(Predicate::new(
+ interner,
+ Binder::dummy(rustc_type_ir::PredicateKind::Clause(
+ rustc_type_ir::ClauseKind::Trait(TraitPredicate {
+ trait_ref,
+ polarity: rustc_type_ir::PredicatePolarity::Positive,
+ }),
+ )),
+ ));
+ predicates.push(clause);
+ };
+ if generics.parent_generics().is_some_and(|parent| filter(parent.def())) {
+ generics.iter_parent().enumerate().for_each(|(param_idx, (param_id, param_data))| {
+ add_sized_clause(param_idx as u32, param_id, param_data);
+ });
+ }
+ if filter(def) {
+ let parent_params_len = generics.len_parent();
+ generics.iter_self().enumerate().for_each(|(param_idx, (param_id, param_data))| {
+ add_sized_clause((param_idx + parent_params_len) as u32, param_id, param_data);
+ });
}
}
@@ -1860,10 +1867,7 @@ pub(crate) fn generic_defaults_with_diagnostics_query(
p: GenericParamDataRef<'_>,
generic_params: &Generics,
) -> (Option<EarlyBinder<'db, crate::next_solver::GenericArg<'db>>>, bool) {
- // Each default can only refer to previous parameters.
- // Type variable default referring to parameter coming
- // after it is forbidden.
- ctx.disallow_params_after(idx as u32);
+ ctx.lowering_param_default(idx as u32);
match p {
GenericParamDataRef::TypeParamData(p) => {
let ty = p.default.map(|ty| ctx.lower_ty(ty));