Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/source_analyzer.rs')
| -rw-r--r-- | crates/hir/src/source_analyzer.rs | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 91ea1c24d1..059b80bcf1 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -21,8 +21,8 @@ use hir_def::{ path::{ModPath, Path, PathKind}, resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs}, type_ref::Mutability, - AsMacroCall, AssocItemId, DefWithBodyId, FieldId, FunctionId, ItemContainerId, LocalFieldId, - Lookup, ModuleDefId, TraitId, VariantId, + AsMacroCall, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, ItemContainerId, + LocalFieldId, Lookup, ModuleDefId, TraitId, VariantId, }; use hir_expand::{ builtin_fn_macro::BuiltinFnLikeExpander, @@ -118,7 +118,7 @@ impl SourceAnalyzer { fn expr_id(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option<ExprId> { let src = match expr { ast::Expr::MacroExpr(expr) => { - self.expand_expr(db, InFile::new(self.file_id, expr.macro_call()?.clone()))? + self.expand_expr(db, InFile::new(self.file_id, expr.macro_call()?))? } _ => InFile::new(self.file_id, expr.clone()), }; @@ -228,7 +228,7 @@ impl SourceAnalyzer { db: &dyn HirDatabase, pat: &ast::Pat, ) -> Option<SmallVec<[Type; 1]>> { - let pat_id = self.pat_id(&pat)?; + let pat_id = self.pat_id(pat)?; let infer = self.infer.as_ref()?; Some( infer @@ -270,7 +270,7 @@ impl SourceAnalyzer { db: &dyn HirDatabase, await_expr: &ast::AwaitExpr, ) -> Option<FunctionId> { - let mut ty = self.ty_of_expr(db, &await_expr.expr()?.into())?.clone(); + let mut ty = self.ty_of_expr(db, &await_expr.expr()?)?.clone(); let into_future_trait = self .resolver @@ -316,7 +316,7 @@ impl SourceAnalyzer { ast::UnaryOp::Not => name![not], ast::UnaryOp::Neg => name![neg], }; - let ty = self.ty_of_expr(db, &prefix_expr.expr()?.into())?; + 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)?; // HACK: subst for all methods coincides with that for their trait because the methods @@ -331,8 +331,8 @@ impl SourceAnalyzer { db: &dyn HirDatabase, index_expr: &ast::IndexExpr, ) -> Option<FunctionId> { - let base_ty = self.ty_of_expr(db, &index_expr.base()?.into())?; - let index_ty = self.ty_of_expr(db, &index_expr.index()?.into())?; + 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]; @@ -352,8 +352,8 @@ impl SourceAnalyzer { binop_expr: &ast::BinExpr, ) -> Option<FunctionId> { let op = binop_expr.op_kind()?; - let lhs = self.ty_of_expr(db, &binop_expr.lhs()?.into())?; - let rhs = self.ty_of_expr(db, &binop_expr.rhs()?.into())?; + 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))?; @@ -372,7 +372,7 @@ impl SourceAnalyzer { db: &dyn HirDatabase, try_expr: &ast::TryExpr, ) -> Option<FunctionId> { - let ty = self.ty_of_expr(db, &try_expr.expr()?.into())?; + 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()?; @@ -482,7 +482,7 @@ impl SourceAnalyzer { let infer = self.infer.as_deref()?; if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) { let expr_id = self.expr_id(db, &path_expr.into())?; - if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) { + if let Some((assoc, subs)) = infer.assoc_resolutions_for_expr(expr_id) { let assoc = match assoc { AssocItemId::FunctionId(f_in_trait) => { match infer.type_of_expr.get(expr_id) { @@ -501,7 +501,9 @@ impl SourceAnalyzer { } } } - + AssocItemId::ConstId(const_id) => { + self.resolve_impl_const_or_trait_def(db, const_id, subs).into() + } _ => assoc, }; @@ -515,7 +517,7 @@ 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, _)) = infer.assoc_resolutions_for_pat(pat_id) { return Some(PathResolution::Def(AssocItem::from(assoc).into())); } if let Some(VariantId::EnumVariantId(variant)) = @@ -792,6 +794,24 @@ impl SourceAnalyzer { method_resolution::lookup_impl_method(db, env, func, substs) } + fn resolve_impl_const_or_trait_def( + &self, + db: &dyn HirDatabase, + const_id: ConstId, + subs: Substitution, + ) -> ConstId { + let krate = self.resolver.krate(); + let owner = match self.resolver.body_owner() { + Some(it) => it, + None => return const_id, + }; + let env = owner.as_generic_def_id().map_or_else( + || Arc::new(hir_ty::TraitEnvironment::empty(krate)), + |d| db.trait_environment(d), + ); + method_resolution::lookup_impl_const(db, env, const_id, subs) + } + fn lang_trait_fn( &self, db: &dyn HirDatabase, @@ -804,7 +824,7 @@ impl SourceAnalyzer { } fn ty_of_expr(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option<&Ty> { - self.infer.as_ref()?.type_of_expr.get(self.expr_id(db, &expr)?) + self.infer.as_ref()?.type_of_expr.get(self.expr_id(db, expr)?) } } @@ -967,7 +987,7 @@ fn resolve_hir_path_( db, def, res.in_type_ns()?, - |name, _, id| (name == unresolved.name).then(|| id), + |name, id| (name == unresolved.name).then_some(id), ) }) .map(TypeAlias::from) |