Skip to content

Commit 755b668

Browse files
bors[bot]Jonas Schievink
and
Jonas Schievink
authored
Merge #10960
10960: fix: fix handling of macros in `extern` blocks r=jonas-schievink a=jonas-schievink - Removes knowledge of what's in an extern block from `ItemTree`. - Treats extern blocks as `AssocContainerId` and renames the latter to `ItemContainerId`. - Threads the container through name resolution (which is a bit messy). - Considers statics to be associated items, since they can be in an extern block. (it might be better to further distinguish potentially-associated-items from potentially-in-an-extern-block-items, but currently I don't expect much of a benefit) - Adds a test for the incorrect-case diagnostic demonstrating the impact of this change. Fixes #8913 bors r+ Co-authored-by: Jonas Schievink <[email protected]>
2 parents b7afb6f + b365b61 commit 755b668

26 files changed

+216
-164
lines changed

crates/hir/src/attrs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ fn resolve_doc_path(
137137
AttrDefId::TraitId(it) => it.resolver(db.upcast()),
138138
AttrDefId::TypeAliasId(it) => it.resolver(db.upcast()),
139139
AttrDefId::ImplId(it) => it.resolver(db.upcast()),
140+
AttrDefId::ExternBlockId(it) => it.resolver(db.upcast()),
140141
AttrDefId::GenericParamId(it) => match it {
141142
GenericParamId::TypeParamId(it) => it.parent,
142143
GenericParamId::LifetimeParamId(it) => it.parent,

crates/hir/src/lib.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,11 @@ pub use {
114114
type_ref::{Mutability, TypeRef},
115115
visibility::Visibility,
116116
AdtId,
117-
AssocContainerId,
118117
AssocItemId,
119118
AssocItemLoc,
120119
DefWithBodyId,
121120
ImplId,
121+
ItemContainerId,
122122
ItemLoc,
123123
Lookup,
124124
ModuleDefId,
@@ -1550,7 +1550,7 @@ impl Static {
15501550
pub fn ty(self, db: &dyn HirDatabase) -> Type {
15511551
let data = db.static_data(self.id);
15521552
let resolver = self.id.resolver(db.upcast());
1553-
let krate = self.id.lookup(db.upcast()).container.krate();
1553+
let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate();
15541554
let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
15551555
let ty = ctx.lower_ty(&data.type_ref);
15561556
Type::new_with_resolver_inner(db, krate, &resolver, ty)
@@ -1820,8 +1820,8 @@ where
18201820
AST: ItemTreeNode,
18211821
{
18221822
match id.lookup(db.upcast()).container {
1823-
AssocContainerId::TraitId(_) | AssocContainerId::ImplId(_) => Some(ctor(DEF::from(id))),
1824-
AssocContainerId::ModuleId(_) => None,
1823+
ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => Some(ctor(DEF::from(id))),
1824+
ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => None,
18251825
}
18261826
}
18271827

@@ -1847,9 +1847,11 @@ impl AssocItem {
18471847
AssocItem::TypeAlias(it) => it.id.lookup(db.upcast()).container,
18481848
};
18491849
match container {
1850-
AssocContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()),
1851-
AssocContainerId::ImplId(id) => AssocItemContainer::Impl(id.into()),
1852-
AssocContainerId::ModuleId(_) => panic!("invalid AssocItem"),
1850+
ItemContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()),
1851+
ItemContainerId::ImplId(id) => AssocItemContainer::Impl(id.into()),
1852+
ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => {
1853+
panic!("invalid AssocItem")
1854+
}
18531855
}
18541856
}
18551857

crates/hir_def/src/attr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ impl AttrsWithOwner {
362362
RawAttrs::from_attrs_owner(db, src.with_value(&src.value[it.local_id]))
363363
}
364364
},
365+
AttrDefId::ExternBlockId(it) => attrs_from_item_tree(it.lookup(db).id, db),
365366
};
366367

