mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 21:13:37 +00:00
replace todo with fixme
This commit is contained in:
parent
2394a2ee35
commit
4fd8cfd6ad
29 changed files with 71 additions and 71 deletions
|
@ -136,7 +136,7 @@ impl CrateGraph {
|
||||||
self.arena[&crate_id].edition
|
self.arena[&crate_id].edition
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this only finds one crate with the given root; we could have multiple
|
// FIXME: this only finds one crate with the given root; we could have multiple
|
||||||
pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
|
pub fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
|
||||||
let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?;
|
let (&crate_id, _) = self.arena.iter().find(|(_crate_id, data)| data.file_id == file_id)?;
|
||||||
Some(crate_id)
|
Some(crate_id)
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl Crate {
|
||||||
crate_graph.edition(self.crate_id)
|
crate_graph.edition(self.crate_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: should this be in source_binder?
|
// FIXME: should this be in source_binder?
|
||||||
pub fn source_root_crates(
|
pub fn source_root_crates(
|
||||||
db: &impl PersistentHirDatabase,
|
db: &impl PersistentHirDatabase,
|
||||||
source_root: SourceRootId,
|
source_root: SourceRootId,
|
||||||
|
@ -301,7 +301,7 @@ impl Struct {
|
||||||
db.type_for_def((*self).into(), Namespace::Values)
|
db.type_for_def((*self).into(), Namespace::Values)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO move to a more general type
|
// FIXME move to a more general type
|
||||||
/// Builds a resolver for type references inside this struct.
|
/// Builds a resolver for type references inside this struct.
|
||||||
pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
|
pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
|
||||||
// take the outer scope...
|
// take the outer scope...
|
||||||
|
@ -361,7 +361,7 @@ impl Enum {
|
||||||
db.type_for_def((*self).into(), Namespace::Types)
|
db.type_for_def((*self).into(), Namespace::Types)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move to a more general type
|
// FIXME: move to a more general type
|
||||||
/// Builds a resolver for type references inside this struct.
|
/// Builds a resolver for type references inside this struct.
|
||||||
pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
|
pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
|
||||||
// take the outer scope...
|
// take the outer scope...
|
||||||
|
@ -513,7 +513,7 @@ impl Function {
|
||||||
ImplBlock::containing(module_impls, (*self).into())
|
ImplBlock::containing(module_impls, (*self).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move to a more general type for 'body-having' items
|
// FIXME: move to a more general type for 'body-having' items
|
||||||
/// 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...
|
// take the outer scope...
|
||||||
|
@ -558,7 +558,7 @@ impl Const {
|
||||||
ImplBlock::containing(module_impls, (*self).into())
|
ImplBlock::containing(module_impls, (*self).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move to a more general type for 'body-having' items
|
// FIXME: move to a more general type for 'body-having' items
|
||||||
/// 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...
|
// take the outer scope...
|
||||||
|
|
|
@ -27,7 +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 {
|
||||||
// TODO: this should be more general, consts & statics also have bodies
|
// FIXME: this should be more general, consts & statics also have bodies
|
||||||
/// The Function of the item this body belongs to
|
/// The Function of the item this body belongs to
|
||||||
owner: Function,
|
owner: Function,
|
||||||
exprs: Arena<ExprId, Expr>,
|
exprs: Arena<ExprId, Expr>,
|
||||||
|
@ -406,7 +406,7 @@ pub enum Pat {
|
||||||
Struct {
|
Struct {
|
||||||
path: Option<Path>,
|
path: Option<Path>,
|
||||||
args: Vec<FieldPat>,
|
args: Vec<FieldPat>,
|
||||||
// TODO: 'ellipsis' option
|
// FIXME: 'ellipsis' option
|
||||||
},
|
},
|
||||||
Range {
|
Range {
|
||||||
start: ExprId,
|
start: ExprId,
|
||||||
|
@ -547,7 +547,7 @@ impl ExprCollector {
|
||||||
if condition.pat().is_none() {
|
if condition.pat().is_none() {
|
||||||
self.collect_expr_opt(condition.expr())
|
self.collect_expr_opt(condition.expr())
|
||||||
} else {
|
} else {
|
||||||
// TODO handle while let
|
// FIXME handle while let
|
||||||
return self.alloc_expr(Expr::Missing, syntax_ptr);
|
return self.alloc_expr(Expr::Missing, syntax_ptr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -610,7 +610,7 @@ impl ExprCollector {
|
||||||
self.alloc_expr(path, syntax_ptr)
|
self.alloc_expr(path, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::ExprKind::ContinueExpr(_e) => {
|
ast::ExprKind::ContinueExpr(_e) => {
|
||||||
// TODO: labels
|
// FIXME: labels
|
||||||
self.alloc_expr(Expr::Continue, syntax_ptr)
|
self.alloc_expr(Expr::Continue, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::ExprKind::BreakExpr(e) => {
|
ast::ExprKind::BreakExpr(e) => {
|
||||||
|
@ -751,7 +751,7 @@ impl ExprCollector {
|
||||||
self.alloc_expr(Expr::Literal(lit), syntax_ptr)
|
self.alloc_expr(Expr::Literal(lit), syntax_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO implement HIR for these:
|
// FIXME implement HIR for these:
|
||||||
ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
ast::ExprKind::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||||
ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||||
ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
|
||||||
|
@ -844,7 +844,7 @@ impl ExprCollector {
|
||||||
Pat::Struct { path, args: fields }
|
Pat::Struct { path, args: fields }
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement
|
// FIXME: implement
|
||||||
ast::PatKind::LiteralPat(_) => Pat::Missing,
|
ast::PatKind::LiteralPat(_) => Pat::Missing,
|
||||||
ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing,
|
ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing,
|
||||||
};
|
};
|
||||||
|
@ -910,7 +910,7 @@ pub(crate) fn body_with_source_map_query(
|
||||||
) -> (Arc<Body>, Arc<BodySourceMap>) {
|
) -> (Arc<Body>, Arc<BodySourceMap>) {
|
||||||
let mut collector = ExprCollector::new(func);
|
let mut collector = ExprCollector::new(func);
|
||||||
|
|
||||||
// TODO: consts, etc.
|
// FIXME: consts, etc.
|
||||||
collector.collect_fn_body(&func.source(db).1);
|
collector.collect_fn_body(&func.source(db).1);
|
||||||
|
|
||||||
let (body, source_map) = collector.finish();
|
let (body, source_map) = collector.finish();
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub struct ScopeData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExprScopes {
|
impl ExprScopes {
|
||||||
// TODO: This should take something more general than Function
|
// FIXME: This should take something more general than Function
|
||||||
pub(crate) fn expr_scopes_query(db: &impl HirDatabase, function: Function) -> Arc<ExprScopes> {
|
pub(crate) fn expr_scopes_query(db: &impl HirDatabase, function: Function) -> Arc<ExprScopes> {
|
||||||
let body = db.body_hir(function);
|
let body = db.body_hir(function);
|
||||||
let res = ExprScopes::new(body);
|
let res = ExprScopes::new(body);
|
||||||
|
@ -148,7 +148,7 @@ impl ScopesWithSourceMap {
|
||||||
|
|
||||||
// XXX: during completion, cursor might be outside of any particular
|
// XXX: during completion, cursor might be outside of any particular
|
||||||
// expression. Try to figure out the correct scope...
|
// expression. Try to figure out the correct scope...
|
||||||
// TODO: move this to source binder?
|
// FIXME: move this to source binder?
|
||||||
fn adjust(&self, ptr: SyntaxNodePtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId {
|
fn adjust(&self, ptr: SyntaxNodePtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId {
|
||||||
let r = ptr.range();
|
let r = ptr.range();
|
||||||
let child_scopes = self
|
let child_scopes = self
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::{
|
||||||
/// Data about a generic parameter (to a function, struct, impl, ...).
|
/// Data about a generic parameter (to a function, struct, impl, ...).
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
pub struct GenericParam {
|
pub struct GenericParam {
|
||||||
// TODO: give generic params proper IDs
|
// FIXME: give generic params proper IDs
|
||||||
pub(crate) idx: u32,
|
pub(crate) idx: u32,
|
||||||
pub(crate) name: Name,
|
pub(crate) name: Name,
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,7 +161,7 @@ impl ImplData {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
//TODO: rename to ImplDef?
|
//FIXME: rename to ImplDef?
|
||||||
pub enum ImplItem {
|
pub enum ImplItem {
|
||||||
Method(Function),
|
Method(Function),
|
||||||
Const(Const),
|
Const(Const),
|
||||||
|
|
|
@ -296,7 +296,7 @@ impl CrateDefMap {
|
||||||
// plain import or absolute path in 2015: crate-relative with
|
// plain import or absolute path in 2015: crate-relative with
|
||||||
// fallback to extern prelude (with the simplification in
|
// fallback to extern prelude (with the simplification in
|
||||||
// rust-lang/rust#57745)
|
// rust-lang/rust#57745)
|
||||||
// TODO there must be a nicer way to write this condition
|
// FIXME there must be a nicer way to write this condition
|
||||||
PathKind::Plain | PathKind::Abs
|
PathKind::Plain | PathKind::Abs
|
||||||
if self.edition == Edition::Edition2015
|
if self.edition == Edition::Edition2015
|
||||||
&& (path.kind == PathKind::Abs || mode == ResolveMode::Import) =>
|
&& (path.kind == PathKind::Abs || mode == ResolveMode::Import) =>
|
||||||
|
|
|
@ -96,7 +96,7 @@ impl Path {
|
||||||
if let Some(q) = path.qualifier() {
|
if let Some(q) = path.qualifier() {
|
||||||
return Some(q);
|
return Some(q);
|
||||||
}
|
}
|
||||||
// TODO: this bottom up traversal is not too precise.
|
// FIXME: this bottom up traversal is not too precise.
|
||||||
// Should we handle do a top-down analysis, recording results?
|
// Should we handle do a top-down analysis, recording results?
|
||||||
let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?;
|
let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?;
|
||||||
let use_tree = use_tree_list.parent_use_tree();
|
let use_tree = use_tree_list.parent_use_tree();
|
||||||
|
@ -166,7 +166,7 @@ fn expand_use_tree<'a>(
|
||||||
// or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`)
|
// or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`)
|
||||||
Some(path) => match convert_path(prefix, path) {
|
Some(path) => match convert_path(prefix, path) {
|
||||||
Some(it) => Some(it),
|
Some(it) => Some(it),
|
||||||
None => return, // TODO: report errors somewhere
|
None => return, // FIXME: report errors somewhere
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
for child_tree in use_tree_list.use_trees() {
|
for child_tree in use_tree_list.use_trees() {
|
||||||
|
@ -194,7 +194,7 @@ fn expand_use_tree<'a>(
|
||||||
cb(path, Some(segment), alias)
|
cb(path, Some(segment), alias)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// TODO: report errors somewhere
|
// FIXME: report errors somewhere
|
||||||
// We get here if we do
|
// We get here if we do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub struct Resolver {
|
||||||
scopes: Vec<Scope>,
|
scopes: Vec<Scope>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO how to store these best
|
// FIXME how to store these best
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct ModuleItemMap {
|
pub(crate) struct ModuleItemMap {
|
||||||
crate_def_map: Arc<CrateDefMap>,
|
crate_def_map: Arc<CrateDefMap>,
|
||||||
|
@ -260,7 +260,7 @@ impl Scope {
|
||||||
fn collect_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, PerNs<Resolution>)) {
|
fn collect_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, PerNs<Resolution>)) {
|
||||||
match self {
|
match self {
|
||||||
Scope::ModuleScope(m) => {
|
Scope::ModuleScope(m) => {
|
||||||
// TODO: should we provide `self` here?
|
// FIXME: should we provide `self` here?
|
||||||
// f(
|
// f(
|
||||||
// Name::self_param(),
|
// Name::self_param(),
|
||||||
// PerNs::types(Resolution::Def {
|
// PerNs::types(Resolution::Def {
|
||||||
|
|
|
@ -164,7 +164,7 @@ pub fn resolver_for_position(db: &impl HirDatabase, position: FilePosition) -> R
|
||||||
let scope = scopes.scope_for_offset(position.offset);
|
let scope = scopes.scope_for_offset(position.offset);
|
||||||
Some(expr::resolver_for_scope(func.body(db), db, scope))
|
Some(expr::resolver_for_scope(func.body(db), db, scope))
|
||||||
} else {
|
} else {
|
||||||
// TODO const/static/array length
|
// FIXME const/static/array length
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -184,7 +184,7 @@ pub fn resolver_for_node(db: &impl HirDatabase, file_id: FileId, node: &SyntaxNo
|
||||||
let scope = scopes.scope_for(&node);
|
let scope = scopes.scope_for(&node);
|
||||||
Some(expr::resolver_for_scope(func.body(db), db, scope))
|
Some(expr::resolver_for_scope(func.body(db), db, scope))
|
||||||
} else {
|
} else {
|
||||||
// TODO const/static/array length
|
// FIXME const/static/array length
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -212,7 +212,7 @@ fn try_get_resolver_for_node(
|
||||||
} else if let Some(f) = ast::FnDef::cast(node) {
|
} else if let Some(f) = ast::FnDef::cast(node) {
|
||||||
function_from_source(db, file_id, f).map(|f| f.resolver(db))
|
function_from_source(db, file_id, f).map(|f| f.resolver(db))
|
||||||
} else {
|
} else {
|
||||||
// TODO add missing cases
|
// FIXME add missing cases
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ impl Ty {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn autoderef_step(&self, _db: &impl HirDatabase) -> Option<Ty> {
|
fn autoderef_step(&self, _db: &impl HirDatabase) -> Option<Ty> {
|
||||||
// TODO Deref::deref
|
// FIXME Deref::deref
|
||||||
self.builtin_deref()
|
self.builtin_deref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,7 +207,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
|
fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
|
||||||
let ty = Ty::from_hir(
|
let ty = Ty::from_hir(
|
||||||
self.db,
|
self.db,
|
||||||
// TODO use right resolver for block
|
// FIXME use right resolver for block
|
||||||
&self.resolver,
|
&self.resolver,
|
||||||
type_ref,
|
type_ref,
|
||||||
);
|
);
|
||||||
|
@ -414,11 +414,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Resolution::GenericParam(..) => {
|
Resolution::GenericParam(..) => {
|
||||||
// TODO associated item of generic param
|
// FIXME associated item of generic param
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Resolution::SelfType(_) => {
|
Resolution::SelfType(_) => {
|
||||||
// TODO associated item of self type
|
// FIXME associated item of self type
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -446,7 +446,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Resolve associated types
|
// FIXME: Resolve associated types
|
||||||
crate::ImplItem::TypeAlias(_) => None,
|
crate::ImplItem::TypeAlias(_) => None,
|
||||||
};
|
};
|
||||||
match matching_def {
|
match matching_def {
|
||||||
|
@ -504,7 +504,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
return (Ty::Unknown, None);
|
return (Ty::Unknown, None);
|
||||||
}
|
}
|
||||||
Some(Resolution::SelfType(..)) => {
|
Some(Resolution::SelfType(..)) => {
|
||||||
// TODO this is allowed in an impl for a struct, handle this
|
// FIXME this is allowed in an impl for a struct, handle this
|
||||||
return (Ty::Unknown, None);
|
return (Ty::Unknown, None);
|
||||||
}
|
}
|
||||||
None => return (Ty::Unknown, None),
|
None => return (Ty::Unknown, None),
|
||||||
|
@ -513,7 +513,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
None => return (Ty::Unknown, None),
|
None => return (Ty::Unknown, None),
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
};
|
};
|
||||||
// TODO remove the duplication between here and `Ty::from_path`?
|
// FIXME remove the duplication between here and `Ty::from_path`?
|
||||||
let substs = Ty::substs_from_path(self.db, resolver, path, def);
|
let substs = Ty::substs_from_path(self.db, resolver, path, def);
|
||||||
match def {
|
match def {
|
||||||
TypableDef::Struct(s) => {
|
TypableDef::Struct(s) => {
|
||||||
|
@ -590,7 +590,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
| Pat::Struct { .. }
|
| Pat::Struct { .. }
|
||||||
| Pat::Range { .. }
|
| Pat::Range { .. }
|
||||||
| Pat::Slice { .. } => true,
|
| Pat::Slice { .. } => true,
|
||||||
// TODO: Path/Lit might actually evaluate to ref, but inference is unimplemented.
|
// FIXME: Path/Lit might actually evaluate to ref, but inference is unimplemented.
|
||||||
Pat::Path(..) | Pat::Lit(..) => true,
|
Pat::Path(..) | Pat::Lit(..) => true,
|
||||||
Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false,
|
Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false,
|
||||||
};
|
};
|
||||||
|
@ -635,7 +635,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
let expectation = match expected.as_reference() {
|
let expectation = match expected.as_reference() {
|
||||||
Some((inner_ty, exp_mut)) => {
|
Some((inner_ty, exp_mut)) => {
|
||||||
if *mutability != exp_mut {
|
if *mutability != exp_mut {
|
||||||
// TODO: emit type error?
|
// FIXME: emit type error?
|
||||||
}
|
}
|
||||||
inner_ty
|
inner_ty
|
||||||
}
|
}
|
||||||
|
@ -651,7 +651,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
self.infer_struct_pat(p.as_ref(), fields, expected, default_bm)
|
self.infer_struct_pat(p.as_ref(), fields, expected, default_bm)
|
||||||
}
|
}
|
||||||
Pat::Path(path) => {
|
Pat::Path(path) => {
|
||||||
// TODO use correct resolver for the surrounding expression
|
// FIXME use correct resolver for the surrounding expression
|
||||||
let resolver = self.resolver.clone();
|
let resolver = self.resolver.clone();
|
||||||
self.infer_path_expr(&resolver, &path, pat.into()).unwrap_or(Ty::Unknown)
|
self.infer_path_expr(&resolver, &path, pat.into()).unwrap_or(Ty::Unknown)
|
||||||
}
|
}
|
||||||
|
@ -741,7 +741,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
|
Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
|
||||||
Expr::Loop { body } => {
|
Expr::Loop { body } => {
|
||||||
self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
|
self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
|
||||||
// TODO handle break with value
|
// FIXME handle break with value
|
||||||
Ty::simple(TypeCtor::Never)
|
Ty::simple(TypeCtor::Never)
|
||||||
}
|
}
|
||||||
Expr::While { condition, body } => {
|
Expr::While { condition, body } => {
|
||||||
|
@ -769,7 +769,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
self.infer_pat(*arg_pat, &expected, BindingMode::default());
|
self.infer_pat(*arg_pat, &expected, BindingMode::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: infer lambda type etc.
|
// FIXME: infer lambda type etc.
|
||||||
let _body_ty = self.infer_expr(*body, &Expectation::none());
|
let _body_ty = self.infer_expr(*body, &Expectation::none());
|
||||||
Ty::Unknown
|
Ty::Unknown
|
||||||
}
|
}
|
||||||
|
@ -795,7 +795,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
// not callable
|
// not callable
|
||||||
// TODO report an error?
|
// FIXME report an error?
|
||||||
(Vec::new(), Ty::Unknown)
|
(Vec::new(), Ty::Unknown)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -894,14 +894,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
expected.ty
|
expected.ty
|
||||||
}
|
}
|
||||||
Expr::Path(p) => {
|
Expr::Path(p) => {
|
||||||
// TODO this could be more efficient...
|
// FIXME this could be more efficient...
|
||||||
let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr);
|
let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr);
|
||||||
self.infer_path_expr(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
|
self.infer_path_expr(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
|
||||||
}
|
}
|
||||||
Expr::Continue => Ty::simple(TypeCtor::Never),
|
Expr::Continue => Ty::simple(TypeCtor::Never),
|
||||||
Expr::Break { expr } => {
|
Expr::Break { expr } => {
|
||||||
if let Some(expr) = expr {
|
if let Some(expr) = expr {
|
||||||
// TODO handle break with value
|
// FIXME handle break with value
|
||||||
self.infer_expr(*expr, &Expectation::none());
|
self.infer_expr(*expr, &Expectation::none());
|
||||||
}
|
}
|
||||||
Ty::simple(TypeCtor::Never)
|
Ty::simple(TypeCtor::Never)
|
||||||
|
@ -957,21 +957,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
Expr::Cast { expr, type_ref } => {
|
Expr::Cast { expr, type_ref } => {
|
||||||
let _inner_ty = self.infer_expr(*expr, &Expectation::none());
|
let _inner_ty = self.infer_expr(*expr, &Expectation::none());
|
||||||
let cast_ty = self.make_ty(type_ref);
|
let cast_ty = self.make_ty(type_ref);
|
||||||
// TODO check the cast...
|
// FIXME check the cast...
|
||||||
cast_ty
|
cast_ty
|
||||||
}
|
}
|
||||||
Expr::Ref { expr, mutability } => {
|
Expr::Ref { expr, mutability } => {
|
||||||
let expectation =
|
let expectation =
|
||||||
if let Some((exp_inner, exp_mutability)) = &expected.ty.as_reference() {
|
if let Some((exp_inner, exp_mutability)) = &expected.ty.as_reference() {
|
||||||
if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared {
|
if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared {
|
||||||
// TODO: throw type error - expected mut reference but found shared ref,
|
// FIXME: throw type error - expected mut reference but found shared ref,
|
||||||
// which cannot be coerced
|
// which cannot be coerced
|
||||||
}
|
}
|
||||||
Expectation::has_type(Ty::clone(exp_inner))
|
Expectation::has_type(Ty::clone(exp_inner))
|
||||||
} else {
|
} else {
|
||||||
Expectation::none()
|
Expectation::none()
|
||||||
};
|
};
|
||||||
// TODO reference coercions etc.
|
// FIXME reference coercions etc.
|
||||||
let inner_ty = self.infer_expr(*expr, &expectation);
|
let inner_ty = self.infer_expr(*expr, &expectation);
|
||||||
Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty)
|
Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty)
|
||||||
}
|
}
|
||||||
|
@ -982,7 +982,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
if let Some(derefed_ty) = inner_ty.builtin_deref() {
|
if let Some(derefed_ty) = inner_ty.builtin_deref() {
|
||||||
derefed_ty
|
derefed_ty
|
||||||
} else {
|
} else {
|
||||||
// TODO Deref::deref
|
// FIXME Deref::deref
|
||||||
Ty::Unknown
|
Ty::Unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1002,7 +1002,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => {
|
Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => {
|
||||||
inner_ty
|
inner_ty
|
||||||
}
|
}
|
||||||
// TODO: resolve ops::Neg trait
|
// FIXME: resolve ops::Neg trait
|
||||||
_ => Ty::Unknown,
|
_ => Ty::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1013,7 +1013,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
_ => Ty::Unknown,
|
_ => Ty::Unknown,
|
||||||
},
|
},
|
||||||
Ty::Infer(InferTy::IntVar(..)) => inner_ty,
|
Ty::Infer(InferTy::IntVar(..)) => inner_ty,
|
||||||
// TODO: resolve ops::Not trait for inner_ty
|
// FIXME: resolve ops::Not trait for inner_ty
|
||||||
_ => Ty::Unknown,
|
_ => Ty::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1028,12 +1028,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
_ => Expectation::none(),
|
_ => Expectation::none(),
|
||||||
};
|
};
|
||||||
let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
|
let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
|
||||||
// TODO: find implementation of trait corresponding to operation
|
// FIXME: find implementation of trait corresponding to operation
|
||||||
// symbol and resolve associated `Output` type
|
// symbol and resolve associated `Output` type
|
||||||
let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty);
|
let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty);
|
||||||
let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation));
|
let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation));
|
||||||
|
|
||||||
// TODO: similar as above, return ty is often associated trait type
|
// FIXME: similar as above, return ty is often associated trait type
|
||||||
op::binary_op_return_ty(*op, rhs_ty)
|
op::binary_op_return_ty(*op, rhs_ty)
|
||||||
}
|
}
|
||||||
_ => Ty::Unknown,
|
_ => Ty::Unknown,
|
||||||
|
@ -1227,7 +1227,7 @@ impl InferTy {
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
struct Expectation {
|
struct Expectation {
|
||||||
ty: Ty,
|
ty: Ty,
|
||||||
// TODO: In some cases, we need to be aware whether the expectation is that
|
// FIXME: In some cases, we need to be aware whether the expectation is that
|
||||||
// the type match exactly what we passed, or whether it just needs to be
|
// the type match exactly what we passed, or whether it just needs to be
|
||||||
// coercible to the expected type. See Expectation::rvalue_hint in rustc.
|
// coercible to the expected type. See Expectation::rvalue_hint in rustc.
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ impl Ty {
|
||||||
|
|
||||||
pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self {
|
pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self {
|
||||||
if let Some(name) = path.as_ident() {
|
if let Some(name) = path.as_ident() {
|
||||||
// TODO handle primitive type names in resolver as well?
|
// FIXME handle primitive type names in resolver as well?
|
||||||
if let Some(int_ty) = primitive::IntTy::from_type_name(name) {
|
if let Some(int_ty) = primitive::IntTy::from_type_name(name) {
|
||||||
return Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Known(int_ty)));
|
return Ty::simple(TypeCtor::Int(primitive::UncertainIntTy::Known(int_ty)));
|
||||||
} else if let Some(float_ty) = primitive::FloatTy::from_type_name(name) {
|
} else if let Some(float_ty) = primitive::FloatTy::from_type_name(name) {
|
||||||
|
@ -87,7 +87,7 @@ impl Ty {
|
||||||
Some(Resolution::GenericParam(idx)) => {
|
Some(Resolution::GenericParam(idx)) => {
|
||||||
return Ty::Param {
|
return Ty::Param {
|
||||||
idx,
|
idx,
|
||||||
// TODO: maybe return name in resolution?
|
// FIXME: maybe return name in resolution?
|
||||||
name: path
|
name: path
|
||||||
.as_ident()
|
.as_ident()
|
||||||
.expect("generic param should be single-segment path")
|
.expect("generic param should be single-segment path")
|
||||||
|
@ -139,7 +139,7 @@ impl Ty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add placeholders for args that were not provided
|
// add placeholders for args that were not provided
|
||||||
// TODO: handle defaults
|
// FIXME: handle defaults
|
||||||
let supplied_params = substs.len();
|
let supplied_params = substs.len();
|
||||||
for _ in supplied_params..def_generics.count_params_including_parent() {
|
for _ in supplied_params..def_generics.count_params_including_parent() {
|
||||||
substs.push(Ty::Unknown);
|
substs.push(Ty::Unknown);
|
||||||
|
|
|
@ -120,7 +120,7 @@ fn def_crate(db: &impl HirDatabase, ty: &Ty) -> Option<Crate> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ty {
|
impl Ty {
|
||||||
// TODO: cache this as a query?
|
// FIXME: cache this as a query?
|
||||||
// - if so, what signature? (TyFingerprint, Name)?
|
// - if so, what signature? (TyFingerprint, Name)?
|
||||||
// - or maybe cache all names and def_ids of methods per fingerprint?
|
// - or maybe cache all names and def_ids of methods per fingerprint?
|
||||||
/// Look up the method with the given name, returning the actual autoderefed
|
/// Look up the method with the given name, returning the actual autoderefed
|
||||||
|
|
|
@ -30,7 +30,7 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty)
|
||||||
acc.add_field(ctx, field, &a_ty.parameters);
|
acc.add_field(ctx, field, &a_ty.parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO unions
|
// FIXME unions
|
||||||
TypeCtor::Tuple => {
|
TypeCtor::Tuple => {
|
||||||
for (i, ty) in a_ty.parameters.iter().enumerate() {
|
for (i, ty) in a_ty.parameters.iter().enumerate() {
|
||||||
acc.add_pos_field(ctx, i, ty);
|
acc.add_pos_field(ctx, i, ty);
|
||||||
|
|
|
@ -5,7 +5,7 @@ pub(super) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
if !ctx.is_pat_binding {
|
if !ctx.is_pat_binding {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: ideally, we should look at the type we are matching against and
|
// FIXME: ideally, we should look at the type we are matching against and
|
||||||
// suggest variants + auto-imports
|
// suggest variants + auto-imports
|
||||||
let names = ctx.resolver.all_names(ctx.db);
|
let names = ctx.resolver.all_names(ctx.db);
|
||||||
for (name, res) in names.into_iter() {
|
for (name, res) in names.into_iter() {
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionCon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO unions
|
// FIXME unions
|
||||||
AdtDef::Enum(_) => (),
|
AdtDef::Enum(_) => (),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ pub(crate) fn reference_definition(
|
||||||
return Exact(nav);
|
return Exact(nav);
|
||||||
}
|
}
|
||||||
Some(Resolution::GenericParam(..)) => {
|
Some(Resolution::GenericParam(..)) => {
|
||||||
// TODO: go to the generic param def
|
// FIXME: go to the generic param def
|
||||||
}
|
}
|
||||||
Some(Resolution::SelfType(impl_block)) => {
|
Some(Resolution::SelfType(impl_block)) => {
|
||||||
let ty = impl_block.target_ty(db);
|
let ty = impl_block.target_ty(db);
|
||||||
|
|
|
@ -204,7 +204,7 @@ impl NavigationTarget {
|
||||||
///
|
///
|
||||||
/// e.g. `struct Name`, `enum Name`, `fn Name`
|
/// e.g. `struct Name`, `enum Name`, `fn Name`
|
||||||
fn description(&self, db: &RootDatabase) -> Option<String> {
|
fn description(&self, db: &RootDatabase) -> Option<String> {
|
||||||
// TODO: After type inference is done, add type information to improve the output
|
// FIXME: After type inference is done, add type information to improve the output
|
||||||
let node = self.node(db)?;
|
let node = self.node(db)?;
|
||||||
|
|
||||||
fn visit_ascribed_node<T>(node: &T, prefix: &str) -> Option<String>
|
fn visit_ascribed_node<T>(node: &T, prefix: &str) -> Option<String>
|
||||||
|
|
|
@ -77,7 +77,7 @@ impl LineIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn offset(&self, line_col: LineCol) -> TextUnit {
|
pub fn offset(&self, line_col: LineCol) -> TextUnit {
|
||||||
//TODO: return Result
|
//FIXME: return Result
|
||||||
let col = self.utf16_to_utf8_col(line_col.line, line_col.col_utf16);
|
let col = self.utf16_to_utf8_col(line_col.line, line_col.col_utf16);
|
||||||
self.newlines[line_col.line as usize] + col
|
self.newlines[line_col.line as usize] + col
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex>
|
||||||
|
|
||||||
let symbols = source_file_to_file_symbols(&source_file, file_id);
|
let symbols = source_file_to_file_symbols(&source_file, file_id);
|
||||||
|
|
||||||
// TODO: add macros here
|
// FIXME: add macros here
|
||||||
|
|
||||||
Arc::new(SymbolIndex::new(symbols))
|
Arc::new(SymbolIndex::new(symbols))
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub(super) fn const_def(p: &mut Parser, m: Marker) {
|
||||||
fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) {
|
fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) {
|
||||||
assert!(p.at(kw));
|
assert!(p.at(kw));
|
||||||
p.bump();
|
p.bump();
|
||||||
p.eat(MUT_KW); // TODO: validator to forbid const mut
|
p.eat(MUT_KW); // FIXME: validator to forbid const mut
|
||||||
name(p);
|
name(p);
|
||||||
types::ascription(p);
|
types::ascription(p);
|
||||||
if p.eat(EQ) {
|
if p.eat(EQ) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub(super) fn struct_def(p: &mut Parser, m: Marker, kind: SyntaxKind) {
|
||||||
}
|
}
|
||||||
L_CURLY => named_field_def_list(p),
|
L_CURLY => named_field_def_list(p),
|
||||||
_ => {
|
_ => {
|
||||||
//TODO: special case `(` error message
|
//FIXME: special case `(` error message
|
||||||
p.error("expected `;` or `{`");
|
p.error("expected `;` or `{`");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ pub(super) fn impl_block(p: &mut Parser) {
|
||||||
type_params::opt_type_param_list(p);
|
type_params::opt_type_param_list(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: never type
|
// FIXME: never type
|
||||||
// impl ! {}
|
// impl ! {}
|
||||||
|
|
||||||
// test impl_block_neg
|
// test impl_block_neg
|
||||||
|
|
|
@ -21,7 +21,7 @@ fn use_tree(p: &mut Parser) {
|
||||||
// This does not handle cases such as `use some::path::*`
|
// This does not handle cases such as `use some::path::*`
|
||||||
// N.B. in Rust 2015 `use *;` imports all from crate root
|
// N.B. in Rust 2015 `use *;` imports all from crate root
|
||||||
// however in Rust 2018 `use *;` errors: ('cannot glob-import all possible crates')
|
// however in Rust 2018 `use *;` errors: ('cannot glob-import all possible crates')
|
||||||
// TODO: Add this error (if not out of scope)
|
// FIXME: Add this error (if not out of scope)
|
||||||
|
|
||||||
// test use_star
|
// test use_star
|
||||||
// use *;
|
// use *;
|
||||||
|
@ -33,7 +33,7 @@ fn use_tree(p: &mut Parser) {
|
||||||
// Parse `use ::*;`, which imports all from the crate root in Rust 2015
|
// Parse `use ::*;`, which imports all from the crate root in Rust 2015
|
||||||
// This is invalid inside a use_tree_list, (e.g. `use some::path::{::*}`)
|
// This is invalid inside a use_tree_list, (e.g. `use some::path::{::*}`)
|
||||||
// but still parses and errors later: ('crate root in paths can only be used in start position')
|
// but still parses and errors later: ('crate root in paths can only be used in start position')
|
||||||
// TODO: Add this error (if not out of scope)
|
// FIXME: Add this error (if not out of scope)
|
||||||
// In Rust 2018, it is always invalid (see above)
|
// In Rust 2018, it is always invalid (see above)
|
||||||
p.bump();
|
p.bump();
|
||||||
p.bump();
|
p.bump();
|
||||||
|
|
|
@ -121,7 +121,7 @@ impl<'t> Parser<'t> {
|
||||||
/// final tree.
|
/// final tree.
|
||||||
pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) {
|
pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) {
|
||||||
if self.nth(0) == EOF {
|
if self.nth(0) == EOF {
|
||||||
// TODO: panic!?
|
// FIXME: panic!?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.do_bump(kind, 1);
|
self.do_bump(kind, 1);
|
||||||
|
@ -135,7 +135,7 @@ impl<'t> Parser<'t> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emit error with the `message`
|
/// Emit error with the `message`
|
||||||
/// TODO: this should be much more fancy and support
|
/// FIXME: this should be much more fancy and support
|
||||||
/// structured errors with spans and notes, like rustc
|
/// structured errors with spans and notes, like rustc
|
||||||
/// does.
|
/// does.
|
||||||
pub(crate) fn error<T: Into<String>>(&mut self, message: T) {
|
pub(crate) fn error<T: Into<String>>(&mut self, message: T) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub use crate::{
|
||||||
sysroot::Sysroot,
|
sysroot::Sysroot,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO use proper error enum
|
// FIXME use proper error enum
|
||||||
pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
|
pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -85,7 +85,7 @@ pub(super) fn is_ascii_escape(code: char) -> bool {
|
||||||
fn validate_ascii_code_escape(text: &str, range: TextRange, errors: &mut Vec<SyntaxError>) {
|
fn validate_ascii_code_escape(text: &str, range: TextRange, errors: &mut Vec<SyntaxError>) {
|
||||||
// An AsciiCodeEscape has 4 chars, example: `\xDD`
|
// An AsciiCodeEscape has 4 chars, example: `\xDD`
|
||||||
if !text.is_ascii() {
|
if !text.is_ascii() {
|
||||||
// TODO: Give a more precise error message (say what the invalid character was)
|
// FIXME: Give a more precise error message (say what the invalid character was)
|
||||||
errors.push(SyntaxError::new(AsciiCodeEscapeOutOfRange, range));
|
errors.push(SyntaxError::new(AsciiCodeEscapeOutOfRange, range));
|
||||||
} else if text.chars().count() < 4 {
|
} else if text.chars().count() < 4 {
|
||||||
errors.push(SyntaxError::new(TooShortAsciiCodeEscape, range));
|
errors.push(SyntaxError::new(TooShortAsciiCodeEscape, range));
|
||||||
|
|
|
@ -61,7 +61,7 @@ fn reparse_fuzz_tests() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test that Rust-analyzer can parse and validate the rust-analyser
|
/// Test that Rust-analyzer can parse and validate the rust-analyser
|
||||||
/// TODO: Use this as a benchmark
|
/// FIXME: Use this as a benchmark
|
||||||
#[test]
|
#[test]
|
||||||
fn self_hosting_parsing() {
|
fn self_hosting_parsing() {
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
|
|
Loading…
Reference in a new issue