mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 13:13:18 +00:00 
			
		
		
		
	Merge #990
990: Forbid TODO markers on master branch r=matklad a=matklad this makes TODO markers useful for things which you want to fix before sending a PR Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
		
						commit
						3d7a330f32
					
				@ -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;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,6 @@
 | 
				
			|||||||
use tools::{generate, gen_tests, run_rustfmt, Verify};
 | 
					use walkdir::WalkDir;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use tools::{generate, gen_tests, run_rustfmt, Verify, project_root};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn generated_grammar_is_fresh() {
 | 
					fn generated_grammar_is_fresh() {
 | 
				
			||||||
@ -20,3 +22,25 @@ fn check_code_formatting() {
 | 
				
			|||||||
        panic!("{}. Please format the code by running `cargo format`", error);
 | 
					        panic!("{}. Please format the code by running `cargo format`", error);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn no_todo() {
 | 
				
			||||||
 | 
					    WalkDir::new(project_root().join("crates")).into_iter().for_each(|e| {
 | 
				
			||||||
 | 
					        let e = e.unwrap();
 | 
				
			||||||
 | 
					        if e.path().extension().map(|it| it != "rs").unwrap_or(true) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if e.path().ends_with("tests/cli.rs") {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        let text = std::fs::read_to_string(e.path()).unwrap();
 | 
				
			||||||
 | 
					        if text.contains("TODO") {
 | 
				
			||||||
 | 
					            panic!(
 | 
				
			||||||
 | 
					                "\nTODO markers should not be commited to the master branch,\n\
 | 
				
			||||||
 | 
					                 use FIXME instead\n\
 | 
				
			||||||
 | 
					                 {}\n",
 | 
				
			||||||
 | 
					                e.path().display(),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user