aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/item_tree
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/item_tree')
-rw-r--r--crates/hir_def/src/item_tree/lower.rs93
1 files changed, 52 insertions, 41 deletions
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index 124dcc866..39e8403b0 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -362,7 +362,7 @@ impl Ctx {
362 } 362 }
363 } 363 }
364 }; 364 };
365 let ty = self.data().type_refs.intern(self_type); 365 let ty = Interned::new(self_type);
366 let idx = self.data().params.alloc(Param::Normal(ty)); 366 let idx = self.data().params.alloc(Param::Normal(ty));
367 self.add_attrs(idx.into(), RawAttrs::new(&self_param, &self.hygiene)); 367 self.add_attrs(idx.into(), RawAttrs::new(&self_param, &self.hygiene));
368 has_self_param = true; 368 has_self_param = true;
@@ -372,7 +372,7 @@ impl Ctx {
372 Some(_) => self.data().params.alloc(Param::Varargs), 372 Some(_) => self.data().params.alloc(Param::Varargs),
373 None => { 373 None => {
374 let type_ref = TypeRef::from_ast_opt(&self.body_ctx, param.ty()); 374 let type_ref = TypeRef::from_ast_opt(&self.body_ctx, param.ty());
375 let ty = self.data().type_refs.intern(type_ref); 375 let ty = Interned::new(type_ref);
376 self.data().params.alloc(Param::Normal(ty)) 376 self.data().params.alloc(Param::Normal(ty))
377 } 377 }
378 }; 378 };
@@ -395,41 +395,51 @@ impl Ctx {
395 ret_type 395 ret_type
396 }; 396 };
397 397
398 let ret_type = self.data().type_refs.intern(ret_type); 398 let abi = func.abi().map(|abi| {
399 399 // FIXME: Abi::abi() -> Option<SyntaxToken>?
400 let has_body = func.body().is_some(); 400 match abi.syntax().last_token() {
401 Some(tok) if tok.kind() == SyntaxKind::STRING => {
402 // FIXME: Better way to unescape?
403 Interned::new_str(tok.text().trim_matches('"'))
404 }
405 _ => {
406 // `extern` default to be `extern "C"`.
407 Interned::new_str("C")
408 }
409 }
410 });
401 411
402 let ast_id = self.source_ast_id_map.ast_id(func); 412 let ast_id = self.source_ast_id_map.ast_id(func);
403 let qualifier = FunctionQualifier { 413
404 is_default: func.default_token().is_some(), 414 let mut flags = FnFlags::empty();
405 is_const: func.const_token().is_some(), 415 if func.body().is_some() {
406 is_async: func.async_token().is_some(), 416 flags |= FnFlags::HAS_BODY;
407 is_unsafe: func.unsafe_token().is_some(), 417 }
408 abi: func.abi().map(|abi| { 418 if has_self_param {
409 // FIXME: Abi::abi() -> Option<SyntaxToken>? 419 flags |= FnFlags::HAS_SELF_PARAM;
410 match abi.syntax().last_token() { 420 }
411 Some(tok) if tok.kind() == SyntaxKind::STRING => { 421 if func.default_token().is_some() {
412 // FIXME: Better way to unescape? 422 flags |= FnFlags::IS_DEFAULT;
413 tok.text().trim_matches('"').into() 423 }
414 } 424 if func.const_token().is_some() {
415 _ => { 425 flags |= FnFlags::IS_CONST;
416 // `extern` default to be `extern "C"`. 426 }
417 "C".into() 427 if func.async_token().is_some() {
418 } 428 flags |= FnFlags::IS_ASYNC;
419 } 429 }
420 }), 430 if func.unsafe_token().is_some() {
421 }; 431 flags |= FnFlags::IS_UNSAFE;
432 }
433
422 let mut res = Function { 434 let mut res = Function {
423 name, 435 name,
424 visibility, 436 visibility,
425 generic_params: GenericParamsId::EMPTY, 437 generic_params: GenericParamsId::EMPTY,
426 has_self_param, 438 abi,
427 has_body,
428 qualifier,
429 is_in_extern_block: false,
430 params, 439 params,
431 ret_type, 440 ret_type: Interned::new(ret_type),
432 ast_id, 441 ast_id,
442 flags,
433 }; 443 };
434 res.generic_params = self.lower_generic_params(GenericsOwner::Function(&res), func); 444 res.generic_params = self.lower_generic_params(GenericsOwner::Function(&res), func);
435 445
@@ -579,7 +589,7 @@ impl Ctx {
579 &self.hygiene, 589 &self.hygiene,
580 |path, _use_tree, is_glob, alias| { 590 |path, _use_tree, is_glob, alias| {
581 imports.push(id(tree.imports.alloc(Import { 591 imports.push(id(tree.imports.alloc(Import {
582 path, 592 path: Interned::new(path),
583 alias, 593 alias,
584 visibility, 594 visibility,
585 is_glob, 595 is_glob,
@@ -608,7 +618,7 @@ impl Ctx {
608 } 618 }
609 619
610 fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> { 620 fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> {
611 let path = ModPath::from_src(m.path()?, &self.hygiene)?; 621 let path = Interned::new(ModPath::from_src(m.path()?, &self.hygiene)?);
612 let ast_id = self.source_ast_id_map.ast_id(m); 622 let ast_id = self.source_ast_id_map.ast_id(m);
613 let res = MacroCall { path, ast_id }; 623 let res = MacroCall { path, ast_id };
614 Some(id(self.data().macro_calls.alloc(res))) 624 Some(id(self.data().macro_calls.alloc(res)))
@@ -642,8 +652,10 @@ impl Ctx {
642 ast::ExternItem::Fn(ast) => { 652 ast::ExternItem::Fn(ast) => {
643 let func_id = self.lower_function(&ast)?; 653 let func_id = self.lower_function(&ast)?;
644 let func = &mut self.data().functions[func_id.index]; 654 let func = &mut self.data().functions[func_id.index];
645 func.qualifier.is_unsafe = is_intrinsic_fn_unsafe(&func.name); 655 if is_intrinsic_fn_unsafe(&func.name) {
646 func.is_in_extern_block = true; 656 func.flags |= FnFlags::IS_UNSAFE;
657 }
658 func.flags |= FnFlags::IS_IN_EXTERN_BLOCK;
647 func_id.into() 659 func_id.into()
648 } 660 }
649 ast::ExternItem::Static(ast) => { 661 ast::ExternItem::Static(ast) => {
@@ -694,8 +706,7 @@ impl Ctx {
694 generics.fill(&self.body_ctx, sm, node); 706 generics.fill(&self.body_ctx, sm, node);
695 // lower `impl Trait` in arguments 707 // lower `impl Trait` in arguments
696 for id in func.params.clone() { 708 for id in func.params.clone() {
697 if let Param::Normal(ty) = self.data().params[id] { 709 if let Param::Normal(ty) = &self.data().params[id] {
698 let ty = self.data().type_refs.lookup(ty);
699 generics.fill_implicit_impl_trait_args(ty); 710 generics.fill_implicit_impl_trait_args(ty);
700 } 711 }
701 } 712 }
@@ -749,20 +760,20 @@ impl Ctx {
749 self.data().vis.alloc(vis) 760 self.data().vis.alloc(vis)
750 } 761 }
751 762
752 fn lower_trait_ref(&mut self, trait_ref: &ast::Type) -> Option<Idx<TraitRef>> { 763 fn lower_trait_ref(&mut self, trait_ref: &ast::Type) -> Option<Interned<TraitRef>> {
753 let trait_ref = TraitRef::from_ast(&self.body_ctx, trait_ref.clone())?; 764 let trait_ref = TraitRef::from_ast(&self.body_ctx, trait_ref.clone())?;
754 Some(self.data().trait_refs.intern(trait_ref)) 765 Some(Interned::new(trait_ref))
755 } 766 }
756 767
757 fn lower_type_ref(&mut self, type_ref: &ast::Type) -> Idx<TypeRef> { 768 fn lower_type_ref(&mut self, type_ref: &ast::Type) -> Interned<TypeRef> {
758 let tyref = TypeRef::from_ast(&self.body_ctx, type_ref.clone()); 769 let tyref = TypeRef::from_ast(&self.body_ctx, type_ref.clone());
759 self.data().type_refs.intern(tyref) 770 Interned::new(tyref)
760 } 771 }
761 772
762 fn lower_type_ref_opt(&mut self, type_ref: Option<ast::Type>) -> Idx<TypeRef> { 773 fn lower_type_ref_opt(&mut self, type_ref: Option<ast::Type>) -> Interned<TypeRef> {
763 match type_ref.map(|ty| self.lower_type_ref(&ty)) { 774 match type_ref.map(|ty| self.lower_type_ref(&ty)) {
764 Some(it) => it, 775 Some(it) => it,
765 None => self.data().type_refs.intern(TypeRef::Error), 776 None => Interned::new(TypeRef::Error),
766 } 777 }
767 } 778 }
768 779