Auto merge of #45551 - michaelwoerister:fix-hir-depnodes-and-ich, r=nikomatsakis

incr.comp.: Fix two problems with HIR hashing.

Fixes https://github.com/rust-lang/rust/issues/45469.

This PR fixes two small problems:
* Overflow checks are always enabled in a constant context, so we need to hash spans of potentially overflowing operations. (Eventually I'd like to handle spans differently so we don't have to make HIR hashing know so much about things like this.)
* The HIR map collector had a bug where it would assign the `DepNode::Hir` instead of the corresponding `DepNode::HirBody` in some nested contexts.

r? @nikomatsakis
This commit is contained in:
bors 2017-10-31 05:03:25 +00:00
commit 6713736275
6 changed files with 111 additions and 50 deletions

View file

@ -219,7 +219,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
f: F) {
let prev_owner = self.current_dep_node_owner;
let prev_signature_dep_index = self.current_signature_dep_index;
let prev_full_dep_index = self.current_signature_dep_index;
let prev_full_dep_index = self.current_full_dep_index;
let prev_in_body = self.currently_in_body;
let def_path_hash = self.definitions.def_path_hash(dep_node_owner);

View file

@ -206,9 +206,10 @@ impl<'gcx> StableHashingContext<'gcx> {
pub fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self,
item_attrs: &[ast::Attribute],
is_const: bool,
f: F) {
let prev_overflow_checks = self.overflow_checks_enabled;
if attr::contains_name(item_attrs, "rustc_inherit_overflow_checks") {
if is_const || attr::contains_name(item_attrs, "rustc_inherit_overflow_checks") {
self.overflow_checks_enabled = true;
}
let prev_hash_node_ids = self.node_id_hashing_mode;

View file

@ -713,7 +713,15 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::TraitItem {
span
} = *self;
hcx.hash_hir_item_like(attrs, |hcx| {
let is_const = match *node {
hir::TraitItemKind::Const(..) |
hir::TraitItemKind::Type(..) => true,
hir::TraitItemKind::Method(hir::MethodSig { constness, .. }, _) => {
constness == hir::Constness::Const
}
};
hcx.hash_hir_item_like(attrs, is_const, |hcx| {
name.hash_stable(hcx, hasher);
attrs.hash_stable(hcx, hasher);
generics.hash_stable(hcx, hasher);
@ -750,7 +758,15 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::ImplItem {
span
} = *self;
hcx.hash_hir_item_like(attrs, |hcx| {
let is_const = match *node {
hir::ImplItemKind::Const(..) |
hir::ImplItemKind::Type(..) => true,
hir::ImplItemKind::Method(hir::MethodSig { constness, .. }, _) => {
constness == hir::Constness::Const
}
};
hcx.hash_hir_item_like(attrs, is_const, |hcx| {
name.hash_stable(hcx, hasher);
vis.hash_stable(hcx, hasher);
defaultness.hash_stable(hcx, hasher);
@ -869,11 +885,13 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Item {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
let hash_spans = match self.node {
let (is_const, hash_spans) = match self.node {
hir::ItemStatic(..) |
hir::ItemConst(..) |
hir::ItemFn(..) => {
hcx.hash_spans()
hir::ItemConst(..) => {
(true, hcx.hash_spans())
}
hir::ItemFn(_, _, constness, ..) => {
(constness == hir::Constness::Const, hcx.hash_spans())
}
hir::ItemUse(..) |
hir::ItemExternCrate(..) |
@ -887,7 +905,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Item {
hir::ItemEnum(..) |
hir::ItemStruct(..) |
hir::ItemUnion(..) => {
false
(false, false)
}
};
@ -901,7 +919,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Item {
span
} = *self;
hcx.hash_hir_item_like(attrs, |hcx| {
hcx.hash_hir_item_like(attrs, is_const, |hcx| {
hcx.while_hashing_spans(hash_spans, |hcx| {
name.hash_stable(hcx, hasher);
attrs.hash_stable(hcx, hasher);

View file

@ -62,48 +62,54 @@ const CONST_CHANGE_TYPE_2: Option<u64> = None;
// Change value between simple literals ---------------------------------------
#[cfg(cfail1)]
const CONST_CHANGE_VALUE_1: i16 = 1;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="HirBody")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail3")]
const CONST_CHANGE_VALUE_1: i16 = 2;
const CONST_CHANGE_VALUE_1: i16 = {
#[cfg(cfail1)]
{ 1 }
#[cfg(not(cfail1))]
{ 2 }
};
// Change value between expressions -------------------------------------------
#[cfg(cfail1)]
const CONST_CHANGE_VALUE_2: i16 = 1 + 1;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="HirBody")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
const CONST_CHANGE_VALUE_2: i16 = 1 + 2;
const CONST_CHANGE_VALUE_2: i16 = {
#[cfg(cfail1)]
{ 1 + 1 }
#[cfg(not(cfail1))]
{ 1 + 2 }
};
#[cfg(cfail1)]
const CONST_CHANGE_VALUE_3: i16 = 2 + 3;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="HirBody")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
const CONST_CHANGE_VALUE_3: i16 = 2 * 3;
const CONST_CHANGE_VALUE_3: i16 = {
#[cfg(cfail1)]
{ 2 + 3 }
#[cfg(not(cfail1))]
{ 2 * 3 }
};
#[cfg(cfail1)]
const CONST_CHANGE_VALUE_4: i16 = 1 + 2 * 3;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="HirBody")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
const CONST_CHANGE_VALUE_4: i16 = 1 + 2 * 4;
const CONST_CHANGE_VALUE_4: i16 = {
#[cfg(cfail1)]
{ 1 + 2 * 3 }
#[cfg(not(cfail1))]
{ 1 + 2 * 4 }
};
// Change type indirectly -----------------------------------------------------

View file

@ -115,49 +115,55 @@ static STATIC_CHANGE_TYPE_2: Option<u16> = None;
// Change value between simple literals ---------------------------------------
#[cfg(cfail1)]
static STATIC_CHANGE_VALUE_1: i16 = 1;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="HirBody")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
static STATIC_CHANGE_VALUE_1: i16 = 2;
static STATIC_CHANGE_VALUE_1: i16 = {
#[cfg(cfail1)]
{ 1 }
#[cfg(not(cfail1))]
{ 2 }
};
// Change value between expressions -------------------------------------------
#[cfg(cfail1)]
static STATIC_CHANGE_VALUE_2: i16 = 1 + 1;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="HirBody")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
static STATIC_CHANGE_VALUE_2: i16 = 1 + 2;
static STATIC_CHANGE_VALUE_2: i16 = {
#[cfg(cfail1)]
{ 1 + 1 }
#[cfg(not(cfail1))]
{ 1 + 2 }
};
#[cfg(cfail1)]
static STATIC_CHANGE_VALUE_3: i16 = 2 + 3;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="HirBody")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
static STATIC_CHANGE_VALUE_3: i16 = 2 * 3;
static STATIC_CHANGE_VALUE_3: i16 = {
#[cfg(cfail1)]
{ 2 + 3 }
#[cfg(not(cfail1))]
{ 2 * 3 }
};
#[cfg(cfail1)]
static STATIC_CHANGE_VALUE_4: i16 = 1 + 2 * 3;
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="HirBody")]
#[rustc_clean(cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
static STATIC_CHANGE_VALUE_4: i16 = 1 + 2 * 4;
static STATIC_CHANGE_VALUE_4: i16 = {
#[cfg(cfail1)]
{ 1 + 2 * 3 }
#[cfg(not(cfail1))]
{ 1 + 2 * 4 }
};
// Change type indirectly -----------------------------------------------------

View file

@ -0,0 +1,30 @@
// Copyright 2017 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 makes sure that just changing a definition's location in the
// source file also changes its incr. comp. hash, if debuginfo is enabled.
// revisions:rpass1 rpass2
// compile-flags: -C overflow-checks=on
#![feature(rustc_attrs)]
#[cfg(rpass1)]
pub fn main() {
let _ = 0u8 + 1;
}
#[cfg(rpass2)]
#[rustc_clean(label="Hir", cfg="rpass2")]
#[rustc_dirty(label="HirBody", cfg="rpass2")]
pub fn main() {
let _ = 0u8 + 1;
}