]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_def/src/item_tree.rs
parameters.split_last()
[rust.git] / crates / hir_def / src / item_tree.rs
index aab3f4b3c8428842a68896ddb0288eceb43ce910..0af5d654af7e3a476ac5b5f64999ec5af392b79d 100644 (file)
@@ -56,6 +56,7 @@
 use profile::Count;
 use rustc_hash::FxHashMap;
 use smallvec::SmallVec;
+use stdx::never;
 use syntax::{ast, match_ast, SyntaxKind};
 
 use crate::{
@@ -109,18 +110,17 @@ pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) ->
             Some(node) => node,
             None => return Default::default(),
         };
-        if syntax.kind() == SyntaxKind::ERROR {
+        if never!(syntax.kind() == SyntaxKind::ERROR) {
             // FIXME: not 100% sure why these crop up, but return an empty tree to avoid a panic
             return Default::default();
         }
 
-        let hygiene = Hygiene::new(db.upcast(), file_id);
-        let ctx = lower::Ctx::new(db, hygiene.clone(), file_id);
+        let ctx = lower::Ctx::new(db, file_id);
         let mut top_attrs = None;
         let mut item_tree = match_ast! {
             match syntax {
                 ast::SourceFile(file) => {
-                    top_attrs = Some(RawAttrs::new(db, &file, &hygiene));
+                    top_attrs = Some(RawAttrs::new(db, &file, ctx.hygiene()));
                     ctx.lower_module_items(&file)
                 },
                 ast::MacroItems(items) => {
@@ -147,8 +147,7 @@ pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) ->
     fn block_item_tree(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
         let loc = db.lookup_intern_block(block);
         let block = loc.ast_id.to_node(db.upcast());
-        let hygiene = Hygiene::new(db.upcast(), loc.ast_id.file_id);
-        let ctx = lower::Ctx::new(db, hygiene.clone(), loc.ast_id.file_id);
+        let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
         Arc::new(ctx.lower_block(&block))
     }
 
@@ -216,7 +215,7 @@ pub(crate) fn raw_attrs(&self, of: AttrOwner) -> &RawAttrs {
         self.attrs.get(&of).unwrap_or(&RawAttrs::EMPTY)
     }
 
-    pub fn attrs(&self, db: &dyn DefDatabase, krate: CrateId, of: AttrOwner) -> Attrs {
+    pub(crate) fn attrs(&self, db: &dyn DefDatabase, krate: CrateId, of: AttrOwner) -> Attrs {
         self.raw_attrs(of).clone().filter(db, krate)
     }
 
@@ -598,7 +597,7 @@ pub struct Function {
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub enum Param {
-    Normal(Interned<TypeRef>),
+    Normal(Option<Name>, Interned<TypeRef>),
     Varargs,
 }
 
@@ -648,7 +647,7 @@ pub struct Enum {
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Const {
-    /// const _: () = ();
+    /// `None` for `const _: () = ();`
     pub name: Option<Name>,
     pub visibility: RawVisibilityId,
     pub type_ref: Interned<TypeRef>,
@@ -660,8 +659,6 @@ pub struct Static {
     pub name: Name,
     pub visibility: RawVisibilityId,
     pub mutable: bool,
-    /// Whether the static is in an `extern` block.
-    pub is_extern: bool,
     pub type_ref: Interned<TypeRef>,
     pub ast_id: FileAstId<ast::Static>,
 }
@@ -695,7 +692,6 @@ pub struct TypeAlias {
     pub bounds: Box<[Interned<TypeBound>]>,
     pub generic_params: Interned<GenericParams>,
     pub type_ref: Option<Interned<TypeRef>>,
-    pub is_extern: bool,
     pub ast_id: FileAstId<ast::TypeAlias>,
 }
 
@@ -794,14 +790,26 @@ fn concat_mod_paths(
                     }
                     Some((prefix, ImportKind::Plain))
                 }
-                (Some(prefix), PathKind::Super(0)) => {
-                    // `some::path::self` == `some::path`
-                    if path.segments().is_empty() {
-                        Some((prefix, ImportKind::TypeOnly))
-                    } else {
-                        None
+                (Some(mut prefix), PathKind::Super(n))
+                    if *n > 0 && prefix.segments().is_empty() =>
+                {
+                    // `super::super` + `super::rest`
+                    match &mut prefix.kind {
+                        PathKind::Super(m) => {
+                            cov_mark::hit!(concat_super_mod_paths);
+                            *m += *n;
+                            for segment in path.segments() {
+                                prefix.push_segment(segment.clone());
+                            }
+                            Some((prefix, ImportKind::Plain))
+                        }
+                        _ => None,
                     }
                 }
+                (Some(prefix), PathKind::Super(0)) if path.segments().is_empty() => {
+                    // `some::path::self` == `some::path`
+                    Some((prefix, ImportKind::TypeOnly))
+                }
                 (Some(_), _) => None,
             }
         }
@@ -924,6 +932,17 @@ fn from(item: AssocItem) -> Self {
     }
 }
 
+impl AssocItem {
+    pub fn ast_id(self, tree: &ItemTree) -> FileAstId<ast::AssocItem> {
+        match self {
+            AssocItem::Function(id) => tree[id].ast_id.upcast(),
+            AssocItem::TypeAlias(id) => tree[id].ast_id.upcast(),
+            AssocItem::Const(id) => tree[id].ast_id.upcast(),
+            AssocItem::MacroCall(id) => tree[id].ast_id.upcast(),
+        }
+    }
+}
+
 #[derive(Debug, Eq, PartialEq)]
 pub struct Variant {
     pub name: Name,