summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/hir
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/hir')
-rw-r--r--src/tools/rust-analyzer/crates/hir/Cargo.toml31
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/display.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs186
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs16
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs48
6 files changed, 189 insertions, 102 deletions
diff --git a/src/tools/rust-analyzer/crates/hir/Cargo.toml b/src/tools/rust-analyzer/crates/hir/Cargo.toml
index f780e3f53..ef40a8902 100644
--- a/src/tools/rust-analyzer/crates/hir/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir/Cargo.toml
@@ -2,9 +2,11 @@
name = "hir"
version = "0.0.0"
description = "TBD"
-license = "MIT OR Apache-2.0"
-edition = "2021"
-rust-version = "1.65"
+
+authors.workspace = true
+edition.workspace = true
+license.workspace = true
+rust-version.workspace = true
[lib]
doctest = false
@@ -14,15 +16,16 @@ rustc-hash = "1.1.0"
either = "1.7.0"
arrayvec = "0.7.2"
itertools = "0.10.5"
-smallvec = "1.10.0"
-once_cell = "1.15.0"
+smallvec.workspace = true
+once_cell = "1.17.0"
-stdx = { path = "../stdx", version = "0.0.0" }
-syntax = { path = "../syntax", version = "0.0.0" }
-base-db = { path = "../base-db", version = "0.0.0" }
-profile = { path = "../profile", version = "0.0.0" }
-hir-expand = { path = "../hir-expand", version = "0.0.0" }
-hir-def = { path = "../hir-def", version = "0.0.0" }
-hir-ty = { path = "../hir-ty", version = "0.0.0" }
-tt = { path = "../tt", version = "0.0.0" }
-cfg = { path = "../cfg", version = "0.0.0" }
+# local deps
+base-db.workspace = true
+cfg.workspace = true
+hir-def.workspace = true
+hir-expand.workspace = true
+hir-ty.workspace = true
+profile.workspace = true
+stdx.workspace = true
+syntax.workspace = true
+tt.workspace = true
diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs
index 5a4b2f334..0d1942012 100644
--- a/src/tools/rust-analyzer/crates/hir/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/display.rs
@@ -4,6 +4,7 @@ use hir_def::{
generics::{
TypeOrConstParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
},
+ lang_item::LangItem,
type_ref::{TypeBound, TypeRef},
AdtId, GenericDefId,
};
@@ -14,7 +15,6 @@ use hir_ty::{
},
Interner, TraitRefExt, WhereClause,
};
-use syntax::SmolStr;
use crate::{
Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasCrate, HasVisibility,
@@ -261,8 +261,7 @@ impl HirDisplay for TypeParam {
bounds.iter().cloned().map(|b| b.substitute(Interner, &substs)).collect();
let krate = self.id.parent().krate(f.db).id;
let sized_trait =
- f.db.lang_item(krate, SmolStr::new_inline("sized"))
- .and_then(|lang_item| lang_item.as_trait());
+ f.db.lang_item(krate, LangItem::Sized).and_then(|lang_item| lang_item.as_trait());
let has_only_sized_bound = predicates.iter().all(move |pred| match pred.skip_binders() {
WhereClause::Implemented(it) => Some(it.hir_trait_id()) == sized_trait,
_ => false,
@@ -270,7 +269,7 @@ impl HirDisplay for TypeParam {
let has_only_not_sized_bound = predicates.is_empty();
if !has_only_sized_bound || has_only_not_sized_bound {
let default_sized = SizedByDefault::Sized { anchor: krate };
- write_bounds_like_dyn_trait_with_prefix(":", &predicates, default_sized, f)?;
+ write_bounds_like_dyn_trait_with_prefix(f, ":", &predicates, default_sized)?;
}
Ok(())
}
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index 08fd4453d..2cb4ed2c3 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -44,12 +44,13 @@ use hir_def::{
expr::{BindingAnnotation, ExprOrPatId, LabelId, Pat, PatId},
generics::{TypeOrConstParamData, TypeParamProvenance},
item_tree::ItemTreeNode,
- lang_item::LangItemTarget,
+ lang_item::{LangItem, LangItemTarget},
layout::{Layout, LayoutError, ReprOptions},
nameres::{self, diagnostics::DefDiagnostic},
per_ns::PerNs,
resolver::{HasResolver, Resolver},
src::HasSource as _,
+ type_ref::ConstScalar,
AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
LocalEnumVariantId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId,
@@ -65,8 +66,9 @@ use hir_ty::{
primitive::UintTy,
traits::FnTrait,
AliasTy, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId,
- GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar, Substitution,
- TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, WhereClause,
+ ConcreteConst, ConstValue, GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar,
+ Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind,
+ WhereClause,
};
use itertools::Itertools;
use nameres::diagnostics::DefDiagnosticKind;
@@ -107,7 +109,7 @@ pub use {
cfg::{CfgAtom, CfgExpr, CfgOptions},
hir_def::{
adt::StructKind,
- attr::{Attr, Attrs, AttrsWithOwner, Documentation},
+ attr::{Attrs, AttrsWithOwner, Documentation},
builtin_attr::AttributeTemplate,
find_path::PrefixKind,
import_map,
@@ -122,11 +124,12 @@ pub use {
ModuleDefId,
},
hir_expand::{
+ attrs::Attr,
name::{known, Name},
ExpandResult, HirFileId, InFile, MacroFile, Origin,
},
hir_ty::{
- display::{HirDisplay, HirWrite},
+ display::{HirDisplay, HirDisplayError, HirWrite},
PointerCast, Safety,
},
};
@@ -471,8 +474,8 @@ impl Module {
let def_map = self.id.def_map(db.upcast());
let children = def_map[self.id.local_id]
.children
- .iter()
- .map(|(_, module_id)| Module { id: def_map.module_id(*module_id) })
+ .values()
+ .map(|module_id| Module { id: def_map.module_id(*module_id) })
.collect::<Vec<_>>();
children.into_iter()
}
@@ -784,7 +787,7 @@ fn precise_macro_call_location(
let token = (|| {
let derive_attr = node
.doc_comments_and_attrs()
- .nth(*derive_attr_index as usize)
+ .nth(derive_attr_index.ast_index())
.and_then(Either::left)?;
let token_tree = derive_attr.meta()?.token_tree()?;
let group_by = token_tree
@@ -812,9 +815,11 @@ fn precise_macro_call_location(
let node = ast_id.to_node(db.upcast());
let attr = node
.doc_comments_and_attrs()
- .nth((*invoc_attr_index) as usize)
+ .nth(invoc_attr_index.ast_index())
.and_then(Either::left)
- .unwrap_or_else(|| panic!("cannot find attribute #{invoc_attr_index}"));
+ .unwrap_or_else(|| {
+ panic!("cannot find attribute #{}", invoc_attr_index.ast_index())
+ });
(
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&attr))),
@@ -920,7 +925,7 @@ impl Struct {
}
pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprOptions> {
- db.struct_data(self.id).repr.clone()
+ db.struct_data(self.id).repr
}
pub fn kind(self, db: &dyn HirDatabase) -> StructKind {
@@ -1831,7 +1836,7 @@ pub struct Trait {
impl Trait {
pub fn lang(db: &dyn HirDatabase, krate: Crate, name: &Name) -> Option<Trait> {
- db.lang_item(krate.into(), name.to_smol_str())
+ db.lang_item(krate.into(), LangItem::from_name(name)?)
.and_then(LangItemTarget::as_trait)
.map(Into::into)
}
@@ -2126,7 +2131,7 @@ pub enum AssocItem {
Const(Const),
TypeAlias(TypeAlias),
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub enum AssocItemContainer {
Trait(Trait),
Impl(Impl),
@@ -2160,6 +2165,16 @@ impl AsAssocItem for ModuleDef {
}
}
}
+impl AsAssocItem for DefWithBody {
+ fn as_assoc_item(self, db: &dyn HirDatabase) -> Option<AssocItem> {
+ match self {
+ DefWithBody::Function(it) => it.as_assoc_item(db),
+ DefWithBody::Const(it) => it.as_assoc_item(db),
+ DefWithBody::Static(_) | DefWithBody::Variant(_) => None,
+ }
+ }
+}
+
fn as_assoc_item<ID, DEF, CTOR, AST>(db: &dyn HirDatabase, ctor: CTOR, id: ID) -> Option<AssocItem>
where
ID: Lookup<Data = AssocItemLoc<AST>>,
@@ -2406,7 +2421,7 @@ impl Local {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct DeriveHelper {
pub(crate) derive: MacroId,
- pub(crate) idx: usize,
+ pub(crate) idx: u32,
}
impl DeriveHelper {
@@ -2416,15 +2431,18 @@ impl DeriveHelper {
pub fn name(&self, db: &dyn HirDatabase) -> Name {
match self.derive {
- MacroId::Macro2Id(it) => {
- db.macro2_data(it).helpers.as_deref().and_then(|it| it.get(self.idx)).cloned()
- }
+ MacroId::Macro2Id(it) => db
+ .macro2_data(it)
+ .helpers
+ .as_deref()
+ .and_then(|it| it.get(self.idx as usize))
+ .cloned(),
MacroId::MacroRulesId(_) => None,
MacroId::ProcMacroId(proc_macro) => db
.proc_macro_data(proc_macro)
.helpers
.as_deref()
- .and_then(|it| it.get(self.idx))
+ .and_then(|it| it.get(self.idx as usize))
.cloned(),
}
.unwrap_or_else(|| Name::missing())
@@ -2435,7 +2453,7 @@ impl DeriveHelper {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct BuiltinAttr {
krate: Option<CrateId>,
- idx: usize,
+ idx: u32,
}
impl BuiltinAttr {
@@ -2444,7 +2462,8 @@ impl BuiltinAttr {
if let builtin @ Some(_) = Self::builtin(name) {
return builtin;
}
- let idx = db.crate_def_map(krate.id).registered_attrs().iter().position(|it| it == name)?;
+ let idx =
+ db.crate_def_map(krate.id).registered_attrs().iter().position(|it| it == name)? as u32;
Some(BuiltinAttr { krate: Some(krate.id), idx })
}
@@ -2452,21 +2471,21 @@ impl BuiltinAttr {
hir_def::builtin_attr::INERT_ATTRIBUTES
.iter()
.position(|tool| tool.name == name)
- .map(|idx| BuiltinAttr { krate: None, idx })
+ .map(|idx| BuiltinAttr { krate: None, idx: idx as u32 })
}
pub fn name(&self, db: &dyn HirDatabase) -> SmolStr {
// FIXME: Return a `Name` here
match self.krate {
- Some(krate) => db.crate_def_map(krate).registered_attrs()[self.idx].clone(),
- None => SmolStr::new(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx].name),
+ Some(krate) => db.crate_def_map(krate).registered_attrs()[self.idx as usize].clone(),
+ None => SmolStr::new(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx as usize].name),
}
}
pub fn template(&self, _: &dyn HirDatabase) -> Option<AttributeTemplate> {
match self.krate {
Some(_) => None,
- None => Some(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx].template),
+ None => Some(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx as usize].template),
}
}
}
@@ -2474,7 +2493,7 @@ impl BuiltinAttr {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ToolModule {
krate: Option<CrateId>,
- idx: usize,
+ idx: u32,
}
impl ToolModule {
@@ -2483,7 +2502,8 @@ impl ToolModule {
if let builtin @ Some(_) = Self::builtin(name) {
return builtin;
}
- let idx = db.crate_def_map(krate.id).registered_tools().iter().position(|it| it == name)?;
+ let idx =
+ db.crate_def_map(krate.id).registered_tools().iter().position(|it| it == name)? as u32;
Some(ToolModule { krate: Some(krate.id), idx })
}
@@ -2491,14 +2511,14 @@ impl ToolModule {
hir_def::builtin_attr::TOOL_MODULES
.iter()
.position(|&tool| tool == name)
- .map(|idx| ToolModule { krate: None, idx })
+ .map(|idx| ToolModule { krate: None, idx: idx as u32 })
}
pub fn name(&self, db: &dyn HirDatabase) -> SmolStr {
// FIXME: Return a `Name` here
match self.krate {
- Some(krate) => db.crate_def_map(krate).registered_tools()[self.idx].clone(),
- None => SmolStr::new(hir_def::builtin_attr::TOOL_MODULES[self.idx]),
+ Some(krate) => db.crate_def_map(krate).registered_tools()[self.idx as usize].clone(),
+ None => SmolStr::new(hir_def::builtin_attr::TOOL_MODULES[self.idx as usize]),
}
}
}
@@ -2555,6 +2575,14 @@ impl GenericParam {
GenericParam::LifetimeParam(it) => it.name(db),
}
}
+
+ pub fn parent(self) -> GenericDef {
+ match self {
+ GenericParam::TypeParam(it) => it.id.parent().into(),
+ GenericParam::ConstParam(it) => it.id.parent().into(),
+ GenericParam::LifetimeParam(it) => it.id.parent.into(),
+ }
+ }
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -2788,14 +2816,19 @@ impl Impl {
all
}
- // FIXME: the return type is wrong. This should be a hir version of
- // `TraitRef` (to account for parameters and qualifiers)
pub fn trait_(self, db: &dyn HirDatabase) -> Option<Trait> {
- let trait_ref = db.impl_trait(self.id)?.skip_binders().clone();
- let id = hir_ty::from_chalk_trait_id(trait_ref.trait_id);
+ let trait_ref = db.impl_trait(self.id)?;
+ let id = trait_ref.skip_binders().hir_trait_id();
Some(Trait { id })
}
+ pub fn trait_ref(self, db: &dyn HirDatabase) -> Option<TraitRef> {
+ let substs = TyBuilder::placeholder_subst(db, self.id);
+ let trait_ref = db.impl_trait(self.id)?.substitute(Interner, &substs);
+ let resolver = self.id.resolver(db.upcast());
+ Some(TraitRef::new_with_resolver(db, &resolver, trait_ref))
+ }
+
pub fn self_ty(self, db: &dyn HirDatabase) -> Type {
let resolver = self.id.resolver(db.upcast());
let substs = TyBuilder::placeholder_subst(db, self.id);
@@ -2821,6 +2854,48 @@ impl Impl {
}
}
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub struct TraitRef {
+ env: Arc<TraitEnvironment>,
+ trait_ref: hir_ty::TraitRef,
+}
+
+impl TraitRef {
+ pub(crate) fn new_with_resolver(
+ db: &dyn HirDatabase,
+ resolver: &Resolver,
+ trait_ref: hir_ty::TraitRef,
+ ) -> TraitRef {
+ let env = resolver.generic_def().map_or_else(
+ || Arc::new(TraitEnvironment::empty(resolver.krate())),
+ |d| db.trait_environment(d),
+ );
+ TraitRef { env, trait_ref }
+ }
+
+ pub fn trait_(&self) -> Trait {
+ let id = self.trait_ref.hir_trait_id();
+ Trait { id }
+ }
+
+ pub fn self_ty(&self) -> Type {
+ let ty = self.trait_ref.self_type_parameter(Interner);
+ Type { env: self.env.clone(), ty }
+ }
+
+ /// Returns `idx`-th argument of this trait reference if it is a type argument. Note that the
+ /// first argument is the `Self` type.
+ pub fn get_type_argument(&self, idx: usize) -> Option<Type> {
+ self.trait_ref
+ .substitution
+ .as_slice(Interner)
+ .get(idx)
+ .and_then(|arg| arg.ty(Interner))
+ .cloned()
+ .map(|ty| Type { env: self.env.clone(), ty })
+ }
+}
+
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Type {
env: Arc<TraitEnvironment>,
@@ -2957,7 +3032,7 @@ impl Type {
/// This function is used in `.await` syntax completion.
pub fn impls_into_future(&self, db: &dyn HirDatabase) -> bool {
let trait_ = db
- .lang_item(self.env.krate, SmolStr::new_inline("into_future"))
+ .lang_item(self.env.krate, LangItem::IntoFutureIntoFuture)
.and_then(|it| {
let into_future_fn = it.as_function()?;
let assoc_item = as_assoc_item(db, AssocItem::Function, into_future_fn)?;
@@ -2965,8 +3040,7 @@ impl Type {
Some(into_future_trait.id)
})
.or_else(|| {
- let future_trait =
- db.lang_item(self.env.krate, SmolStr::new_inline("future_trait"))?;
+ let future_trait = db.lang_item(self.env.krate, LangItem::Future)?;
future_trait.as_trait()
});
@@ -3059,9 +3133,9 @@ impl Type {
}
pub fn is_copy(&self, db: &dyn HirDatabase) -> bool {
- let lang_item = db.lang_item(self.env.krate, SmolStr::new_inline("copy"));
+ let lang_item = db.lang_item(self.env.krate, LangItem::Copy);
let copy_trait = match lang_item {
- Some(LangItemTarget::TraitId(it)) => it,
+ Some(LangItemTarget::Trait(it)) => it,
_ => return false,
};
self.impls_trait(db, copy_trait.into(), &[])
@@ -3088,15 +3162,15 @@ impl Type {
}
pub fn is_closure(&self) -> bool {
- matches!(&self.ty.kind(Interner), TyKind::Closure { .. })
+ matches!(self.ty.kind(Interner), TyKind::Closure { .. })
}
pub fn is_fn(&self) -> bool {
- matches!(&self.ty.kind(Interner), TyKind::FnDef(..) | TyKind::Function { .. })
+ matches!(self.ty.kind(Interner), TyKind::FnDef(..) | TyKind::Function { .. })
}
pub fn is_array(&self) -> bool {
- matches!(&self.ty.kind(Interner), TyKind::Array(..))
+ matches!(self.ty.kind(Interner), TyKind::Array(..))
}
pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
@@ -3113,10 +3187,12 @@ impl Type {
}
pub fn is_raw_ptr(&self) -> bool {
- matches!(&self.ty.kind(Interner), TyKind::Raw(..))
+ matches!(self.ty.kind(Interner), TyKind::Raw(..))
}
pub fn contains_unknown(&self) -> bool {
+ // FIXME: When we get rid of `ConstScalar::Unknown`, we can just look at precomputed
+ // `TypeFlags` in `TyData`.
return go(&self.ty);
fn go(ty: &Ty) -> bool {
@@ -3182,6 +3258,19 @@ impl Type {
}
}
+ pub fn as_array(&self, _db: &dyn HirDatabase) -> Option<(Type, usize)> {
+ if let TyKind::Array(ty, len) = &self.ty.kind(Interner) {
+ match len.data(Interner).value {
+ ConstValue::Concrete(ConcreteConst { interned: ConstScalar::UInt(len) }) => {
+ Some((self.derived(ty.clone()), len as usize))
+ }
+ _ => None,
+ }
+ } else {
+ None
+ }
+ }
+
pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a {
self.autoderef_(db).map(move |ty| self.derived(ty))
}
@@ -3418,10 +3507,9 @@ impl Type {
Type { env: self.env.clone(), ty }
}
+ /// Visits every type, including generic arguments, in this type. `cb` is called with type
+ /// itself first, and then with its generic arguments.
pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) {
- // TypeWalk::walk for a Ty at first visits parameters and only after that the Ty itself.
- // We need a different order here.
-
fn walk_substs(
db: &dyn HirDatabase,
type_: &Type,
@@ -3534,6 +3622,14 @@ impl Type {
_ => None,
}
}
+
+ /// Returns unique `GenericParam`s contained in this type.
+ pub fn generic_params(&self, db: &dyn HirDatabase) -> FxHashSet<GenericParam> {
+ hir_ty::collect_placeholders(&self.ty, db)
+ .into_iter()
+ .map(|id| TypeOrConstParam { id }.split(db).either_into())
+ .collect()
+ }
}
#[derive(Debug)]
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index e0d261039..486b7ee62 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -1319,10 +1319,7 @@ impl<'db> SemanticsImpl<'db> {
let _p = profile::span("Semantics::analyze_impl");
let node = self.find_file(node);
- let container = match self.with_ctx(|ctx| ctx.find_container(node)) {
- Some(it) => it,
- None => return None,
- };
+ let container = self.with_ctx(|ctx| ctx.find_container(node))?;
let resolver = match container {
ChildContainer::DefWithBodyId(def) => {
@@ -1472,14 +1469,7 @@ impl<'db> SemanticsImpl<'db> {
}
fn is_inside_unsafe(&self, expr: &ast::Expr) -> bool {
- let item_or_variant = |ancestor: SyntaxNode| {
- if ast::Item::can_cast(ancestor.kind()) {
- ast::Item::cast(ancestor).map(Either::Left)
- } else {
- ast::Variant::cast(ancestor).map(Either::Right)
- }
- };
- let Some(enclosing_item) = expr.syntax().ancestors().find_map(item_or_variant) else { return false };
+ let Some(enclosing_item) = expr.syntax().ancestors().find_map(Either::<ast::Item, ast::Variant>::cast) else { return false };
let def = match &enclosing_item {
Either::Left(ast::Item::Fn(it)) if it.unsafe_token().is_some() => return true,
@@ -1589,7 +1579,7 @@ fn find_root(node: &SyntaxNode) -> SyntaxNode {
node.ancestors().last().unwrap()
}
-/// `SemanticScope` encapsulates the notion of a scope (the set of visible
+/// `SemanticsScope` encapsulates the notion of a scope (the set of visible
/// names) at a particular program point.
///
/// It is a bit tricky, as scopes do not really exist inside the compiler.
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
index fa45e3c12..2b5bfda1d 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs
@@ -87,7 +87,6 @@
use base_db::FileId;
use hir_def::{
- attr::AttrId,
child_by_source::ChildBySource,
dyn_map::DynMap,
expr::{LabelId, PatId},
@@ -96,7 +95,7 @@ use hir_def::{
GenericDefId, GenericParamId, ImplId, LifetimeParamId, MacroId, ModuleId, StaticId, StructId,
TraitId, TypeAliasId, TypeParamId, UnionId, VariantId,
};
-use hir_expand::{name::AsName, HirFileId, MacroCallId};
+use hir_expand::{attrs::AttrId, name::AsName, HirFileId, MacroCallId};
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use stdx::impl_from;
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index 059b80bcf..3b39e9fa9 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -17,6 +17,7 @@ use hir_def::{
Body, BodySourceMap,
},
expr::{ExprId, Pat, PatId},
+ lang_item::LangItem,
macro_id_to_def_id,
path::{ModPath, Path, PathKind},
resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs},
@@ -37,7 +38,7 @@ use hir_ty::{
record_literal_missing_fields, record_pattern_missing_fields, unsafe_expressions,
UnsafeExpr,
},
- method_resolution::{self, lang_names_for_bin_op},
+ method_resolution::{self, lang_items_for_bin_op},
Adjustment, InferenceResult, Interner, Substitution, Ty, TyExt, TyKind, TyLoweringContext,
};
use itertools::Itertools;
@@ -294,12 +295,8 @@ impl SourceAnalyzer {
}
}
- let future_trait = db
- .lang_item(self.resolver.krate(), hir_expand::name![future_trait].to_smol_str())?
- .as_trait()?;
- let poll_fn = db
- .lang_item(self.resolver.krate(), hir_expand::name![poll].to_smol_str())?
- .as_function()?;
+ let future_trait = db.lang_item(self.resolver.krate(), LangItem::Future)?.as_trait()?;
+ let poll_fn = db.lang_item(self.resolver.krate(), LangItem::FuturePoll)?.as_function()?;
// HACK: subst for `poll()` coincides with that for `Future` because `poll()` itself
// doesn't have any generic parameters, so we skip building another subst for `poll()`.
let substs = hir_ty::TyBuilder::subst_for_def(db, future_trait, None).push(ty).build();
@@ -311,14 +308,14 @@ impl SourceAnalyzer {
db: &dyn HirDatabase,
prefix_expr: &ast::PrefixExpr,
) -> Option<FunctionId> {
- let lang_item_name = match prefix_expr.op_kind()? {
- ast::UnaryOp::Deref => name![deref],
- ast::UnaryOp::Not => name![not],
- ast::UnaryOp::Neg => name![neg],
+ let (lang_item, fn_name) = match prefix_expr.op_kind()? {
+ ast::UnaryOp::Deref => (LangItem::Deref, name![deref]),
+ ast::UnaryOp::Not => (LangItem::Not, name![not]),
+ ast::UnaryOp::Neg => (LangItem::Neg, name![neg]),
};
let ty = self.ty_of_expr(db, &prefix_expr.expr()?)?;
- let (op_trait, op_fn) = self.lang_trait_fn(db, &lang_item_name, &lang_item_name)?;
+ let (op_trait, op_fn) = self.lang_trait_fn(db, lang_item, &fn_name)?;
// HACK: subst for all methods coincides with that for their trait because the methods
// don't have any generic parameters, so we skip building another subst for the methods.
let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None).push(ty.clone()).build();
@@ -334,9 +331,7 @@ impl SourceAnalyzer {
let base_ty = self.ty_of_expr(db, &index_expr.base()?)?;
let index_ty = self.ty_of_expr(db, &index_expr.index()?)?;
- let lang_item_name = name![index];
-
- let (op_trait, op_fn) = self.lang_trait_fn(db, &lang_item_name, &lang_item_name)?;
+ let (op_trait, op_fn) = self.lang_trait_fn(db, LangItem::Index, &name![index])?;
// HACK: subst for all methods coincides with that for their trait because the methods
// don't have any generic parameters, so we skip building another subst for the methods.
let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None)
@@ -355,8 +350,8 @@ impl SourceAnalyzer {
let lhs = self.ty_of_expr(db, &binop_expr.lhs()?)?;
let rhs = self.ty_of_expr(db, &binop_expr.rhs()?)?;
- let (op_trait, op_fn) = lang_names_for_bin_op(op)
- .and_then(|(name, lang_item)| self.lang_trait_fn(db, &lang_item, &name))?;
+ let (op_trait, op_fn) = lang_items_for_bin_op(op)
+ .and_then(|(name, lang_item)| self.lang_trait_fn(db, lang_item, &name))?;
// HACK: subst for `index()` coincides with that for `Index` because `index()` itself
// doesn't have any generic parameters, so we skip building another subst for `index()`.
let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None)
@@ -374,8 +369,7 @@ impl SourceAnalyzer {
) -> Option<FunctionId> {
let ty = self.ty_of_expr(db, &try_expr.expr()?)?;
- let op_fn =
- db.lang_item(self.resolver.krate(), name![branch].to_smol_str())?.as_function()?;
+ let op_fn = db.lang_item(self.resolver.krate(), LangItem::TryTraitBranch)?.as_function()?;
let op_trait = match op_fn.lookup(db.upcast()).container {
ItemContainerId::TraitId(id) => id,
_ => return None,
@@ -504,7 +498,7 @@ impl SourceAnalyzer {
AssocItemId::ConstId(const_id) => {
self.resolve_impl_const_or_trait_def(db, const_id, subs).into()
}
- _ => assoc,
+ assoc => assoc,
};
return Some(PathResolution::Def(AssocItem::from(assoc).into()));
@@ -517,7 +511,13 @@ impl SourceAnalyzer {
prefer_value_ns = true;
} else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
let pat_id = self.pat_id(&path_pat.into())?;
- if let Some((assoc, _)) = infer.assoc_resolutions_for_pat(pat_id) {
+ if let Some((assoc, subs)) = infer.assoc_resolutions_for_pat(pat_id) {
+ let assoc = match assoc {
+ AssocItemId::ConstId(const_id) => {
+ self.resolve_impl_const_or_trait_def(db, const_id, subs).into()
+ }
+ assoc => assoc,
+ };
return Some(PathResolution::Def(AssocItem::from(assoc).into()));
}
if let Some(VariantId::EnumVariantId(variant)) =
@@ -628,7 +628,7 @@ impl SourceAnalyzer {
{
return Some(PathResolution::DeriveHelper(DeriveHelper {
derive: *macro_id,
- idx,
+ idx: idx as u32,
}));
}
}
@@ -815,10 +815,10 @@ impl SourceAnalyzer {
fn lang_trait_fn(
&self,
db: &dyn HirDatabase,
- lang_trait: &Name,
+ lang_trait: LangItem,
method_name: &Name,
) -> Option<(TraitId, FunctionId)> {
- let trait_id = db.lang_item(self.resolver.krate(), lang_trait.to_smol_str())?.as_trait()?;
+ let trait_id = db.lang_item(self.resolver.krate(), lang_trait)?.as_trait()?;
let fn_id = db.trait_data(trait_id).method_by_name(method_name)?;
Some((trait_id, fn_id))
}