aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoroxalica <[email protected]>2021-03-14 10:00:11 +0000
committeroxalica <[email protected]>2021-03-15 17:03:07 +0000
commit2bb8956a102cb2efbea35e414a8214fba2efcaf6 (patch)
treed1ab34b0c43e603f294ecb8f09ae5b5a5736d809
parentb9c172a977135760006b6222820ac7240be67d58 (diff)
Introduce FunctionQualifier for hir::FunctionData
-rw-r--r--crates/hir/src/lib.rs2
-rw-r--r--crates/hir_def/src/data.rs10
-rw-r--r--crates/hir_def/src/item_tree.rs15
-rw-r--r--crates/hir_def/src/item_tree/lower.rs27
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs2
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs6
6 files changed, 45 insertions, 17 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 469ed5b5e..0d0e757fc 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -844,7 +844,7 @@ impl Function {
844 } 844 }
845 845
846 pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { 846 pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
847 db.function_data(self.id).is_unsafe 847 db.function_data(self.id).qualifier.is_unsafe
848 } 848 }
849 849
850 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { 850 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs
index aea53d527..b09da0697 100644
--- a/crates/hir_def/src/data.rs
+++ b/crates/hir_def/src/data.rs
@@ -9,7 +9,7 @@ use crate::{
9 attr::Attrs, 9 attr::Attrs,
10 body::Expander, 10 body::Expander,
11 db::DefDatabase, 11 db::DefDatabase,
12 item_tree::{AssocItem, ItemTreeId, ModItem}, 12 item_tree::{AssocItem, FunctionQualifier, ItemTreeId, ModItem},
13 type_ref::{TypeBound, TypeRef}, 13 type_ref::{TypeBound, TypeRef},
14 visibility::RawVisibility, 14 visibility::RawVisibility,
15 AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, 15 AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
@@ -26,9 +26,9 @@ pub struct FunctionData {
26 /// can be called as a method. 26 /// can be called as a method.
27 pub has_self_param: bool, 27 pub has_self_param: bool,
28 pub has_body: bool, 28 pub has_body: bool,
29 pub is_unsafe: bool, 29 pub qualifier: FunctionQualifier,
30 pub is_in_extern_block: bool,
30 pub is_varargs: bool, 31 pub is_varargs: bool,
31 pub is_extern: bool,
32 pub visibility: RawVisibility, 32 pub visibility: RawVisibility,
33} 33}
34 34
@@ -46,9 +46,9 @@ impl FunctionData {
46 attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()), 46 attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
47 has_self_param: func.has_self_param, 47 has_self_param: func.has_self_param,
48 has_body: func.has_body, 48 has_body: func.has_body,
49 is_unsafe: func.is_unsafe, 49 qualifier: func.qualifier.clone(),
50 is_in_extern_block: func.is_in_extern_block,
50 is_varargs: func.is_varargs, 51 is_varargs: func.is_varargs,
51 is_extern: func.is_extern,
52 visibility: item_tree[func.visibility].clone(), 52 visibility: item_tree[func.visibility].clone(),
53 }) 53 })
54 } 54 }
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 09bcb10dc..d8f22d442 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -24,7 +24,7 @@ use la_arena::{Arena, Idx, RawIdx};
24use profile::Count; 24use profile::Count;
25use rustc_hash::FxHashMap; 25use rustc_hash::FxHashMap;
26use smallvec::SmallVec; 26use smallvec::SmallVec;
27use syntax::{ast, match_ast, SyntaxKind}; 27use syntax::{ast, match_ast, SmolStr, SyntaxKind};
28 28
29use crate::{ 29use crate::{
30 attr::{Attrs, RawAttrs}, 30 attr::{Attrs, RawAttrs},
@@ -551,16 +551,25 @@ pub struct Function {
551 pub generic_params: GenericParamsId, 551 pub generic_params: GenericParamsId,
552 pub has_self_param: bool, 552 pub has_self_param: bool,
553 pub has_body: bool, 553 pub has_body: bool,
554 pub is_unsafe: bool, 554 pub qualifier: FunctionQualifier,
555 /// Whether the function is located in an `extern` block (*not* whether it is an 555 /// Whether the function is located in an `extern` block (*not* whether it is an
556 /// `extern "abi" fn`). 556 /// `extern "abi" fn`).
557 pub is_extern: bool, 557 pub is_in_extern_block: bool,
558 pub params: Box<[Idx<TypeRef>]>, 558 pub params: Box<[Idx<TypeRef>]>,
559 pub is_varargs: bool, 559 pub is_varargs: bool,
560 pub ret_type: Idx<TypeRef>, 560 pub ret_type: Idx<TypeRef>,
561 pub ast_id: FileAstId<ast::Fn>, 561 pub ast_id: FileAstId<ast::Fn>,
562} 562}
563 563
564#[derive(Debug, Clone, PartialEq, Eq)]
565pub struct FunctionQualifier {
566 pub is_default: bool,
567 pub is_const: bool,
568 pub is_async: bool,
569 pub is_unsafe: bool,
570 pub abi: Option<SmolStr>,
571}
572
564#[derive(Debug, Clone, Eq, PartialEq)] 573#[derive(Debug, Clone, Eq, PartialEq)]
565pub struct Struct { 574pub struct Struct {
566 pub name: Name, 575 pub name: Name,
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index 240fdacf9..6b5438dc9 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -391,14 +391,33 @@ impl Ctx {
391 let has_body = func.body().is_some(); 391 let has_body = func.body().is_some();
392 392
393 let ast_id = self.source_ast_id_map.ast_id(func); 393 let ast_id = self.source_ast_id_map.ast_id(func);
394 let qualifier = FunctionQualifier {
395 is_default: func.default_token().is_some(),
396 is_const: func.const_token().is_some(),
397 is_async: func.async_token().is_some(),
398 is_unsafe: func.unsafe_token().is_some(),
399 abi: func.abi().map(|abi| {
400 // FIXME: Abi::abi() -> Option<SyntaxToken>?
401 match abi.syntax().last_token() {
402 Some(tok) if tok.kind() == SyntaxKind::STRING => {
403 // FIXME: Better way to unescape?
404 tok.text().trim_matches('"').into()
405 }
406 _ => {
407 // `extern` default to be `extern "C"`.
408 "C".into()
409 }
410 }
411 }),
412 };
394 let mut res = Function { 413 let mut res = Function {
395 name, 414 name,
396 visibility, 415 visibility,
397 generic_params: GenericParamsId::EMPTY, 416 generic_params: GenericParamsId::EMPTY,
398 has_self_param, 417 has_self_param,
399 has_body, 418 has_body,
400 is_unsafe: func.unsafe_token().is_some(), 419 qualifier,
401 is_extern: false, 420 is_in_extern_block: false,
402 params, 421 params,
403 is_varargs, 422 is_varargs,
404 ret_type, 423 ret_type,
@@ -608,8 +627,8 @@ impl Ctx {
608 ast::ExternItem::Fn(ast) => { 627 ast::ExternItem::Fn(ast) => {
609 let func_id = self.lower_function(&ast)?; 628 let func_id = self.lower_function(&ast)?;
610 let func = &mut self.data().functions[func_id.index]; 629 let func = &mut self.data().functions[func_id.index];
611 func.is_unsafe = is_intrinsic_fn_unsafe(&func.name); 630 func.qualifier.is_unsafe = is_intrinsic_fn_unsafe(&func.name);
612 func.is_extern = true; 631 func.is_in_extern_block = true;
613 func_id.into() 632 func_id.into()
614 } 633 }
615 ast::ExternItem::Static(ast) => { 634 ast::ExternItem::Static(ast) => {
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs
index 3605ca581..982ad5b9e 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -91,7 +91,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
91 91
92 fn validate_func(&mut self, func: FunctionId) { 92 fn validate_func(&mut self, func: FunctionId) {
93 let data = self.db.function_data(func); 93 let data = self.db.function_data(func);
94 if data.is_extern { 94 if data.is_in_extern_block {
95 cov_mark::hit!(extern_func_incorrect_case_ignored); 95 cov_mark::hit!(extern_func_incorrect_case_ignored);
96 return; 96 return;
97 } 97 }
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs
index 20bb64827..44a7e5506 100644
--- a/crates/hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs
@@ -32,7 +32,7 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> {
32 let def = self.owner.into(); 32 let def = self.owner.into();
33 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); 33 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def);
34 let is_unsafe = match self.owner { 34 let is_unsafe = match self.owner {
35 DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe, 35 DefWithBodyId::FunctionId(it) => db.function_data(it).qualifier.is_unsafe,
36 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false, 36 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false,
37 }; 37 };
38 if is_unsafe 38 if is_unsafe
@@ -86,7 +86,7 @@ fn walk_unsafe(
86 match expr { 86 match expr {
87 &Expr::Call { callee, .. } => { 87 &Expr::Call { callee, .. } => {
88 if let Some(func) = infer[callee].as_fn_def(db) { 88 if let Some(func) = infer[callee].as_fn_def(db) {
89 if db.function_data(func).is_unsafe { 89 if db.function_data(func).qualifier.is_unsafe {
90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
91 } 91 }
92 } 92 }
@@ -103,7 +103,7 @@ fn walk_unsafe(
103 Expr::MethodCall { .. } => { 103 Expr::MethodCall { .. } => {
104 if infer 104 if infer
105 .method_resolution(current) 105 .method_resolution(current)
106 .map(|func| db.function_data(func).is_unsafe) 106 .map(|func| db.function_data(func).qualifier.is_unsafe)
107 .unwrap_or(false) 107 .unwrap_or(false)
108 { 108 {
109 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 109 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });