Skip to content

Commit b10b981

Browse files
committed
hash the contents of impl-item-ref by adding them to visitor
Also simplify some of the `ty::AssociatedItem` representation, in particular by folding `has_value` into `hir::Defaultness`
1 parent c17be9e commit b10b981

File tree

17 files changed

+234
-55
lines changed

17 files changed

+234
-55
lines changed

src/librustc/hir/intravisit.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,12 @@ pub trait Visitor<'v> : Sized {
267267
fn visit_vis(&mut self, vis: &'v Visibility) {
268268
walk_vis(self, vis)
269269
}
270+
fn visit_associated_item_kind(&mut self, kind: &'v AssociatedItemKind) {
271+
walk_associated_item_kind(self, kind);
272+
}
273+
fn visit_defaultness(&mut self, defaultness: &'v Defaultness) {
274+
walk_defaultness(self, defaultness);
275+
}
270276
}
271277

272278
pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name: Option<Name>) {
@@ -740,10 +746,14 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
740746
}
741747

742748
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
743-
visitor.visit_vis(&impl_item.vis);
744-
visitor.visit_name(impl_item.span, impl_item.name);
745-
walk_list!(visitor, visit_attribute, &impl_item.attrs);
746-
match impl_item.node {
749+
// NB: Deliberately force a compilation error if/when new fields are added.
750+
let ImplItem { id: _, name, ref vis, ref defaultness, ref attrs, ref node, span } = *impl_item;
751+
752+
visitor.visit_name(span, name);
753+
visitor.visit_vis(vis);
754+
visitor.visit_defaultness(defaultness);
755+
walk_list!(visitor, visit_attribute, attrs);
756+
match *node {
747757
ImplItemKind::Const(ref ty, ref expr) => {
748758
visitor.visit_id(impl_item.id);
749759
visitor.visit_ty(ty);
@@ -767,8 +777,13 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
767777
}
768778

769779
pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef) {
770-
visitor.visit_nested_impl_item(impl_item_ref.id);
771-
visitor.visit_name(impl_item_ref.span, impl_item_ref.name);
780+
// NB: Deliberately force a compilation error if/when new fields are added.
781+
let ImplItemRef { id, name, ref kind, span, ref vis, ref defaultness } = *impl_item_ref;
782+
visitor.visit_nested_impl_item(id);
783+
visitor.visit_name(span, name);
784+
visitor.visit_associated_item_kind(kind);
785+
visitor.visit_vis(vis);
786+
visitor.visit_defaultness(defaultness);
772787
}
773788

774789

@@ -941,6 +956,18 @@ pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) {
941956
}
942957
}
943958

959+
pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssociatedItemKind) {
960+
// No visitable content here: this fn exists so you can call it if
961+
// the right thing to do, should content be added in the future,
962+
// would be to walk it.
963+
}
964+
965+
pub fn walk_defaultness<'v, V: Visitor<'v>>(_: &mut V, _: &'v Defaultness) {
966+
// No visitable content here: this fn exists so you can call it if
967+
// the right thing to do, should content be added in the future,
968+
// would be to walk it.
969+
}
970+
944971
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq)]
945972
pub struct IdRange {
946973
pub min: NodeId,

src/librustc/hir/lowering.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ impl<'a> LoweringContext<'a> {
699699
name: i.ident.name,
700700
attrs: this.lower_attrs(&i.attrs),
701701
vis: this.lower_visibility(&i.vis),
702-
defaultness: this.lower_defaultness(i.defaultness),
702+
defaultness: this.lower_defaultness(i.defaultness, true /* [1] */),
703703
node: match i.node {
704704
ImplItemKind::Const(ref ty, ref expr) => {
705705
hir::ImplItemKind::Const(this.lower_ty(ty), this.lower_expr(expr))
@@ -715,6 +715,8 @@ impl<'a> LoweringContext<'a> {
715715
span: i.span,
716716
}
717717
})
718+
719+
// [1] since `default impl` is not yet implemented, this is always true in impls
718720
}
719721

720722
fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
@@ -723,7 +725,7 @@ impl<'a> LoweringContext<'a> {
723725
name: i.ident.name,
724726
span: i.span,
725727
vis: self.lower_visibility(&i.vis),
726-
defaultness: self.lower_defaultness(i.defaultness),
728+
defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
727729
kind: match i.node {
728730
ImplItemKind::Const(..) => hir::AssociatedItemKind::Const,
729731
ImplItemKind::Type(..) => hir::AssociatedItemKind::Type,
@@ -732,9 +734,9 @@ impl<'a> LoweringContext<'a> {
732734
},
733735
ImplItemKind::Macro(..) => unimplemented!(),
734736
},
735-
// since `default impl` is not yet implemented, this is always true in impls
736-
has_value: true,
737737
}
738+
739+
// [1] since `default impl` is not yet implemented, this is always true in impls
738740
}
739741

