diff options
-rw-r--r-- | crates/hir_def/src/data.rs | 4 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 5 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 13 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/decl_check.rs | 19 |
4 files changed, 36 insertions, 5 deletions
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs index 146045938..dd3a906af 100644 --- a/crates/hir_def/src/data.rs +++ b/crates/hir_def/src/data.rs | |||
@@ -28,6 +28,7 @@ pub struct FunctionData { | |||
28 | pub has_body: bool, | 28 | pub has_body: bool, |
29 | pub is_unsafe: bool, | 29 | pub is_unsafe: bool, |
30 | pub is_varargs: bool, | 30 | pub is_varargs: bool, |
31 | pub is_extern: bool, | ||
31 | pub visibility: RawVisibility, | 32 | pub visibility: RawVisibility, |
32 | } | 33 | } |
33 | 34 | ||
@@ -46,6 +47,7 @@ impl FunctionData { | |||
46 | has_body: func.has_body, | 47 | has_body: func.has_body, |
47 | is_unsafe: func.is_unsafe, | 48 | is_unsafe: func.is_unsafe, |
48 | is_varargs: func.is_varargs, | 49 | is_varargs: func.is_varargs, |
50 | is_extern: func.is_extern, | ||
49 | visibility: item_tree[func.visibility].clone(), | 51 | visibility: item_tree[func.visibility].clone(), |
50 | }) | 52 | }) |
51 | } | 53 | } |
@@ -191,6 +193,7 @@ pub struct StaticData { | |||
191 | pub type_ref: TypeRef, | 193 | pub type_ref: TypeRef, |
192 | pub visibility: RawVisibility, | 194 | pub visibility: RawVisibility, |
193 | pub mutable: bool, | 195 | pub mutable: bool, |
196 | pub is_extern: bool, | ||
194 | } | 197 | } |
195 | 198 | ||
196 | impl StaticData { | 199 | impl StaticData { |
@@ -204,6 +207,7 @@ impl StaticData { | |||
204 | type_ref: statik.type_ref.clone(), | 207 | type_ref: statik.type_ref.clone(), |
205 | visibility: item_tree[statik.visibility].clone(), | 208 | visibility: item_tree[statik.visibility].clone(), |
206 | mutable: statik.mutable, | 209 | mutable: statik.mutable, |
210 | is_extern: statik.is_extern, | ||
207 | }) | 211 | }) |
208 | } | 212 | } |
209 | } | 213 | } |
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 7eb388bae..b3ec252fd 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -507,6 +507,9 @@ pub struct Function { | |||
507 | pub has_self_param: bool, | 507 | pub has_self_param: bool, |
508 | pub has_body: bool, | 508 | pub has_body: bool, |
509 | pub is_unsafe: bool, | 509 | pub is_unsafe: bool, |
510 | /// Whether the function is located in an `extern` block (*not* whether it is an | ||
511 | /// `extern "abi" fn`). | ||
512 | pub is_extern: bool, | ||
510 | pub params: Box<[TypeRef]>, | 513 | pub params: Box<[TypeRef]>, |
511 | pub is_varargs: bool, | 514 | pub is_varargs: bool, |
512 | pub ret_type: TypeRef, | 515 | pub ret_type: TypeRef, |
@@ -565,6 +568,8 @@ pub struct Static { | |||
565 | pub name: Name, | 568 | pub name: Name, |
566 | pub visibility: RawVisibilityId, | 569 | pub visibility: RawVisibilityId, |
567 | pub mutable: bool, | 570 | pub mutable: bool, |
571 | /// Whether the static is in an `extern` block. | ||
572 | pub is_extern: bool, | ||
568 | pub type_ref: TypeRef, | 573 | pub type_ref: TypeRef, |
569 | pub ast_id: FileAstId<ast::Static>, | 574 | pub ast_id: FileAstId<ast::Static>, |
570 | } | 575 | } |
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index ca7fb4a43..63b2826f8 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -340,6 +340,7 @@ impl Ctx { | |||
340 | has_self_param, | 340 | has_self_param, |
341 | has_body, | 341 | has_body, |
342 | is_unsafe: func.unsafe_token().is_some(), | 342 | is_unsafe: func.unsafe_token().is_some(), |
343 | is_extern: false, | ||
343 | params: params.into_boxed_slice(), | 344 | params: params.into_boxed_slice(), |
344 | is_varargs, | 345 | is_varargs, |
345 | ret_type, | 346 | ret_type, |
@@ -378,7 +379,7 @@ impl Ctx { | |||
378 | let visibility = self.lower_visibility(static_); | 379 | let visibility = self.lower_visibility(static_); |
379 | let mutable = static_.mut_token().is_some(); | 380 | let mutable = static_.mut_token().is_some(); |
380 | let ast_id = self.source_ast_id_map.ast_id(static_); | 381 | let ast_id = self.source_ast_id_map.ast_id(static_); |
381 | let res = Static { name, visibility, mutable, type_ref, ast_id }; | 382 | let res = Static { name, visibility, mutable, type_ref, ast_id, is_extern: false }; |
382 | Some(id(self.data().statics.alloc(res))) | 383 | Some(id(self.data().statics.alloc(res))) |
383 | } | 384 | } |
384 | 385 | ||
@@ -554,13 +555,15 @@ impl Ctx { | |||
554 | let attrs = Attrs::new(&item, &self.hygiene); | 555 | let attrs = Attrs::new(&item, &self.hygiene); |
555 | let id: ModItem = match item { | 556 | let id: ModItem = match item { |
556 | ast::ExternItem::Fn(ast) => { | 557 | ast::ExternItem::Fn(ast) => { |
557 | let func = self.lower_function(&ast)?; | 558 | let func_id = self.lower_function(&ast)?; |
558 | self.data().functions[func.index].is_unsafe = | 559 | let func = &mut self.data().functions[func_id.index]; |
559 | is_intrinsic_fn_unsafe(&self.data().functions[func.index].name); | 560 | func.is_unsafe = is_intrinsic_fn_unsafe(&func.name); |
560 | func.into() | 561 | func.is_extern = true; |
562 | func_id.into() | ||
561 | } | 563 | } |
562 | ast::ExternItem::Static(ast) => { | 564 | ast::ExternItem::Static(ast) => { |
563 | let statik = self.lower_static(&ast)?; | 565 | let statik = self.lower_static(&ast)?; |
566 | self.data().statics[statik.index].is_extern = true; | ||
564 | statik.into() | 567 | statik.into() |
565 | } | 568 | } |
566 | ast::ExternItem::TypeAlias(ty) => { | 569 | ast::ExternItem::TypeAlias(ty) => { |
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs index 4b3e2fa8f..724bad867 100644 --- a/crates/hir_ty/src/diagnostics/decl_check.rs +++ b/crates/hir_ty/src/diagnostics/decl_check.rs | |||
@@ -87,6 +87,10 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
87 | 87 | ||
88 | fn validate_func(&mut self, db: &dyn HirDatabase, func: FunctionId) { | 88 | fn validate_func(&mut self, db: &dyn HirDatabase, func: FunctionId) { |
89 | let data = db.function_data(func); | 89 | let data = db.function_data(func); |
90 | if data.is_extern { | ||
91 | return; | ||
92 | } | ||
93 | |||
90 | let body = db.body(func.into()); | 94 | let body = db.body(func.into()); |
91 | 95 | ||
92 | // Recursively validate inner scope items, such as static variables and constants. | 96 | // Recursively validate inner scope items, such as static variables and constants. |
@@ -648,6 +652,9 @@ impl<'a, 'b> DeclValidator<'a, 'b> { | |||
648 | 652 | ||
649 | fn validate_static(&mut self, db: &dyn HirDatabase, static_id: StaticId) { | 653 | fn validate_static(&mut self, db: &dyn HirDatabase, static_id: StaticId) { |
650 | let data = db.static_data(static_id); | 654 | let data = db.static_data(static_id); |
655 | if data.is_extern { | ||
656 | return; | ||
657 | } | ||
651 | 658 | ||
652 | if self.allowed(db, static_id.into(), allow::NON_UPPER_CASE_GLOBAL) { | 659 | if self.allowed(db, static_id.into(), allow::NON_UPPER_CASE_GLOBAL) { |
653 | return; | 660 | return; |
@@ -920,4 +927,16 @@ fn main() { | |||
920 | "#, | 927 | "#, |
921 | ); | 928 | ); |
922 | } | 929 | } |
930 | |||
931 | #[test] | ||
932 | fn ignores_extern_items() { | ||
933 | check_diagnostics( | ||
934 | r#" | ||
935 | extern { | ||
936 | fn NonSnakeCaseName(SOME_VAR: u8) -> u8; | ||
937 | pub static SomeStatic: u8 = 10; | ||
938 | } | ||
939 | "#, | ||
940 | ); | ||
941 | } | ||
923 | } | 942 | } |