diff options
Diffstat (limited to 'crates/hir_def/src/item_tree')
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 93 |
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 | ||