Skip to content

Commit a871a0f

Browse files
committed
Only store a LocalDefId in hir::TraitItem.
1 parent cebbba0 commit a871a0f

File tree

45 files changed

+139
-125
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+139
-125
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
9292
self.lctx.with_hir_id_owner(item.id, |lctx| match ctxt {
9393
AssocCtxt::Trait => {
9494
let hir_item = lctx.lower_trait_item(item);
95-
let id = hir::TraitItemId { hir_id: hir_item.hir_id };
95+
let id = hir_item.trait_item_id();
9696
lctx.trait_items.insert(id, hir_item);
9797
lctx.modules.get_mut(&lctx.current_module).unwrap().trait_items.insert(id);
9898
}
@@ -846,7 +846,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
846846
};
847847

848848
hir::TraitItem {
849-
hir_id: self.lower_node_id(i.id),
849+
def_id: trait_item_def_id,
850850
ident: i.ident,
851851
attrs: self.lower_attrs(&i.attrs),
852852
generics,
@@ -866,7 +866,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
866866
}
867867
AssocItemKind::MacCall(..) => unimplemented!(),
868868
};
869-
let id = hir::TraitItemId { hir_id: self.lower_node_id(i.id) };
869+
let id = hir::TraitItemId { def_id: self.lower_node_id(i.id).expect_owner() };
870870
let defaultness = hir::Defaultness::Default { has_value: has_default };
871871
hir::TraitItemRef { id, ident: i.ident, span: i.span, defaultness, kind }
872872
}

compiler/rustc_hir/src/hir.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1907,7 +1907,14 @@ pub struct FnSig<'hir> {
19071907
// so it can fetched later.
19081908
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Debug)]
19091909
pub struct TraitItemId {
1910-
pub hir_id: HirId,
1910+
pub def_id: LocalDefId,
1911+
}
1912+
1913+
impl TraitItemId {
1914+
pub fn hir_id(&self) -> HirId {
1915+
// Items are always HIR owners.
1916+
HirId::make_owner(self.def_id)
1917+
}
19111918
}
19121919

19131920
/// Represents an item declaration within a trait declaration,
@@ -1917,13 +1924,24 @@ pub struct TraitItemId {
19171924
#[derive(Debug)]
19181925
pub struct TraitItem<'hir> {
19191926
pub ident: Ident,
1920-
pub hir_id: HirId,
1927+
pub def_id: LocalDefId,
19211928
pub attrs: &'hir [Attribute],
19221929
pub generics: Generics<'hir>,
19231930
pub kind: TraitItemKind<'hir>,
19241931
pub span: Span,
19251932
}
19261933

