diff options
9 files changed, 42 insertions, 18 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/generics.rs index a9a0e36312c..94e683cb0f8 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/hir/generics.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs index 1aa7e0fcf88..e3dd74534cb 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs index a3ed39934cd..f14872e68c3 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/generics.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 3134793054e..40adfca7fc6 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs index 905fd8a3bca..692397a5a61 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/incremental.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs index 4c8e635eff9..d655320310f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs index 112558bdd04..18bab7cbf99 100644 --- a/src/tools/rust-analyzer/crates/hir/src/display.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 46d2e881600..6d9f0f3a3e3 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/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; } diff --git a/src/tools/rust-analyzer/docs/book/src/troubleshooting.md b/src/tools/rust-analyzer/docs/book/src/troubleshooting.md index 3f7caf0db4b..a357cbef415 100644 --- a/src/tools/rust-analyzer/docs/book/src/troubleshooting.md +++ b/src/tools/rust-analyzer/docs/book/src/troubleshooting.md @@ -1,8 +1,7 @@ # Troubleshooting -First, search the [troubleshooting FAQ](troubleshooting/faq.html). If -your problem appears there (and the proposed solution works for you), -great! Otherwise, read on. +First, search the [troubleshooting FAQ](faq.html). If your problem appears +there (and the proposed solution works for you), great! Otherwise, read on. Start with looking at the rust-analyzer version. Try **rust-analyzer: Show RA Version** in VS Code (using **Command Palette** feature |
