Skip to content

Commit 1ae0258

Browse files
authored
Merge pull request #18825 from Veykril/push-sllokkprznkq
minor: Encode TraitData bools as bitflags
2 parents 70ba3b5 + b763a97 commit 1ae0258

File tree

7 files changed

+81
-50
lines changed

7 files changed

+81
-50
lines changed

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

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -229,20 +229,24 @@ impl TypeAliasData {
229229
}
230230
}
231231

232+
bitflags::bitflags! {
233+
#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
234+
pub struct TraitFlags: u8 {
235+
const IS_AUTO = 1 << 0;
236+
const IS_UNSAFE = 1 << 1;
237+
const IS_FUNDAMENTAL = 1 << 2;
238+
const RUSTC_HAS_INCOHERENT_INHERENT_IMPLS = 1 << 3;
239+
const SKIP_ARRAY_DURING_METHOD_DISPATCH = 1 << 4;
240+
const SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH = 1 << 5;
241+
}
242+
}
243+
232244
#[derive(Debug, Clone, PartialEq, Eq)]
233245
pub struct TraitData {
234246
pub name: Name,
235247
pub items: Vec<(Name, AssocItemId)>,
236-
pub is_auto: bool,
237-
pub is_unsafe: bool,
238-
pub rustc_has_incoherent_inherent_impls: bool,
239-
pub skip_array_during_method_dispatch: bool,
240-
pub skip_boxed_slice_during_method_dispatch: bool,
241-
pub fundamental: bool,
248+
pub flags: TraitFlags,
242249
pub visibility: RawVisibility,
243-
/// Whether the trait has `#[rust_skip_array_during_method_dispatch]`. `hir_ty` will ignore
244-
/// method calls to this trait's methods when the receiver is an array and the crate edition is
245-
/// 2015 or 2018.
246250
// box it as the vec is usually empty anyways
247251
pub macro_calls: Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>,
248252
}
@@ -261,10 +265,24 @@ impl TraitData {
261265
let item_tree = tree_id.item_tree(db);
262266
let tr_def = &item_tree[tree_id.value];
263267
let name = tr_def.name.clone();
264-
let is_auto = tr_def.is_auto;
265-
let is_unsafe = tr_def.is_unsafe;
266268
let visibility = item_tree[tr_def.visibility].clone();
267269
let attrs = item_tree.attrs(db, module_id.krate(), ModItem::from(tree_id.value).into());
270+
271+
let mut flags = TraitFlags::empty();
272+
273+
if tr_def.is_auto {
274+
flags |= TraitFlags::IS_AUTO;
275+
}
276+
if tr_def.is_unsafe {
277+
flags |= TraitFlags::IS_UNSAFE;
278+
}
279+
if attrs.by_key(&sym::fundamental).exists() {
280+
flags |= TraitFlags::IS_FUNDAMENTAL;
281+
}
282+
if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() {
283+
flags |= TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS;
284+
}
285+
268286
let mut skip_array_during_method_dispatch =
269287
attrs.by_key(&sym::rustc_skip_array_during_method_dispatch).exists();
270288
let mut skip_boxed_slice_during_method_dispatch = false;
@@ -276,27 +294,21 @@ impl TraitData {
276294
}
277295
}
278296
}
279-
let rustc_has_incoherent_inherent_impls =
280-
attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists();
281-
let fundamental = attrs.by_key(&sym::fundamental).exists();
297+
298+
if skip_array_during_method_dispatch {
299+
flags |= TraitFlags::SKIP_ARRAY_DURING_METHOD_DISPATCH;
300+
}
301+
if skip_boxed_slice_during_method_dispatch {
302+
flags |= TraitFlags::SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH;
303+
}
304+
282305
let mut collector =
283306
AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::TraitId(tr));
284307
collector.collect(&item_tree, tree_id.tree_id(), &tr_def.items);
285308
let (items, macro_calls, diagnostics) = collector.finish();
286309

287310
(
288-
Arc::new(TraitData {
289-
name,
290-
macro_calls,
291-
items,
292-
is_auto,
293-
is_unsafe,
294-
visibility,
295-
skip_array_during_method_dispatch,
296-
skip_boxed_slice_during_method_dispatch,
297-
rustc_has_incoherent_inherent_impls,
298-
fundamental,
299-
}),
311+
Arc::new(TraitData { name, macro_calls, items, visibility, flags }),
300312
DefDiagnostics::new(diagnostics),
301313
)
302314
}

src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
1313

