Skip to content

Commit 2de7529

Browse files
authored
Merge pull request rust-lang#19109 from Veykril/push-nzpuuqommpnq
fix: Do not show safety hints for extern items lacking semantics
2 parents 4a15593 + a09ece2 commit 2de7529

File tree

10 files changed

+97
-31
lines changed

10 files changed

+97
-31
lines changed

src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ pub mod keys {
3131

3232
use crate::{
3333
dyn_map::{DynMap, Policy},
34-
BlockId, ConstId, EnumId, EnumVariantId, ExternCrateId, FieldId, FunctionId, ImplId,
35-
LifetimeParamId, Macro2Id, MacroRulesId, ProcMacroId, StaticId, StructId, TraitAliasId,
36-
TraitId, TypeAliasId, TypeOrConstParamId, UnionId, UseId,
34+
BlockId, ConstId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, FieldId, FunctionId,
35+
ImplId, LifetimeParamId, Macro2Id, MacroRulesId, ProcMacroId, StaticId, StructId,
36+
TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, UnionId, UseId,
3737
};
3838

3939
pub type Key<K, V> = crate::dyn_map::Key<AstPtr<K>, V, AstPtrPolicy<K, V>>;
@@ -44,6 +44,7 @@ pub mod keys {
4444
pub const STATIC: Key<ast::Static, StaticId> = Key::new();
4545
pub const TYPE_ALIAS: Key<ast::TypeAlias, TypeAliasId> = Key::new();
4646
pub const IMPL: Key<ast::Impl, ImplId> = Key::new();
47+
pub const EXTERN_BLOCK: Key<ast::ExternBlock, ExternBlockId> = Key::new();
4748
pub const TRAIT: Key<ast::Trait, TraitId> = Key::new();
4849
pub const TRAIT_ALIAS: Key<ast::TraitAlias, TraitAliasId> = Key::new();
4950
pub const STRUCT: Key<ast::Struct, StructId> = Key::new();

src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use crate::{
1818
db::DefDatabase,
1919
per_ns::{Item, MacrosItem, PerNs, TypesItem, ValuesItem},
2020
visibility::{Visibility, VisibilityExplicitness},
21-
AdtId, BuiltinType, ConstId, ExternCrateId, FxIndexMap, HasModule, ImplId, LocalModuleId,
22-
Lookup, MacroId, ModuleDefId, ModuleId, TraitId, UseId,
21+
AdtId, BuiltinType, ConstId, ExternBlockId, ExternCrateId, FxIndexMap, HasModule, ImplId,
22+
LocalModuleId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, UseId,
2323
};
2424

2525
#[derive(Debug, Default)]
@@ -158,6 +158,8 @@ pub struct ItemScope {
158158
declarations: Vec<ModuleDefId>,
159159

160160
impls: Vec<ImplId>,
161+
#[allow(clippy::box_collection)]
162+
extern_blocks: Option<Box<Vec<ExternBlockId>>>,
161163
unnamed_consts: Vec<ConstId>,
162164
/// Traits imported via `use Trait as _;`.
163165
unnamed_trait_imports: FxHashMap<TraitId, Item<()>>,
@@ -319,6 +321,10 @@ impl ItemScope {
319321
self.extern_crate_decls.iter().copied()
320322
}
321323

324+
pub fn extern_blocks(&self) -> impl Iterator<Item = ExternBlockId> + '_ {
325+
self.extern_blocks.iter().flat_map(|it| it.iter()).copied()
326+
}
327+
322328
pub fn use_decls(&self) -> impl ExactSizeIterator<Item = UseId> + '_ {
323329
self.use_decls.iter().copied()
324330
}
@@ -469,6 +475,10 @@ impl ItemScope {
469475
self.impls.push(imp);
470476
}
471477

478+
pub(crate) fn define_extern_block(&mut self, extern_block: ExternBlockId) {
479+
self.extern_blocks.get_or_insert_default().push(extern_block);
480+
}
481+
472482
pub(crate) fn define_extern_crate_decl(&mut self, extern_crate: ExternCrateId) {
473483
self.extern_crate_decls.push(extern_crate);
474484
}
@@ -806,7 +816,11 @@ impl ItemScope {
806816
use_imports_types,
807817
use_imports_macros,
808818
macro_invocations,
819+
extern_blocks,
809820
} = self;
821+
if let Some(it) = extern_blocks {
822+
it.shrink_to_fit();
823+
}
810824
types.shrink_to_fit();
811825
values.shrink_to_fit();
812826
macros.shrink_to_fit();

src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -1759,16 +1759,20 @@ impl ModCollector<'_, '_> {
17591759
);
17601760
}
17611761
}
1762-
ModItem::ExternBlock(block) => self.collect(
1763-
&self.item_tree[block].children,
1764-
ItemContainerId::ExternBlockId(
1765-
ExternBlockLoc {
1766-
container: module,
1767-
id: ItemTreeId::new(self.tree_id, block),
1768-
}
1769-
.intern(db),
1770-
),
1771-
),
1762+
ModItem::ExternBlock(block) => {
1763+
let extern_block_id = ExternBlockLoc {
1764+
container: module,
1765+
id: ItemTreeId::new(self.tree_id, block),
1766+
}
1767+
.intern(db);
1768+
self.def_collector.def_map.modules[self.module_id]
1769+
.scope
1770+
.define_extern_block(extern_block_id);
1771+
self.collect(
1772+
&self.item_tree[block].children,
1773+
ItemContainerId::ExternBlockId(extern_block_id),
1774+
)
1775+
}
17721776
ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac], container),
17731777
ModItem::MacroRules(id) => self.collect_macro_rules(id, module),
17741778
ModItem::Macro2(id) => self.collect_macro_def(id, module),

src/tools/rust-analyzer/crates/hir/src/from_id.rs

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ from_id![
4949
(hir_def::LifetimeParamId, crate::LifetimeParam),
5050
(hir_def::MacroId, crate::Macro),
5151
(hir_def::ExternCrateId, crate::ExternCrateDecl),
52+
(hir_def::ExternBlockId, crate::ExternBlock),
5253
];
5354

5455
impl From<AdtId> for Adt {

src/tools/rust-analyzer/crates/hir/src/lib.rs

+35-4
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ use hir_def::{
5555
resolver::{HasResolver, Resolver},
5656
type_ref::TypesSourceMap,
5757
AdtId, AssocItemId, AssocItemLoc, AttrDefId, CallableDefId, ConstId, ConstParamId,
58-
CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternCrateId, FunctionId,
59-
GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstId, ItemContainerId,
58+
CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId,
59+
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstId, ItemContainerId,
6060
LifetimeParamId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId,
6161
SyntheticSyntax, TraitAliasId, TupleId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
6262
};
@@ -2327,6 +2327,13 @@ impl Function {
23272327
db.function_data(self.id).is_async()
23282328
}
23292329

2330+
pub fn extern_block(self, db: &dyn HirDatabase) -> Option<ExternBlock> {
2331+
match self.id.lookup(db.upcast()).container {
2332+
ItemContainerId::ExternBlockId(id) => Some(ExternBlock { id }),
2333+
_ => None,
2334+
}
2335+
}
2336+
23302337
pub fn returns_impl_future(self, db: &dyn HirDatabase) -> bool {
23312338
if self.is_async(db) {
23322339
return true;
@@ -2761,6 +2768,13 @@ impl Static {
27612768
Type::from_value_def(db, self.id)
27622769
}
27632770

2771+
pub fn extern_block(self, db: &dyn HirDatabase) -> Option<ExternBlock> {
2772+
match self.id.lookup(db.upcast()).container {
2773+
ItemContainerId::ExternBlockId(id) => Some(ExternBlock { id }),
2774+
_ => None,
2775+
}
2776+
}
2777+
27642778
/// Evaluate the static initializer.
27652779
pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst, ConstEvalError> {
27662780
db.const_eval(self.id.into(), Substitution::empty(Interner), None)
@@ -2928,6 +2942,17 @@ impl HasVisibility for TypeAlias {
29282942
}
29292943
}
29302944

2945+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2946+
pub struct ExternBlock {
2947+
pub(crate) id: ExternBlockId,
2948+
}
2949+
2950+
impl ExternBlock {
2951+
pub fn module(self, db: &dyn HirDatabase) -> Module {
2952+
Module { id: self.id.module(db.upcast()) }
2953+
}
2954+
}
2955+
29312956
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
29322957
pub struct StaticLifetime;
29332958

@@ -6177,9 +6202,15 @@ impl HasContainer for TraitAlias {
61776202
}
61786203
}
61796204

6205+
impl HasContainer for ExternBlock {
6206+
fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
6207+
ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
6208+
}
6209+
}
6210+
61806211
fn container_id_to_hir(c: ItemContainerId) -> ItemContainer {
61816212
match c {
6182-
ItemContainerId::ExternBlockId(_id) => ItemContainer::ExternBlock(),
6213+
ItemContainerId::ExternBlockId(id) => ItemContainer::ExternBlock(ExternBlock { id }),
61836214
ItemContainerId::ModuleId(id) => ItemContainer::Module(Module { id }),
61846215
ItemContainerId::ImplId(id) => ItemContainer::Impl(Impl { id }),
61856216
ItemContainerId::TraitId(id) => ItemContainer::Trait(Trait { id }),
@@ -6191,7 +6222,7 @@ pub enum ItemContainer {
61916222
Trait(Trait),
61926223
Impl(Impl),
61936224
Module(Module),
6194-
ExternBlock(),
6225+
ExternBlock(ExternBlock),
61956226
Crate(CrateId),
61966227
}
61976228

src/tools/rust-analyzer/crates/hir/src/semantics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1998,6 +1998,7 @@ to_def_impls![
19981998
(crate::Adt, ast::Adt, adt_to_def),
19991999
(crate::ExternCrateDecl, ast::ExternCrate, extern_crate_to_def),
20002000
(crate::InlineAsmOperand, ast::AsmOperandNamed, asm_operand_to_def),
2001+
(crate::ExternBlock, ast::ExternBlock, extern_block_to_def),
20012002
(MacroCallId, ast::MacroCall, macro_call_to_macro_call),
20022003
];
20032004

src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs

+3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ impl ChildBySource for ItemScope {
7474
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
7575
self.declarations().for_each(|item| add_module_def(db, res, file_id, item));
7676
self.impls().for_each(|imp| insert_item_loc(db, res, file_id, imp, keys::IMPL));
77+
self.extern_blocks().for_each(|extern_block| {
78+
insert_item_loc(db, res, file_id, extern_block, keys::EXTERN_BLOCK)
79+
});
7780
self.extern_crate_decls()
7881
.for_each(|ext| insert_item_loc(db, res, file_id, ext, keys::EXTERN_CRATE));
7982
self.use_decls().for_each(|ext| insert_item_loc(db, res, file_id, ext, keys::USE));

src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ use hir_def::{
9292
DynMap,
9393
},
9494
hir::{BindingId, Expr, LabelId},
95-
AdtId, BlockId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternCrateId,
96-
FieldId, FunctionId, GenericDefId, GenericParamId, ImplId, LifetimeParamId, Lookup, MacroId,
97-
ModuleId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, TypeParamId, UnionId, UseId,
98-
VariantId,
95+
AdtId, BlockId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId,
96+
ExternCrateId, FieldId, FunctionId, GenericDefId, GenericParamId, ImplId, LifetimeParamId,
97+
Lookup, MacroId, ModuleId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, TypeParamId,
98+
UnionId, UseId, VariantId,
9999
};
100100
use hir_expand::{
101101
attrs::AttrId, name::AsName, ExpansionInfo, HirFileId, HirFileIdExt, InMacroFile, MacroCallId,
@@ -308,6 +308,12 @@ impl SourceToDefCtx<'_, '_> {
308308
) -> Option<ExternCrateId> {
309309
self.to_def(src, keys::EXTERN_CRATE)
310310
}
311+
pub(super) fn extern_block_to_def(
312+
&mut self,
313+
src: InFile<&ast::ExternBlock>,
314+
) -> Option<ExternBlockId> {
315+
self.to_def(src, keys::EXTERN_BLOCK)
316+
}
311317
#[allow(dead_code)]
312318
pub(super) fn use_to_def(&mut self, src: InFile<&ast::Use>) -> Option<UseId> {
313319
self.to_def(src, keys::USE)

src/tools/rust-analyzer/crates/ide-db/src/defs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ impl Definition {
108108
ItemContainer::Trait(it) => Some(it.into()),
109109
ItemContainer::Impl(it) => Some(it.into()),
110110
ItemContainer::Module(it) => Some(it.into()),
111-
ItemContainer::ExternBlock() | ItemContainer::Crate(_) => None,
111+
ItemContainer::ExternBlock(_) | ItemContainer::Crate(_) => None,
112112
}
113113
}
114114
match self {

src/tools/rust-analyzer/crates/ide/src/inlay_hints/extern_block.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{InlayHint, InlayHintsConfig};
77

88
pub(super) fn extern_block_hints(
99
acc: &mut Vec<InlayHint>,
10-
FamousDefs(_sema, _): &FamousDefs<'_, '_>,
10+
FamousDefs(sema, _): &FamousDefs<'_, '_>,
1111
config: &InlayHintsConfig,
1212
_file_id: EditionedFileId,
1313
extern_block: ast::ExternBlock,
@@ -16,6 +16,7 @@ pub(super) fn extern_block_hints(
1616
return None;
1717
}
1818
let abi = extern_block.abi()?;
19+
sema.to_def(&extern_block)?;
1920
acc.push(InlayHint {
2021
range: abi.syntax().text_range(),
2122
position: crate::InlayHintPosition::Before,
@@ -33,7 +34,7 @@ pub(super) fn extern_block_hints(
3334

3435
pub(super) fn fn_hints(
3536
acc: &mut Vec<InlayHint>,
36-
FamousDefs(_sema, _): &FamousDefs<'_, '_>,
37+
FamousDefs(sema, _): &FamousDefs<'_, '_>,
3738
config: &InlayHintsConfig,
3839
_file_id: EditionedFileId,
3940
fn_: &ast::Fn,
@@ -43,14 +44,16 @@ pub(super) fn fn_hints(
4344
if !implicit_unsafe {
4445
return None;
4546
}
46-
let fn_ = fn_.fn_token()?;
47-
acc.push(item_hint(config, extern_block, fn_));
47+
let fn_token = fn_.fn_token()?;
48+
if sema.to_def(fn_).is_some_and(|def| def.extern_block(sema.db).is_some()) {
49+
acc.push(item_hint(config, extern_block, fn_token));
50+
}
4851
Some(())
4952
}
5053

5154
pub(super) fn static_hints(
5255
acc: &mut Vec<InlayHint>,
53-
FamousDefs(_sema, _): &FamousDefs<'_, '_>,
56+
FamousDefs(sema, _): &FamousDefs<'_, '_>,
5457
config: &InlayHintsConfig,
5558
_file_id: EditionedFileId,
5659
static_: &ast::Static,
@@ -60,8 +63,10 @@ pub(super) fn static_hints(
6063
if !implicit_unsafe {
6164
return None;
6265
}
63-
let static_ = static_.static_token()?;
64-
acc.push(item_hint(config, extern_block, static_));
66+
let static_token = static_.static_token()?;
67+
if sema.to_def(static_).is_some_and(|def| def.extern_block(sema.db).is_some()) {
68+
acc.push(item_hint(config, extern_block, static_token));
69+
}
6570
Some(())
6671
}
6772

0 commit comments

Comments
 (0)