740742
fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
@@ -1650,10 +1652,13 @@ impl<'a> LoweringContext<'a> {
16501652
}
16511653
}
16521654

1653-
fn lower_defaultness(&mut self, d: Defaultness) -> hir::Defaultness {
1655+
fn lower_defaultness(&mut self, d: Defaultness, has_value: bool) -> hir::Defaultness {
16541656
match d {
1655-
Defaultness::Default => hir::Defaultness::Default,
1656-
Defaultness::Final => hir::Defaultness::Final,
1657+
Defaultness::Default => hir::Defaultness::Default { has_value: has_value },
1658+
Defaultness::Final => {
1659+
assert!(has_value);
1660+
hir::Defaultness::Final
1661+
}
16571662
}
16581663
}
16591664

src/librustc/hir/mod.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,17 +1259,27 @@ pub enum Constness {
12591259

12601260
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
12611261
pub enum Defaultness {
1262-
Default,
1262+
Default { has_value: bool },
12631263
Final,
12641264
}
12651265

12661266
impl Defaultness {
1267+
pub fn has_value(&self) -> bool {
1268+
match *self {
1269+
Defaultness::Default { has_value, .. } => has_value,
1270+
Defaultness::Final => true,
1271+
}
1272+
}
1273+
12671274
pub fn is_final(&self) -> bool {
12681275
*self == Defaultness::Final
12691276
}
12701277

12711278
pub fn is_default(&self) -> bool {
1272-
*self == Defaultness::Default
1279+
match *self {
1280+
Defaultness::Default { .. } => true,
1281+
_ => false,
1282+
}
12731283
}
12741284
}
12751285

@@ -1584,7 +1594,6 @@ pub struct ImplItemRef {
15841594
pub span: Span,
15851595
pub vis: Visibility,
15861596
pub defaultness: Defaultness,
1587-
pub has_value: bool,
15881597
}
15891598

15901599
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]

src/librustc/hir/print.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,8 +1036,9 @@ impl<'a> State<'a> {
10361036
self.maybe_print_comment(ii.span.lo)?;
10371037
self.print_outer_attributes(&ii.attrs)?;
10381038

1039-
if let hir::Defaultness::Default = ii.defaultness {
1040-
self.word_nbsp("default")?;
1039+
match ii.defaultness {
1040+
hir::Defaultness::Default { .. } => self.word_nbsp("default")?,
1041+
hir::Defaultness::Final => (),
10411042
}
10421043

10431044
match ii.node {

src/librustc/traits/project.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,7 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
943943
// an error when we confirm the candidate
944944
// (which will ultimately lead to `normalize_to_error`
945945
// being invoked).
946-
node_item.item.has_value
946+
node_item.item.defaultness.has_value()
947947
} else {
948948
node_item.item.defaultness.is_default()
949949
};
@@ -1304,7 +1304,7 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
13041304

13051305
match assoc_ty {
13061306
Some(node_item) => {
1307-
let ty = if !node_item.item.has_value {
1307+
let ty = if !node_item.item.defaultness.has_value() {
13081308
// This means that the impl is missing a definition for the
13091309
// associated type. This error will be reported by the type
13101310
// checker method `check_impl_items_against_trait`, so here we

src/librustc/ty/mod.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ pub struct AssociatedItem {
189189
pub kind: AssociatedKind,
190190
pub vis: Visibility,
191191
pub defaultness: hir::Defaultness,
192-
pub has_value: bool,
193192
pub container: AssociatedItemContainer,
194193

195194
/// Whether this is a method with an explicit self
@@ -2072,7 +2071,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
20722071

20732072
pub fn provided_trait_methods(self, id: DefId) -> Vec<AssociatedItem> {
20742073
self.associated_items(id)
2075-
.filter(|item| item.kind == AssociatedKind::Method && item.has_value)
2074+
.filter(|item| item.kind == AssociatedKind::Method && item.defaultness.has_value())
20762075
.collect()
20772076
}
20782077

@@ -2180,8 +2179,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
21802179
name: trait_item.name,
21812180
kind: kind,
21822181
vis: Visibility::from_hir(&hir::Inherited, trait_item.id, self),
2183-
defaultness: hir::Defaultness::Default,
2184-
has_value: has_value,
2182+
defaultness: hir::Defaultness::Default { has_value: has_value },
21852183
def_id: def_id,
21862184
container: TraitContainer(parent_def_id),
21872185
method_has_self_argument: has_self
@@ -2211,7 +2209,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
22112209
kind: kind,
22122210
vis: ty::Visibility::from_hir(vis, impl_item_ref.id.node_id, self),
22132211
defaultness: impl_item_ref.defaultness,
2214-
has_value: true,
22152212
def_id: def_id,
22162213
container: ImplContainer(parent_def_id),
22172214
method_has_self_argument: has_self

src/librustc_incremental/calculate_svh/svh_visitor.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ enum SawAbiComponent<'a> {
199199
SawExpr(SawExprComponent<'a>),
200200
SawStmt,
201201
SawVis,
202+
SawAssociatedItemKind(hir::AssociatedItemKind),
203+
SawDefaultness(hir::Defaultness),
202204
SawWherePredicate,
203205
SawTyParamBound,
204206
SawPolyTraitRef,
@@ -693,6 +695,18 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has
693695
visit::walk_vis(self, v)
694696
}
695697

698+
fn visit_associated_item_kind(&mut self, kind: &'tcx AssociatedItemKind) {
699+
debug!("visit_associated_item_kind: st={:?}", self.st);
700+
SawAssociatedItemKind(*kind).hash(self.st);
701+
visit::walk_associated_item_kind(self, kind);
702+
}
703+
704+
fn visit_defaultness(&mut self, defaultness: &'tcx Defaultness) {
705+
debug!("visit_associated_item_kind: st={:?}", self.st);
706+
SawDefaultness(*defaultness).hash(self.st);
707+
visit::walk_defaultness(self, defaultness);
708+
}
709+
696710
fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate) {
697711
debug!("visit_where_predicate: st={:?}", self.st);
698712
SawWherePredicate.hash(self.st);

src/librustc_metadata/decoder.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,6 @@ impl<'a, 'tcx> CrateMetadata {
834834
kind: ty::AssociatedKind::Const,
835835
vis: item.visibility,
836836
defaultness: container.defaultness(),
837-
has_value: container.has_value(),
838837
def_id: self.local_def_id(id),
839838
container: container.with_def_id(parent),
840839
method_has_self_argument: false
@@ -848,7 +847,6 @@ impl<'a, 'tcx> CrateMetadata {
848847
kind: ty::AssociatedKind::Method,
849848
vis: item.visibility,
850849
defaultness: data.container.defaultness(),
851-
has_value: data.container.has_value(),
852850
def_id: self.local_def_id(id),
853851
container: data.container.with_def_id(parent),
854852
method_has_self_argument: data.has_self
@@ -861,7 +859,6 @@ impl<'a, 'tcx> CrateMetadata {
861859
kind: ty::AssociatedKind::Type,
862860
vis: item.visibility,
863861
defaultness: container.defaultness(),
864-
has_value: container.has_value(),
865862
def_id: self.local_def_id(id),
866863
container: container.with_def_id(parent),
867864
method_has_self_argument: false

src/librustc_metadata/encoder.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -460,10 +460,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
460460
let ast_item = tcx.map.expect_trait_item(node_id);
461461
let trait_item = tcx.associated_item(def_id);
462462

463-
let container = if trait_item.has_value {
464-
AssociatedContainer::TraitWithDefault
465-
} else {
466-
AssociatedContainer::TraitRequired
463+
let container = match trait_item.defaultness {
464+
hir::Defaultness::Default { has_value: true } =>
465+
AssociatedContainer::TraitWithDefault,
466+
hir::Defaultness::Default { has_value: false } =>
467+
AssociatedContainer::TraitRequired,
468+
hir::Defaultness::Final =>
469+
span_bug!(ast_item.span, "traits cannot have final items"),
467470
};
468471

469472
let kind = match trait_item.kind {
@@ -501,7 +504,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
501504
Some(self.encode_item_type(def_id))
502505
}
503506
ty::AssociatedKind::Type => {
504-
if trait_item.has_value {
507+
if trait_item.defaultness.has_value() {
505508
Some(self.encode_item_type(def_id))
506509
} else {
507510
None
@@ -530,8 +533,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
530533
let impl_def_id = impl_item.container.id();
531534

532535
let container = match impl_item.defaultness {
533-
hir::Defaultness::Default => AssociatedContainer::ImplDefault,
536+
hir::Defaultness::Default { has_value: true } => AssociatedContainer::ImplDefault,
534537
hir::Defaultness::Final => AssociatedContainer::ImplFinal,
538+
hir::Defaultness::Default { has_value: false } =>
539+
span_bug!(ast_item.span, "impl items always have values (currently)"),
535540
};
536541

537542
let kind = match impl_item.kind {

src/librustc_metadata/schema.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -310,21 +310,16 @@ impl AssociatedContainer {
310310
}
311311
}
312312

313-
pub fn has_value(&self) -> bool {
314-
match *self {
315-
AssociatedContainer::TraitRequired => false,
316-
317-
AssociatedContainer::TraitWithDefault |
318-
AssociatedContainer::ImplDefault |
319-
AssociatedContainer::ImplFinal => true,
320-
}
321-
}
322-
323313
pub fn defaultness(&self) -> hir::Defaultness {
324314
match *self {
325-
AssociatedContainer::TraitRequired |
315+
AssociatedContainer::TraitRequired => hir::Defaultness::Default {
316+
has_value: false,
317+
},
318+
326319
AssociatedContainer::TraitWithDefault |
327-
AssociatedContainer::ImplDefault => hir::Defaultness::Default,
320+
AssociatedContainer::ImplDefault => hir::Defaultness::Default {
321+
has_value: true,
322+
},
328323

329324
AssociatedContainer::ImplFinal => hir::Defaultness::Final,
330325
}

src/librustc_save_analysis/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
536536
let def_id = if decl_id.is_local() {
537537
let ti = self.tcx.associated_item(decl_id);
538538
self.tcx.associated_items(ti.container.id())
539-
.find(|item| item.name == ti.name && item.has_value)
539+
.find(|item| item.name == ti.name && item.defaultness.has_value())
540540
.map(|item| item.def_id)
541541
} else {
542542
None

src/librustc_typeck/check/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
11101110
}
11111111
hir::ImplItemKind::Type(_) => {
11121112
if ty_trait_item.kind == ty::AssociatedKind::Type {
1113-
if ty_trait_item.has_value {
1113+
if ty_trait_item.defaultness.has_value() {
11141114
overridden_associated_type = Some(impl_item);
11151115
}
11161116
} else {
@@ -1144,7 +1144,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
11441144
.unwrap_or(false);
11451145

11461146
if !is_implemented {
1147-
if !trait_item.has_value {
1147+
if !trait_item.defaultness.has_value() {
11481148
missing_items.push(trait_item);
11491149
} else if associated_type_overridden {
11501150
invalidated_items.push(trait_item.name);

src/librustc_typeck/check/wfcheck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
204204
free_id_outlive, self_ty);
205205
}
206206
ty::AssociatedKind::Type => {
207-
if item.has_value {
207+
if item.defaultness.has_value() {
208208
let ty = fcx.tcx.item_type(item.def_id);
209209
let ty = fcx.instantiate_type_scheme(span, free_substs, &ty);
210210
fcx.register_wf_obligation(ty, span, code.clone());

src/librustc_typeck/impl_wf_check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
118118
.map(|item_ref| ccx.tcx.map.local_def_id(item_ref.id.node_id))
119119
.filter(|&def_id| {
120120
let item = ccx.tcx.associated_item(def_id);
121-
item.kind == ty::AssociatedKind::Type && item.has_value
121+
item.kind == ty::AssociatedKind::Type && item.defaultness.has_value()
122122
})
123123
.flat_map(|def_id| {
124124
ctp::parameters_for(&ccx.tcx.item_type(def_id), true)

0 commit comments

Comments
 (0)