1934+
impl TraitItem<'_> {
1935+
pub fn hir_id(&self) -> HirId {
1936+
// Items are always HIR owners.
1937+
HirId::make_owner(self.def_id)
1938+
}
1939+
1940+
pub fn trait_item_id(&self) -> TraitItemId {
1941+
TraitItemId { def_id: self.def_id }
1942+
}
1943+
}
1944+
19271945
/// Represents a trait method's body (or just argument names).
19281946
#[derive(Encodable, Debug, HashStable_Generic)]
19291947
pub enum TraitFn<'hir> {
@@ -2885,9 +2903,10 @@ impl<'hir> Node<'hir> {
28852903

28862904
pub fn hir_id(&self) -> Option<HirId> {
28872905
match self {
2888-
Node::Item(Item { def_id, .. }) => Some(HirId::make_owner(*def_id)),
2906+
Node::Item(Item { def_id, .. }) | Node::TraitItem(TraitItem { def_id, .. }) => {
2907+
Some(HirId::make_owner(*def_id))
2908+
}
28892909
Node::ForeignItem(ForeignItem { hir_id, .. })
2890-
| Node::TraitItem(TraitItem { hir_id, .. })
28912910
| Node::ImplItem(ImplItem { hir_id, .. })
28922911
| Node::Field(StructField { hir_id, .. })
28932912
| Node::AnonConst(AnonConst { hir_id, .. })
@@ -2922,7 +2941,7 @@ mod size_asserts {
29222941
rustc_data_structures::static_assert_size!(super::Ty<'static>, 72);
29232942

29242943
rustc_data_structures::static_assert_size!(super::Item<'static>, 200);
2925-
rustc_data_structures::static_assert_size!(super::TraitItem<'static>, 152);
2944+
rustc_data_structures::static_assert_size!(super::TraitItem<'static>, 144);
29262945
rustc_data_structures::static_assert_size!(super::ImplItem<'static>, 168);
29272946
rustc_data_structures::static_assert_size!(super::ForeignItem<'static>, 160);
29282947
}

compiler/rustc_hir/src/intravisit.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -964,12 +964,12 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
964964
visitor.visit_generics(&trait_item.generics);
965965
match trait_item.kind {
966966
TraitItemKind::Const(ref ty, default) => {
967-
visitor.visit_id(trait_item.hir_id);
967+
visitor.visit_id(trait_item.hir_id());
968968
visitor.visit_ty(ty);
969969
walk_list!(visitor, visit_nested_body, default);
970970
}
971971
TraitItemKind::Fn(ref sig, TraitFn::Required(param_names)) => {
972-
visitor.visit_id(trait_item.hir_id);
972+
visitor.visit_id(trait_item.hir_id());
973973
visitor.visit_fn_decl(&sig.decl);
974974
for &param_name in param_names {
975975
visitor.visit_ident(param_name);
@@ -981,11 +981,11 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
981981
&sig.decl,
982982
body_id,
983983
trait_item.span,
984-
trait_item.hir_id,
984+
trait_item.hir_id(),
985985
);
986986
}
987987
TraitItemKind::Type(bounds, ref default) => {
988-
visitor.visit_id(trait_item.hir_id);
988+
visitor.visit_id(trait_item.hir_id());
989989
walk_list!(visitor, visit_param_bound, bounds);
990990
walk_list!(visitor, visit_ty, default);
991991
}

compiler/rustc_hir/src/stable_hash_impls.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for ItemId {
4444
}
4545

4646
impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for TraitItemId {
47-
type KeyType = (DefPathHash, ItemLocalId);
47+
type KeyType = DefPathHash;
4848

4949
#[inline]
50-
fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
51-
self.hir_id.to_stable_hash_key(hcx)
50+
fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
51+
hcx.local_def_path_hash(self.def_id)
5252
}
5353
}
5454

@@ -109,7 +109,7 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for ImplItemId {
109109

110110
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for TraitItemId {
111111
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
112-
hcx.hash_reference_to_item(self.hir_id, hasher)
112+
hcx.hash_reference_to_item(self.hir_id(), hasher)
113113
}
114114
}
115115

@@ -139,7 +139,7 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for VisibilityKind<'_>
139139

140140
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for TraitItem<'_> {
141141
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
142-
let TraitItem { hir_id: _, ident, ref attrs, ref generics, ref kind, span } = *self;
142+
let TraitItem { def_id: _, ident, ref attrs, ref generics, ref kind, span } = *self;
143143

144144
hcx.hash_hir_item_like(|hcx| {
145145
ident.name.hash_stable(hcx, hasher);

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,7 @@ impl<'a> State<'a> {
934934
}
935935

936936
pub fn print_trait_item(&mut self, ti: &hir::TraitItem<'_>) {
937-
self.ann.pre(self, AnnNode::SubItem(ti.hir_id));
937+
self.ann.pre(self, AnnNode::SubItem(ti.hir_id()));
938938
self.hardbreak_if_not_bol();
939939
self.maybe_print_comment(ti.span.lo());
940940
self.print_outer_attributes(&ti.attrs);
@@ -969,7 +969,7 @@ impl<'a> State<'a> {
969969
);
970970
}
971971
}
972-
self.ann.post(self, AnnNode::SubItem(ti.hir_id))
972+
self.ann.post(self, AnnNode::SubItem(ti.hir_id()))
973973
}
974974

975975
pub fn print_impl_item(&mut self, ii: &hir::ImplItem<'_>) {

compiler/rustc_incremental/src/assert_dep_graph.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ impl Visitor<'tcx> for IfThisChanged<'tcx> {
172172
}
173173

174174
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
175-
self.process_attrs(trait_item.hir_id, &trait_item.attrs);
175+
self.process_attrs(trait_item.hir_id(), &trait_item.attrs);
176176
intravisit::walk_trait_item(self, trait_item);
177177
}
178178

compiler/rustc_incremental/src/persist/dirty_clean.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ impl ItemLikeVisitor<'tcx> for DirtyCleanVisitor<'tcx> {
454454
}
455455

456456
fn visit_trait_item(&mut self, item: &hir::TraitItem<'_>) {
457-
self.check_item(item.hir_id, item.span);
457+
self.check_item(item.hir_id(), item.span);
458458
}
459459

460460
fn visit_impl_item(&mut self, item: &hir::ImplItem<'_>) {

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorRepor
88
use rustc_hir::def_id::DefId;
99
use rustc_hir::intravisit::{walk_ty, ErasedMap, NestedVisitorMap, Visitor};
1010
use rustc_hir::{
11-
self as hir, GenericBound, ImplItem, Item, ItemKind, Lifetime, LifetimeName, Node, TraitItem,
12-
TyKind,
11+
self as hir, GenericBound, ImplItem, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind,
1312
};
1413
use rustc_middle::ty::{self, AssocItemContainer, RegionKind, Ty, TypeFoldable, TypeVisitor};
1514
use rustc_span::symbol::Ident;
@@ -352,8 +351,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
352351
_ => None,
353352
}
354353
}
355-
Some(Node::TraitItem(TraitItem { ident, hir_id, .. })) => {
356-
let parent_id = tcx.hir().get_parent_item(*hir_id);
354+
Some(Node::TraitItem(trait_item)) => {
355+
let parent_id = tcx.hir().get_parent_item(trait_item.hir_id());
357356
match tcx.hir().find(parent_id) {
358357
Some(Node::Item(Item { kind: ItemKind::Trait(..), .. })) => {
359358
// The method being called is defined in the `trait`, but the `'static`
@@ -389,7 +388,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
389388
})
390389
.next()
391390
{
392-
Some(self_ty) => Some((*ident, self_ty)),
391+
Some(self_ty) => Some((trait_item.ident, self_ty)),
393392
_ => None,
394393
}
395394
}

compiler/rustc_lint/src/builtin.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
586586
if let hir::VisibilityKind::Inherited = it.vis.node {
587587
self.private_traits.insert(it.hir_id());
588588
for trait_item_ref in trait_item_refs {
589-
self.private_traits.insert(trait_item_ref.id.hir_id);
589+
self.private_traits.insert(trait_item_ref.id.hir_id());
590590
}
591591
return;
592592
}
@@ -626,16 +626,15 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
626626
}
627627

628628
fn check_trait_item(&mut self, cx: &LateContext<'_>, trait_item: &hir::TraitItem<'_>) {
629-
if self.private_traits.contains(&trait_item.hir_id) {
629+
if self.private_traits.contains(&trait_item.hir_id()) {
630630
return;
631631
}
632632

633-
let def_id = cx.tcx.hir().local_def_id(trait_item.hir_id);
634-
let (article, desc) = cx.tcx.article_and_description(def_id.to_def_id());
633+
let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id());
635634

636635
self.check_missing_docs_attrs(
637636
cx,
638-
Some(trait_item.hir_id),
637+
Some(trait_item.hir_id()),
639638
&trait_item.attrs,
640639
trait_item.span,
641640
article,

compiler/rustc_lint/src/late.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,8 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
301301
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
302302
let generics = self.context.generics.take();
303303
self.context.generics = Some(&trait_item.generics);
304-
self.with_lint_attrs(trait_item.hir_id, &trait_item.attrs, |cx| {
305-
cx.with_param_env(trait_item.hir_id, |cx| {
304+
self.with_lint_attrs(trait_item.hir_id(), &trait_item.attrs, |cx| {
305+
cx.with_param_env(trait_item.hir_id(), |cx| {
306306
lint_callback!(cx, check_trait_item, trait_item);
307307
hir_visit::walk_trait_item(cx, trait_item);
308308
lint_callback!(cx, check_trait_item_post, trait_item);

compiler/rustc_lint/src/levels.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'_, 'tcx> {
631631
}
632632

633633
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
634-
self.with_lint_attrs(trait_item.hir_id, &trait_item.attrs, |builder| {
634+
self.with_lint_attrs(trait_item.hir_id(), &trait_item.attrs, |builder| {
635635
intravisit::walk_trait_item(builder, trait_item);
636636
});
637637
}

compiler/rustc_middle/src/hir/map/blocks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ impl<'a> FnLikeNode<'a> {
229229
},
230230
Node::TraitItem(ti) => match ti.kind {
231231
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
232-
method(ti.hir_id, ti.ident, sig, None, body, ti.span, &ti.attrs)
232+
method(ti.hir_id(), ti.ident, sig, None, body, ti.span, &ti.attrs)
233233
}
234234
_ => bug!("trait method FnLikeNode that is not fn-like"),
235235
},

compiler/rustc_middle/src/hir/map/collector.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -391,14 +391,10 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
391391
}
392392

393393
fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
394-
debug_assert_eq!(
395-
ti.hir_id.owner,
396-
self.definitions.opt_hir_id_to_local_def_id(ti.hir_id).unwrap()
397-
);
398-
self.with_dep_node_owner(ti.hir_id.owner, ti, |this, hash| {
399-
this.insert_with_hash(ti.span, ti.hir_id, Node::TraitItem(ti), hash);
394+
self.with_dep_node_owner(ti.def_id, ti, |this, hash| {
395+
this.insert_with_hash(ti.span, ti.hir_id(), Node::TraitItem(ti), hash);
400396

401-
this.with_parent(ti.hir_id, |this| {
397+
this.with_parent(ti.hir_id(), |this| {
402398
intravisit::walk_trait_item(this, ti);
403399
});
404400
});

compiler/rustc_middle/src/hir/map/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ impl<'hir> Map<'hir> {
308308
}
309309

310310
pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
311-
match self.find(id.hir_id).unwrap() {
311+
match self.find(id.hir_id()).unwrap() {
312312
Node::TraitItem(item) => item,
313313
_ => bug!(),
314314
}

compiler/rustc_middle/src/ty/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ fn foo(&self) -> Self::T { String::new() }
816816
// an assoc type as a return type (#72076).
817817
if let hir::Defaultness::Default { has_value: true } = item.defaultness
818818
{
819-
if self.type_of(self.hir().local_def_id(item.id.hir_id)) == found {
819+
if self.type_of(item.id.def_id) == found {
820820
db.span_label(
821821
item.span,
822822
"associated type defaults can't be assumed inside the \

compiler/rustc_passes/src/check_attr.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,13 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
10811081

10821082
fn visit_trait_item(&mut self, trait_item: &'tcx TraitItem<'tcx>) {
10831083
let target = Target::from_trait_item(trait_item);
1084-
self.check_attributes(trait_item.hir_id, &trait_item.attrs, &trait_item.span, target, None);
1084+
self.check_attributes(
1085+
trait_item.hir_id(),
1086+
&trait_item.attrs,
1087+
&trait_item.span,
1088+
target,
1089+
None,
1090+
);
10851091
intravisit::walk_trait_item(self, trait_item)
10861092
}
10871093

compiler/rustc_passes/src/dead.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,9 +440,9 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
440440
fn visit_trait_item(&mut self, trait_item: &hir::TraitItem<'_>) {
441441
use hir::TraitItemKind::{Const, Fn};
442442
if matches!(trait_item.kind, Const(_, Some(_)) | Fn(_, hir::TraitFn::Provided(_)))
443-
&& has_allow_dead_code_or_lang_attr(self.tcx, trait_item.hir_id, &trait_item.attrs)
443+
&& has_allow_dead_code_or_lang_attr(self.tcx, trait_item.hir_id(), &trait_item.attrs)
444444
{
445-
self.worklist.push(trait_item.hir_id);
445+
self.worklist.push(trait_item.hir_id());
446446
}
447447
}
448448

compiler/rustc_passes/src/diagnostic_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ impl<'v, 'tcx> ItemLikeVisitor<'v> for DiagnosticItemCollector<'tcx> {
3131
}
3232

3333
fn visit_trait_item(&mut self, trait_item: &hir::TraitItem<'_>) {
34-
self.observe_item(&trait_item.attrs, trait_item.hir_id);
34+
self.observe_item(&trait_item.attrs, trait_item.hir_id());
3535
}
3636

3737
fn visit_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) {

compiler/rustc_passes/src/hir_id_validator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl<'a, 'hir> ItemLikeVisitor<'hir> for OuterVisitor<'a, 'hir> {
6161

6262
fn visit_trait_item(&mut self, i: &'hir hir::TraitItem<'hir>) {
6363
let mut inner_visitor = self.new_inner_visitor(self.hir_map);
64-
inner_visitor.check(i.hir_id, |this| intravisit::walk_trait_item(this, i));
64+
inner_visitor.check(i.hir_id(), |this| intravisit::walk_trait_item(this, i));
6565
}
6666

6767
fn visit_impl_item(&mut self, i: &'hir hir::ImplItem<'hir>) {

compiler/rustc_passes/src/hir_stats.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
187187
}
188188

189189
fn visit_trait_item(&mut self, ti: &'v hir::TraitItem<'v>) {
190-
self.record("TraitItem", Id::Node(ti.hir_id), ti);
190+
self.record("TraitItem", Id::Node(ti.hir_id()), ti);
191191
hir_visit::walk_trait_item(self, ti)
192192
}
193193

compiler/rustc_passes/src/lang_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl ItemLikeVisitor<'v> for LanguageItemCollector<'tcx> {
4242
fn visit_trait_item(&mut self, trait_item: &hir::TraitItem<'_>) {
4343
self.check_for_lang(
4444
Target::from_trait_item(trait_item),
45-
trait_item.hir_id,
45+
trait_item.hir_id(),
4646
trait_item.attrs,
4747
)
4848
}

compiler/rustc_passes/src/stability.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
389389

390390
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) {
391391
self.annotate(
392-
ti.hir_id,
392+
ti.hir_id(),
393393
&ti.attrs,
394394
ti.span,
395395
AnnotationKind::Required,
@@ -571,7 +571,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
571571
}
572572

573573
fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) {
574-
self.check_missing_stability(ti.hir_id, ti.span);
574+
self.check_missing_stability(ti.hir_id(), ti.span);
575575
intravisit::walk_trait_item(self, ti);
576576
}
577577

0 commit comments

Comments
 (0)