]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir/src/semantics.rs
Add ConstParams to the HIR
[rust.git] / crates / hir / src / semantics.rs
index e4fc21cedf97dc5425b1640d72a292637cc66b80..cd689c86935e24ebad1be98f3685126b96d99bf9 100644 (file)
@@ -15,7 +15,7 @@
 use rustc_hash::{FxHashMap, FxHashSet};
 use syntax::{
     algo::find_node_at_offset,
-    ast::{self, GenericParamsOwner},
+    ast::{self, GenericParamsOwner, LoopBodyOwner},
     match_ast, AstNode, SyntaxNode, SyntaxToken, TextSize,
 };
 
@@ -25,9 +25,9 @@
     diagnostics::Diagnostic,
     semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
     source_analyzer::{resolve_hir_path, SourceAnalyzer},
-    AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, LifetimeParam, Local,
-    MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam,
-    VariantDef,
+    AssocItem, Callable, ConstParam, Crate, Field, Function, HirFileId, Impl, InFile, Label,
+    LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type,
+    TypeAlias, TypeParam, VariantDef,
 };
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -38,7 +38,8 @@ pub enum PathResolution {
     Local(Local),
     /// A generic parameter
     TypeParam(TypeParam),
-    SelfType(ImplDef),
+    ConstParam(ConstParam),
+    SelfType(Impl),
     Macro(MacroDef),
     AssocItem(AssocItem),
 }
@@ -51,7 +52,7 @@ fn in_type_ns(&self) -> Option<TypeNs> {
                 Some(TypeNs::BuiltinType(*builtin))
             }
             PathResolution::Def(ModuleDef::Const(_))
-            | PathResolution::Def(ModuleDef::EnumVariant(_))
+            | PathResolution::Def(ModuleDef::Variant(_))
             | PathResolution::Def(ModuleDef::Function(_))
             | PathResolution::Def(ModuleDef::Module(_))
             | PathResolution::Def(ModuleDef::Static(_))
@@ -59,7 +60,9 @@ fn in_type_ns(&self) -> Option<TypeNs> {
             PathResolution::Def(ModuleDef::TypeAlias(alias)) => {
                 Some(TypeNs::TypeAliasId((*alias).into()))
             }
-            PathResolution::Local(_) | PathResolution::Macro(_) => None,
+            PathResolution::Local(_) | PathResolution::Macro(_) | PathResolution::ConstParam(_) => {
+                None
+            }
             PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
             PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
             PathResolution::AssocItem(AssocItem::Const(_))
@@ -178,9 +181,12 @@ pub fn find_node_at_offset_with_descend<N: AstNode>(
         self.imp.descend_node_at_offset(node, offset).find_map(N::cast)
     }
 
-    // FIXME: Replace the SyntaxToken with a typed ast Node/Token
-    pub fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> {
-        self.imp.resolve_lifetime_param(lifetime_token)
+    pub fn resolve_lifetime_param(&self, lifetime: &ast::Lifetime) -> Option<LifetimeParam> {
+        self.imp.resolve_lifetime_param(lifetime)
+    }
+
+    pub fn resolve_label(&self, lifetime: &ast::Lifetime) -> Option<Label> {
+        self.imp.resolve_label(lifetime)
     }
 
     pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
@@ -402,13 +408,9 @@ fn ancestors_at_offset_with_macros(
             .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len())
     }
 
-    // FIXME: Replace the SyntaxToken with a typed ast Node/Token
-    fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> {
-        if lifetime_token.kind() != syntax::SyntaxKind::LIFETIME {
-            return None;
-        }
-        let lifetime_text = lifetime_token.text();
-        let lifetime_param = lifetime_token.parent().ancestors().find_map(|syn| {
+    fn resolve_lifetime_param(&self, lifetime: &ast::Lifetime) -> Option<LifetimeParam> {
+        let text = lifetime.text();
+        let lifetime_param = lifetime.syntax().ancestors().find_map(|syn| {
             let gpl = match_ast! {
                 match syn {
                     ast::Fn(it) => it.generic_param_list()?,
@@ -424,12 +426,34 @@ fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<Lifetim
                 }
             };
             gpl.lifetime_params()
-                .find(|tp| tp.lifetime_token().as_ref().map(|lt| lt.text()) == Some(lifetime_text))
+                .find(|tp| tp.lifetime().as_ref().map(|lt| lt.text()) == Some(text))
         })?;
         let src = self.find_file(lifetime_param.syntax().clone()).with_value(lifetime_param);
         ToDef::to_def(self, src)
     }
 
+    fn resolve_label(&self, lifetime: &ast::Lifetime) -> Option<Label> {
+        let text = lifetime.text();
+        let label = lifetime.syntax().ancestors().find_map(|syn| {
+            let label = match_ast! {
+                match syn {
+                    ast::ForExpr(it) => it.label(),
+                    ast::WhileExpr(it) => it.label(),
+                    ast::LoopExpr(it) => it.label(),
+                    ast::EffectExpr(it) => it.label(),
+                    _ => None,
+                }
+            };
+            label.filter(|l| {
+                l.lifetime()
+                    .and_then(|lt| lt.lifetime_ident_token())
+                    .map_or(false, |lt| lt.text() == text)
+            })
+        })?;
+        let src = self.find_file(label.syntax().clone()).with_value(label);
+        ToDef::to_def(self, src)
+    }
+
     fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
         self.analyze(expr.syntax()).type_of_expr(self.db, expr)
     }
@@ -713,18 +737,20 @@ fn to_def(sema: &SemanticsImpl, src: InFile<Self>) -> Option<Self::Def> {
     (crate::Enum, ast::Enum, enum_to_def),
     (crate::Union, ast::Union, union_to_def),
     (crate::Trait, ast::Trait, trait_to_def),
-    (crate::ImplDef, ast::Impl, impl_to_def),
+    (crate::Impl, ast::Impl, impl_to_def),
     (crate::TypeAlias, ast::TypeAlias, type_alias_to_def),
     (crate::Const, ast::Const, const_to_def),
     (crate::Static, ast::Static, static_to_def),
     (crate::Function, ast::Fn, fn_to_def),
     (crate::Field, ast::RecordField, record_field_to_def),
     (crate::Field, ast::TupleField, tuple_field_to_def),
-    (crate::EnumVariant, ast::Variant, enum_variant_to_def),
+    (crate::Variant, ast::Variant, enum_variant_to_def),
     (crate::TypeParam, ast::TypeParam, type_param_to_def),
     (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def),
-    (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros
+    (crate::ConstParam, ast::ConstParam, const_param_to_def),
+    (crate::MacroDef, ast::MacroRules, macro_rules_to_def),
     (crate::Local, ast::IdentPat, bind_pat_to_def),
+    (crate::Label, ast::Label, label_to_def),
 ];
 
 fn find_root(node: &SyntaxNode) -> SyntaxNode {