mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 06:03:58 +00:00
Save allocations for empty generic_defaults query results
This commit is contained in:
parent
2761b1e236
commit
34ba8db3ed
3 changed files with 67 additions and 60 deletions
|
@ -21,12 +21,12 @@ use crate::{
|
||||||
chalk_db,
|
chalk_db,
|
||||||
consteval::ConstEvalError,
|
consteval::ConstEvalError,
|
||||||
layout::{Layout, LayoutError},
|
layout::{Layout, LayoutError},
|
||||||
lower::GenericPredicates,
|
lower::{GenericDefaults, GenericPredicates},
|
||||||
method_resolution::{InherentImpls, TraitImpls, TyFingerprint},
|
method_resolution::{InherentImpls, TraitImpls, TyFingerprint},
|
||||||
mir::{BorrowckResult, MirBody, MirLowerError},
|
mir::{BorrowckResult, MirBody, MirLowerError},
|
||||||
Binders, CallableDefId, ClosureId, Const, FnDefId, GenericArg, ImplTraitId, ImplTraits,
|
Binders, CallableDefId, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult,
|
||||||
InferenceResult, Interner, PolyFnSig, QuantifiedWhereClause, Substitution, TraitEnvironment,
|
Interner, PolyFnSig, QuantifiedWhereClause, Substitution, TraitEnvironment, TraitRef, Ty,
|
||||||
TraitRef, Ty, TyDefId, ValueTyDefId,
|
TyDefId, ValueTyDefId,
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
|
||||||
|
|
||||||
#[salsa::invoke(crate::lower::generic_defaults_query)]
|
#[salsa::invoke(crate::lower::generic_defaults_query)]
|
||||||
#[salsa::cycle(crate::lower::generic_defaults_recover)]
|
#[salsa::cycle(crate::lower::generic_defaults_recover)]
|
||||||
fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<GenericArg>]>;
|
fn generic_defaults(&self, def: GenericDefId) -> GenericDefaults;
|
||||||
|
|
||||||
#[salsa::invoke(InherentImpls::inherent_impls_in_crate_query)]
|
#[salsa::invoke(InherentImpls::inherent_impls_in_crate_query)]
|
||||||
fn inherent_impls_in_crate(&self, krate: CrateId) -> Arc<InherentImpls>;
|
fn inherent_impls_in_crate(&self, krate: CrateId) -> Arc<InherentImpls>;
|
||||||
|
|
|
@ -330,18 +330,15 @@ pub(crate) fn make_single_type_binders<T: HasInterner<Interner = Interner>>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn make_binders_with_count<T: HasInterner<Interner = Interner>>(
|
pub(crate) fn make_binders<T: HasInterner<Interner = Interner>>(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
count: usize,
|
|
||||||
generics: &Generics,
|
generics: &Generics,
|
||||||
value: T,
|
value: T,
|
||||||
) -> Binders<T> {
|
) -> Binders<T> {
|
||||||
let it = generics.iter_id().take(count);
|
|
||||||
|
|
||||||
Binders::new(
|
Binders::new(
|
||||||
VariableKinds::from_iter(
|
VariableKinds::from_iter(
|
||||||
Interner,
|
Interner,
|
||||||
it.map(|x| match x {
|
generics.iter_id().map(|x| match x {
|
||||||
hir_def::GenericParamId::ConstParamId(id) => {
|
hir_def::GenericParamId::ConstParamId(id) => {
|
||||||
chalk_ir::VariableKind::Const(db.const_param_ty(id))
|
chalk_ir::VariableKind::Const(db.const_param_ty(id))
|
||||||
}
|
}
|
||||||
|
@ -355,14 +352,6 @@ pub(crate) fn make_binders_with_count<T: HasInterner<Interner = Interner>>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn make_binders<T: HasInterner<Interner = Interner>>(
|
|
||||||
db: &dyn HirDatabase,
|
|
||||||
generics: &Generics,
|
|
||||||
value: T,
|
|
||||||
) -> Binders<T> {
|
|
||||||
make_binders_with_count(db, usize::MAX, generics, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: get rid of this, just replace it by FnPointer
|
// FIXME: get rid of this, just replace it by FnPointer
|
||||||
/// A function signature as seen by type inference: Several parameter types and
|
/// A function signature as seen by type inference: Several parameter types and
|
||||||
/// one return type.
|
/// one return type.
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
use std::{
|
use std::{
|
||||||
cell::{Cell, RefCell, RefMut},
|
cell::{Cell, RefCell, RefMut},
|
||||||
iter,
|
iter,
|
||||||
ops::Not as _,
|
ops::{self, Not as _},
|
||||||
};
|
};
|
||||||
|
|
||||||
use base_db::{
|
use base_db::{
|
||||||
|
@ -1693,9 +1693,11 @@ pub(crate) fn trait_environment_query(
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct GenericPredicates(Option<Arc<[Binders<QuantifiedWhereClause>]>>);
|
pub struct GenericPredicates(Option<Arc<[Binders<QuantifiedWhereClause>]>>);
|
||||||
|
|
||||||
impl GenericPredicates {
|
impl ops::Deref for GenericPredicates {
|
||||||
pub fn iter(&self) -> impl Iterator<Item = &Binders<QuantifiedWhereClause>> + '_ + Clone {
|
type Target = [Binders<crate::QuantifiedWhereClause>];
|
||||||
self.0.as_ref().into_iter().flat_map(Arc::as_ref)
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.0.as_deref().unwrap_or(&[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1767,68 +1769,84 @@ fn implicitly_sized_clauses<'a, 'subst: 'a>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct GenericDefaults(Option<Arc<[Binders<crate::GenericArg>]>>);
|
||||||
|
|
||||||
|
impl ops::Deref for GenericDefaults {
|
||||||
|
type Target = [Binders<crate::GenericArg>];
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.0.as_deref().unwrap_or(&[])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Resolve the default type params from generics
|
/// Resolve the default type params from generics
|
||||||
pub(crate) fn generic_defaults_query(
|
pub(crate) fn generic_defaults_query(db: &dyn HirDatabase, def: GenericDefId) -> GenericDefaults {
|
||||||
db: &dyn HirDatabase,
|
|
||||||
def: GenericDefId,
|
|
||||||
) -> Arc<[Binders<crate::GenericArg>]> {
|
|
||||||
let resolver = def.resolver(db.upcast());
|
|
||||||
let generic_params = generics(db.upcast(), def);
|
let generic_params = generics(db.upcast(), def);
|
||||||
|
if generic_params.len() == 0 {
|
||||||
|
return GenericDefaults(None);
|
||||||
|
}
|
||||||
|
let resolver = def.resolver(db.upcast());
|
||||||
let parent_start_idx = generic_params.len_self();
|
let parent_start_idx = generic_params.len_self();
|
||||||
|
|
||||||
let ctx = TyLoweringContext::new(db, &resolver, def.into())
|
let ctx = TyLoweringContext::new(db, &resolver, def.into())
|
||||||
.with_impl_trait_mode(ImplTraitLoweringMode::Disallowed)
|
.with_impl_trait_mode(ImplTraitLoweringMode::Disallowed)
|
||||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||||
Arc::from_iter(generic_params.iter().enumerate().map(|(idx, (id, p))| {
|
GenericDefaults(Some(Arc::from_iter(generic_params.iter().enumerate().map(
|
||||||
match p {
|
|(idx, (id, p))| {
|
||||||
GenericParamDataRef::TypeParamData(p) => {
|
match p {
|
||||||
let mut ty =
|
GenericParamDataRef::TypeParamData(p) => {
|
||||||
p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t));
|
let ty = p.default.as_ref().map_or(TyKind::Error.intern(Interner), |ty| {
|
||||||
// Each default can only refer to previous parameters.
|
// Each default can only refer to previous parameters.
|
||||||
// Type variable default referring to parameter coming
|
// Type variable default referring to parameter coming
|
||||||
// after it is forbidden (FIXME: report diagnostic)
|
// after it is forbidden (FIXME: report diagnostic)
|
||||||
ty = fallback_bound_vars(ty, idx, parent_start_idx);
|
fallback_bound_vars(ctx.lower_ty(ty), idx, parent_start_idx)
|
||||||
crate::make_binders(db, &generic_params, ty.cast(Interner))
|
});
|
||||||
}
|
crate::make_binders(db, &generic_params, ty.cast(Interner))
|
||||||
GenericParamDataRef::ConstParamData(p) => {
|
}
|
||||||
let GenericParamId::ConstParamId(id) = id else {
|
GenericParamDataRef::ConstParamData(p) => {
|
||||||
unreachable!("Unexpected lifetime or type argument")
|
let GenericParamId::ConstParamId(id) = id else {
|
||||||
};
|
unreachable!("Unexpected lifetime or type argument")
|
||||||
|
};
|
||||||
|
|
||||||
let mut val = p.default.as_ref().map_or_else(
|
let mut val = p.default.as_ref().map_or_else(
|
||||||
|| unknown_const_as_generic(db.const_param_ty(id)),
|
|| unknown_const_as_generic(db.const_param_ty(id)),
|
||||||
|c| {
|
|c| {
|
||||||
let c = ctx.lower_const(c, ctx.lower_ty(&p.ty));
|
let c = ctx.lower_const(c, ctx.lower_ty(&p.ty));
|
||||||
c.cast(Interner)
|
c.cast(Interner)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
// Each default can only refer to previous parameters, see above.
|
// Each default can only refer to previous parameters, see above.
|
||||||
val = fallback_bound_vars(val, idx, parent_start_idx);
|
val = fallback_bound_vars(val, idx, parent_start_idx);
|
||||||
make_binders(db, &generic_params, val)
|
make_binders(db, &generic_params, val)
|
||||||
|
}
|
||||||
|
GenericParamDataRef::LifetimeParamData(_) => {
|
||||||
|
make_binders(db, &generic_params, error_lifetime().cast(Interner))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
GenericParamDataRef::LifetimeParamData(_) => {
|
},
|
||||||
make_binders(db, &generic_params, error_lifetime().cast(Interner))
|
))))
|
||||||
}
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn generic_defaults_recover(
|
pub(crate) fn generic_defaults_recover(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
_cycle: &Cycle,
|
_cycle: &Cycle,
|
||||||
def: &GenericDefId,
|
def: &GenericDefId,
|
||||||
) -> Arc<[Binders<crate::GenericArg>]> {
|
) -> GenericDefaults {
|
||||||
let generic_params = generics(db.upcast(), *def);
|
let generic_params = generics(db.upcast(), *def);
|
||||||
|
if generic_params.len() == 0 {
|
||||||
|
return GenericDefaults(None);
|
||||||
|
}
|
||||||
// FIXME: this code is not covered in tests.
|
// FIXME: this code is not covered in tests.
|
||||||
// we still need one default per parameter
|
// we still need one default per parameter
|
||||||
Arc::from_iter(generic_params.iter_id().map(|id| {
|
GenericDefaults(Some(Arc::from_iter(generic_params.iter_id().map(|id| {
|
||||||
let val = match id {
|
let val = match id {
|
||||||
GenericParamId::TypeParamId(_) => TyKind::Error.intern(Interner).cast(Interner),
|
GenericParamId::TypeParamId(_) => TyKind::Error.intern(Interner).cast(Interner),
|
||||||
GenericParamId::ConstParamId(id) => unknown_const_as_generic(db.const_param_ty(id)),
|
GenericParamId::ConstParamId(id) => unknown_const_as_generic(db.const_param_ty(id)),
|
||||||
GenericParamId::LifetimeParamId(_) => error_lifetime().cast(Interner),
|
GenericParamId::LifetimeParamId(_) => error_lifetime().cast(Interner),
|
||||||
};
|
};
|
||||||
crate::make_binders(db, &generic_params, val)
|
crate::make_binders(db, &generic_params, val)
|
||||||
}))
|
}))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
|
fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
|
||||||
|
|
Loading…
Reference in a new issue