diff --git a/crates/hir-def/src/generics.rs b/crates/hir-def/src/generics.rs index f54f084ec3feb..0b2e78bdcfbed 100644 --- a/crates/hir-def/src/generics.rs +++ b/crates/hir-def/src/generics.rs @@ -146,6 +146,15 @@ impl GenericParams { ) -> Interned { let _p = profile::span("generic_params_query"); + macro_rules! id_to_generics { + ($id:ident) => {{ + let id = $id.lookup(db).id; + let tree = id.item_tree(db); + let item = &tree[id.value]; + item.generic_params.clone() + }}; + } + match def { GenericDefId::FunctionId(id) => { let loc = id.lookup(db); @@ -166,42 +175,12 @@ impl GenericParams { Interned::new(generic_params) } - GenericDefId::AdtId(AdtId::StructId(id)) => { - let id = id.lookup(db).id; - let tree = id.item_tree(db); - let item = &tree[id.value]; - item.generic_params.clone() - } - GenericDefId::AdtId(AdtId::EnumId(id)) => { - let id = id.lookup(db).id; - let tree = id.item_tree(db); - let item = &tree[id.value]; - item.generic_params.clone() - } - GenericDefId::AdtId(AdtId::UnionId(id)) => { - let id = id.lookup(db).id; - let tree = id.item_tree(db); - let item = &tree[id.value]; - item.generic_params.clone() - } - GenericDefId::TraitId(id) => { - let id = id.lookup(db).id; - let tree = id.item_tree(db); - let item = &tree[id.value]; - item.generic_params.clone() - } - GenericDefId::TypeAliasId(id) => { - let id = id.lookup(db).id; - let tree = id.item_tree(db); - let item = &tree[id.value]; - item.generic_params.clone() - } - GenericDefId::ImplId(id) => { - let id = id.lookup(db).id; - let tree = id.item_tree(db); - let item = &tree[id.value]; - item.generic_params.clone() - } + GenericDefId::AdtId(AdtId::StructId(id)) => id_to_generics!(id), + GenericDefId::AdtId(AdtId::EnumId(id)) => id_to_generics!(id), + GenericDefId::AdtId(AdtId::UnionId(id)) => id_to_generics!(id), + GenericDefId::TraitId(id) => id_to_generics!(id), + GenericDefId::TypeAliasId(id) => id_to_generics!(id), + GenericDefId::ImplId(id) => id_to_generics!(id), GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => { Interned::new(GenericParams::default()) } @@ -393,15 +372,14 @@ impl GenericParams { pub fn find_trait_self_param(&self) -> Option { self.type_or_consts.iter().find_map(|(id, p)| { - if let TypeOrConstParamData::TypeParamData(p) = p { - if p.provenance == TypeParamProvenance::TraitSelf { - Some(id) - } else { - None - } - } else { - None - } + matches!( + p, + TypeOrConstParamData::TypeParamData(TypeParamData { + provenance: TypeParamProvenance::TraitSelf, + .. + }) + ) + .then(|| id) }) } } diff --git a/crates/hir-def/src/path.rs b/crates/hir-def/src/path.rs index 37c09a0984578..3aade788d7e87 100644 --- a/crates/hir-def/src/path.rs +++ b/crates/hir-def/src/path.rs @@ -11,7 +11,7 @@ use crate::{ intern::Interned, type_ref::{ConstScalarOrPath, LifetimeRef}, }; -use hir_expand::name::{name, Name}; +use hir_expand::name::Name; use syntax::ast; use crate::type_ref::{TypeBound, TypeRef}; @@ -134,9 +134,7 @@ impl Path { } pub fn is_self_type(&self) -> bool { - self.type_anchor.is_none() - && *self.generic_args == [None] - && self.mod_path.as_ident() == Some(&name!(Self)) + self.type_anchor.is_none() && *self.generic_args == [None] && self.mod_path.is_Self() } } diff --git a/crates/hir-def/src/type_ref.rs b/crates/hir-def/src/type_ref.rs index 8e9336a0cc49f..6b16a0c876f8e 100644 --- a/crates/hir-def/src/type_ref.rs +++ b/crates/hir-def/src/type_ref.rs @@ -109,7 +109,6 @@ pub enum TypeRef { Slice(Box), /// A fn pointer. Last element of the vector is the return type. Fn(Vec<(Option, TypeRef)>, bool /*varargs*/), - // For ImplTrait(Vec>), DynTrait(Vec>), Macro(AstId), diff --git a/crates/hir-expand/src/mod_path.rs b/crates/hir-expand/src/mod_path.rs index bb2f6350c677d..d38e4a52a8cb4 100644 --- a/crates/hir-expand/src/mod_path.rs +++ b/crates/hir-expand/src/mod_path.rs @@ -80,6 +80,12 @@ impl ModPath { self.kind == PathKind::Super(0) && self.segments.is_empty() } + #[allow(non_snake_case)] + pub fn is_Self(&self) -> bool { + self.kind == PathKind::Plain + && matches!(&*self.segments, [name] if *name == known::SELF_TYPE) + } + /// If this path is a single identifier, like `foo`, return its name. pub fn as_ident(&self) -> Option<&Name> { if self.kind != PathKind::Plain { diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index f64027c218379..adee8cf958fb5 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -5,31 +5,33 @@ //! - Building the type for an item: This happens through the `type_for_def` query. //! //! This usually involves resolving names, collecting generic arguments etc. -use std::cell::{Cell, RefCell}; -use std::{iter, sync::Arc}; +use std::{ + cell::{Cell, RefCell}, + iter, + sync::Arc, +}; use base_db::CrateId; -use chalk_ir::fold::Fold; -use chalk_ir::interner::HasInterner; -use chalk_ir::{cast::Cast, fold::Shift, Mutability, Safety}; -use hir_def::generics::TypeOrConstParamData; -use hir_def::intern::Interned; -use hir_def::lang_item::lang_attr; -use hir_def::path::{ModPath, PathKind}; -use hir_def::type_ref::ConstScalarOrPath; +use chalk_ir::{cast::Cast, fold::Fold, fold::Shift, interner::HasInterner, Mutability, Safety}; + use hir_def::{ adt::StructKind, body::{Expander, LowerCtx}, builtin_type::BuiltinType, - generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, - path::{GenericArg, Path, PathSegment, PathSegments}, + generics::{ + TypeOrConstParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget, + }, + intern::Interned, + lang_item::lang_attr, + path::{GenericArg, ModPath, Path, PathKind, PathSegment, PathSegments}, resolver::{HasResolver, Resolver, TypeNs}, - type_ref::{TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef}, - AdtId, AssocItemId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, - ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, - UnionId, VariantId, + type_ref::{ + ConstScalarOrPath, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef, + }, + AdtId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId, + HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TraitId, + TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId, }; -use hir_def::{ConstParamId, TypeOrConstParamId, TypeParamId}; use hir_expand::{name::Name, ExpandResult}; use itertools::Either; use la_arena::ArenaMap; @@ -38,20 +40,19 @@ use smallvec::SmallVec; use stdx::{impl_from, never}; use syntax::{ast, SmolStr}; -use crate::consteval::{ - intern_scalar_const, path_to_const, unknown_const, unknown_const_as_generic, -}; -use crate::utils::Generics; -use crate::{all_super_traits, make_binders, Const, GenericArgData, ParamKind}; use crate::{ + all_super_traits, + consteval::{intern_scalar_const, path_to_const, unknown_const, unknown_const_as_generic}, db::HirDatabase, + make_binders, mapping::ToChalk, static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx, + utils::Generics, utils::{all_super_trait_refs, associated_type_by_name_including_super_traits, generics}, - AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, - FnSubst, ImplTraitId, Interner, PolyFnSig, ProjectionTy, QuantifiedWhereClause, - QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, - TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause, + AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, DebruijnIndex, DynTy, FnPointer, + FnSig, FnSubst, GenericArgData, ImplTraitId, Interner, ParamKind, PolyFnSig, ProjectionTy, + QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, + Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause, }; #[derive(Debug)] diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs index e608f85774108..2e1447936888d 100644 --- a/crates/hir-ty/src/utils.rs +++ b/crates/hir-ty/src/utils.rs @@ -12,13 +12,12 @@ use hir_def::{ WherePredicateTypeTarget, }, intern::Interned, - path::Path, resolver::{HasResolver, TypeNs}, type_ref::{TraitBoundModifier, TypeRef}, ConstParamId, FunctionId, GenericDefId, ItemContainerId, Lookup, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, }; -use hir_expand::name::{known, name, Name}; +use hir_expand::name::{known, Name}; use itertools::Either; use rustc_hash::FxHashSet; use smallvec::{smallvec, SmallVec}; @@ -53,25 +52,25 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> SmallVec<[Trait .iter() .filter_map(|pred| match pred { WherePredicate::ForLifetime { target, bound, .. } - | WherePredicate::TypeBound { target, bound } => match target { - WherePredicateTypeTarget::TypeRef(type_ref) => match &**type_ref { - TypeRef::Path(p) if p == &Path::from(name![Self]) => bound.as_path(), - _ => None, - }, - WherePredicateTypeTarget::TypeOrConstParam(local_id) - if Some(*local_id) == trait_self => - { - bound.as_path() + | WherePredicate::TypeBound { target, bound } => { + let is_trait = match target { + WherePredicateTypeTarget::TypeRef(type_ref) => match &**type_ref { + TypeRef::Path(p) => p.is_self_type(), + _ => false, + }, + WherePredicateTypeTarget::TypeOrConstParam(local_id) => { + Some(*local_id) == trait_self + } + }; + match is_trait { + true => bound.as_path(), + false => None, } - _ => None, - }, + } WherePredicate::Lifetime { .. } => None, }) - .filter_map(|(path, bound_modifier)| match bound_modifier { - TraitBoundModifier::None => Some(path), - TraitBoundModifier::Maybe => None, - }) - .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) { + .filter(|(_, bound_modifier)| matches!(bound_modifier, TraitBoundModifier::None)) + .filter_map(|(path, _)| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) { Some(TypeNs::TraitId(t)) => Some(t), _ => None, })