]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir/src/lib.rs
Use hir formatter more
[rust.git] / crates / hir / src / lib.rs
index 42a805c57503fa4661a32a0723de03c918119071..98135602a5367539b8bcef5b05b7b5f13207289d 100644 (file)
@@ -29,6 +29,8 @@
 pub mod diagnostics;
 pub mod db;
 
+mod display;
+
 use std::{iter, sync::Arc};
 
 use arrayvec::ArrayVec;
@@ -50,7 +52,6 @@
 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},
@@ -267,8 +268,7 @@ pub fn module(self, db: &dyn HirDatabase) -> Option<Module> {
     }
 
     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()))
         }
@@ -572,6 +572,12 @@ fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
     }
 }
 
+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,
@@ -604,6 +610,12 @@ fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
     }
 }
 
+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,
@@ -631,6 +643,12 @@ pub fn ty(self, db: &dyn HirDatabase) -> Type {
     }
 }
 
+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,
@@ -822,7 +840,8 @@ pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param> {
         db.function_data(self.id)
             .params
             .iter()
-            .map(|type_ref| {
+            .enumerate()
+            .map(|(idx, type_ref)| {
                 let ty = Type {
                     krate,
                     ty: InEnvironment {
@@ -830,7 +849,7 @@ pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param> {
                         environment: environment.clone(),
                     },
                 };
-                Param { ty }
+                Param { func: self, ty, idx }
             })
             .collect()
     }
@@ -844,7 +863,7 @@ pub fn method_params(self, db: &dyn HirDatabase) -> Option<Vec<Param>> {
     }
 
     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) {
@@ -893,6 +912,9 @@ fn from(mutability: hir_ty::Mutability) -> Access {
 
 #[derive(Debug)]
 pub struct Param {
+    func: Function,
+    /// The index in parameter list, including self parameter.
+    idx: usize,
     ty: Type,
 }
 
@@ -900,6 +922,15 @@ impl Param {
     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)]
@@ -949,6 +980,10 @@ pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
     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 {
@@ -982,6 +1017,12 @@ pub fn is_mut(self, db: &dyn HirDatabase) -> bool {
     }
 }
 
+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,
@@ -1001,7 +1042,13 @@ pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
     }
 
     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()))
     }
 }
 
@@ -1413,19 +1460,6 @@ pub fn default(self, db: &dyn HirDatabase) -> Option<Type> {
     }
 }
 
-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,
@@ -1488,7 +1522,7 @@ pub fn all_in_crate(db: &dyn HirDatabase, krate: Crate) -> Vec<Impl> {
     pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> {
         let def_crates = match ty.value.def_crates(db, krate) {
             Some(def_crates) => def_crates,
-            None => return vec![],
+            None => return Vec::new(),
         };
 
         let filter = |impl_def: &Impl| {
@@ -1498,16 +1532,11 @@ pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl>
         };
 
         let mut all = Vec::new();
-        def_crates.iter().for_each(|&id| {
+        def_crates.into_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);
-        for id in def_crates
-            .iter()
-            .flat_map(|&id| Crate { id }.reverse_dependencies(db))
-            .map(|Crate { id }| id)
-            .chain(def_crates.iter().copied())
-        {
+        for id in db.crate_graph().iter() {
             match fp {
                 Some(fp) => all.extend(
                     db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter),
@@ -1639,7 +1668,7 @@ pub fn is_mutable_reference(&self) -> bool {
 
     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,
         }
     }
@@ -1793,10 +1822,30 @@ pub fn contains_unknown(&self) -> bool {
         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,
             }
         }
     }
@@ -2025,6 +2074,10 @@ fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
                     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() {
@@ -2036,12 +2089,6 @@ fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
     }
 }
 
-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 {