7483: Classify function calls as functions when shadowed by types r=matklad a=Veykril

Fixes #7479

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-01-30 15:23:21 +00:00 committed by GitHub
commit f408ff5013
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 27 deletions

View File

@ -222,16 +222,19 @@ impl SourceAnalyzer {
db: &dyn HirDatabase,
path: &ast::Path,
) -> Option<PathResolution> {
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())?;
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())));
}
prefer_value_ns = true;
}
if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) {
@ -277,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(
@ -447,12 +450,22 @@ fn adjust(
.map(|(_ptr, scope)| *scope)
}
#[inline]
pub(crate) fn resolve_hir_path(
db: &dyn HirDatabase,
resolver: &Resolver,
path: &Path,
) -> Option<PathResolution> {
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<PathResolution> {
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 }),
@ -463,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) => {
@ -482,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.

View File

@ -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 });
}

View File

@ -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<FunctionId> {
match self {
&Ty::Apply(ApplicationTy {
ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)),
..
}) => Some(func),
_ => None,
}
}
pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> {
match self {
Ty::Apply(a_ty) => match a_ty.ctor {

View File

@ -108,6 +108,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="brace">}</span>
<span class="brace">}</span>
<span class="keyword">fn</span> <span class="function declaration">str</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
<span class="function">str</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
<span class="brace">}</span>
<span class="keyword">static</span> <span class="keyword">mut</span> <span class="static declaration mutable unsafe">STATIC_MUT</span><span class="colon">:</span> <span class="builtin_type">i32</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span>
<span class="keyword">fn</span> <span class="function declaration">foo</span><span class="angle">&lt;</span><span class="lifetime declaration">'a</span><span class="comma">,</span> <span class="type_param declaration">T</span><span class="angle">&gt;</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="type_param">T</span> <span class="brace">{</span>

View File

@ -81,6 +81,10 @@ impl FooCopy {
}
}
fn str() {
str();
}
static mut STATIC_MUT: i32 = 0;
fn foo<'a, T>() -> T {