Create LowerCtx on the fly

This commit is contained in:
Edwin Cheng 2020-05-17 23:37:30 +08:00
parent ebaa05a447
commit 12a3bf3c31
2 changed files with 41 additions and 9 deletions

View File

@ -60,13 +60,10 @@ pub(super) fn lower(
params: Option<ast::ParamList>, params: Option<ast::ParamList>,
body: Option<ast::Expr>, body: Option<ast::Expr>,
) -> (Body, BodySourceMap) { ) -> (Body, BodySourceMap) {
let ctx = LowerCtx::new(db, expander.current_file_id.clone());
ExprCollector { ExprCollector {
db, db,
def, def,
expander, expander,
ctx,
source_map: BodySourceMap::default(), source_map: BodySourceMap::default(),
body: Body { body: Body {
exprs: Arena::default(), exprs: Arena::default(),
@ -83,7 +80,6 @@ struct ExprCollector<'a> {
db: &'a dyn DefDatabase, db: &'a dyn DefDatabase,
def: DefWithBodyId, def: DefWithBodyId,
expander: Expander, expander: Expander,
ctx: LowerCtx,
body: Body, body: Body,
source_map: BodySourceMap, source_map: BodySourceMap,
} }
@ -122,6 +118,10 @@ impl ExprCollector<'_> {
(self.body, self.source_map) (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<ast::Expr>) -> ExprId { fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr<ast::Expr>) -> ExprId {
let src = self.expander.to_source(ptr); let src = self.expander.to_source(ptr);
let id = self.make_expr(expr, Ok(src.clone())); let id = self.make_expr(expr, Ok(src.clone()));
@ -268,7 +268,7 @@ impl ExprCollector<'_> {
}; };
let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing);
let generic_args = 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( self.alloc_expr(
Expr::MethodCall { receiver, method_name, args, generic_args }, Expr::MethodCall { receiver, method_name, args, generic_args },
syntax_ptr, syntax_ptr,
@ -373,7 +373,7 @@ impl ExprCollector<'_> {
} }
ast::Expr::CastExpr(e) => { ast::Expr::CastExpr(e) => {
let expr = self.collect_expr_opt(e.expr()); 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) self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
} }
ast::Expr::RefExpr(e) => { ast::Expr::RefExpr(e) => {
@ -396,7 +396,7 @@ impl ExprCollector<'_> {
for param in pl.params() { for param in pl.params() {
let pat = self.collect_pat_opt(param.pat()); let pat = self.collect_pat_opt(param.pat());
let type_ref = 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); args.push(pat);
arg_types.push(type_ref); arg_types.push(type_ref);
} }
@ -404,7 +404,7 @@ impl ExprCollector<'_> {
let ret_type = e let ret_type = e
.ret_type() .ret_type()
.and_then(|r| r.type_ref()) .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()); let body = self.collect_expr_opt(e.body());
self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr)
} }
@ -507,7 +507,8 @@ impl ExprCollector<'_> {
.map(|s| match s { .map(|s| match s {
ast::Stmt::LetStmt(stmt) => { ast::Stmt::LetStmt(stmt) => {
let pat = self.collect_pat_opt(stmt.pat()); 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)); let initializer = stmt.initializer().map(|e| self.collect_expr(e));
Statement::Let { pat, type_ref, initializer } Statement::Let { pat, type_ref, initializer }
} }

View File

@ -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>() -> 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>() -> Foo
!18..28 'anything()': Foo
!29..30 'r': Foo
164..188 '{ ...!(); }': ()
174..176 '_a': Foo
"###);
}
#[test] #[test]
fn issue_4053_diesel_where_clauses() { fn issue_4053_diesel_where_clauses() {
assert_snapshot!( assert_snapshot!(