Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #20087 from Veykril/push-rrtkwpzmmwwz
Short circuit a couple hir-ty/lower queries
Lukas Wirth 10 months ago
parent 70cbf83 · parent c43e7c7 · commit c68c8a8
-rw-r--r--crates/hir-def/src/hir/generics.rs6
-rw-r--r--crates/hir-ty/src/display.rs1
-rw-r--r--crates/hir-ty/src/generics.rs11
-rw-r--r--crates/hir-ty/src/lower.rs23
-rw-r--r--crates/hir-ty/src/tests/incremental.rs3
-rw-r--r--crates/hir-ty/src/utils.rs5
-rw-r--r--crates/hir/src/display.rs4
-rw-r--r--crates/hir/src/lib.rs2
8 files changed, 40 insertions, 15 deletions
diff --git a/crates/hir-def/src/hir/generics.rs b/crates/hir-def/src/hir/generics.rs
index a9a0e36312..94e683cb0f 100644
--- a/crates/hir-def/src/hir/generics.rs
+++ b/crates/hir-def/src/hir/generics.rs
@@ -331,13 +331,13 @@ impl GenericParams {
}
#[inline]
- pub fn no_predicates(&self) -> bool {
+ pub fn has_no_predicates(&self) -> bool {
self.where_predicates.is_empty()
}
#[inline]
- pub fn where_predicates(&self) -> std::slice::Iter<'_, WherePredicate> {
- self.where_predicates.iter()
+ pub fn where_predicates(&self) -> &[WherePredicate] {
+ &self.where_predicates
}
/// Iterator of type_or_consts field
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 1aa7e0fcf8..e3dd74534c 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -2178,6 +2178,7 @@ impl HirDisplayWithExpressionStore for TypeRefId {
f.write_joined(
generic_params
.where_predicates()
+ .iter()
.filter_map(|it| match it {
WherePredicate::TypeBound { target, bound }
| WherePredicate::ForLifetime { lifetimes: _, target, bound }
diff --git a/crates/hir-ty/src/generics.rs b/crates/hir-ty/src/generics.rs
index a3ed39934c..f14872e68c 100644
--- a/crates/hir-ty/src/generics.rs
+++ b/crates/hir-ty/src/generics.rs
@@ -60,7 +60,16 @@ impl Generics {
}
pub(crate) fn where_predicates(&self) -> impl Iterator<Item = &WherePredicate> {
- self.params.where_predicates()
+ self.params.where_predicates().iter()
+ }
+
+ pub(crate) fn has_no_predicates(&self) -> bool {
+ self.params.has_no_predicates()
+ && self.parent_generics.as_ref().is_none_or(|g| g.params.has_no_predicates())
+ }
+
+ pub(crate) fn is_empty(&self) -> bool {
+ self.params.is_empty() && self.parent_generics.as_ref().is_none_or(|g| g.params.is_empty())
}
pub(crate) fn iter_id(&self) -> impl Iterator<Item = GenericParamId> + '_ {
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 3134793054..40adfca7fc 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -884,6 +884,11 @@ pub(crate) fn field_types_with_diagnostics_query(
variant_id: VariantId,
) -> (Arc<ArenaMap<LocalFieldId, Binders<Ty>>>, Diagnostics) {
let var_data = db.variant_fields(variant_id);
+ let fields = var_data.fields();
+ if fields.is_empty() {
+ return (Arc::new(ArenaMap::default()), None);
+ }
+
let (resolver, def): (_, GenericDefId) = match variant_id {
VariantId::StructId(it) => (it.resolver(db), it.into()),
VariantId::UnionId(it) => (it.resolver(db), it.into()),
@@ -899,7 +904,7 @@ pub(crate) fn field_types_with_diagnostics_query(
LifetimeElisionKind::AnonymousReportError,
)
.with_type_param_mode(ParamLoweringMode::Variable);
- for (field_id, field_data) in var_data.fields().iter() {
+ for (field_id, field_data) in fields.iter() {
res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(field_data.type_ref)));
}
(Arc::new(res), create_diagnostics(ctx.diagnostics))
@@ -920,6 +925,10 @@ pub(crate) fn generic_predicates_for_param_query(
assoc_name: Option<Name>,
) -> GenericPredicates {
let generics = generics(db, def);
+ if generics.has_no_predicates() && generics.is_empty() {
+ return GenericPredicates(None);
+ }
+
let resolver = def.resolver(db);
let mut ctx = TyLoweringContext::new(
db,
@@ -1025,6 +1034,10 @@ pub(crate) fn trait_environment_query(
def: GenericDefId,
) -> Arc<TraitEnvironment> {
let generics = generics(db, def);
+ if generics.has_no_predicates() && generics.is_empty() {
+ return TraitEnvironment::empty(def.krate(db));
+ }
+
let resolver = def.resolver(db);
let mut ctx = TyLoweringContext::new(
db,
@@ -1128,6 +1141,10 @@ where
F: Fn(&WherePredicate, GenericDefId) -> bool,
{
let generics = generics(db, def);
+ if generics.has_no_predicates() && generics.is_empty() {
+ return (GenericPredicates(None), None);
+ }
+
let resolver = def.resolver(db);
let mut ctx = TyLoweringContext::new(
db,
@@ -1154,7 +1171,7 @@ where
}
}
- if generics.len() > 0 {
+ if !generics.is_empty() {
let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
let explicitly_unsized_tys = ctx.unsized_types;
if let Some(implicitly_sized_predicates) =
@@ -1229,7 +1246,7 @@ pub(crate) fn generic_defaults_with_diagnostics_query(
def: GenericDefId,
) -> (GenericDefaults, Diagnostics) {
let generic_params = generics(db, def);
- if generic_params.len() == 0 {
+ if generic_params.is_empty() {
return (GenericDefaults(None), None);
}
let resolver = def.resolver(db);
diff --git a/crates/hir-ty/src/tests/incremental.rs b/crates/hir-ty/src/tests/incremental.rs
index 905fd8a3bc..692397a5a6 100644
--- a/crates/hir-ty/src/tests/incremental.rs
+++ b/crates/hir-ty/src/tests/incremental.rs
@@ -695,10 +695,8 @@ fn main() {
"return_type_impl_traits_shim",
"infer_shim",
"function_signature_with_source_map_shim",
- "trait_environment_shim",
"expr_scopes_shim",
"struct_signature_with_source_map_shim",
- "generic_predicates_shim",
"variant_fields_with_source_map_shim",
"inherent_impls_in_crate_shim",
"impl_signature_with_source_map_shim",
@@ -709,7 +707,6 @@ fn main() {
"impl_trait_with_diagnostics_shim",
"impl_self_ty_with_diagnostics_shim",
"generic_predicates_shim",
- "generic_predicates_shim",
]
"#]],
);
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs
index 4c8e635eff..d655320310 100644
--- a/crates/hir-ty/src/utils.rs
+++ b/crates/hir-ty/src/utils.rs
@@ -1,7 +1,7 @@
//! Helper functions for working with def, which don't need to be a separate
//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
-use std::iter;
+use std::{cell::LazyCell, iter};
use base_db::Crate;
use chalk_ir::{
@@ -161,11 +161,12 @@ impl Iterator for ClauseElaborator<'_> {
}
fn direct_super_traits_cb(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(TraitId)) {
- let resolver = trait_.resolver(db);
+ let resolver = LazyCell::new(|| trait_.resolver(db));
let (generic_params, store) = db.generic_params_and_store(trait_.into());
let trait_self = generic_params.trait_self_param();
generic_params
.where_predicates()
+ .iter()
.filter_map(|pred| match pred {
WherePredicate::ForLifetime { target, bound, .. }
| WherePredicate::TypeBound { target, bound } => {
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index 112558bdd0..18bab7cbf9 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -633,7 +633,7 @@ fn has_disaplayable_predicates(
params: &GenericParams,
store: &ExpressionStore,
) -> bool {
- params.where_predicates().any(|pred| {
+ params.where_predicates().iter().any(|pred| {
!matches!(
pred,
WherePredicate::TypeBound { target, .. }
@@ -668,7 +668,7 @@ fn write_where_predicates(
_ => false,
};
- let mut iter = params.where_predicates().peekable();
+ let mut iter = params.where_predicates().iter().peekable();
while let Some(pred) = iter.next() {
if matches!(pred, TypeBound { target, .. } if is_unnamed_type_target(*target)) {
continue;
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 46d2e88160..6d9f0f3a3e 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -3667,7 +3667,7 @@ impl GenericDef {
let generics = db.generic_params(def);
- if generics.is_empty() && generics.no_predicates() {
+ if generics.is_empty() && generics.has_no_predicates() {
return;
}