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`
This commit is contained in:
parent
c17be9ea11
commit
b10b98169f
17 changed files with 234 additions and 55 deletions
|
|
@ -267,6 +267,12 @@ pub trait Visitor<'v> : Sized {
|
|||
fn visit_vis(&mut self, vis: &'v Visibility) {
|
||||
walk_vis(self, vis)
|
||||
}
|
||||
fn visit_associated_item_kind(&mut self, kind: &'v AssociatedItemKind) {
|
||||
walk_associated_item_kind(self, kind);
|
||||
}
|
||||
fn visit_defaultness(&mut self, defaultness: &'v Defaultness) {
|
||||
walk_defaultness(self, defaultness);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
|||
}
|
||||
|
||||
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
|
||||
visitor.visit_vis(&impl_item.vis);
|
||||
visitor.visit_name(impl_item.span, impl_item.name);
|
||||
walk_list!(visitor, visit_attribute, &impl_item.attrs);
|
||||
match impl_item.node {
|
||||
// NB: Deliberately force a compilation error if/when new fields are added.
|
||||
let ImplItem { id: _, name, ref vis, ref defaultness, ref attrs, ref node, span } = *impl_item;
|
||||
|
||||
visitor.visit_name(span, name);
|
||||
visitor.visit_vis(vis);
|
||||
visitor.visit_defaultness(defaultness);
|
||||
walk_list!(visitor, visit_attribute, attrs);
|
||||
match *node {
|
||||
ImplItemKind::Const(ref ty, ref expr) => {
|
||||
visitor.visit_id(impl_item.id);
|
||||
visitor.visit_ty(ty);
|
||||
|
|
@ -767,8 +777,13 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
|
|||
}
|
||||
|
||||
pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef) {
|
||||
visitor.visit_nested_impl_item(impl_item_ref.id);
|
||||
visitor.visit_name(impl_item_ref.span, impl_item_ref.name);
|
||||
// NB: Deliberately force a compilation error if/when new fields are added.
|
||||
let ImplItemRef { id, name, ref kind, span, ref vis, ref defaultness } = *impl_item_ref;
|
||||
visitor.visit_nested_impl_item(id);
|
||||
visitor.visit_name(span, name);
|
||||
visitor.visit_associated_item_kind(kind);
|
||||
visitor.visit_vis(vis);
|
||||
visitor.visit_defaultness(defaultness);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -941,6 +956,18 @@ pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssociatedItemKind) {
|
||||
// No visitable content here: this fn exists so you can call it if
|
||||
// the right thing to do, should content be added in the future,
|
||||
// would be to walk it.
|
||||
}
|
||||
|
||||
pub fn walk_defaultness<'v, V: Visitor<'v>>(_: &mut V, _: &'v Defaultness) {
|
||||
// No visitable content here: this fn exists so you can call it if
|
||||
// the right thing to do, should content be added in the future,
|
||||
// would be to walk it.
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq)]
|
||||
pub struct IdRange {
|
||||
pub min: NodeId,
|
||||
|
|
|
|||
|
|
@ -699,7 +699,7 @@ impl<'a> LoweringContext<'a> {
|
|||
name: i.ident.name,
|
||||
attrs: this.lower_attrs(&i.attrs),
|
||||
vis: this.lower_visibility(&i.vis),
|
||||
defaultness: this.lower_defaultness(i.defaultness),
|
||||
defaultness: this.lower_defaultness(i.defaultness, true /* [1] */),
|
||||
node: match i.node {
|
||||
ImplItemKind::Const(ref ty, ref expr) => {
|
||||
hir::ImplItemKind::Const(this.lower_ty(ty), this.lower_expr(expr))
|
||||
|
|
@ -715,6 +715,8 @@ impl<'a> LoweringContext<'a> {
|
|||
span: i.span,
|
||||
}
|
||||
})
|
||||
|
||||
// [1] since `default impl` is not yet implemented, this is always true in impls
|
||||
}
|
||||
|
||||
fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
|
||||
|
|
@ -723,7 +725,7 @@ impl<'a> LoweringContext<'a> {
|
|||
name: i.ident.name,
|
||||
span: i.span,
|
||||
vis: self.lower_visibility(&i.vis),
|
||||
defaultness: self.lower_defaultness(i.defaultness),
|
||||
defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
|
||||
kind: match i.node {
|
||||
ImplItemKind::Const(..) => hir::AssociatedItemKind::Const,
|
||||
ImplItemKind::Type(..) => hir::AssociatedItemKind::Type,
|
||||
|
|
@ -732,9 +734,9 @@ impl<'a> LoweringContext<'a> {
|
|||
},
|
||||
ImplItemKind::Macro(..) => unimplemented!(),
|
||||
},
|
||||
// since `default impl` is not yet implemented, this is always true in impls
|
||||
has_value: true,
|
||||
}
|
||||
|
||||
// [1] since `default impl` is not yet implemented, this is always true in impls
|
||||
}
|
||||
|
||||
fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
|
||||
|
|
@ -1650,10 +1652,13 @@ impl<'a> LoweringContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn lower_defaultness(&mut self, d: Defaultness) -> hir::Defaultness {
|
||||
fn lower_defaultness(&mut self, d: Defaultness, has_value: bool) -> hir::Defaultness {
|
||||
match d {
|
||||
Defaultness::Default => hir::Defaultness::Default,
|
||||
Defaultness::Final => hir::Defaultness::Final,
|
||||
Defaultness::Default => hir::Defaultness::Default { has_value: has_value },
|
||||
Defaultness::Final => {
|
||||
assert!(has_value);
|
||||
hir::Defaultness::Final
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1259,17 +1259,27 @@ pub enum Constness {
|
|||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum Defaultness {
|
||||
Default,
|
||||
Default { has_value: bool },
|
||||
Final,
|
||||
}
|
||||
|
||||
impl Defaultness {
|
||||
pub fn has_value(&self) -> bool {
|
||||
match *self {
|
||||
Defaultness::Default { has_value, .. } => has_value,
|
||||
Defaultness::Final => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_final(&self) -> bool {
|
||||
*self == Defaultness::Final
|
||||
}
|
||||
|
||||
pub fn is_default(&self) -> bool {
|
||||
*self == Defaultness::Default
|
||||
match *self {
|
||||
Defaultness::Default { .. } => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1584,7 +1594,6 @@ pub struct ImplItemRef {
|
|||
pub span: Span,
|
||||
pub vis: Visibility,
|
||||
pub defaultness: Defaultness,
|
||||
pub has_value: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
|
|
|
|||
|
|
@ -1036,8 +1036,9 @@ impl<'a> State<'a> {
|
|||
self.maybe_print_comment(ii.span.lo)?;
|
||||
self.print_outer_attributes(&ii.attrs)?;
|
||||
|
||||
if let hir::Defaultness::Default = ii.defaultness {
|
||||
self.word_nbsp("default")?;
|
||||
match ii.defaultness {
|
||||
hir::Defaultness::Default { .. } => self.word_nbsp("default")?,
|
||||
hir::Defaultness::Final => (),
|
||||
}
|
||||
|
||||
match ii.node {
|
||||
|
|
|
|||
|
|
@ -943,7 +943,7 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
|
|||
// an error when we confirm the candidate
|
||||
// (which will ultimately lead to `normalize_to_error`
|
||||
// being invoked).
|
||||
node_item.item.has_value
|
||||
node_item.item.defaultness.has_value()
|
||||
} else {
|
||||
node_item.item.defaultness.is_default()
|
||||
};
|
||||
|
|
@ -1304,7 +1304,7 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
|
|||
|
||||
match assoc_ty {
|
||||
Some(node_item) => {
|
||||
let ty = if !node_item.item.has_value {
|
||||
let ty = if !node_item.item.defaultness.has_value() {
|
||||
// This means that the impl is missing a definition for the
|
||||
// associated type. This error will be reported by the type
|
||||
// checker method `check_impl_items_against_trait`, so here we
|
||||
|
|
|
|||
|
|
@ -189,7 +189,6 @@ pub struct AssociatedItem {
|
|||
pub kind: AssociatedKind,
|
||||
pub vis: Visibility,
|
||||
pub defaultness: hir::Defaultness,
|
||||
pub has_value: bool,
|
||||
pub container: AssociatedItemContainer,
|
||||
|
||||
/// Whether this is a method with an explicit self
|
||||
|
|
@ -2072,7 +2071,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
pub fn provided_trait_methods(self, id: DefId) -> Vec<AssociatedItem> {
|
||||
self.associated_items(id)
|
||||
.filter(|item| item.kind == AssociatedKind::Method && item.has_value)
|
||||
.filter(|item| item.kind == AssociatedKind::Method && item.defaultness.has_value())
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
@ -2180,8 +2179,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
name: trait_item.name,
|
||||
kind: kind,
|
||||
vis: Visibility::from_hir(&hir::Inherited, trait_item.id, self),
|
||||
defaultness: hir::Defaultness::Default,
|
||||
has_value: has_value,
|
||||
defaultness: hir::Defaultness::Default { has_value: has_value },
|
||||
def_id: def_id,
|
||||
container: TraitContainer(parent_def_id),
|
||||
method_has_self_argument: has_self
|
||||
|
|
@ -2211,7 +2209,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
kind: kind,
|
||||
vis: ty::Visibility::from_hir(vis, impl_item_ref.id.node_id, self),
|
||||
defaultness: impl_item_ref.defaultness,
|
||||
has_value: true,
|
||||
def_id: def_id,
|
||||
container: ImplContainer(parent_def_id),
|
||||
method_has_self_argument: has_self
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue