From 262b9c39824b58068d89d6c5cf53d8fea782b11c Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 23 Dec 2020 16:34:30 +0100 Subject: Track labels in the HIR --- crates/hir/src/code_model.rs | 30 +++++++++++++++++++++++++++- crates/hir/src/from_id.rs | 15 +++++++++++--- crates/hir/src/lib.rs | 4 ++-- crates/hir/src/semantics.rs | 33 ++++++++++++++++++++++++++++--- crates/hir/src/semantics/source_to_def.rs | 15 +++++++++++--- 5 files changed, 85 insertions(+), 12 deletions(-) (limited to 'crates/hir') diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 1d7e5ddd7..1ddf68c08 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -9,7 +9,7 @@ use hir_def::{ adt::StructKind, adt::VariantData, builtin_type::BuiltinType, - expr::{BindingAnnotation, Pat, PatId}, + expr::{BindingAnnotation, LabelId, Pat, PatId}, import_map, item_tree::ItemTreeNode, lang_item::LangItemTarget, @@ -1205,6 +1205,34 @@ impl Local { } } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct Label { + pub(crate) parent: DefWithBodyId, + pub(crate) label_id: LabelId, +} + +impl Label { + pub fn module(self, db: &dyn HirDatabase) -> Module { + self.parent(db).module(db) + } + + pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody { + self.parent.into() + } + + pub fn name(self, db: &dyn HirDatabase) -> Name { + let body = db.body(self.parent.into()); + body[self.label_id].name.clone() + } + + pub fn source(self, db: &dyn HirDatabase) -> InFile { + let (_body, source_map) = db.body_with_source_map(self.parent.into()); + let src = source_map.label_syntax(self.label_id); + let root = src.file_syntax(db.upcast()); + src.map(|ast| ast.to_node(&root)) + } +} + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum GenericParam { TypeParam(TypeParam), diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs index 8e0c571b8..a0792b9a6 100644 --- a/crates/hir/src/from_id.rs +++ b/crates/hir/src/from_id.rs @@ -4,12 +4,15 @@ //! are splitting the hir. use hir_def::{ - expr::PatId, item_scope::ItemInNs, AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, - GenericDefId, ModuleDefId, VariantId, + expr::{LabelId, PatId}, + item_scope::ItemInNs, + AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, GenericDefId, ModuleDefId, + VariantId, }; use crate::{ - Adt, AssocItem, DefWithBody, Field, GenericDef, Local, MacroDef, ModuleDef, Variant, VariantDef, + Adt, AssocItem, DefWithBody, Field, GenericDef, Label, Local, MacroDef, ModuleDef, Variant, + VariantDef, }; macro_rules! from_id { @@ -228,6 +231,12 @@ impl From<(DefWithBodyId, PatId)> for Local { } } +impl From<(DefWithBodyId, LabelId)> for Label { + fn from((parent, label_id): (DefWithBodyId, LabelId)) -> Self { + Label { parent, label_id } + } +} + impl From for ItemInNs { fn from(macro_def: MacroDef) -> Self { ItemInNs::Macros(macro_def.into()) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index bdd270c58..7ac9fd507 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -35,8 +35,8 @@ pub use crate::{ code_model::{ Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const, Crate, CrateDependency, DefWithBody, Enum, Field, FieldSource, Function, GenericDef, - HasVisibility, Impl, LifetimeParam, Local, MacroDef, Module, ModuleDef, ScopeDef, Static, - Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, + HasVisibility, Impl, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, ScopeDef, + Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, }, has_source::HasSource, semantics::{PathResolution, Semantics, SemanticsScope}, diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 25ebf73d8..67cd16e31 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -15,7 +15,7 @@ use itertools::Itertools; 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,8 +25,8 @@ use crate::{ diagnostics::Diagnostic, semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, source_analyzer::{resolve_hir_path, SourceAnalyzer}, - AssocItem, Callable, Crate, Field, Function, HirFileId, Impl, InFile, LifetimeParam, Local, - MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, + AssocItem, Callable, Crate, Field, Function, HirFileId, Impl, InFile, Label, LifetimeParam, + Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, VariantDef, }; @@ -182,6 +182,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.imp.resolve_lifetime_param(lifetime) } + pub fn resolve_label(&self, lifetime: &ast::Lifetime) -> Option