diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs index ad1c1f2ce5..b9f8c2f297 100644 --- a/crates/hir_def/src/data.rs +++ b/crates/hir_def/src/data.rs @@ -255,7 +255,7 @@ impl ImplData { #[derive(Debug, Clone, PartialEq, Eq)] pub struct ConstData { - /// const _: () = (); + /// `None` for `const _: () = ();` pub name: Option, pub type_ref: Interned, pub visibility: RawVisibility, diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 405cc2d00f..68d77084a3 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -648,7 +648,7 @@ pub struct Enum { #[derive(Debug, Clone, Eq, PartialEq)] pub struct Const { - /// const _: () = (); + /// `None` for `const _: () = ();` pub name: Option, pub visibility: RawVisibilityId, pub type_ref: Interned, diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index e9af991785..4396801116 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -375,12 +375,7 @@ impl<'a> Ctx<'a> { } fn lower_const(&mut self, konst: &ast::Const) -> FileItemTreeId { - let mut name = konst.name().map(|it| it.as_name()); - if name.as_ref().map_or(false, |n| n.to_smol_str().starts_with("_DERIVE_")) { - // FIXME: this is a hack to treat consts generated by synstructure as unnamed - // remove this some time in the future - name = None; - } + let name = konst.name().map(|it| it.as_name()); let type_ref = self.lower_type_ref_opt(konst.ty()); let visibility = self.lower_visibility(konst); let ast_id = self.source_ast_id_map.ast_id(konst); diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 6b3f48b194..1e53d392e8 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -8,8 +8,9 @@ use arrayvec::ArrayVec; use base_db::{CrateId, Edition}; use chalk_ir::{cast::Cast, Mutability, UniverseIndex}; use hir_def::{ - lang_item::LangItemTarget, nameres::DefMap, AssocItemId, BlockId, FunctionId, GenericDefId, - HasModule, ImplId, ItemContainerId, Lookup, ModuleId, TraitId, + item_scope::ItemScope, lang_item::LangItemTarget, nameres::DefMap, AssocItemId, BlockId, + ConstId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, Lookup, ModuleDefId, + ModuleId, TraitId, }; use hir_expand::name::Name; use rustc_hash::{FxHashMap, FxHashSet}; @@ -177,7 +178,7 @@ impl TraitImpls { // To better support custom derives, collect impls in all unnamed const items. // const _: () = { ... }; - for konst in module_data.scope.unnamed_consts() { + for konst in collect_unnamed_consts(db, &module_data.scope) { let body = db.body(konst.into()); for (_, block_def_map) in body.blocks(db.upcast()) { self.collect_def_map(db, &block_def_map); @@ -297,7 +298,7 @@ impl InherentImpls { // To better support custom derives, collect impls in all unnamed const items. // const _: () = { ... }; - for konst in module_data.scope.unnamed_consts() { + for konst in collect_unnamed_consts(db, &module_data.scope) { let body = db.body(konst.into()); for (_, block_def_map) in body.blocks(db.upcast()) { self.collect_def_map(db, &block_def_map); @@ -318,6 +319,34 @@ impl InherentImpls { } } +fn collect_unnamed_consts<'a>( + db: &'a dyn HirDatabase, + scope: &'a ItemScope, +) -> impl Iterator + 'a { + let unnamed_consts = scope.unnamed_consts(); + + // FIXME: Also treat consts named `_DERIVE_*` as unnamed, since synstructure generates those. + // Should be removed once synstructure stops doing that. + let synstructure_hack_consts = scope.values().filter_map(|(item, _)| match item { + ModuleDefId::ConstId(id) => { + let loc = id.lookup(db.upcast()); + let item_tree = loc.id.item_tree(db.upcast()); + if item_tree[loc.id.value] + .name + .as_ref() + .map_or(false, |n| n.to_smol_str().starts_with("_DERIVE_")) + { + Some(id) + } else { + None + } + } + _ => None, + }); + + unnamed_consts.chain(synstructure_hack_consts) +} + pub fn def_crates( db: &dyn HirDatabase, ty: &Ty, diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs index 9b1f682b61..731605ced1 100644 --- a/crates/hir_ty/src/tests/method_resolution.rs +++ b/crates/hir_ty/src/tests/method_resolution.rs @@ -1248,6 +1248,28 @@ fn f() { ); } +#[test] +fn trait_impl_in_synstructure_const() { + check_types( + r#" +struct S; + +trait Tr { + fn method(&self) -> u16; +} + +const _DERIVE_Tr_: () = { + impl Tr for S {} +}; + +fn f() { + S.method(); + //^^^^^^^^^^ u16 +} + "#, + ); +} + #[test] fn inherent_impl_in_unnamed_const() { check_types(