mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 12:29:21 +00:00
Added const bodies and static body to the ast
and added inference the inference test reduce code duplication
This commit is contained in:
parent
7f3bf7cc73
commit
88e22e9d70
10 changed files with 180 additions and 91 deletions
|
@ -436,65 +436,33 @@ impl Docs for EnumVariant {
|
||||||
/// The defs which have a body.
|
/// The defs which have a body.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum DefWithBody {
|
pub enum DefWithBody {
|
||||||
Func(Function),
|
Function(Function),
|
||||||
Const(Const),
|
Const(Const),
|
||||||
Static(Static),
|
Static(Static),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_froms!(DefWithBody: Function, Const, Static);
|
||||||
|
|
||||||
impl DefWithBody {
|
impl DefWithBody {
|
||||||
pub fn get_funct(&self) -> &Function {
|
|
||||||
match *self {
|
|
||||||
DefWithBody::Func(ref f) => f,
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn const_source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::ConstDef>) {
|
|
||||||
match *self {
|
|
||||||
DefWithBody::Const(ref c) => c.source(db),
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn func_source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::FnDef>) {
|
|
||||||
match *self {
|
|
||||||
DefWithBody::Func(ref f) => f.source(db),
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn static_source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StaticDef>) {
|
|
||||||
match *self {
|
|
||||||
DefWithBody::Static(ref s) => s.source(db),
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> {
|
pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> {
|
||||||
db.infer(*self)
|
db.infer(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
|
||||||
|
db.body_with_source_map(*self).1
|
||||||
|
}
|
||||||
|
|
||||||
pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> {
|
pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> {
|
||||||
db.body_hir(*self)
|
db.body_hir(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a resolver for code inside this item.
|
/// Builds a resolver for code inside this item.
|
||||||
pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
|
pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
|
||||||
// // take the outer scope...
|
match *self {
|
||||||
// let r = self
|
DefWithBody::Const(ref c) => c.resolver(db),
|
||||||
// .impl_block(db)
|
DefWithBody::Function(ref f) => f.resolver(db),
|
||||||
// .map(|ib| ib.resolver(db))
|
DefWithBody::Static(ref s) => s.resolver(db),
|
||||||
// .unwrap_or_else(|| self.module(db).resolver(db));
|
|
||||||
// // ...and add generic params, if present
|
|
||||||
// let p = self.generic_params(db);
|
|
||||||
// let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r };
|
|
||||||
// r
|
|
||||||
unimplemented!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> {
|
|
||||||
// db.fn_signature(*self)
|
|
||||||
unimplemented!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSourceMap {
|
pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSourceMap {
|
||||||
|
@ -502,7 +470,6 @@ impl DefWithBody {
|
||||||
let source_map = db.body_with_source_map(*self).1;
|
let source_map = db.body_with_source_map(*self).1;
|
||||||
ScopesWithSourceMap { scopes, source_map }
|
ScopesWithSourceMap { scopes, source_map }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
@ -555,11 +522,11 @@ impl Function {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
|
pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
|
||||||
db.body_with_source_map(DefWithBody::Func(*self)).1
|
db.body_with_source_map((*self).into()).1
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> {
|
pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> {
|
||||||
db.body_hir(DefWithBody::Func(*self))
|
db.body_hir((*self).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty(&self, db: &impl HirDatabase) -> Ty {
|
pub fn ty(&self, db: &impl HirDatabase) -> Ty {
|
||||||
|
@ -567,8 +534,8 @@ impl Function {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSourceMap {
|
pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSourceMap {
|
||||||
let scopes = db.expr_scopes( DefWithBody::Func(*self));
|
let scopes = db.expr_scopes((*self).into());
|
||||||
let source_map = db.body_with_source_map(DefWithBody::Func(*self)).1;
|
let source_map = db.body_with_source_map((*self).into()).1;
|
||||||
ScopesWithSourceMap { scopes, source_map }
|
ScopesWithSourceMap { scopes, source_map }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,7 +544,7 @@ impl Function {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> {
|
pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> {
|
||||||
db.infer(DefWithBody::Func(*self))
|
db.infer((*self).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> {
|
pub fn generic_params(&self, db: &impl DefDatabase) -> Arc<GenericParams> {
|
||||||
|
@ -633,6 +600,14 @@ impl Const {
|
||||||
db.const_signature(*self)
|
db.const_signature(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> {
|
||||||
|
db.infer((*self).into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
|
||||||
|
db.body_with_source_map((*self).into()).1
|
||||||
|
}
|
||||||
|
|
||||||
/// The containing impl block, if this is a method.
|
/// The containing impl block, if this is a method.
|
||||||
pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> {
|
pub fn impl_block(&self, db: &impl DefDatabase) -> Option<ImplBlock> {
|
||||||
let module_impls = db.impls_in_module(self.module(db));
|
let module_impls = db.impls_in_module(self.module(db));
|
||||||
|
@ -697,6 +672,14 @@ impl Static {
|
||||||
// take the outer scope...
|
// take the outer scope...
|
||||||
self.module(db).resolver(db)
|
self.module(db).resolver(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn infer(&self, db: &impl HirDatabase) -> Arc<InferenceResult> {
|
||||||
|
db.infer((*self).into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
|
||||||
|
db.body_with_source_map((*self).into()).1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Docs for Static {
|
impl Docs for Static {
|
||||||
|
|
|
@ -87,7 +87,7 @@ pub trait HirDatabase: DefDatabase {
|
||||||
fn expr_scopes(&self, def: DefWithBody) -> Arc<ExprScopes>;
|
fn expr_scopes(&self, def: DefWithBody) -> Arc<ExprScopes>;
|
||||||
|
|
||||||
#[salsa::invoke(crate::ty::infer)]
|
#[salsa::invoke(crate::ty::infer)]
|
||||||
fn infer(&self, def:DefWithBody) -> Arc<InferenceResult>;
|
fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>;
|
||||||
|
|
||||||
#[salsa::invoke(crate::ty::type_for_def)]
|
#[salsa::invoke(crate::ty::type_for_def)]
|
||||||
fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty;
|
fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty;
|
||||||
|
|
|
@ -10,7 +10,7 @@ use ra_syntax::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Path, Name, HirDatabase, Function, Resolver,DefWithBody,
|
Path, Name, HirDatabase, Resolver,DefWithBody,
|
||||||
name::AsName,
|
name::AsName,
|
||||||
type_ref::{Mutability, TypeRef},
|
type_ref::{Mutability, TypeRef},
|
||||||
};
|
};
|
||||||
|
@ -27,8 +27,7 @@ impl_arena_id!(ExprId);
|
||||||
/// The body of an item (function, const etc.).
|
/// The body of an item (function, const etc.).
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub struct Body {
|
pub struct Body {
|
||||||
// FIXME: this should be more general, consts & statics also have bodies
|
/// The def of the item this body belongs to
|
||||||
/// The Function of the item this body belongs to
|
|
||||||
owner: DefWithBody,
|
owner: DefWithBody,
|
||||||
exprs: Arena<ExprId, Expr>,
|
exprs: Arena<ExprId, Expr>,
|
||||||
pats: Arena<PatId, Pat>,
|
pats: Arena<PatId, Pat>,
|
||||||
|
@ -503,9 +502,6 @@ impl ExprCollector {
|
||||||
self.exprs.alloc(block)
|
self.exprs.alloc(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn collect_expr(&mut self, expr: &ast::Expr) -> ExprId {
|
fn collect_expr(&mut self, expr: &ast::Expr) -> ExprId {
|
||||||
let syntax_ptr = SyntaxNodePtr::new(expr.syntax());
|
let syntax_ptr = SyntaxNodePtr::new(expr.syntax());
|
||||||
match expr.kind() {
|
match expr.kind() {
|
||||||
|
@ -874,13 +870,14 @@ impl ExprCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collect_const_body(&mut self, node: &ast::ConstDef) {
|
||||||
fn collect_const_body(&mut self,node:&ast::ConstDef) {
|
let body = self.collect_expr_opt(node.body());
|
||||||
|
self.body_expr = Some(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_static_body(&mut self,node:&ast::StaticDef) {
|
fn collect_static_body(&mut self, node: &ast::StaticDef) {
|
||||||
|
let body = self.collect_expr_opt(node.body());
|
||||||
|
self.body_expr = Some(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_fn_body(&mut self, node: &ast::FnDef) {
|
fn collect_fn_body(&mut self, node: &ast::FnDef) {
|
||||||
|
@ -931,15 +928,12 @@ pub(crate) fn body_with_source_map_query(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
def: DefWithBody,
|
def: DefWithBody,
|
||||||
) -> (Arc<Body>, Arc<BodySourceMap>) {
|
) -> (Arc<Body>, Arc<BodySourceMap>) {
|
||||||
|
|
||||||
let mut collector = ExprCollector::new(def);
|
let mut collector = ExprCollector::new(def);
|
||||||
|
|
||||||
// FIXME: do can this be turned into a method
|
|
||||||
|
|
||||||
match def {
|
match def {
|
||||||
DefWithBody::Const(ref c) => collector.collect_const_body(&def.const_source(db).1),
|
DefWithBody::Const(ref c) => collector.collect_const_body(&c.source(db).1),
|
||||||
DefWithBody::Func(ref f) => collector.collect_fn_body(&def.func_source(db).1),
|
DefWithBody::Function(ref f) => collector.collect_fn_body(&f.source(db).1),
|
||||||
DefWithBody::Static(ref s) => collector.collect_static_body(&def.static_source(db).1)
|
DefWithBody::Static(ref s) => collector.collect_static_body(&s.source(db).1),
|
||||||
}
|
}
|
||||||
|
|
||||||
let (body, source_map) = collector.finish();
|
let (body, source_map) = collector.finish();
|
||||||
|
@ -950,9 +944,11 @@ pub(crate) fn body_hir_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<Bod
|
||||||
db.body_with_source_map(def).0
|
db.body_with_source_map(def).0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
use crate::{Function};
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn collect_fn_body_syntax(function: Function, node: &ast::FnDef) -> (Body, BodySourceMap) {
|
fn collect_fn_body_syntax(function: Function, node: &ast::FnDef) -> (Body, BodySourceMap) {
|
||||||
let mut collector = ExprCollector::new(function);
|
let mut collector = ExprCollector::new(DefWithBody::Function(function));
|
||||||
collector.collect_fn_body(node);
|
collector.collect_fn_body(node);
|
||||||
collector.finish()
|
collector.finish()
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use ra_syntax::{
|
||||||
use ra_arena::{Arena, RawId, impl_arena_id};
|
use ra_arena::{Arena, RawId, impl_arena_id};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Name, AsName, Function,DefWithBody,
|
Name, AsName,DefWithBody,
|
||||||
expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySourceMap},
|
expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySourceMap},
|
||||||
HirDatabase,
|
HirDatabase,
|
||||||
};
|
};
|
||||||
|
@ -297,6 +297,7 @@ mod tests {
|
||||||
use ra_syntax::{SourceFile, algo::find_node_at_offset};
|
use ra_syntax::{SourceFile, algo::find_node_at_offset};
|
||||||
use test_utils::{extract_offset, assert_eq_text};
|
use test_utils::{extract_offset, assert_eq_text};
|
||||||
use ra_arena::ArenaId;
|
use ra_arena::ArenaId;
|
||||||
|
use crate::{Function};
|
||||||
|
|
||||||
use crate::expr;
|
use crate::expr;
|
||||||
|
|
||||||
|
|
|
@ -74,5 +74,4 @@ pub use self::code_model_api::{
|
||||||
StructField, FieldSource,
|
StructField, FieldSource,
|
||||||
Static, Const, ConstSignature,
|
Static, Const, ConstSignature,
|
||||||
Trait, TypeAlias,
|
Trait, TypeAlias,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,7 +13,7 @@ use ra_syntax::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
HirDatabase, Function, Struct, Enum,
|
HirDatabase, Function, Struct, Enum,Const,Static,
|
||||||
AsName, Module, HirFileId, Crate, Trait, Resolver,
|
AsName, Module, HirFileId, Crate, Trait, Resolver,
|
||||||
ids::LocationCtx,
|
ids::LocationCtx,
|
||||||
expr, AstId
|
expr, AstId
|
||||||
|
@ -87,6 +87,27 @@ fn module_from_source(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn const_from_source(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
file_id: FileId,
|
||||||
|
const_def: &ast::ConstDef,
|
||||||
|
) -> Option<Const> {
|
||||||
|
let module = module_from_child_node(db, file_id, const_def.syntax())?;
|
||||||
|
let res = const_from_module(db, module, const_def);
|
||||||
|
Some(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn const_from_module(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
module: Module,
|
||||||
|
const_def: &ast::ConstDef,
|
||||||
|
) -> Const {
|
||||||
|
let (file_id, _) = module.definition_source(db);
|
||||||
|
let file_id = file_id.into();
|
||||||
|
let ctx = LocationCtx::new(db, module, file_id);
|
||||||
|
Const { id: ctx.to_def(const_def) }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> {
|
pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> {
|
||||||
let file = db.parse(position.file_id);
|
let file = db.parse(position.file_id);
|
||||||
let fn_def = find_node_at_offset::<ast::FnDef>(file.syntax(), position.offset)?;
|
let fn_def = find_node_at_offset::<ast::FnDef>(file.syntax(), position.offset)?;
|
||||||
|
@ -134,6 +155,27 @@ pub fn struct_from_module(
|
||||||
Struct { id: ctx.to_def(struct_def) }
|
Struct { id: ctx.to_def(struct_def) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn static_from_source(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
file_id: FileId,
|
||||||
|
static_def: &ast::StaticDef,
|
||||||
|
) -> Option<Static> {
|
||||||
|
let module = module_from_child_node(db, file_id, static_def.syntax())?;
|
||||||
|
let res = static_from_module(db, module, static_def);
|
||||||
|
Some(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn static_from_module(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
module: Module,
|
||||||
|
static_def: &ast::StaticDef,
|
||||||
|
) -> Static {
|
||||||
|
let (file_id, _) = module.definition_source(db);
|
||||||
|
let file_id = file_id.into();
|
||||||
|
let ctx = LocationCtx::new(db, module, file_id);
|
||||||
|
Static { id: ctx.to_def(static_def) }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum {
|
pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum {
|
||||||
let (file_id, _) = module.definition_source(db);
|
let (file_id, _) = module.definition_source(db);
|
||||||
let file_id = file_id.into();
|
let file_id = file_id.into();
|
||||||
|
|
|
@ -27,8 +27,9 @@ use test_utils::tested_by;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Function, StructField, Path, Name,
|
Function, StructField, Path, Name,
|
||||||
FnSignature, AdtDef,
|
FnSignature, AdtDef,ConstSignature,
|
||||||
HirDatabase,
|
HirDatabase,
|
||||||
|
DefWithBody,
|
||||||
ImplItem,
|
ImplItem,
|
||||||
type_ref::{TypeRef, Mutability},
|
type_ref::{TypeRef, Mutability},
|
||||||
expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self},
|
expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self},
|
||||||
|
@ -43,14 +44,17 @@ use crate::{
|
||||||
use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor};
|
use super::{Ty, TypableDef, Substs, primitive, op, FnSig, ApplicationTy, TypeCtor};
|
||||||
|
|
||||||
/// The entry point of type inference.
|
/// The entry point of type inference.
|
||||||
pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> {
|
pub fn infer(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> {
|
||||||
db.check_canceled();
|
db.check_canceled();
|
||||||
let body = func.body(db);
|
let body = def.body(db);
|
||||||
let resolver = func.resolver(db);
|
let resolver = def.resolver(db);
|
||||||
let mut ctx = InferenceContext::new(db, body, resolver);
|
let mut ctx = InferenceContext::new(db, body, resolver);
|
||||||
|
|
||||||
let signature = func.signature(db);
|
match def {
|
||||||
ctx.collect_fn_signature(&signature);
|
DefWithBody::Const(ref c) => ctx.collect_const_signature(&c.signature(db)),
|
||||||
|
DefWithBody::Function(ref f) => ctx.collect_fn_signature(&f.signature(db)),
|
||||||
|
DefWithBody::Static(ref s) => ctx.collect_const_signature(&s.signature(db)),
|
||||||
|
}
|
||||||
|
|
||||||
ctx.infer_body();
|
ctx.infer_body();
|
||||||
|
|
||||||
|
@ -1142,6 +1146,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
ty
|
ty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn collect_const_signature(&mut self, signature: &ConstSignature) {
|
||||||
|
self.return_ty = self.make_ty(signature.type_ref());
|
||||||
|
}
|
||||||
|
|
||||||
fn collect_fn_signature(&mut self, signature: &FnSignature) {
|
fn collect_fn_signature(&mut self, signature: &FnSignature) {
|
||||||
let body = Arc::clone(&self.body); // avoid borrow checker problem
|
let body = Arc::clone(&self.body); // avoid borrow checker problem
|
||||||
for (type_ref, pat) in signature.params().iter().zip(body.params()) {
|
for (type_ref, pat) in signature.params().iter().zip(body.params()) {
|
||||||
|
|
|
@ -11,6 +11,8 @@ use crate::{
|
||||||
source_binder,
|
source_binder,
|
||||||
mock::MockDatabase,
|
mock::MockDatabase,
|
||||||
ty::display::HirDisplay,
|
ty::display::HirDisplay,
|
||||||
|
ty::InferenceResult,
|
||||||
|
expr::BodySourceMap
|
||||||
};
|
};
|
||||||
|
|
||||||
// These tests compare the inference results for all expressions in a file
|
// These tests compare the inference results for all expressions in a file
|
||||||
|
@ -1267,6 +1269,9 @@ fn test() {
|
||||||
}
|
}
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
|
[52; 53) '1': u32
|
||||||
|
[103; 104) '2': u32
|
||||||
|
[211; 212) '5': u32
|
||||||
[227; 305) '{ ...:ID; }': ()
|
[227; 305) '{ ...:ID; }': ()
|
||||||
[237; 238) 'x': u32
|
[237; 238) 'x': u32
|
||||||
[241; 252) 'Struct::FOO': u32
|
[241; 252) 'Struct::FOO': u32
|
||||||
|
@ -1855,6 +1860,9 @@ fn test() {
|
||||||
}
|
}
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
|
[49; 50) '0': u32
|
||||||
|
[80; 83) '101': u32
|
||||||
|
[126; 128) '99': u32
|
||||||
[95; 213) '{ ...NST; }': ()
|
[95; 213) '{ ...NST; }': ()
|
||||||
[138; 139) 'x': {unknown}
|
[138; 139) 'x': {unknown}
|
||||||
[142; 153) 'LOCAL_CONST': {unknown}
|
[142; 153) 'LOCAL_CONST': {unknown}
|
||||||
|
@ -1881,6 +1889,10 @@ fn test() {
|
||||||
}
|
}
|
||||||
"#),
|
"#),
|
||||||
@r###"
|
@r###"
|
||||||
|
[29; 32) '101': u32
|
||||||
|
[70; 73) '101': u32
|
||||||
|
[118; 120) '99': u32
|
||||||
|
[161; 163) '99': u32
|
||||||
[85; 280) '{ ...MUT; }': ()
|
[85; 280) '{ ...MUT; }': ()
|
||||||
[173; 174) 'x': {unknown}
|
[173; 174) 'x': {unknown}
|
||||||
[177; 189) 'LOCAL_STATIC': {unknown}
|
[177; 189) 'LOCAL_STATIC': {unknown}
|
||||||
|
@ -2212,6 +2224,24 @@ fn test<T: Iterable<Item=u32>>() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn infer_const_body() {
|
||||||
|
assert_snapshot_matches!(
|
||||||
|
infer(r#"
|
||||||
|
const A: u32 = 1 + 1;
|
||||||
|
static B: u64 = { let x = 1; x };
|
||||||
|
"#),
|
||||||
|
@r###"
|
||||||
|
[16; 17) '1': u32
|
||||||
|
[16; 21) '1 + 1': u32
|
||||||
|
[20; 21) '1': u32
|
||||||
|
[39; 55) '{ let ...1; x }': u64
|
||||||
|
[45; 46) 'x': u64
|
||||||
|
[49; 50) '1': u64
|
||||||
|
[52; 53) 'x': u64"###
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
|
fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
|
||||||
let func = source_binder::function_from_position(db, pos).unwrap();
|
let func = source_binder::function_from_position(db, pos).unwrap();
|
||||||
let body_source_map = func.body_source_map(db);
|
let body_source_map = func.body_source_map(db);
|
||||||
|
@ -2228,11 +2258,11 @@ fn infer(content: &str) -> String {
|
||||||
let source_file = db.parse(file_id);
|
let source_file = db.parse(file_id);
|
||||||
let mut acc = String::new();
|
let mut acc = String::new();
|
||||||
acc.push_str("\n");
|
acc.push_str("\n");
|
||||||
for fn_def in source_file.syntax().descendants().filter_map(ast::FnDef::cast) {
|
|
||||||
let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap();
|
let mut infer_def = |inference_result: Arc<InferenceResult>,
|
||||||
let inference_result = func.infer(&db);
|
body_source_map: Arc<BodySourceMap>| {
|
||||||
let body_source_map = func.body_source_map(&db);
|
|
||||||
let mut types = Vec::new();
|
let mut types = Vec::new();
|
||||||
|
|
||||||
for (pat, ty) in inference_result.type_of_pat.iter() {
|
for (pat, ty) in inference_result.type_of_pat.iter() {
|
||||||
let syntax_ptr = match body_source_map.pat_syntax(pat) {
|
let syntax_ptr = match body_source_map.pat_syntax(pat) {
|
||||||
Some(sp) => sp,
|
Some(sp) => sp,
|
||||||
|
@ -2240,6 +2270,7 @@ fn infer(content: &str) -> String {
|
||||||
};
|
};
|
||||||
types.push((syntax_ptr, ty));
|
types.push((syntax_ptr, ty));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (expr, ty) in inference_result.type_of_expr.iter() {
|
for (expr, ty) in inference_result.type_of_expr.iter() {
|
||||||
let syntax_ptr = match body_source_map.expr_syntax(expr) {
|
let syntax_ptr = match body_source_map.expr_syntax(expr) {
|
||||||
Some(sp) => sp,
|
Some(sp) => sp,
|
||||||
|
@ -2260,7 +2291,29 @@ fn infer(content: &str) -> String {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for const_def in source_file.syntax().descendants().filter_map(ast::ConstDef::cast) {
|
||||||
|
let konst = source_binder::const_from_source(&db, file_id, const_def).unwrap();
|
||||||
|
let inference_result = konst.infer(&db);
|
||||||
|
let body_source_map = konst.body_source_map(&db);
|
||||||
|
infer_def(inference_result, body_source_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for static_def in source_file.syntax().descendants().filter_map(ast::StaticDef::cast) {
|
||||||
|
let static_ = source_binder::static_from_source(&db, file_id, static_def).unwrap();
|
||||||
|
let inference_result = static_.infer(&db);
|
||||||
|
let body_source_map = static_.body_source_map(&db);
|
||||||
|
infer_def(inference_result, body_source_map)
|
||||||
|
}
|
||||||
|
|
||||||
|
for fn_def in source_file.syntax().descendants().filter_map(ast::FnDef::cast) {
|
||||||
|
let func = source_binder::function_from_source(&db, file_id, fn_def).unwrap();
|
||||||
|
let inference_result = func.infer(&db);
|
||||||
|
let body_source_map = func.body_source_map(&db);
|
||||||
|
infer_def(inference_result, body_source_map)
|
||||||
|
}
|
||||||
|
|
||||||
acc.truncate(acc.trim_end().len());
|
acc.truncate(acc.trim_end().len());
|
||||||
acc
|
acc
|
||||||
}
|
}
|
||||||
|
|
|
@ -629,7 +629,11 @@ impl ast::TypeParamsOwner for ConstDef {}
|
||||||
impl ast::AttrsOwner for ConstDef {}
|
impl ast::AttrsOwner for ConstDef {}
|
||||||
impl ast::DocCommentsOwner for ConstDef {}
|
impl ast::DocCommentsOwner for ConstDef {}
|
||||||
impl ast::TypeAscriptionOwner for ConstDef {}
|
impl ast::TypeAscriptionOwner for ConstDef {}
|
||||||
impl ConstDef {}
|
impl ConstDef {
|
||||||
|
pub fn body(&self) -> Option<&Expr> {
|
||||||
|
super::child_opt(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ContinueExpr
|
// ContinueExpr
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
|
@ -657,7 +661,6 @@ impl ToOwned for ContinueExpr {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl ContinueExpr {}
|
impl ContinueExpr {}
|
||||||
|
|
||||||
// DynTraitType
|
// DynTraitType
|
||||||
|
@ -3808,7 +3811,11 @@ impl ast::TypeParamsOwner for StaticDef {}
|
||||||
impl ast::AttrsOwner for StaticDef {}
|
impl ast::AttrsOwner for StaticDef {}
|
||||||
impl ast::DocCommentsOwner for StaticDef {}
|
impl ast::DocCommentsOwner for StaticDef {}
|
||||||
impl ast::TypeAscriptionOwner for StaticDef {}
|
impl ast::TypeAscriptionOwner for StaticDef {}
|
||||||
impl StaticDef {}
|
impl StaticDef {
|
||||||
|
pub fn body(&self) -> Option<&Expr> {
|
||||||
|
super::child_opt(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Stmt
|
// Stmt
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
|
|
|
@ -313,7 +313,7 @@ Grammar(
|
||||||
"DocCommentsOwner",
|
"DocCommentsOwner",
|
||||||
"TypeAscriptionOwner",
|
"TypeAscriptionOwner",
|
||||||
],
|
],
|
||||||
options: ["body","Block"],
|
options: [ ["body","Expr"]],
|
||||||
),
|
),
|
||||||
"StaticDef": (
|
"StaticDef": (
|
||||||
traits: [
|
traits: [
|
||||||
|
@ -324,7 +324,7 @@ Grammar(
|
||||||
"DocCommentsOwner",
|
"DocCommentsOwner",
|
||||||
"TypeAscriptionOwner",
|
"TypeAscriptionOwner",
|
||||||
],
|
],
|
||||||
options: ["body","Block"],
|
options: [ ["body","Expr"]],
|
||||||
),
|
),
|
||||||
"TypeAliasDef": (
|
"TypeAliasDef": (
|
||||||
traits: [
|
traits: [
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue