From 426ad8e165aeb70a3d12b8bc870cb0c57a308bc7 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 28 Jan 2021 19:06:33 +0100 Subject: [PATCH 1/2] Classify function calls as functions when shadowed by types --- crates/hir/src/source_analyzer.rs | 8 ++++++-- crates/hir_ty/src/diagnostics/unsafe_check.rs | 12 +++--------- crates/hir_ty/src/lib.rs | 19 ++++++++++++++----- .../test_data/highlighting.html | 4 ++++ crates/ide/src/syntax_highlighting/tests.rs | 4 ++++ 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 30a8e513dd1..524120d0858 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -224,14 +224,18 @@ impl SourceAnalyzer { ) -> Option { if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { let expr_id = self.expr_id(db, &path_expr.into())?; - if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) { + let infer = self.infer.as_ref()?; + if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) { return Some(PathResolution::AssocItem(assoc.into())); } if let Some(VariantId::EnumVariantId(variant)) = - self.infer.as_ref()?.variant_resolution_for_expr(expr_id) + infer.variant_resolution_for_expr(expr_id) { return Some(PathResolution::Def(ModuleDef::Variant(variant.into()))); } + if let Some(func) = infer[expr_id].as_fn_def() { + return Some(PathResolution::Def(ModuleDef::Function(func.into()))); + } } if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs index 6dc86282647..9c506112da2 100644 --- a/crates/hir_ty/src/diagnostics/unsafe_check.rs +++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs @@ -12,8 +12,7 @@ use hir_def::{ use hir_expand::diagnostics::DiagnosticSink; use crate::{ - db::HirDatabase, diagnostics::MissingUnsafe, lower::CallableDefId, ApplicationTy, - InferenceResult, Ty, TypeCtor, + db::HirDatabase, diagnostics::MissingUnsafe, ApplicationTy, InferenceResult, Ty, TypeCtor, }; pub(super) struct UnsafeValidator<'a, 'b: 'a> { @@ -87,13 +86,8 @@ fn walk_unsafe( ) { let expr = &body.exprs[current]; match expr { - Expr::Call { callee, .. } => { - let ty = &infer[*callee]; - if let &Ty::Apply(ApplicationTy { - ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)), - .. - }) = ty - { + &Expr::Call { callee, .. } => { + if let Some(func) = infer[callee].as_fn_def() { if db.function_data(func).is_unsafe { unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); } diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index d47f975d29f..6bec389f83e 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -29,8 +29,8 @@ use base_db::{salsa, CrateId}; use hir_def::{ expr::ExprId, type_ref::{Mutability, Rawness}, - AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, LifetimeParamId, Lookup, - TraitId, TypeAliasId, TypeParamId, + AdtId, AssocContainerId, DefWithBodyId, FunctionId, GenericDefId, HasModule, LifetimeParamId, + Lookup, TraitId, TypeAliasId, TypeParamId, }; use itertools::Itertools; @@ -43,10 +43,9 @@ use crate::{ pub use autoderef::autoderef; pub use infer::{InferTy, InferenceResult}; -pub use lower::CallableDefId; pub use lower::{ - associated_type_shorthand_candidates, callable_item_sig, ImplTraitLoweringMode, TyDefId, - TyLoweringContext, ValueTyDefId, + associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, + TyDefId, TyLoweringContext, ValueTyDefId, }; pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; @@ -824,6 +823,16 @@ impl Ty { } } + pub fn as_fn_def(&self) -> Option { + match self { + &Ty::Apply(ApplicationTy { + ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)), + .. + }) => Some(func), + _ => None, + } + } + pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option { match self { Ty::Apply(a_ty) => match a_ty.ctor { diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index 23714956660..2f983c0b8a1 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html @@ -108,6 +108,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } } +fn str() { + str(); +} + static mut STATIC_MUT: i32 = 0; fn foo<'a, T>() -> T { diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index a62704c39e7..1854da91421 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs @@ -81,6 +81,10 @@ impl FooCopy { } } +fn str() { + str(); +} + static mut STATIC_MUT: i32 = 0; fn foo<'a, T>() -> T { From e3eeccf8ef2029bb54ba05af420a65b429763477 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 29 Jan 2021 15:59:52 +0100 Subject: [PATCH 2/2] Prefer ValueNS when resolving hir path for PathExpressions --- crates/hir/src/source_analyzer.rs | 45 +++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 524120d0858..626c3078a01 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -222,6 +222,7 @@ impl SourceAnalyzer { db: &dyn HirDatabase, path: &ast::Path, ) -> Option { + let mut prefer_value_ns = false; if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { let expr_id = self.expr_id(db, &path_expr.into())?; let infer = self.infer.as_ref()?; @@ -233,9 +234,7 @@ impl SourceAnalyzer { { return Some(PathResolution::Def(ModuleDef::Variant(variant.into()))); } - if let Some(func) = infer[expr_id].as_fn_def() { - return Some(PathResolution::Def(ModuleDef::Function(func.into()))); - } + prefer_value_ns = true; } if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { @@ -281,7 +280,7 @@ impl SourceAnalyzer { } } - resolve_hir_path(db, &self.resolver, &hir_path) + resolve_hir_path_(db, &self.resolver, &hir_path, prefer_value_ns) } pub(crate) fn record_literal_missing_fields( @@ -451,12 +450,22 @@ fn adjust( .map(|(_ptr, scope)| *scope) } +#[inline] pub(crate) fn resolve_hir_path( db: &dyn HirDatabase, resolver: &Resolver, path: &Path, ) -> Option { - let types = + resolve_hir_path_(db, resolver, path, false) +} + +fn resolve_hir_path_( + db: &dyn HirDatabase, + resolver: &Resolver, + path: &Path, + prefer_value_ns: bool, +) -> Option { + let types = || { resolver.resolve_path_in_type_ns_fully(db.upcast(), path.mod_path()).map(|ty| match ty { TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), @@ -467,10 +476,11 @@ pub(crate) fn resolve_hir_path( TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), - }); + }) + }; let body_owner = resolver.body_owner(); - let values = + let values = || { resolver.resolve_path_in_value_ns_fully(db.upcast(), path.mod_path()).and_then(|val| { let res = match val { ValueNs::LocalBinding(pat_id) => { @@ -486,18 +496,25 @@ pub(crate) fn resolve_hir_path( ValueNs::GenericParam(it) => PathResolution::ConstParam(it.into()), }; Some(res) - }); + }) + }; - let items = resolver - .resolve_module_path_in_items(db.upcast(), path.mod_path()) - .take_types() - .map(|it| PathResolution::Def(it.into())); + let items = || { + resolver + .resolve_module_path_in_items(db.upcast(), path.mod_path()) + .take_types() + .map(|it| PathResolution::Def(it.into())) + }; - types.or(values).or(items).or_else(|| { + let macros = || { resolver .resolve_path_as_macro(db.upcast(), path.mod_path()) .map(|def| PathResolution::Macro(def.into())) - }) + }; + + if prefer_value_ns { values().or_else(types) } else { types().or_else(values) } + .or_else(items) + .or_else(macros) } /// Resolves a path where we know it is a qualifier of another path.