mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Decouple more
This commit is contained in:
parent
35f57f35ec
commit
d569869f7a
5 changed files with 41 additions and 40 deletions
|
@ -647,7 +647,7 @@ impl Function {
|
||||||
|
|
||||||
pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
|
pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
|
||||||
let infer = self.infer(db);
|
let infer = self.infer(db);
|
||||||
infer.add_diagnostics(db, self, sink);
|
infer.add_diagnostics(db, self.id, sink);
|
||||||
let mut validator = ExprValidator::new(self, infer, sink);
|
let mut validator = ExprValidator::new(self, infer, sink);
|
||||||
validator.validate_body(db);
|
validator.validate_body(db);
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,17 +214,17 @@ impl SourceAnalyzer {
|
||||||
|
|
||||||
pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> {
|
pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> {
|
||||||
let expr_id = self.expr_id(&call.clone().into())?;
|
let expr_id = self.expr_id(&call.clone().into())?;
|
||||||
self.infer.as_ref()?.method_resolution(expr_id)
|
self.infer.as_ref()?.method_resolution(expr_id).map(Function::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<crate::StructField> {
|
pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<crate::StructField> {
|
||||||
let expr_id = self.expr_id(&field.clone().into())?;
|
let expr_id = self.expr_id(&field.clone().into())?;
|
||||||
self.infer.as_ref()?.field_resolution(expr_id)
|
self.infer.as_ref()?.field_resolution(expr_id).map(|it| it.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> {
|
pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> {
|
||||||
let expr_id = self.expr_id(&field.expr()?)?;
|
let expr_id = self.expr_id(&field.expr()?)?;
|
||||||
self.infer.as_ref()?.record_field_resolution(expr_id)
|
self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> {
|
pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> {
|
||||||
|
|
|
@ -22,11 +22,13 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
|
body::Body,
|
||||||
data::{ConstData, FunctionData},
|
data::{ConstData, FunctionData},
|
||||||
path::known,
|
expr::{BindingAnnotation, ExprId, PatId},
|
||||||
|
path::{known, Path},
|
||||||
resolver::{HasResolver, Resolver, TypeNs},
|
resolver::{HasResolver, Resolver, TypeNs},
|
||||||
type_ref::{Mutability, TypeRef},
|
type_ref::{Mutability, TypeRef},
|
||||||
AdtId, AssocItemId, DefWithBodyId,
|
AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId,
|
||||||
};
|
};
|
||||||
use hir_expand::{diagnostics::DiagnosticSink, name};
|
use hir_expand::{diagnostics::DiagnosticSink, name};
|
||||||
use ra_arena::map::ArenaMap;
|
use ra_arena::map::ArenaMap;
|
||||||
|
@ -34,16 +36,14 @@ use ra_prof::profile;
|
||||||
use test_utils::tested_by;
|
use test_utils::tested_by;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
primitive::{FloatTy, IntTy},
|
||||||
traits::{Guidance, Obligation, ProjectionPredicate, Solution},
|
traits::{Guidance, Obligation, ProjectionPredicate, Solution},
|
||||||
ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor,
|
ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor,
|
||||||
TypeWalk, Uncertain,
|
TypeWalk, Uncertain,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
code_model::TypeAlias,
|
db::HirDatabase, ty::infer::diagnostics::InferenceDiagnostic, AssocItem, DefWithBody,
|
||||||
db::HirDatabase,
|
VariantDef,
|
||||||
expr::{BindingAnnotation, Body, ExprId, PatId},
|
|
||||||
ty::infer::diagnostics::InferenceDiagnostic,
|
|
||||||
AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, VariantDef,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! ty_app {
|
macro_rules! ty_app {
|
||||||
|
@ -121,11 +121,11 @@ pub struct TypeMismatch {
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Default)]
|
#[derive(Clone, PartialEq, Eq, Debug, Default)]
|
||||||
pub struct InferenceResult {
|
pub struct InferenceResult {
|
||||||
/// For each method call expr, records the function it resolves to.
|
/// For each method call expr, records the function it resolves to.
|
||||||
method_resolutions: FxHashMap<ExprId, Function>,
|
method_resolutions: FxHashMap<ExprId, FunctionId>,
|
||||||
/// For each field access expr, records the field it resolves to.
|
/// For each field access expr, records the field it resolves to.
|
||||||
field_resolutions: FxHashMap<ExprId, StructField>,
|
field_resolutions: FxHashMap<ExprId, StructFieldId>,
|
||||||
/// For each field in record literal, records the field it resolves to.
|
/// For each field in record literal, records the field it resolves to.
|
||||||
record_field_resolutions: FxHashMap<ExprId, StructField>,
|
record_field_resolutions: FxHashMap<ExprId, StructFieldId>,
|
||||||
/// For each struct literal, records the variant it resolves to.
|
/// For each struct literal, records the variant it resolves to.
|
||||||
variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>,
|
variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>,
|
||||||
/// For each associated item record what it resolves to
|
/// For each associated item record what it resolves to
|
||||||
|
@ -137,13 +137,13 @@ pub struct InferenceResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InferenceResult {
|
impl InferenceResult {
|
||||||
pub fn method_resolution(&self, expr: ExprId) -> Option<Function> {
|
pub fn method_resolution(&self, expr: ExprId) -> Option<FunctionId> {
|
||||||
self.method_resolutions.get(&expr).copied()
|
self.method_resolutions.get(&expr).copied()
|
||||||
}
|
}
|
||||||
pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> {
|
pub fn field_resolution(&self, expr: ExprId) -> Option<StructFieldId> {
|
||||||
self.field_resolutions.get(&expr).copied()
|
self.field_resolutions.get(&expr).copied()
|
||||||
}
|
}
|
||||||
pub fn record_field_resolution(&self, expr: ExprId) -> Option<StructField> {
|
pub fn record_field_resolution(&self, expr: ExprId) -> Option<StructFieldId> {
|
||||||
self.record_field_resolutions.get(&expr).copied()
|
self.record_field_resolutions.get(&expr).copied()
|
||||||
}
|
}
|
||||||
pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantDef> {
|
pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantDef> {
|
||||||
|
@ -164,7 +164,7 @@ impl InferenceResult {
|
||||||
pub(crate) fn add_diagnostics(
|
pub(crate) fn add_diagnostics(
|
||||||
&self,
|
&self,
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
owner: Function,
|
owner: FunctionId,
|
||||||
sink: &mut DiagnosticSink,
|
sink: &mut DiagnosticSink,
|
||||||
) {
|
) {
|
||||||
self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink))
|
self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink))
|
||||||
|
@ -243,11 +243,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
self.result.type_of_expr.insert(expr, ty);
|
self.result.type_of_expr.insert(expr, ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_method_resolution(&mut self, expr: ExprId, func: Function) {
|
fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId) {
|
||||||
self.result.method_resolutions.insert(expr, func);
|
self.result.method_resolutions.insert(expr, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_field_resolution(&mut self, expr: ExprId, field: StructField) {
|
fn write_field_resolution(&mut self, expr: ExprId, field: StructFieldId) {
|
||||||
self.result.field_resolutions.insert(expr, field);
|
self.result.field_resolutions.insert(expr, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,22 +557,22 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
self.infer_expr(self.body.body_expr, &Expectation::has_type(self.return_ty.clone()));
|
self.infer_expr(self.body.body_expr, &Expectation::has_type(self.return_ty.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_into_iter_item(&self) -> Option<TypeAlias> {
|
fn resolve_into_iter_item(&self) -> Option<TypeAliasId> {
|
||||||
let path = known::std_iter_into_iterator();
|
let path = known::std_iter_into_iterator();
|
||||||
let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
|
let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
|
||||||
self.db.trait_data(trait_).associated_type_by_name(&name::ITEM_TYPE).map(TypeAlias::from)
|
self.db.trait_data(trait_).associated_type_by_name(&name::ITEM_TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_ops_try_ok(&self) -> Option<TypeAlias> {
|
fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> {
|
||||||
let path = known::std_ops_try();
|
let path = known::std_ops_try();
|
||||||
let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
|
let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
|
||||||
self.db.trait_data(trait_).associated_type_by_name(&name::OK_TYPE).map(TypeAlias::from)
|
self.db.trait_data(trait_).associated_type_by_name(&name::OK_TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_future_future_output(&self) -> Option<TypeAlias> {
|
fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
|
||||||
let path = known::std_future_future();
|
let path = known::std_future_future();
|
||||||
let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
|
let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
|
||||||
self.db.trait_data(trait_).associated_type_by_name(&name::OUTPUT_TYPE).map(TypeAlias::from)
|
self.db.trait_data(trait_).associated_type_by_name(&name::OUTPUT_TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_boxed_box(&self) -> Option<AdtId> {
|
fn resolve_boxed_box(&self) -> Option<AdtId> {
|
||||||
|
@ -696,9 +696,10 @@ impl Expectation {
|
||||||
}
|
}
|
||||||
|
|
||||||
mod diagnostics {
|
mod diagnostics {
|
||||||
|
use hir_def::{expr::ExprId, FunctionId, HasSource, Lookup};
|
||||||
use hir_expand::diagnostics::DiagnosticSink;
|
use hir_expand::diagnostics::DiagnosticSink;
|
||||||
|
|
||||||
use crate::{db::HirDatabase, diagnostics::NoSuchField, expr::ExprId, Function, HasSource};
|
use crate::{db::HirDatabase, diagnostics::NoSuchField};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub(super) enum InferenceDiagnostic {
|
pub(super) enum InferenceDiagnostic {
|
||||||
|
@ -709,13 +710,14 @@ mod diagnostics {
|
||||||
pub(super) fn add_to(
|
pub(super) fn add_to(
|
||||||
&self,
|
&self,
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
owner: Function,
|
owner: FunctionId,
|
||||||
sink: &mut DiagnosticSink,
|
sink: &mut DiagnosticSink,
|
||||||
) {
|
) {
|
||||||
match self {
|
match self {
|
||||||
InferenceDiagnostic::NoSuchField { expr, field } => {
|
InferenceDiagnostic::NoSuchField { expr, field } => {
|
||||||
let file = owner.source(db).file_id;
|
let file = owner.lookup(db).source(db).file_id;
|
||||||
let field = owner.body_source_map(db).field_syntax(*expr, *field);
|
let (_, source_map) = db.body_with_source_map(owner.into());
|
||||||
|
let field = source_map.field_syntax(*expr, *field);
|
||||||
sink.push(NoSuchField { file, field })
|
sink.push(NoSuchField { file, field })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
let projection = ProjectionPredicate {
|
let projection = ProjectionPredicate {
|
||||||
ty: pat_ty.clone(),
|
ty: pat_ty.clone(),
|
||||||
projection_ty: ProjectionTy {
|
projection_ty: ProjectionTy {
|
||||||
associated_ty: into_iter_item_alias.id,
|
associated_ty: into_iter_item_alias,
|
||||||
parameters: Substs::single(iterable_ty),
|
parameters: Substs::single(iterable_ty),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -230,7 +230,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if let Some(field_def) = field_def {
|
if let Some(field_def) = field_def {
|
||||||
self.result.record_field_resolutions.insert(field.expr, field_def);
|
self.result.record_field_resolutions.insert(field.expr, field_def.into());
|
||||||
}
|
}
|
||||||
let field_ty = field_def
|
let field_ty = field_def
|
||||||
.map_or(Ty::Unknown, |it| field_types[it.id].clone())
|
.map_or(Ty::Unknown, |it| field_types[it.id].clone())
|
||||||
|
@ -262,7 +262,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
self.db.struct_data(s).variant_data.field(name).map(|local_id| {
|
self.db.struct_data(s).variant_data.field(name).map(|local_id| {
|
||||||
let field = StructFieldId { parent: s.into(), local_id }.into();
|
let field = StructFieldId { parent: s.into(), local_id }.into();
|
||||||
self.write_field_resolution(tgt_expr, field);
|
self.write_field_resolution(tgt_expr, field);
|
||||||
self.db.field_types(s.into())[field.id]
|
self.db.field_types(s.into())[field.local_id]
|
||||||
.clone()
|
.clone()
|
||||||
.subst(&a_ty.parameters)
|
.subst(&a_ty.parameters)
|
||||||
})
|
})
|
||||||
|
@ -285,7 +285,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
let projection = ProjectionPredicate {
|
let projection = ProjectionPredicate {
|
||||||
ty: ty.clone(),
|
ty: ty.clone(),
|
||||||
projection_ty: ProjectionTy {
|
projection_ty: ProjectionTy {
|
||||||
associated_ty: future_future_output_alias.id,
|
associated_ty: future_future_output_alias,
|
||||||
parameters: Substs::single(inner_ty),
|
parameters: Substs::single(inner_ty),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -304,7 +304,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
let projection = ProjectionPredicate {
|
let projection = ProjectionPredicate {
|
||||||
ty: ty.clone(),
|
ty: ty.clone(),
|
||||||
projection_ty: ProjectionTy {
|
projection_ty: ProjectionTy {
|
||||||
associated_ty: ops_try_ok_alias.id,
|
associated_ty: ops_try_ok_alias,
|
||||||
parameters: Substs::single(inner_ty),
|
parameters: Substs::single(inner_ty),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -557,7 +557,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
Some((ty, func)) => {
|
Some((ty, func)) => {
|
||||||
let ty = canonicalized_receiver.decanonicalize_ty(ty);
|
let ty = canonicalized_receiver.decanonicalize_ty(ty);
|
||||||
self.write_method_resolution(tgt_expr, func);
|
self.write_method_resolution(tgt_expr, func);
|
||||||
(ty, self.db.value_ty(func.id.into()), Some(self.db.generic_params(func.id.into())))
|
(ty, self.db.value_ty(func.into()), Some(self.db.generic_params(func.into())))
|
||||||
}
|
}
|
||||||
None => (receiver_ty, Ty::Unknown, None),
|
None => (receiver_ty, Ty::Unknown, None),
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::sync::Arc;
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, type_ref::Mutability,
|
lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, type_ref::Mutability,
|
||||||
AssocItemId, AstItemDef, HasModule, ImplId, TraitId,
|
AssocItemId, AstItemDef, FunctionId, HasModule, ImplId, TraitId,
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
use ra_db::CrateId;
|
use ra_db::CrateId;
|
||||||
|
@ -18,7 +18,6 @@ use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
ty::primitive::{FloatBitness, Uncertain},
|
ty::primitive::{FloatBitness, Uncertain},
|
||||||
ty::{utils::all_super_traits, Ty, TypeCtor},
|
ty::{utils::all_super_traits, Ty, TypeCtor},
|
||||||
Function,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef};
|
use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef};
|
||||||
|
@ -154,10 +153,10 @@ pub(crate) fn lookup_method(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
name: &Name,
|
name: &Name,
|
||||||
resolver: &Resolver,
|
resolver: &Resolver,
|
||||||
) -> Option<(Ty, Function)> {
|
) -> Option<(Ty, FunctionId)> {
|
||||||
iterate_method_candidates(ty, db, resolver, Some(name), LookupMode::MethodCall, |ty, f| match f
|
iterate_method_candidates(ty, db, resolver, Some(name), LookupMode::MethodCall, |ty, f| match f
|
||||||
{
|
{
|
||||||
AssocItemId::FunctionId(f) => Some((ty.clone(), f.into())),
|
AssocItemId::FunctionId(f) => Some((ty.clone(), f)),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue