diff options
author | oxalica <[email protected]> | 2021-03-14 10:00:11 +0000 |
---|---|---|
committer | oxalica <[email protected]> | 2021-03-15 17:03:07 +0000 |
commit | 2bb8956a102cb2efbea35e414a8214fba2efcaf6 (patch) | |
tree | d1ab34b0c43e603f294ecb8f09ae5b5a5736d809 | |
parent | b9c172a977135760006b6222820ac7240be67d58 (diff) |
Introduce FunctionQualifier for hir::FunctionData
-rw-r--r-- | crates/hir/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/data.rs | 10 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 15 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 27 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/decl_check.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/unsafe_check.rs | 6 |
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}; | |||
24 | use profile::Count; | 24 | use profile::Count; |
25 | use rustc_hash::FxHashMap; | 25 | use rustc_hash::FxHashMap; |
26 | use smallvec::SmallVec; | 26 | use smallvec::SmallVec; |
27 | use syntax::{ast, match_ast, SyntaxKind}; | 27 | use syntax::{ast, match_ast, SmolStr, SyntaxKind}; |
28 | 28 | ||
29 | use crate::{ | 29 | use 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)] | ||
565 | pub 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)] |
565 | pub struct Struct { | 574 | pub 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 }); |