1414
use base_db::CrateId;
1515
use hir_def::{
16-
data::adt::StructFlags,
16+
data::{adt::StructFlags, TraitFlags},
1717
hir::Movability,
1818
lang_item::{LangItem, LangItemTarget},
1919
AssocItemId, BlockId, CallableDefId, GenericDefId, HasModule, ItemContainerId, Lookup,
@@ -675,13 +675,13 @@ pub(crate) fn trait_datum_query(
675675
let generic_params = generics(db.upcast(), trait_.into());
676676
let bound_vars = generic_params.bound_vars_subst(db, DebruijnIndex::INNERMOST);
677677
let flags = rust_ir::TraitFlags {
678-
auto: trait_data.is_auto,
678+
auto: trait_data.flags.contains(TraitFlags::IS_AUTO),
679679
upstream: trait_.lookup(db.upcast()).container.krate() != krate,
680680
non_enumerable: true,
681681
coinductive: false, // only relevant for Chalk testing
682682
// FIXME: set these flags correctly
683683
marker: false,
684-
fundamental: trait_data.fundamental,
684+
fundamental: trait_data.flags.contains(TraitFlags::IS_FUNDAMENTAL),
685685
};
686686
let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars);
687687
let associated_ty_ids = trait_data.associated_types().map(to_assoc_type_id).collect();

src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use chalk_ir::{
99
};
1010
use chalk_solve::rust_ir::InlineBound;
1111
use hir_def::{
12-
lang_item::LangItem, AssocItemId, ConstId, FunctionId, GenericDefId, HasModule, TraitId,
13-
TypeAliasId,
12+
data::TraitFlags, lang_item::LangItem, AssocItemId, ConstId, FunctionId, GenericDefId,
13+
HasModule, TraitId, TypeAliasId,
1414
};
1515
use rustc_hash::FxHashSet;
1616
use smallvec::SmallVec;
@@ -432,7 +432,7 @@ where
432432
// Allow `impl AutoTrait` predicates
433433
if let WhereClause::Implemented(TraitRef { trait_id, substitution }) = pred {
434434
let trait_data = db.trait_data(from_chalk_trait_id(*trait_id));
435-
if trait_data.is_auto
435+
if trait_data.flags.contains(TraitFlags::IS_AUTO)
436436
&& substitution
437437
.as_slice(Interner)
438438
.first()

src/tools/rust-analyzer/crates/hir-ty/src/lower.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use either::Either;
2525
use hir_def::{
2626
body::HygieneId,
2727
builtin_type::BuiltinType,
28-
data::adt::StructKind,
28+
data::{adt::StructKind, TraitFlags},
2929
expander::Expander,
3030
generics::{
3131
GenericParamDataRef, TypeOrConstParamData, TypeParamProvenance, WherePredicate,
@@ -1567,9 +1567,17 @@ impl<'a> TyLoweringContext<'a> {
15671567
match (lhs.skip_binders(), rhs.skip_binders()) {
15681568
(WhereClause::Implemented(lhs), WhereClause::Implemented(rhs)) => {
15691569
let lhs_id = lhs.trait_id;
1570-
let lhs_is_auto = ctx.db.trait_data(from_chalk_trait_id(lhs_id)).is_auto;
1570+
let lhs_is_auto = ctx
1571+
.db
1572+
.trait_data(from_chalk_trait_id(lhs_id))
1573+
.flags
1574+
.contains(TraitFlags::IS_AUTO);
15711575
let rhs_id = rhs.trait_id;
1572-
let rhs_is_auto = ctx.db.trait_data(from_chalk_trait_id(rhs_id)).is_auto;
1576+
let rhs_is_auto = ctx
1577+
.db
1578+
.trait_data(from_chalk_trait_id(rhs_id))
1579+
.flags
1580+
.contains(TraitFlags::IS_AUTO);
15731581

15741582
if !lhs_is_auto && !rhs_is_auto {
15751583
multiple_regular_traits = true;

src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::ops::ControlFlow;
77
use base_db::CrateId;
88
use chalk_ir::{cast::Cast, UniverseIndex, WithKind};
99
use hir_def::{
10-
data::{adt::StructFlags, ImplData},
10+
data::{adt::StructFlags, ImplData, TraitFlags},
1111
nameres::DefMap,
1212
AssocItemId, BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup,
1313
ModuleId, TraitId,
@@ -419,11 +419,17 @@ pub fn def_crates(
419419
}
420420
TyKind::Dyn(_) => {
421421
let trait_id = ty.dyn_trait()?;
422-
Some(if db.trait_data(trait_id).rustc_has_incoherent_inherent_impls {
423-
db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::Dyn(trait_id))
424-
} else {
425-
smallvec![trait_id.module(db.upcast()).krate()]
426-
})
422+
Some(
423+
if db
424+
.trait_data(trait_id)
425+
.flags
426+
.contains(TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS)
427+
{
428+
db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::Dyn(trait_id))
429+
} else {
430+
smallvec![trait_id.module(db.upcast()).krate()]
431+
},
432+
)
427433
}
428434
// for primitives, there may be impls in various places (core and alloc
429435
// mostly). We just check the whole crate graph for crates with impls
@@ -835,7 +841,9 @@ fn is_inherent_impl_coherent(
835841
hir_def::AdtId::EnumId(it) => db.enum_data(it).rustc_has_incoherent_inherent_impls,
836842
},
837843
TyKind::Dyn(it) => it.principal_id().map_or(false, |trait_id| {
838-
db.trait_data(from_chalk_trait_id(trait_id)).rustc_has_incoherent_inherent_impls
844+
db.trait_data(from_chalk_trait_id(trait_id))
845+
.flags
846+
.contains(TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS)
839847
}),
840848

841849
_ => false,
@@ -1204,7 +1212,7 @@ fn iterate_trait_method_candidates(
12041212
// 2021.
12051213
// This is to make `[a].into_iter()` not break code with the new `IntoIterator` impl for
12061214
// arrays.
1207-
if data.skip_array_during_method_dispatch
1215+
if data.flags.contains(TraitFlags::SKIP_ARRAY_DURING_METHOD_DISPATCH)
12081216
&& matches!(self_ty.kind(Interner), TyKind::Array(..))
12091217
{
12101218
// FIXME: this should really be using the edition of the method name's span, in case it
@@ -1213,7 +1221,7 @@ fn iterate_trait_method_candidates(
12131221
continue;
12141222
}
12151223
}
1216-
if data.skip_boxed_slice_during_method_dispatch
1224+
if data.flags.contains(TraitFlags::SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH)
12171225
&& matches!(
12181226
self_ty.kind(Interner), TyKind::Adt(AdtId(def), subst)
12191227
if is_box(table.db, *def)

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
//! HirDisplay implementations for various hir types.
22
use either::Either;
33
use hir_def::{
4-
data::adt::{StructKind, VariantData},
4+
data::{
5+
adt::{StructKind, VariantData},
6+
TraitFlags,
7+
},
58
generics::{
69
GenericParams, TypeOrConstParamData, TypeParamProvenance, WherePredicate,
710
WherePredicateTypeTarget,
@@ -791,10 +794,10 @@ impl HirDisplay for Trait {
791794
fn write_trait_header(trait_: &Trait, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
792795
write_visibility(trait_.module(f.db).id, trait_.visibility(f.db), f)?;
793796
let data = f.db.trait_data(trait_.id);
794-
if data.is_unsafe {
797+
if data.flags.contains(TraitFlags::IS_UNSAFE) {
795798
f.write_str("unsafe ")?;
796799
}
797-
if data.is_auto {
800+
if data.flags.contains(TraitFlags::IS_AUTO) {
798801
f.write_str("auto ")?;
799802
}
800803
write!(f, "trait {}", data.name.display(f.db.upcast(), f.edition()))?;

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use base_db::{CrateDisplayName, CrateId, CrateOrigin};
4343
use either::Either;
4444
use hir_def::{
4545
body::BodyDiagnostic,
46-
data::adt::VariantData,
46+
data::{adt::VariantData, TraitFlags},
4747
generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
4848
hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, Pat},
4949
item_tree::{AttrOwner, FieldParent, ItemTreeFieldId, ItemTreeNode},
@@ -2778,11 +2778,11 @@ impl Trait {
27782778
}
27792779

27802780
pub fn is_auto(self, db: &dyn HirDatabase) -> bool {
2781-
db.trait_data(self.id).is_auto
2781+
db.trait_data(self.id).flags.contains(TraitFlags::IS_AUTO)
27822782
}
27832783

27842784
pub fn is_unsafe(&self, db: &dyn HirDatabase) -> bool {
2785-
db.trait_data(self.id).is_unsafe
2785+
db.trait_data(self.id).flags.contains(TraitFlags::IS_UNSAFE)
27862786
}
27872787

27882788
pub fn type_or_const_param_count(

0 commit comments

Comments
 (0)