367368
let attrs = raw_attrs.filter(db, def.krate(db));
@@ -443,6 +444,7 @@ impl AttrsWithOwner {
443444
.child_source(db)
444445
.map(|source| ast::AnyHasAttrs::new(source[id.local_id].clone())),
445446
},
447+
AttrDefId::ExternBlockId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
446448
};
447449

448450
AttrSourceMap::new(owner.as_ref().map(|node| node as &dyn HasAttrs))

crates/hir_def/src/data.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use crate::{
1313
item_tree::{self, AssocItem, FnFlags, ItemTreeId, ModItem, Param},
1414
type_ref::{TraitRef, TypeBound, TypeRef},
1515
visibility::RawVisibility,
16-
AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
17-
Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
16+
AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, Intern,
17+
ItemContainerId, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
1818
};
1919

2020
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -54,6 +54,10 @@ impl FunctionData {
5454
flags.bits |= FnFlags::IS_VARARGS;
5555
}
5656

57+
if matches!(loc.container, ItemContainerId::ExternBlockId(_)) {
58+
flags.bits |= FnFlags::IS_IN_EXTERN_BLOCK;
59+
}
60+
5761
Arc::new(FunctionData {
5862
name: func.name.clone(),
5963
params: enabled_params
@@ -130,7 +134,7 @@ impl TypeAliasData {
130134
name: typ.name.clone(),
131135
type_ref: typ.type_ref.clone(),
132136
visibility: item_tree[typ.visibility].clone(),
133-
is_extern: typ.is_extern,
137+
is_extern: matches!(loc.container, ItemContainerId::ExternBlockId(_)),
134138
bounds: typ.bounds.to_vec(),
135139
})
136140
}
@@ -162,7 +166,7 @@ impl TraitData {
162166
let is_auto = tr_def.is_auto;
163167
let is_unsafe = tr_def.is_unsafe;
164168
let module_id = tr_loc.container;
165-
let container = AssocContainerId::TraitId(tr);
169+
let container = ItemContainerId::TraitId(tr);
166170
let visibility = item_tree[tr_def.visibility].clone();
167171
let mut expander = Expander::new(db, tr_loc.id.file_id(), module_id);
168172
let skip_array_during_method_dispatch = item_tree
@@ -231,7 +235,7 @@ impl ImplData {
231235
let self_ty = impl_def.self_ty.clone();
232236
let is_negative = impl_def.is_negative;
233237
let module_id = impl_loc.container;
234-
let container = AssocContainerId::ImplId(id);
238+
let container = ItemContainerId::ImplId(id);
235239
let mut expander = Expander::new(db, impl_loc.id.file_id(), module_id);
236240

237241
let items = collect_items(
@@ -282,16 +286,16 @@ pub struct StaticData {
282286

283287
impl StaticData {
284288
pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<StaticData> {
285-
let node = konst.lookup(db);
286-
let item_tree = node.id.item_tree(db);
287-
let statik = &item_tree[node.id.value];
289+
let loc = konst.lookup(db);
290+
let item_tree = loc.id.item_tree(db);
291+
let statik = &item_tree[loc.id.value];
288292

289293
Arc::new(StaticData {
290294
name: statik.name.clone(),
291295
type_ref: statik.type_ref.clone(),
292296
visibility: item_tree[statik.visibility].clone(),
293297
mutable: statik.mutable,
294-
is_extern: statik.is_extern,
298+
is_extern: matches!(loc.container, ItemContainerId::ExternBlockId(_)),
295299
})
296300
}
297301
}
@@ -302,7 +306,7 @@ fn collect_items(
302306
expander: &mut Expander,
303307
assoc_items: impl Iterator<Item = AssocItem>,
304308
tree_id: item_tree::TreeId,
305-
container: AssocContainerId,
309+
container: ItemContainerId,
306310
limit: usize,
307311
) -> Vec<(Name, AssocItemId)> {
308312
if limit == 0 {

crates/hir_def/src/db.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ use crate::{
1919
lang_item::{LangItemTarget, LangItems},
2020
nameres::DefMap,
2121
visibility::{self, Visibility},
22-
AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId,
23-
FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId, LocalFieldId, StaticId,
24-
StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId,
25-
UnionLoc, VariantId,
22+
AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId,
23+
ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId,
24+
LocalFieldId, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId,
25+
TypeAliasLoc, UnionId, UnionLoc, VariantId,
2626
};
2727

2828
#[salsa::query_group(InternDatabaseStorage)]
@@ -46,6 +46,8 @@ pub trait InternDatabase: SourceDatabase {
4646
#[salsa::interned]
4747
fn intern_impl(&self, loc: ImplLoc) -> ImplId;
4848
#[salsa::interned]
49+
fn intern_extern_block(&self, loc: ExternBlockLoc) -> ExternBlockId;
50+
#[salsa::interned]
4951
fn intern_block(&self, loc: BlockLoc) -> BlockId;
5052
}
5153

crates/hir_def/src/import_map.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ mod tests {
468468
use base_db::{fixture::WithFixture, SourceDatabase, Upcast};
469469
use expect_test::{expect, Expect};
470470

471-
use crate::{test_db::TestDB, AssocContainerId, Lookup};
471+
use crate::{test_db::TestDB, ItemContainerId, Lookup};
472472

473473
use super::*;
474474

@@ -563,7 +563,7 @@ mod tests {
563563
};
564564

565565
match container {
566-
AssocContainerId::TraitId(it) => Some(ItemInNs::Types(it.into())),
566+
ItemContainerId::TraitId(it) => Some(ItemInNs::Types(it.into())),
567567
_ => None,
568568
}
569569
}

crates/hir_def/src/item_tree.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -660,8 +660,6 @@ pub struct Static {
660660
pub name: Name,
661661
pub visibility: RawVisibilityId,
662662
pub mutable: bool,
663-
/// Whether the static is in an `extern` block.
664-
pub is_extern: bool,
665663
pub type_ref: Interned<TypeRef>,
666664
pub ast_id: FileAstId<ast::Static>,
667665
}
@@ -695,7 +693,6 @@ pub struct TypeAlias {
695693
pub bounds: Box<[Interned<TypeBound>]>,
696694
pub generic_params: Interned<GenericParams>,
697695
pub type_ref: Option<Interned<TypeRef>>,
698-
pub is_extern: bool,
699696
pub ast_id: FileAstId<ast::TypeAlias>,
700697
}
701698

crates/hir_def/src/item_tree/lower.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,6 @@ impl<'a> Ctx<'a> {
360360
generic_params,
361361
type_ref,
362362
ast_id,
363-
is_extern: false,
364363
};
365364
Some(id(self.data().type_aliases.alloc(res)))
366365
}
@@ -371,7 +370,7 @@ impl<'a> Ctx<'a> {
371370
let visibility = self.lower_visibility(static_);
372371
let mutable = static_.mut_token().is_some();
373372
let ast_id = self.source_ast_id_map.ast_id(static_);
374-
let res = Static { name, visibility, mutable, type_ref, ast_id, is_extern: false };
373+
let res = Static { name, visibility, mutable, type_ref, ast_id };
375374
Some(id(self.data().statics.alloc(res)))
376375
}
377376

@@ -525,27 +524,23 @@ impl<'a> Ctx<'a> {
525524
let children: Box<[_]> = block.extern_item_list().map_or(Box::new([]), |list| {
526525
list.extern_items()
527526
.filter_map(|item| {
527+
// Note: All items in an `extern` block need to be lowered as if they're outside of one
528+
// (in other words, the knowledge that they're in an extern block must not be used).
529+
// This is because an extern block can contain macros whose ItemTree's top-level items
530+
// should be considered to be in an extern block too.
528531
let attrs = RawAttrs::new(self.db, &item, &self.hygiene);
529532
let id: ModItem = match item {
530533
ast::ExternItem::Fn(ast) => {
531534
let func_id = self.lower_function(&ast)?;
532535
let func = &mut self.data().functions[func_id.index];
533536
if is_intrinsic_fn_unsafe(&func.name) {
537+
// FIXME: this breaks in macros
534538
func.flags.bits |= FnFlags::IS_UNSAFE;
535539
}
536-
func.flags.bits |= FnFlags::IS_IN_EXTERN_BLOCK;
537540
func_id.into()
538541
}
539-
ast::ExternItem::Static(ast) => {
540-
let statik = self.lower_static(&ast)?;
541-
self.data().statics[statik.index].is_extern = true;
542-
statik.into()
543-
}
544-
ast::ExternItem::TypeAlias(ty) => {
545-
let foreign_ty = self.lower_type_alias(&ty)?;
546-
self.data().type_aliases[foreign_ty.index].is_extern = true;
547-
foreign_ty.into()
548-
}
542+
ast::ExternItem::Static(ast) => self.lower_static(&ast)?.into(),
543+
ast::ExternItem::TypeAlias(ty) => self.lower_type_alias(&ty)?.into(),
549544
ast::ExternItem::MacroCall(call) => {
550545
// FIXME: we need some way of tracking that the macro call is in an
551546
// extern block

crates/hir_def/src/item_tree/pretty.rs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,7 @@ impl<'a> Printer<'a> {
328328
wln!(self, " = _;");
329329
}
330330
ModItem::Static(it) => {
331-
let Static { name, visibility, mutable, is_extern, type_ref, ast_id: _ } =
332-
&self.tree[it];
331+
let Static { name, visibility, mutable, type_ref, ast_id: _ } = &self.tree[it];
333332
self.print_visibility(*visibility);
334333
w!(self, "static ");
335334
if *mutable {
@@ -338,9 +337,6 @@ impl<'a> Printer<'a> {
338337
w!(self, "{}: ", name);
339338
self.print_type_ref(type_ref);
340339
w!(self, " = _;");
341-
if *is_extern {
342-
w!(self, " // extern");
343-
}
344340
wln!(self);
345341
}
346342
ModItem::Trait(it) => {
@@ -393,15 +389,8 @@ impl<'a> Printer<'a> {
393389
wln!(self, "}}");
394390
}
395391
ModItem::TypeAlias(it) => {
396-
let TypeAlias {
397-
name,
398-
visibility,
399-
bounds,
400-
type_ref,
401-
is_extern,
402-
generic_params,
403-
ast_id: _,
404-
} = &self.tree[it];
392+
let TypeAlias { name, visibility, bounds, type_ref, generic_params, ast_id: _ } =
393+
&self.tree[it];
405394
self.print_visibility(*visibility);
406395
w!(self, "type {}", name);
407396
self.print_generic_params(generic_params);
@@ -415,9 +404,6 @@ impl<'a> Printer<'a> {
415404
}
416405
self.print_where_clause(generic_params);
417406
w!(self, ";");
418-
if *is_extern {
419-
w!(self, " // extern");
420-
}
421407
wln!(self);
422408
}
423409
ModItem::Mod(it) => {

crates/hir_def/src/item_tree/tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,13 @@ extern "C" {
7070
#[on_extern_block] // AttrId { is_doc_comment: false, ast_index: 0 }
7171
extern "C" {
7272
#[on_extern_type] // AttrId { is_doc_comment: false, ast_index: 0 }
73-
pub(self) type ExType; // extern
73+
pub(self) type ExType;
7474
7575
#[on_extern_static] // AttrId { is_doc_comment: false, ast_index: 0 }
76-
pub(self) static EX_STATIC: u8 = _; // extern
76+
pub(self) static EX_STATIC: u8 = _;
7777
7878
#[on_extern_fn] // AttrId { is_doc_comment: false, ast_index: 0 }
79-
// flags = 0x60
79+
// flags = 0x20
8080
pub(self) fn ex_fn() -> ();
8181
}
8282
"##]],

0 commit comments

Comments
 (0)