per_ns::PerNs,
resolver::{HasResolver, Resolver},
src::HasSource as _,
+ type_ref::TraitRef,
AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId,
DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId,
LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
};
use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind};
use hir_ty::{
- autoderef,
+ autoderef, could_unify,
method_resolution::{self, TyFingerprint},
primitive::UintTy,
- to_assoc_type_id,
- traits::{FnTrait, Solution, SolutionVariables},
- AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex,
- GenericPredicate, InEnvironment, Interner, Obligation, ProjectionTy, Scalar, Substitution, Ty,
- TyDefId, TyKind, TyVariableKind,
+ traits::FnTrait,
+ AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast,
+ DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Solution,
+ SolutionVariables, Substitution, TraitEnvironment, Ty, TyBuilder, TyDefId, TyKind,
+ TyVariableKind, WhereClause,
};
use itertools::Itertools;
use rustc_hash::FxHashSet;
}
pub fn transitive_reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> {
- db.crate_graph()
- .transitive_reverse_dependencies(self.id)
- .into_iter()
- .map(|id| Crate { id })
- .collect()
+ db.crate_graph().transitive_rev_deps(self.id).into_iter().map(|id| Crate { id }).collect()
}
pub fn root_module(self, db: &dyn HirDatabase) -> Module {
Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text),
_ => None
}
- }).flat_map(|t| t).next();
+ }).flatten().next();
doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/")
}
VariantDef::Union(it) => it.id.into(),
VariantDef::Variant(it) => it.parent.id.into(),
};
- let substs = Substitution::type_params(db, generic_def_id);
+ let substs = TyBuilder::type_params_subst(db, generic_def_id);
let ty = db.field_types(var_id)[self.id].clone().subst(&substs);
Type::new(db, self.parent.module(db).id.krate(), var_id, ty)
}
}
pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> {
- if !db.function_data(self.id).has_self_param {
+ if !db.function_data(self.id).has_self_param() {
return None;
}
Some(SelfParam { func: self.id })
.iter()
.enumerate()
.map(|(idx, type_ref)| {
- let ty = Type {
- krate,
- ty: InEnvironment {
- value: ctx.lower_ty(type_ref),
- environment: environment.clone(),
- },
- };
+ let ty = Type { krate, env: environment.clone(), ty: ctx.lower_ty(type_ref) };
Param { func: self, ty, idx }
})
.collect()
}
+
pub fn method_params(self, db: &dyn HirDatabase) -> Option<Vec<Param>> {
if self.self_param(db).is_none() {
return None;
}
pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
- db.function_data(self.id).qualifier.is_unsafe
+ db.function_data(self.id).is_unsafe()
}
pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
///
/// This is false in the case of required (not provided) trait methods.
pub fn has_body(self, db: &dyn HirDatabase) -> bool {
- db.function_data(self.id).has_body
+ db.function_data(self.id).has_body()
}
/// A textual representation of the HIR of this function for debugging purposes.
}
}
-#[derive(Debug)]
+#[derive(Clone, Debug)]
pub struct Param {
func: Function,
/// The index in parameter list, including self parameter.
&self.ty
}
+ pub fn as_local(&self, db: &dyn HirDatabase) -> Local {
+ let parent = DefWithBodyId::FunctionId(self.func.into());
+ let body = db.body(parent);
+ Local { parent, pat_id: body.params[self.idx] }
+ }
+
pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> {
- let params = self.func.source(db)?.value.param_list()?;
+ self.source(db).and_then(|p| p.value.pat())
+ }
+
+ pub fn source(&self, db: &dyn HirDatabase) -> Option<InFile<ast::Param>> {
+ let InFile { file_id, value } = self.func.source(db)?;
+ let params = value.param_list()?;
if params.self_param().is_some() {
- params.params().nth(self.idx.checked_sub(1)?)?.pat()
+ params.params().nth(self.idx.checked_sub(1)?)
} else {
- params.params().nth(self.idx)?.pat()
+ params.params().nth(self.idx)
}
+ .map(|value| InFile { file_id, value })
}
}
func_data
.params
.first()
- .map(|param| match *param {
+ .map(|param| match &**param {
TypeRef::Reference(.., mutability) => match mutability {
hir_def::type_ref::Mutability::Shared => Access::Shared,
hir_def::type_ref::Mutability::Mut => Access::Exclusive,
Access::Owned => "self",
}
}
+
+ pub fn source(&self, db: &dyn HirDatabase) -> Option<InFile<ast::SelfParam>> {
+ let InFile { file_id, value } = Function::from(self.func).source(db)?;
+ value
+ .param_list()
+ .and_then(|params| params.self_param())
+ .map(|value| InFile { file_id, value })
+ }
}
impl HasVisibility for Function {
}
pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef {
- db.const_data(self.id).type_ref.clone()
+ db.const_data(self.id).type_ref.as_ref().clone()
}
}
}
pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> {
- db.type_alias_data(self.id).type_ref.clone()
+ db.type_alias_data(self.id).type_ref.as_deref().cloned()
}
pub fn ty(self, db: &dyn HirDatabase) -> Type {
impl BuiltinType {
pub fn ty(self, db: &dyn HirDatabase, module: Module) -> Type {
let resolver = module.id.resolver(db.upcast());
- Type::new_with_resolver(db, &resolver, Ty::builtin(self.inner))
+ Type::new_with_resolver(db, &resolver, TyBuilder::builtin(self.inner))
.expect("crate not present in resolver")
}
}
}
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub enum MacroKind {
+ Declarative,
+ ProcMacro,
+ Derive,
+ BuiltIn,
+}
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MacroDef {
pub(crate) id: MacroDefId,
}
}
- /// Indicate it is a proc-macro
- pub fn is_proc_macro(&self) -> bool {
- matches!(self.id.kind, MacroDefKind::ProcMacro(..))
- }
-
- /// Indicate it is a derive macro
- pub fn is_derive_macro(&self) -> bool {
- // FIXME: wrong for `ProcMacro`
- matches!(self.id.kind, MacroDefKind::ProcMacro(..) | MacroDefKind::BuiltInDerive(..))
+ pub fn kind(&self) -> MacroKind {
+ match self.id.kind {
+ MacroDefKind::Declarative(_) => MacroKind::Declarative,
+ MacroDefKind::BuiltIn(_, _) => MacroKind::BuiltIn,
+ MacroDefKind::BuiltInDerive(_, _) => MacroKind::Derive,
+ MacroDefKind::BuiltInEager(_, _) => MacroKind::BuiltIn,
+ // FIXME might be a derive
+ MacroDefKind::ProcMacro(_, _) => MacroKind::ProcMacro,
+ }
}
}
}
}
+ pub fn as_self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> {
+ match self.parent {
+ DefWithBodyId::FunctionId(func) if self.is_self(db) => Some(SelfParam { func }),
+ _ => None,
+ }
+ }
+
// FIXME: why is this an option? It shouldn't be?
pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
let body = db.body(self.parent);
pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
db.generic_predicates_for_param(self.id)
.into_iter()
- .filter_map(|pred| match &pred.value {
- hir_ty::GenericPredicate::Implemented(trait_ref) => {
+ .filter_map(|pred| match &pred.skip_binders().skip_binders() {
+ hir_ty::WhereClause::Implemented(trait_ref) => {
Some(Trait::from(trait_ref.hir_trait_id()))
}
_ => None,
let resolver = self.id.parent.resolver(db.upcast());
let krate = self.id.parent.module(db.upcast()).krate();
let ty = params.get(local_idx)?.clone();
- let subst = Substitution::type_params(db, self.id.parent);
+ let subst = TyBuilder::type_params_subst(db, self.id.parent);
let ty = ty.subst(&subst.prefix(local_idx));
Some(Type::new_with_resolver_inner(db, krate, &resolver, ty))
}
inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
}
- pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> {
- let def_crates = match ty.value.def_crates(db, krate) {
+ pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> {
+ let def_crates = match ty.def_crates(db, krate) {
Some(def_crates) => def_crates,
None => return Vec::new(),
};
let filter = |impl_def: &Impl| {
- let target_ty = impl_def.target_ty(db);
- let rref = target_ty.remove_ref();
- ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value))
+ let self_ty = impl_def.self_ty(db);
+ let rref = self_ty.remove_ref();
+ ty.equals_ctor(rref.as_ref().map_or(&self_ty.ty, |it| &it.ty))
};
let mut all = Vec::new();
def_crates.iter().for_each(|&id| {
all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter))
});
- let fp = TyFingerprint::for_impl(&ty.value);
+ let fp = TyFingerprint::for_impl(&ty);
for id in def_crates
.iter()
.flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db))
pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
let krate = trait_.module(db).krate();
let mut all = Vec::new();
- for Crate { id } in krate.transitive_reverse_dependencies(db).into_iter().chain(Some(krate))
- {
+ for Crate { id } in krate.transitive_reverse_dependencies(db).into_iter() {
let impls = db.trait_impls_in_crate(id);
all.extend(impls.for_trait(trait_.id).map(Self::from))
}
// FIXME: the return type is wrong. This should be a hir version of
// `TraitRef` (ie, resolved `TypeRef`).
- pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> {
- db.impl_data(self.id).target_trait.clone()
+ pub fn trait_(self, db: &dyn HirDatabase) -> Option<TraitRef> {
+ db.impl_data(self.id).target_trait.as_deref().cloned()
}
- pub fn target_ty(self, db: &dyn HirDatabase) -> Type {
+ pub fn self_ty(self, db: &dyn HirDatabase) -> Type {
let impl_data = db.impl_data(self.id);
let resolver = self.id.resolver(db.upcast());
let krate = self.id.lookup(db.upcast()).container.krate();
let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
- let ty = ctx.lower_ty(&impl_data.target_type);
+ let ty = ctx.lower_ty(&impl_data.self_ty);
Type::new_with_resolver_inner(db, krate, &resolver, ty)
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Type {
krate: CrateId,
- ty: InEnvironment<Ty>,
+ env: Arc<TraitEnvironment>,
+ ty: Ty,
}
impl Type {
) -> Type {
let environment =
resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
- Type { krate, ty: InEnvironment { value: ty, environment } }
+ Type { krate, env: environment, ty }
}
fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
let resolver = lexical_env.resolver(db.upcast());
let environment =
resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
- Type { krate, ty: InEnvironment { value: ty, environment } }
+ Type { krate, env: environment, ty }
}
fn from_def(
db: &dyn HirDatabase,
krate: CrateId,
- def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>,
+ def: impl HasResolver + Into<TyDefId>,
) -> Type {
- let substs = Substitution::build_for_def(db, def).fill_with_unknown().build();
- let ty = db.ty(def.into()).subst(&substs);
+ let ty = TyBuilder::def_ty(db, def.into()).fill_with_unknown().build();
Type::new(db, krate, def, ty)
}
pub fn is_unit(&self) -> bool {
- matches!(self.ty.value.interned(&Interner), TyKind::Tuple(0, ..))
+ matches!(self.ty.kind(&Interner), TyKind::Tuple(0, ..))
}
pub fn is_bool(&self) -> bool {
- matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Bool))
+ matches!(self.ty.kind(&Interner), TyKind::Scalar(Scalar::Bool))
}
pub fn is_mutable_reference(&self) -> bool {
- matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
+ matches!(self.ty.kind(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
}
pub fn is_usize(&self) -> bool {
- matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
+ matches!(self.ty.kind(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
}
pub fn remove_ref(&self) -> Option<Type> {
- match &self.ty.value.interned(&Interner) {
+ match &self.ty.kind(&Interner) {
TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
_ => None,
}
}
pub fn is_unknown(&self) -> bool {
- self.ty.value.is_unknown()
+ self.ty.is_unknown()
}
/// Checks that particular type `ty` implements `std::future::Future`.
None => return false,
};
- let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
+ let canonical_ty =
+ Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
method_resolution::implements_trait(
&canonical_ty,
db,
- self.ty.environment.clone(),
+ self.env.clone(),
krate,
std_future_trait,
)
None => return false,
};
- let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
+ let canonical_ty =
+ Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
method_resolution::implements_trait_unique(
&canonical_ty,
db,
- self.ty.environment.clone(),
+ self.env.clone(),
krate,
fnonce_trait,
)
}
pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool {
- let trait_ref = hir_ty::TraitRef {
- trait_id: hir_ty::to_chalk_trait_id(trait_.id),
- substitution: Substitution::build_for_def(db, trait_.id)
- .push(self.ty.value.clone())
- .fill(args.iter().map(|t| t.ty.value.clone()))
- .build(),
- };
+ let trait_ref = TyBuilder::trait_ref(db, trait_.id)
+ .push(self.ty.clone())
+ .fill(args.iter().map(|t| t.ty.clone()))
+ .build();
let goal = Canonical {
- value: hir_ty::InEnvironment::new(
- self.ty.environment.clone(),
- hir_ty::Obligation::Trait(trait_ref),
- ),
- kinds: Arc::new([]),
+ value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)),
+ binders: CanonicalVarKinds::empty(&Interner),
};
db.trait_solve(self.krate, goal).is_some()
pub fn normalize_trait_assoc_type(
&self,
db: &dyn HirDatabase,
- trait_: Trait,
args: &[Type],
alias: TypeAlias,
) -> Option<Type> {
- let subst = Substitution::build_for_def(db, trait_.id)
- .push(self.ty.value.clone())
- .fill(args.iter().map(|t| t.ty.value.clone()))
+ let projection = TyBuilder::assoc_type_projection(db, alias.id)
+ .push(self.ty.clone())
+ .fill(args.iter().map(|t| t.ty.clone()))
.build();
- let goal = Canonical {
- value: InEnvironment::new(
- self.ty.environment.clone(),
- Obligation::AliasEq(AliasEq {
- alias: AliasTy::Projection(ProjectionTy {
- associated_ty_id: to_assoc_type_id(alias.id),
- substitution: subst,
- }),
+ let goal = Canonical::new(
+ InEnvironment::new(
+ self.env.env.clone(),
+ AliasEq {
+ alias: AliasTy::Projection(projection),
ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
.intern(&Interner),
- }),
+ }
+ .cast(&Interner),
),
- kinds: Arc::new([TyVariableKind::General]),
- };
+ [TyVariableKind::General].iter().copied(),
+ );
match db.trait_solve(self.krate, goal)? {
- Solution::Unique(SolutionVariables(subst)) => {
- subst.value.first().map(|ty| self.derived(ty.clone()))
- }
+ Solution::Unique(SolutionVariables(subst)) => subst
+ .value
+ .interned()
+ .first()
+ .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())),
Solution::Ambig(_) => None,
}
}
}
pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
- let def = self.ty.value.callable_def(db);
+ let def = self.ty.callable_def(db);
- let sig = self.ty.value.callable_sig(db)?;
+ let sig = self.ty.callable_sig(db)?;
Some(Callable { ty: self.clone(), sig, def, is_bound_method: false })
}
pub fn is_closure(&self) -> bool {
- matches!(&self.ty.value.interned(&Interner), TyKind::Closure { .. })
+ matches!(&self.ty.kind(&Interner), TyKind::Closure { .. })
}
pub fn is_fn(&self) -> bool {
- matches!(&self.ty.value.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. })
+ matches!(&self.ty.kind(&Interner), TyKind::FnDef(..) | TyKind::Function { .. })
}
pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
- let adt_id = match self.ty.value.interned(&Interner) {
+ let adt_id = match self.ty.kind(&Interner) {
&TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id,
_ => return false,
};
}
pub fn is_raw_ptr(&self) -> bool {
- matches!(&self.ty.value.interned(&Interner), TyKind::Raw(..))
+ matches!(&self.ty.kind(&Interner), TyKind::Raw(..))
}
pub fn contains_unknown(&self) -> bool {
- return go(&self.ty.value);
+ return go(&self.ty);
fn go(ty: &Ty) -> bool {
- match ty.interned(&Interner) {
- TyKind::Unknown => true,
+ match ty.kind(&Interner) {
+ TyKind::Error => true,
TyKind::Adt(_, substs)
| TyKind::AssociatedType(_, substs)
| TyKind::Tuple(_, substs)
| TyKind::OpaqueType(_, substs)
| TyKind::FnDef(_, substs)
- | TyKind::Closure(_, substs) => substs.iter().any(go),
+ | TyKind::Closure(_, substs) => {
+ substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go)
+ }
TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => {
go(ty)
| TyKind::Dyn(_)
| TyKind::Function(_)
| TyKind::Alias(_)
- | TyKind::ForeignType(_) => false,
+ | TyKind::Foreign(_) => false,
}
}
}
pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
- let (variant_id, substs) = match self.ty.value.interned(&Interner) {
+ let (variant_id, substs) = match self.ty.kind(&Interner) {
&TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs),
&TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs),
_ => return Vec::new(),
}
pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
- if let TyKind::Tuple(_, substs) = &self.ty.value.interned(&Interner) {
- substs.iter().map(|ty| self.derived(ty.clone())).collect()
+ if let TyKind::Tuple(_, substs) = &self.ty.kind(&Interner) {
+ substs
+ .iter(&Interner)
+ .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone()))
+ .collect()
} else {
Vec::new()
}
pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a {
// There should be no inference vars in types passed here
// FIXME check that?
- let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
- let environment = self.ty.environment.clone();
- let ty = InEnvironment { value: canonical, environment };
+ let canonical =
+ Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
+ let environment = self.env.env.clone();
+ let ty = InEnvironment { goal: canonical, environment };
autoderef(db, Some(self.krate), ty)
.map(|canonical| canonical.value)
.map(move |ty| self.derived(ty))
krate: Crate,
mut callback: impl FnMut(AssocItem) -> Option<T>,
) -> Option<T> {
- for krate in self.ty.value.def_crates(db, krate.id)? {
+ for krate in self.ty.def_crates(db, krate.id)? {
let impls = db.inherent_impls_in_crate(krate);
- for impl_def in impls.for_self_ty(&self.ty.value) {
+ for impl_def in impls.for_self_ty(&self.ty) {
for &item in db.impl_data(*impl_def).items.iter() {
if let Some(result) = callback(item.into()) {
return Some(result);
pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ {
self.ty
- .value
.strip_references()
.substs()
.into_iter()
- .flat_map(|substs| substs.iter())
- .map(move |ty| self.derived(ty.clone()))
+ .flat_map(|substs| substs.iter(&Interner))
+ .filter_map(|arg| arg.ty(&Interner).cloned())
+ .map(move |ty| self.derived(ty))
}
pub fn iterate_method_candidates<T>(
// There should be no inference vars in types passed here
// FIXME check that?
// FIXME replace Unknown by bound vars here
- let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
+ let canonical =
+ Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
- let env = self.ty.environment.clone();
+ let env = self.env.clone();
let krate = krate.id;
method_resolution::iterate_method_candidates(
env,
krate,
traits_in_scope,
+ None,
name,
method_resolution::LookupMode::MethodCall,
|ty, it| match it {
// There should be no inference vars in types passed here
// FIXME check that?
// FIXME replace Unknown by bound vars here
- let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) };
+ let canonical =
+ Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
- let env = self.ty.environment.clone();
+ let env = self.env.clone();
let krate = krate.id;
method_resolution::iterate_method_candidates(
env,
krate,
traits_in_scope,
+ None,
name,
method_resolution::LookupMode::Path,
|ty, it| callback(ty, it.into()),
}
pub fn as_adt(&self) -> Option<Adt> {
- let (adt, _subst) = self.ty.value.as_adt()?;
+ let (adt, _subst) = self.ty.as_adt()?;
Some(adt.into())
}
pub fn as_dyn_trait(&self) -> Option<Trait> {
- self.ty.value.dyn_trait().map(Into::into)
+ self.ty.dyn_trait().map(Into::into)
}
pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
- self.ty.value.impl_trait_bounds(db).map(|it| {
+ self.ty.impl_trait_bounds(db).map(|it| {
it.into_iter()
- .filter_map(|pred| match pred {
- hir_ty::GenericPredicate::Implemented(trait_ref) => {
+ .filter_map(|pred| match pred.skip_binders() {
+ hir_ty::WhereClause::Implemented(trait_ref) => {
Some(Trait::from(trait_ref.hir_trait_id()))
}
_ => None,
}
pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> {
- self.ty.value.associated_type_parent_trait(db).map(Into::into)
+ self.ty.associated_type_parent_trait(db).map(Into::into)
}
fn derived(&self, ty: Ty) -> Type {
- Type {
- krate: self.krate,
- ty: InEnvironment { value: ty, environment: self.ty.environment.clone() },
- }
+ Type { krate: self.krate, env: self.env.clone(), ty }
}
pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) {
substs: &Substitution,
cb: &mut impl FnMut(Type),
) {
- for ty in substs.iter() {
+ for ty in substs.iter(&Interner).filter_map(|a| a.ty(&Interner)) {
walk_type(db, &type_.derived(ty.clone()), cb);
}
}
fn walk_bounds(
db: &dyn HirDatabase,
type_: &Type,
- bounds: &[GenericPredicate],
+ bounds: &[QuantifiedWhereClause],
cb: &mut impl FnMut(Type),
) {
for pred in bounds {
- match pred {
- GenericPredicate::Implemented(trait_ref) => {
+ match pred.skip_binders() {
+ WhereClause::Implemented(trait_ref) => {
cb(type_.clone());
- walk_substs(db, type_, &trait_ref.substitution, cb);
+ // skip the self type. it's likely the type we just got the bounds from
+ for ty in trait_ref
+ .substitution
+ .iter(&Interner)
+ .skip(1)
+ .filter_map(|a| a.ty(&Interner))
+ {
+ walk_type(db, &type_.derived(ty.clone()), cb);
+ }
}
_ => (),
}
}
fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
- let ty = type_.ty.value.strip_references();
- match ty.interned(&Interner) {
+ let ty = type_.ty.strip_references();
+ match ty.kind(&Interner) {
TyKind::Adt(..) => {
cb(type_.derived(ty.clone()));
}
}
}
TyKind::Dyn(bounds) => {
- walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb);
+ walk_bounds(
+ db,
+ &type_.derived(ty.clone()),
+ bounds.bounds.skip_binders().interned(),
+ cb,
+ );
}
TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => {
walk_type(db, self, &mut cb);
}
+
+ pub fn could_unify_with(&self, other: &Type) -> bool {
+ could_unify(&self.ty, &other.ty)
+ }
}
// FIXME: closures
ImplSelfType(Impl),
AdtSelfType(Adt),
Local(Local),
+ Label(Label),
Unknown,
}
impl ScopeDef {
- pub fn all_items(def: PerNs) -> ArrayVec<[Self; 3]> {
+ pub fn all_items(def: PerNs) -> ArrayVec<Self, 3> {
let mut items = ArrayVec::new();
match (def.take_types(), def.take_values()) {