Decouple more

This commit is contained in:
Aleksey Kladov 2019-11-27 15:56:20 +03:00
parent 35f57f35ec
commit d569869f7a
5 changed files with 41 additions and 40 deletions

View file

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

View file

@ -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> {

View file

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

View file

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

View file

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