From 12a3bf3c31d4c9a6d9ee110db174604f688ca0f0 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 17 May 2020 23:37:30 +0800 Subject: [PATCH] Create LowerCtx on the fly --- crates/ra_hir_def/src/body/lower.rs | 19 ++++++++------- crates/ra_hir_ty/src/tests/regression.rs | 31 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 443b057abea..c69e0efea6c 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -60,13 +60,10 @@ pub(super) fn lower( params: Option, body: Option, ) -> (Body, BodySourceMap) { - let ctx = LowerCtx::new(db, expander.current_file_id.clone()); - ExprCollector { db, def, expander, - ctx, source_map: BodySourceMap::default(), body: Body { exprs: Arena::default(), @@ -83,7 +80,6 @@ struct ExprCollector<'a> { db: &'a dyn DefDatabase, def: DefWithBodyId, expander: Expander, - ctx: LowerCtx, body: Body, source_map: BodySourceMap, } @@ -122,6 +118,10 @@ fn collect( (self.body, self.source_map) } + fn ctx(&self) -> LowerCtx { + LowerCtx::new(self.db, self.expander.current_file_id) + } + fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr) -> ExprId { let src = self.expander.to_source(ptr); let id = self.make_expr(expr, Ok(src.clone())); @@ -268,7 +268,7 @@ fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { }; let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); let generic_args = - e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx, it)); + e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx(), it)); self.alloc_expr( Expr::MethodCall { receiver, method_name, args, generic_args }, syntax_ptr, @@ -373,7 +373,7 @@ fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { } ast::Expr::CastExpr(e) => { let expr = self.collect_expr_opt(e.expr()); - let type_ref = TypeRef::from_ast_opt(&self.ctx, e.type_ref()); + let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.type_ref()); self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) } ast::Expr::RefExpr(e) => { @@ -396,7 +396,7 @@ fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { for param in pl.params() { let pat = self.collect_pat_opt(param.pat()); let type_ref = - param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); + param.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx(), it)); args.push(pat); arg_types.push(type_ref); } @@ -404,7 +404,7 @@ fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { let ret_type = e .ret_type() .and_then(|r| r.type_ref()) - .map(|it| TypeRef::from_ast(&self.ctx, it)); + .map(|it| TypeRef::from_ast(&self.ctx(), it)); let body = self.collect_expr_opt(e.body()); self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) } @@ -507,7 +507,8 @@ fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId { .map(|s| match s { ast::Stmt::LetStmt(stmt) => { let pat = self.collect_pat_opt(stmt.pat()); - let type_ref = stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx, it)); + let type_ref = + stmt.ascribed_type().map(|it| TypeRef::from_ast(&self.ctx(), it)); let initializer = stmt.initializer().map(|e| self.collect_expr(e)); Statement::Let { pat, type_ref, initializer } } diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index 115ad832891..c2168222ee5 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs @@ -563,6 +563,37 @@ fn main() { ); } +#[test] +fn issue_4465_dollar_crate_at_type() { + assert_snapshot!( + infer(r#" +pub struct Foo {} +pub fn anything() -> T { + loop {} +} +macro_rules! foo { + () => {{ + let r: $crate::Foo = anything(); + r + }}; +} +fn main() { + let _a = foo!(); +} +"#), @r###" + 45..60 '{ loop {} }': T + 51..58 'loop {}': ! + 56..58 '{}': () + !0..31 '{letr:...g();r}': Foo + !4..5 'r': Foo + !18..26 'anything': fn anything() -> Foo + !18..28 'anything()': Foo + !29..30 'r': Foo + 164..188 '{ ...!(); }': () + 174..176 '_a': Foo +"###); +} + #[test] fn issue_4053_diesel_where_clauses() { assert_snapshot!(