pub mod diagnostics;
pub mod db;
+mod display;
+
use std::{iter, sync::Arc};
use arrayvec::ArrayVec;
use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind};
use hir_ty::{
autoderef,
- display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter},
method_resolution::{self, TyFingerprint},
to_assoc_type_id,
traits::{FnTrait, Solution, SolutionVariables},
}
pub fn canonical_path(&self, db: &dyn HirDatabase) -> Option<String> {
- let mut segments = Vec::new();
- segments.push(self.name(db)?.to_string());
+ let mut segments = vec![self.name(db)?.to_string()];
for m in self.module(db)?.path_to_root(db) {
segments.extend(m.name(db).map(|it| it.to_string()))
}
}
}
+impl HasVisibility for Struct {
+ fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
+ db.struct_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
+ }
+}
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Union {
pub(crate) id: UnionId,
}
}
+impl HasVisibility for Union {
+ fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
+ db.union_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
+ }
+}
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Enum {
pub(crate) id: EnumId,
}
}
+impl HasVisibility for Enum {
+ fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
+ db.enum_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
+ }
+}
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Variant {
pub(crate) parent: Enum,
db.function_data(self.id)
.params
.iter()
- .map(|type_ref| {
+ .enumerate()
+ .map(|(idx, type_ref)| {
let ty = Type {
krate,
ty: InEnvironment {
environment: environment.clone(),
},
};
- Param { ty }
+ Param { func: self, ty, idx }
})
.collect()
}
}
pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
- db.function_data(self.id).is_unsafe
+ db.function_data(self.id).qualifier.is_unsafe
}
pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
#[derive(Debug)]
pub struct Param {
+ func: Function,
+ /// The index in parameter list, including self parameter.
+ idx: usize,
ty: Type,
}
pub fn ty(&self) -> &Type {
&self.ty
}
+
+ pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> {
+ let params = self.func.source(db)?.value.param_list()?;
+ if params.self_param().is_some() {
+ params.params().nth(self.idx.checked_sub(1)?)?.pat()
+ } else {
+ params.params().nth(self.idx)?.pat()
+ }
+ }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
db.const_data(self.id).name.clone()
}
+
+ pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef {
+ db.const_data(self.id).type_ref.clone()
+ }
}
impl HasVisibility for Const {
}
}
+impl HasVisibility for Static {
+ fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
+ db.static_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
+ }
+}
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Trait {
pub(crate) id: TraitId,
}
pub fn is_auto(self, db: &dyn HirDatabase) -> bool {
- db.trait_data(self.id).auto
+ db.trait_data(self.id).is_auto
+ }
+}
+
+impl HasVisibility for Trait {
+ fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
+ db.trait_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
}
}
}
}
-impl HirDisplay for TypeParam {
- fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
- write!(f, "{}", self.name(f.db))?;
- let bounds = f.db.generic_predicates_for_param(self.id);
- let substs = Substs::type_params(f.db, self.id.parent);
- let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>();
- if !(predicates.is_empty() || f.omit_verbose_types()) {
- write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?;
- }
- Ok(())
- }
-}
-
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct LifetimeParam {
pub(crate) id: LifetimeParamId,
pub fn remove_ref(&self) -> Option<Type> {
match &self.ty.value.interned(&Interner) {
- TyKind::Ref(.., substs) => Some(self.derived(substs[0].clone())),
+ TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
_ => None,
}
}
return go(&self.ty.value);
fn go(ty: &Ty) -> bool {
- if ty.is_unknown() {
- true
- } else {
- ty.substs().map_or(false, |substs| substs.iter().any(go))
+ match ty.interned(&Interner) {
+ TyKind::Unknown => true,
+
+ TyKind::Adt(_, substs)
+ | TyKind::AssociatedType(_, substs)
+ | TyKind::Tuple(_, substs)
+ | TyKind::OpaqueType(_, substs)
+ | TyKind::FnDef(_, substs)
+ | TyKind::Closure(_, substs) => substs.iter().any(go),
+
+ TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => {
+ go(ty)
+ }
+
+ TyKind::Scalar(_)
+ | TyKind::Str
+ | TyKind::Never
+ | TyKind::Placeholder(_)
+ | TyKind::BoundVar(_)
+ | TyKind::InferenceVar(_, _)
+ | TyKind::Dyn(_)
+ | TyKind::Function(_)
+ | TyKind::Alias(_)
+ | TyKind::ForeignType(_) => false,
}
}
}
walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb);
}
+ TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => {
+ walk_type(db, &type_.derived(ty.clone()), cb);
+ }
+
_ => {}
}
if let Some(substs) = ty.substs() {
}
}
-impl HirDisplay for Type {
- fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
- self.ty.value.hir_fmt(f)
- }
-}
-
// FIXME: closures
#[derive(Debug)]
pub struct Callable {