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
@ -267,6 +267,12 @@ fn visit_macro_def(&mut self, macro_def: &'v MacroDef) {
|
|||||||
fn visit_vis(&mut self, vis: &'v Visibility) {
|
fn visit_vis(&mut self, vis: &'v Visibility) {
|
||||||
walk_vis(self, vis)
|
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>) {
|
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) {
|
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
|
||||||
visitor.visit_vis(&impl_item.vis);
|
// NB: Deliberately force a compilation error if/when new fields are added.
|
||||||
visitor.visit_name(impl_item.span, impl_item.name);
|
let ImplItem { id: _, name, ref vis, ref defaultness, ref attrs, ref node, span } = *impl_item;
|
||||||
walk_list!(visitor, visit_attribute, &impl_item.attrs);
|
|
||||||
match impl_item.node {
|
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) => {
|
ImplItemKind::Const(ref ty, ref expr) => {
|
||||||
visitor.visit_id(impl_item.id);
|
visitor.visit_id(impl_item.id);
|
||||||
visitor.visit_ty(ty);
|
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) {
|
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);
|
// NB: Deliberately force a compilation error if/when new fields are added.
|
||||||
visitor.visit_name(impl_item_ref.span, impl_item_ref.name);
|
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)]
|
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq)]
|
||||||
pub struct IdRange {
|
pub struct IdRange {
|
||||||
pub min: NodeId,
|
pub min: NodeId,
|
||||||
|
@ -699,7 +699,7 @@ fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
|
|||||||
name: i.ident.name,
|
name: i.ident.name,
|
||||||
attrs: this.lower_attrs(&i.attrs),
|
attrs: this.lower_attrs(&i.attrs),
|
||||||
vis: this.lower_visibility(&i.vis),
|
vis: this.lower_visibility(&i.vis),
|
||||||
defaultness: this.lower_defaultness(i.defaultness),
|
defaultness: this.lower_defaultness(i.defaultness, true /* [1] */),
|
||||||
node: match i.node {
|
node: match i.node {
|
||||||
ImplItemKind::Const(ref ty, ref expr) => {
|
ImplItemKind::Const(ref ty, ref expr) => {
|
||||||
hir::ImplItemKind::Const(this.lower_ty(ty), this.lower_expr(expr))
|
hir::ImplItemKind::Const(this.lower_ty(ty), this.lower_expr(expr))
|
||||||
@ -715,6 +715,8 @@ fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
|
|||||||
span: i.span,
|
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 {
|
fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
|
||||||
@ -723,7 +725,7 @@ fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
|
|||||||
name: i.ident.name,
|
name: i.ident.name,
|
||||||
span: i.span,
|
span: i.span,
|
||||||
vis: self.lower_visibility(&i.vis),
|
vis: self.lower_visibility(&i.vis),
|
||||||
defaultness: self.lower_defaultness(i.defaultness),
|
defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
|
||||||
kind: match i.node {
|
kind: match i.node {
|
||||||
ImplItemKind::Const(..) => hir::AssociatedItemKind::Const,
|
ImplItemKind::Const(..) => hir::AssociatedItemKind::Const,
|
||||||
ImplItemKind::Type(..) => hir::AssociatedItemKind::Type,
|
ImplItemKind::Type(..) => hir::AssociatedItemKind::Type,
|
||||||
@ -732,9 +734,9 @@ fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
|
|||||||
},
|
},
|
||||||
ImplItemKind::Macro(..) => unimplemented!(),
|
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 {
|
fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
|
||||||
@ -1650,10 +1652,13 @@ fn lower_visibility(&mut self, v: &Visibility) -> hir::Visibility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_defaultness(&mut self, d: Defaultness) -> hir::Defaultness {
|
fn lower_defaultness(&mut self, d: Defaultness, has_value: bool) -> hir::Defaultness {
|
||||||
match d {
|
match d {
|
||||||
Defaultness::Default => hir::Defaultness::Default,
|
Defaultness::Default => hir::Defaultness::Default { has_value: has_value },
|
||||||
Defaultness::Final => hir::Defaultness::Final,
|
Defaultness::Final => {
|
||||||
|
assert!(has_value);
|
||||||
|
hir::Defaultness::Final
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1259,17 +1259,27 @@ pub enum Constness {
|
|||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
pub enum Defaultness {
|
pub enum Defaultness {
|
||||||
Default,
|
Default { has_value: bool },
|
||||||
Final,
|
Final,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Defaultness {
|
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 {
|
pub fn is_final(&self) -> bool {
|
||||||
*self == Defaultness::Final
|
*self == Defaultness::Final
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_default(&self) -> bool {
|
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 span: Span,
|
||||||
pub vis: Visibility,
|
pub vis: Visibility,
|
||||||
pub defaultness: Defaultness,
|
pub defaultness: Defaultness,
|
||||||
pub has_value: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
|
@ -1036,8 +1036,9 @@ pub fn print_impl_item(&mut self, ii: &hir::ImplItem) -> io::Result<()> {
|
|||||||
self.maybe_print_comment(ii.span.lo)?;
|
self.maybe_print_comment(ii.span.lo)?;
|
||||||
self.print_outer_attributes(&ii.attrs)?;
|
self.print_outer_attributes(&ii.attrs)?;
|
||||||
|
|
||||||
if let hir::Defaultness::Default = ii.defaultness {
|
match ii.defaultness {
|
||||||
self.word_nbsp("default")?;
|
hir::Defaultness::Default { .. } => self.word_nbsp("default")?,
|
||||||
|
hir::Defaultness::Final => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
match ii.node {
|
match ii.node {
|
||||||
|
@ -943,7 +943,7 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
|
|||||||
// an error when we confirm the candidate
|
// an error when we confirm the candidate
|
||||||
// (which will ultimately lead to `normalize_to_error`
|
// (which will ultimately lead to `normalize_to_error`
|
||||||
// being invoked).
|
// being invoked).
|
||||||
node_item.item.has_value
|
node_item.item.defaultness.has_value()
|
||||||
} else {
|
} else {
|
||||||
node_item.item.defaultness.is_default()
|
node_item.item.defaultness.is_default()
|
||||||
};
|
};
|
||||||
@ -1304,7 +1304,7 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
|
|||||||
|
|
||||||
match assoc_ty {
|
match assoc_ty {
|
||||||
Some(node_item) => {
|
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
|
// This means that the impl is missing a definition for the
|
||||||
// associated type. This error will be reported by the type
|
// associated type. This error will be reported by the type
|
||||||
// checker method `check_impl_items_against_trait`, so here we
|
// checker method `check_impl_items_against_trait`, so here we
|
||||||
|
@ -189,7 +189,6 @@ pub struct AssociatedItem {
|
|||||||
pub kind: AssociatedKind,
|
pub kind: AssociatedKind,
|
||||||
pub vis: Visibility,
|
pub vis: Visibility,
|
||||||
pub defaultness: hir::Defaultness,
|
pub defaultness: hir::Defaultness,
|
||||||
pub has_value: bool,
|
|
||||||
pub container: AssociatedItemContainer,
|
pub container: AssociatedItemContainer,
|
||||||
|
|
||||||
/// Whether this is a method with an explicit self
|
/// Whether this is a method with an explicit self
|
||||||
@ -2072,7 +2071,7 @@ pub fn expr_is_lval(self, expr: &hir::Expr) -> bool {
|
|||||||
|
|
||||||
pub fn provided_trait_methods(self, id: DefId) -> Vec<AssociatedItem> {
|
pub fn provided_trait_methods(self, id: DefId) -> Vec<AssociatedItem> {
|
||||||
self.associated_items(id)
|
self.associated_items(id)
|
||||||
.filter(|item| item.kind == AssociatedKind::Method && item.has_value)
|
.filter(|item| item.kind == AssociatedKind::Method && item.defaultness.has_value())
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2180,8 +2179,7 @@ fn associated_item_from_trait_item_ref(self,
|
|||||||
name: trait_item.name,
|
name: trait_item.name,
|
||||||
kind: kind,
|
kind: kind,
|
||||||
vis: Visibility::from_hir(&hir::Inherited, trait_item.id, self),
|
vis: Visibility::from_hir(&hir::Inherited, trait_item.id, self),
|
||||||
defaultness: hir::Defaultness::Default,
|
defaultness: hir::Defaultness::Default { has_value: has_value },
|
||||||
has_value: has_value,
|
|
||||||
def_id: def_id,
|
def_id: def_id,
|
||||||
container: TraitContainer(parent_def_id),
|
container: TraitContainer(parent_def_id),
|
||||||
method_has_self_argument: has_self
|
method_has_self_argument: has_self
|
||||||
@ -2211,7 +2209,6 @@ fn associated_item_from_impl_item_ref(self,
|
|||||||
kind: kind,
|
kind: kind,
|
||||||
vis: ty::Visibility::from_hir(vis, impl_item_ref.id.node_id, self),
|
vis: ty::Visibility::from_hir(vis, impl_item_ref.id.node_id, self),
|
||||||
defaultness: impl_item_ref.defaultness,
|
defaultness: impl_item_ref.defaultness,
|
||||||
has_value: true,
|
|
||||||
def_id: def_id,
|
def_id: def_id,
|
||||||
container: ImplContainer(parent_def_id),
|
container: ImplContainer(parent_def_id),
|
||||||
method_has_self_argument: has_self
|
method_has_self_argument: has_self
|
||||||
|
@ -199,6 +199,8 @@ enum SawAbiComponent<'a> {
|
|||||||
SawExpr(SawExprComponent<'a>),
|
SawExpr(SawExprComponent<'a>),
|
||||||
SawStmt,
|
SawStmt,
|
||||||
SawVis,
|
SawVis,
|
||||||
|
SawAssociatedItemKind(hir::AssociatedItemKind),
|
||||||
|
SawDefaultness(hir::Defaultness),
|
||||||
SawWherePredicate,
|
SawWherePredicate,
|
||||||
SawTyParamBound,
|
SawTyParamBound,
|
||||||
SawPolyTraitRef,
|
SawPolyTraitRef,
|
||||||
@ -693,6 +695,18 @@ fn visit_vis(&mut self, v: &'tcx Visibility) {
|
|||||||
visit::walk_vis(self, v)
|
visit::walk_vis(self, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_associated_item_kind(&mut self, kind: &'tcx AssociatedItemKind) {
|
||||||
|
debug!("visit_associated_item_kind: st={:?}", self.st);
|
||||||
|
SawAssociatedItemKind(*kind).hash(self.st);
|
||||||
|
visit::walk_associated_item_kind(self, kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_defaultness(&mut self, defaultness: &'tcx Defaultness) {
|
||||||
|
debug!("visit_associated_item_kind: st={:?}", self.st);
|
||||||
|
SawDefaultness(*defaultness).hash(self.st);
|
||||||
|
visit::walk_defaultness(self, defaultness);
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate) {
|
fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate) {
|
||||||
debug!("visit_where_predicate: st={:?}", self.st);
|
debug!("visit_where_predicate: st={:?}", self.st);
|
||||||
SawWherePredicate.hash(self.st);
|
SawWherePredicate.hash(self.st);
|
||||||
|
@ -834,7 +834,6 @@ pub fn get_associated_item(&self, id: DefIndex) -> Option<ty::AssociatedItem> {
|
|||||||
kind: ty::AssociatedKind::Const,
|
kind: ty::AssociatedKind::Const,
|
||||||
vis: item.visibility,
|
vis: item.visibility,
|
||||||
defaultness: container.defaultness(),
|
defaultness: container.defaultness(),
|
||||||
has_value: container.has_value(),
|
|
||||||
def_id: self.local_def_id(id),
|
def_id: self.local_def_id(id),
|
||||||
container: container.with_def_id(parent),
|
container: container.with_def_id(parent),
|
||||||
method_has_self_argument: false
|
method_has_self_argument: false
|
||||||
@ -848,7 +847,6 @@ pub fn get_associated_item(&self, id: DefIndex) -> Option<ty::AssociatedItem> {
|
|||||||
kind: ty::AssociatedKind::Method,
|
kind: ty::AssociatedKind::Method,
|
||||||
vis: item.visibility,
|
vis: item.visibility,
|
||||||
defaultness: data.container.defaultness(),
|
defaultness: data.container.defaultness(),
|
||||||
has_value: data.container.has_value(),
|
|
||||||
def_id: self.local_def_id(id),
|
def_id: self.local_def_id(id),
|
||||||
container: data.container.with_def_id(parent),
|
container: data.container.with_def_id(parent),
|
||||||
method_has_self_argument: data.has_self
|
method_has_self_argument: data.has_self
|
||||||
@ -861,7 +859,6 @@ pub fn get_associated_item(&self, id: DefIndex) -> Option<ty::AssociatedItem> {
|
|||||||
kind: ty::AssociatedKind::Type,
|
kind: ty::AssociatedKind::Type,
|
||||||
vis: item.visibility,
|
vis: item.visibility,
|
||||||
defaultness: container.defaultness(),
|
defaultness: container.defaultness(),
|
||||||
has_value: container.has_value(),
|
|
||||||
def_id: self.local_def_id(id),
|
def_id: self.local_def_id(id),
|
||||||
container: container.with_def_id(parent),
|
container: container.with_def_id(parent),
|
||||||
method_has_self_argument: false
|
method_has_self_argument: false
|
||||||
|
@ -460,10 +460,13 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
|
|||||||
let ast_item = tcx.map.expect_trait_item(node_id);
|
let ast_item = tcx.map.expect_trait_item(node_id);
|
||||||
let trait_item = tcx.associated_item(def_id);
|
let trait_item = tcx.associated_item(def_id);
|
||||||
|
|
||||||
let container = if trait_item.has_value {
|
let container = match trait_item.defaultness {
|
||||||
AssociatedContainer::TraitWithDefault
|
hir::Defaultness::Default { has_value: true } =>
|
||||||
} else {
|
AssociatedContainer::TraitWithDefault,
|
||||||
AssociatedContainer::TraitRequired
|
hir::Defaultness::Default { has_value: false } =>
|
||||||
|
AssociatedContainer::TraitRequired,
|
||||||
|
hir::Defaultness::Final =>
|
||||||
|
span_bug!(ast_item.span, "traits cannot have final items"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let kind = match trait_item.kind {
|
let kind = match trait_item.kind {
|
||||||
@ -501,7 +504,7 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
|
|||||||
Some(self.encode_item_type(def_id))
|
Some(self.encode_item_type(def_id))
|
||||||
}
|
}
|
||||||
ty::AssociatedKind::Type => {
|
ty::AssociatedKind::Type => {
|
||||||
if trait_item.has_value {
|
if trait_item.defaultness.has_value() {
|
||||||
Some(self.encode_item_type(def_id))
|
Some(self.encode_item_type(def_id))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -530,8 +533,10 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
|
|||||||
let impl_def_id = impl_item.container.id();
|
let impl_def_id = impl_item.container.id();
|
||||||
|
|
||||||
let container = match impl_item.defaultness {
|
let container = match impl_item.defaultness {
|
||||||
hir::Defaultness::Default => AssociatedContainer::ImplDefault,
|
hir::Defaultness::Default { has_value: true } => AssociatedContainer::ImplDefault,
|
||||||
hir::Defaultness::Final => AssociatedContainer::ImplFinal,
|
hir::Defaultness::Final => AssociatedContainer::ImplFinal,
|
||||||
|
hir::Defaultness::Default { has_value: false } =>
|
||||||
|
span_bug!(ast_item.span, "impl items always have values (currently)"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let kind = match impl_item.kind {
|
let kind = match impl_item.kind {
|
||||||
|
@ -310,21 +310,16 @@ pub fn with_def_id(&self, def_id: DefId) -> ty::AssociatedItemContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_value(&self) -> bool {
|
|
||||||
match *self {
|
|
||||||
AssociatedContainer::TraitRequired => false,
|
|
||||||
|
|
||||||
AssociatedContainer::TraitWithDefault |
|
|
||||||
AssociatedContainer::ImplDefault |
|
|
||||||
AssociatedContainer::ImplFinal => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn defaultness(&self) -> hir::Defaultness {
|
pub fn defaultness(&self) -> hir::Defaultness {
|
||||||
match *self {
|
match *self {
|
||||||
AssociatedContainer::TraitRequired |
|
AssociatedContainer::TraitRequired => hir::Defaultness::Default {
|
||||||
|
has_value: false,
|
||||||
|
},
|
||||||
|
|
||||||
AssociatedContainer::TraitWithDefault |
|
AssociatedContainer::TraitWithDefault |
|
||||||
AssociatedContainer::ImplDefault => hir::Defaultness::Default,
|
AssociatedContainer::ImplDefault => hir::Defaultness::Default {
|
||||||
|
has_value: true,
|
||||||
|
},
|
||||||
|
|
||||||
AssociatedContainer::ImplFinal => hir::Defaultness::Final,
|
AssociatedContainer::ImplFinal => hir::Defaultness::Final,
|
||||||
}
|
}
|
||||||
|
@ -536,7 +536,7 @@ pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option<Data> {
|
|||||||
let def_id = if decl_id.is_local() {
|
let def_id = if decl_id.is_local() {
|
||||||
let ti = self.tcx.associated_item(decl_id);
|
let ti = self.tcx.associated_item(decl_id);
|
||||||
self.tcx.associated_items(ti.container.id())
|
self.tcx.associated_items(ti.container.id())
|
||||||
.find(|item| item.name == ti.name && item.has_value)
|
.find(|item| item.name == ti.name && item.defaultness.has_value())
|
||||||
.map(|item| item.def_id)
|
.map(|item| item.def_id)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1110,7 +1110,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
}
|
}
|
||||||
hir::ImplItemKind::Type(_) => {
|
hir::ImplItemKind::Type(_) => {
|
||||||
if ty_trait_item.kind == ty::AssociatedKind::Type {
|
if ty_trait_item.kind == ty::AssociatedKind::Type {
|
||||||
if ty_trait_item.has_value {
|
if ty_trait_item.defaultness.has_value() {
|
||||||
overridden_associated_type = Some(impl_item);
|
overridden_associated_type = Some(impl_item);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1144,7 +1144,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
|
|
||||||
if !is_implemented {
|
if !is_implemented {
|
||||||
if !trait_item.has_value {
|
if !trait_item.defaultness.has_value() {
|
||||||
missing_items.push(trait_item);
|
missing_items.push(trait_item);
|
||||||
} else if associated_type_overridden {
|
} else if associated_type_overridden {
|
||||||
invalidated_items.push(trait_item.name);
|
invalidated_items.push(trait_item.name);
|
||||||
|
@ -204,7 +204,7 @@ fn check_trait_or_impl_item(&mut self,
|
|||||||
free_id_outlive, self_ty);
|
free_id_outlive, self_ty);
|
||||||
}
|
}
|
||||||
ty::AssociatedKind::Type => {
|
ty::AssociatedKind::Type => {
|
||||||
if item.has_value {
|
if item.defaultness.has_value() {
|
||||||
let ty = fcx.tcx.item_type(item.def_id);
|
let ty = fcx.tcx.item_type(item.def_id);
|
||||||
let ty = fcx.instantiate_type_scheme(span, free_substs, &ty);
|
let ty = fcx.instantiate_type_scheme(span, free_substs, &ty);
|
||||||
fcx.register_wf_obligation(ty, span, code.clone());
|
fcx.register_wf_obligation(ty, span, code.clone());
|
||||||
|
@ -118,7 +118,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
.map(|item_ref| ccx.tcx.map.local_def_id(item_ref.id.node_id))
|
.map(|item_ref| ccx.tcx.map.local_def_id(item_ref.id.node_id))
|
||||||
.filter(|&def_id| {
|
.filter(|&def_id| {
|
||||||
let item = ccx.tcx.associated_item(def_id);
|
let item = ccx.tcx.associated_item(def_id);
|
||||||
item.kind == ty::AssociatedKind::Type && item.has_value
|
item.kind == ty::AssociatedKind::Type && item.defaultness.has_value()
|
||||||
})
|
})
|
||||||
.flat_map(|def_id| {
|
.flat_map(|def_id| {
|
||||||
ctp::parameters_for(&ccx.tcx.item_type(def_id), true)
|
ctp::parameters_for(&ccx.tcx.item_type(def_id), true)
|
||||||
|
@ -364,7 +364,7 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
|
|||||||
let trait_items = tcx.associated_items(did).filter_map(|item| {
|
let trait_items = tcx.associated_items(did).filter_map(|item| {
|
||||||
match item.kind {
|
match item.kind {
|
||||||
ty::AssociatedKind::Const => {
|
ty::AssociatedKind::Const => {
|
||||||
let default = if item.has_value {
|
let default = if item.defaultness.has_value() {
|
||||||
Some(pprust::expr_to_string(
|
Some(pprust::expr_to_string(
|
||||||
lookup_const_by_id(tcx, item.def_id, None).unwrap().0))
|
lookup_const_by_id(tcx, item.def_id, None).unwrap().0))
|
||||||
} else {
|
} else {
|
||||||
@ -407,7 +407,7 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
|
|||||||
abi: abi
|
abi: abi
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => panic!("not a tymethod"),
|
ref r => panic!("not a tymethod: {:?}", r),
|
||||||
};
|
};
|
||||||
Some(cleaned)
|
Some(cleaned)
|
||||||
}
|
}
|
||||||
|
@ -1373,9 +1373,10 @@ fn clean(&self, cx: &DocContext) -> Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let provided = match self.container {
|
let provided = match self.container {
|
||||||
ty::ImplContainer(_) => false,
|
ty::ImplContainer(_) => false,
|
||||||
ty::TraitContainer(_) => self.has_value
|
ty::TraitContainer(_) => self.defaultness.has_value()
|
||||||
};
|
};
|
||||||
if provided {
|
if provided {
|
||||||
MethodItem(Method {
|
MethodItem(Method {
|
||||||
@ -1440,7 +1441,7 @@ fn clean(&self, cx: &DocContext) -> Item {
|
|||||||
None => bounds.push(TyParamBound::maybe_sized(cx)),
|
None => bounds.push(TyParamBound::maybe_sized(cx)),
|
||||||
}
|
}
|
||||||
|
|
||||||
let ty = if self.has_value {
|
let ty = if self.defaultness.has_value() {
|
||||||
Some(cx.tcx().item_type(self.def_id))
|
Some(cx.tcx().item_type(self.def_id))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
128
src/test/incremental/hashes/inherent_impls.rs
Normal file
128
src/test/incremental/hashes/inherent_impls.rs
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
|
||||||
|
// This test case tests the incremental compilation hash (ICH) implementation
|
||||||
|
// for let expressions.
|
||||||
|
|
||||||
|
// The general pattern followed here is: Change one thing between rev1 and rev2
|
||||||
|
// and make sure that the hash has changed, then change nothing between rev2 and
|
||||||
|
// rev3 and make sure that the hash has not changed.
|
||||||
|
|
||||||
|
// must-compile-successfully
|
||||||
|
// revisions: cfail1 cfail2 cfail3
|
||||||
|
// compile-flags: -Z query-dep-graph
|
||||||
|
|
||||||
|
|
||||||
|
#![allow(warnings)]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![crate_type="rlib"]
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
// Change Method Name -----------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
impl Foo {
|
||||||
|
pub fn method_name() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
impl Foo {
|
||||||
|
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
pub fn method_name2() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change Method Body -----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This should affect the method itself, but not the impl.
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
impl Foo {
|
||||||
|
pub fn method_body() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
impl Foo {
|
||||||
|
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
pub fn method_body() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change Method Privacy -----------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
impl Foo {
|
||||||
|
pub fn method_privacy() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
impl Foo {
|
||||||
|
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn method_privacy() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change Method Selfness -----------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
impl Foo {
|
||||||
|
pub fn method_selfness() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
impl Foo {
|
||||||
|
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
pub fn method_selfness(&self) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change Method Selfmutness -----------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
impl Foo {
|
||||||
|
pub fn method_selfmutness(&self) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
impl Foo {
|
||||||
|
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
pub fn method_selfmutness(&mut self) { }
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user