mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Lazy generics
This commit is contained in:
parent
c01f4cf902
commit
7a16e06009
4 changed files with 26 additions and 11 deletions
|
@ -71,12 +71,12 @@ impl From<MirEvalError> for ConstEvalError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn path_to_const(
|
pub(crate) fn path_to_const<'g>(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
resolver: &Resolver,
|
resolver: &Resolver,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
mode: ParamLoweringMode,
|
mode: ParamLoweringMode,
|
||||||
args: impl FnOnce() -> Option<Generics>,
|
args: impl FnOnce() -> Option<&'g Generics>,
|
||||||
debruijn: DebruijnIndex,
|
debruijn: DebruijnIndex,
|
||||||
expected_ty: Ty,
|
expected_ty: Ty,
|
||||||
) -> Option<Const> {
|
) -> Option<Const> {
|
||||||
|
@ -89,7 +89,7 @@ pub(crate) fn path_to_const(
|
||||||
}
|
}
|
||||||
ParamLoweringMode::Variable => {
|
ParamLoweringMode::Variable => {
|
||||||
let args = args();
|
let args = args();
|
||||||
match args.as_ref().and_then(|args| args.type_or_const_param_idx(p.into())) {
|
match args.and_then(|args| args.type_or_const_param_idx(p.into())) {
|
||||||
Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
|
Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
|
||||||
None => {
|
None => {
|
||||||
never!(
|
never!(
|
||||||
|
|
|
@ -49,6 +49,7 @@ use hir_def::{
|
||||||
use hir_expand::name::{name, Name};
|
use hir_expand::name::{name, Name};
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use la_arena::{ArenaMap, Entry};
|
use la_arena::{ArenaMap, Entry};
|
||||||
|
use once_cell::unsync::OnceCell;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use stdx::{always, never};
|
use stdx::{always, never};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
@ -527,6 +528,7 @@ pub(crate) struct InferenceContext<'a> {
|
||||||
pub(crate) owner: DefWithBodyId,
|
pub(crate) owner: DefWithBodyId,
|
||||||
pub(crate) body: &'a Body,
|
pub(crate) body: &'a Body,
|
||||||
pub(crate) resolver: Resolver,
|
pub(crate) resolver: Resolver,
|
||||||
|
generics: OnceCell<Option<Generics>>,
|
||||||
table: unify::InferenceTable<'a>,
|
table: unify::InferenceTable<'a>,
|
||||||
/// The traits in scope, disregarding block modules. This is used for caching purposes.
|
/// The traits in scope, disregarding block modules. This is used for caching purposes.
|
||||||
traits_in_scope: FxHashSet<TraitId>,
|
traits_in_scope: FxHashSet<TraitId>,
|
||||||
|
@ -612,6 +614,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let trait_env = db.trait_environment_for_body(owner);
|
let trait_env = db.trait_environment_for_body(owner);
|
||||||
InferenceContext {
|
InferenceContext {
|
||||||
|
generics: OnceCell::new(),
|
||||||
result: InferenceResult::default(),
|
result: InferenceResult::default(),
|
||||||
table: unify::InferenceTable::new(db, trait_env),
|
table: unify::InferenceTable::new(db, trait_env),
|
||||||
tuple_field_accesses_rev: Default::default(),
|
tuple_field_accesses_rev: Default::default(),
|
||||||
|
@ -633,8 +636,14 @@ impl<'a> InferenceContext<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn generics(&self) -> Option<Generics> {
|
pub(crate) fn generics(&self) -> Option<&Generics> {
|
||||||
Some(crate::generics::generics(self.db.upcast(), self.resolver.generic_def()?))
|
self.generics
|
||||||
|
.get_or_init(|| {
|
||||||
|
self.resolver
|
||||||
|
.generic_def()
|
||||||
|
.map(|def| crate::generics::generics(self.db.upcast(), def))
|
||||||
|
})
|
||||||
|
.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: This function should be private in module. It is currently only used in the consteval, since we need
|
// FIXME: This function should be private in module. It is currently only used in the consteval, since we need
|
||||||
|
|
|
@ -339,7 +339,7 @@ impl CapturedItemWithoutTy {
|
||||||
fn replace_placeholder_with_binder(ctx: &mut InferenceContext<'_>, ty: Ty) -> Binders<Ty> {
|
fn replace_placeholder_with_binder(ctx: &mut InferenceContext<'_>, ty: Ty) -> Binders<Ty> {
|
||||||
struct Filler<'a> {
|
struct Filler<'a> {
|
||||||
db: &'a dyn HirDatabase,
|
db: &'a dyn HirDatabase,
|
||||||
generics: Generics,
|
generics: &'a Generics,
|
||||||
}
|
}
|
||||||
impl FallibleTypeFolder<Interner> for Filler<'_> {
|
impl FallibleTypeFolder<Interner> for Filler<'_> {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
@ -382,7 +382,7 @@ impl CapturedItemWithoutTy {
|
||||||
};
|
};
|
||||||
let filler = &mut Filler { db: ctx.db, generics };
|
let filler = &mut Filler { db: ctx.db, generics };
|
||||||
let result = ty.clone().try_fold_with(filler, DebruijnIndex::INNERMOST).unwrap_or(ty);
|
let result = ty.clone().try_fold_with(filler, DebruijnIndex::INNERMOST).unwrap_or(ty);
|
||||||
make_binders(ctx.db, &filler.generics, result)
|
make_binders(ctx.db, filler.generics, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ use hir_def::{
|
||||||
use hir_expand::{name::Name, ExpandResult};
|
use hir_expand::{name::Name, ExpandResult};
|
||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
use la_arena::{Arena, ArenaMap};
|
use la_arena::{Arena, ArenaMap};
|
||||||
|
use once_cell::unsync::OnceCell;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use stdx::{impl_from, never};
|
use stdx::{impl_from, never};
|
||||||
|
@ -122,6 +123,7 @@ impl ImplTraitLoweringState {
|
||||||
pub struct TyLoweringContext<'a> {
|
pub struct TyLoweringContext<'a> {
|
||||||
pub db: &'a dyn HirDatabase,
|
pub db: &'a dyn HirDatabase,
|
||||||
resolver: &'a Resolver,
|
resolver: &'a Resolver,
|
||||||
|
generics: OnceCell<Option<Generics>>,
|
||||||
in_binders: DebruijnIndex,
|
in_binders: DebruijnIndex,
|
||||||
// FIXME: Should not be an `Option` but `Resolver` currently does not return owners in all cases
|
// FIXME: Should not be an `Option` but `Resolver` currently does not return owners in all cases
|
||||||
// where expected
|
// where expected
|
||||||
|
@ -153,6 +155,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
Self {
|
Self {
|
||||||
db,
|
db,
|
||||||
resolver,
|
resolver,
|
||||||
|
generics: OnceCell::new(),
|
||||||
owner,
|
owner,
|
||||||
in_binders,
|
in_binders,
|
||||||
impl_trait_mode,
|
impl_trait_mode,
|
||||||
|
@ -175,6 +178,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
impl_trait_mode,
|
impl_trait_mode,
|
||||||
expander: RefCell::new(expander),
|
expander: RefCell::new(expander),
|
||||||
unsized_types: RefCell::new(unsized_types),
|
unsized_types: RefCell::new(unsized_types),
|
||||||
|
generics: self.generics.clone(),
|
||||||
..*self
|
..*self
|
||||||
};
|
};
|
||||||
let result = f(&new_ctx);
|
let result = f(&new_ctx);
|
||||||
|
@ -246,8 +250,10 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generics(&self) -> Option<Generics> {
|
fn generics(&self) -> Option<&Generics> {
|
||||||
Some(generics(self.db.upcast(), self.resolver.generic_def()?))
|
self.generics
|
||||||
|
.get_or_init(|| self.resolver.generic_def().map(|def| generics(self.db.upcast(), def)))
|
||||||
|
.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
|
pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
|
||||||
|
@ -2207,14 +2213,14 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn const_or_path_to_chalk(
|
pub(crate) fn const_or_path_to_chalk<'g>(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
resolver: &Resolver,
|
resolver: &Resolver,
|
||||||
owner: TypeOwnerId,
|
owner: TypeOwnerId,
|
||||||
expected_ty: Ty,
|
expected_ty: Ty,
|
||||||
value: &ConstRef,
|
value: &ConstRef,
|
||||||
mode: ParamLoweringMode,
|
mode: ParamLoweringMode,
|
||||||
args: impl FnOnce() -> Option<Generics>,
|
args: impl FnOnce() -> Option<&'g Generics>,
|
||||||
debruijn: DebruijnIndex,
|
debruijn: DebruijnIndex,
|
||||||
) -> Const {
|
) -> Const {
|
||||||
match value {
|
match value {
|
||||||
|
|
Loading…
Reference in a new issue