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