Skip to content

Rollup of 8 pull requests #41116

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3fb1a84
Add a common Build::src_is_git flag
cuviper Apr 3, 2017
e9cfc30
Only use cargo-vendor if building from git sources
cuviper Apr 3, 2017
4d32ff4
Loosen src_is_git to just check exists()
cuviper Apr 3, 2017
631f761
travis: Update musl for i686/x86_64
alexcrichton Apr 5, 2017
4c7e277
add an #[used] attribute
Feb 20, 2017
4e1147f
Add example to std::process::abort
rap2hpoutre Apr 5, 2017
bc1bd8a
add tracking issue and feature-gate and run-make tests
Mar 6, 2017
c759eea
fix location of the emitted object file
Mar 6, 2017
c1635d7
cast the #[used] static to *i8
Apr 6, 2017
ecddad6
don't test for the absence of BAR in the rmake test
Apr 6, 2017
bbe5411
document the implementation a bit more
Apr 6, 2017
763beff
add documentation to the unstable book
Apr 6, 2017
16c77d7
Update process.rs
rap2hpoutre Apr 6, 2017
b4be475
Fix Markdown issues in the docs
ollie27 Apr 6, 2017
f9fb381
rustdoc: Use pulldown-cmark for Markdown HTML rendering
ollie27 Apr 6, 2017
7d25e76
add link to issue number, ignore snippet that requires custom linking
Apr 6, 2017
1f93a78
.gitmodules: use the official Git URL w/o redirect
nodakai Apr 6, 2017
c47cdc0
Introduce HashStable trait and base ICH implementations on it.
michaelwoerister Mar 30, 2017
1220eca
Rollup merge of #39987 - japaric:used, r=arielb1
frewsxcv Apr 6, 2017
51650b4
Rollup merge of #40878 - michaelwoerister:dmh, r=nikomatsakis
frewsxcv Apr 6, 2017
3925445
Rollup merge of #41047 - cuviper:src_is_git, r=alexcrichton
frewsxcv Apr 6, 2017
f05abfe
Rollup merge of #41089 - alexcrichton:update-musl, r=brson
frewsxcv Apr 6, 2017
eba47aa
Rollup merge of #41090 - rap2hpoutre:patch-2, r=steveklabnik
frewsxcv Apr 6, 2017
5fbf6b2
Rollup merge of #41111 - ollie27:docs_markdown_fix, r=GuillaumeGomez
frewsxcv Apr 6, 2017
f66edec
Rollup merge of #41112 - ollie27:rustdoc_pull, r=GuillaumeGomez
frewsxcv Apr 6, 2017
ad59ff8
Rollup merge of #41114 - nodakai:patch-2, r=petrochenkov
frewsxcv Apr 6, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Introduce HashStable trait and base ICH implementations on it.
This initial commit provides implementations for HIR, MIR, and
everything that also needs to be supported for those two.
  • Loading branch information
michaelwoerister committed Apr 6, 2017
commit c47cdc0d93726429ee18b418b1f85fae67b82d41
4 changes: 4 additions & 0 deletions src/librustc/hir/map/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,10 @@ impl Definitions {
}
}

pub fn node_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId {
self.node_to_hir_id[node_id]
}

/// Add a definition with a parent definition.
pub fn create_def_with_parent(&mut self,
parent: Option<DefIndex>,
Expand Down
300 changes: 300 additions & 0 deletions src/librustc/ich/hcx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
// 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.

use hir;
use hir::def_id::DefId;
use ich::{self, CachingCodemapView, DefPathHashes};
use session::config::DebugInfoLevel::NoDebugInfo;
use ty;

use std::hash as std_hash;

use syntax::ast;
use syntax::attr;
use syntax::ext::hygiene::SyntaxContext;
use syntax::symbol::Symbol;
use syntax_pos::Span;

use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
StableHasherResult};
use rustc_data_structures::accumulate_vec::AccumulateVec;

/// This is the context state available during incr. comp. hashing. It contains
/// enough information to transform DefIds and HirIds into stable DefPaths (i.e.
/// a reference to the TyCtxt) and it holds a few caches for speeding up various
/// things (e.g. each DefId/DefPath is only hashed once).
pub struct StableHashingContext<'a, 'tcx: 'a> {
tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
def_path_hashes: DefPathHashes<'a, 'tcx>,
codemap: CachingCodemapView<'tcx>,
hash_spans: bool,
hash_bodies: bool,
overflow_checks_enabled: bool,
node_id_hashing_mode: NodeIdHashingMode,
// A sorted array of symbol keys for fast lookup.
ignored_attr_names: Vec<Symbol>,
}

#[derive(PartialEq, Eq, Clone, Copy)]
pub enum NodeIdHashingMode {
Ignore,
HashDefPath,
HashTraitsInScope,
}

impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> {

pub fn new(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Self {
let hash_spans_initial = tcx.sess.opts.debuginfo != NoDebugInfo;
let check_overflow_initial = tcx.sess.overflow_checks();

let mut ignored_attr_names: Vec<_> = ich::IGNORED_ATTRIBUTES
.iter()
.map(|&s| Symbol::intern(s))
.collect();

ignored_attr_names.sort();

StableHashingContext {
tcx: tcx,
def_path_hashes: DefPathHashes::new(tcx),
codemap: CachingCodemapView::new(tcx),
hash_spans: hash_spans_initial,
hash_bodies: true,
overflow_checks_enabled: check_overflow_initial,
node_id_hashing_mode: NodeIdHashingMode::HashDefPath,
ignored_attr_names: ignored_attr_names,
}
}

#[inline]
pub fn while_hashing_hir_bodies<F: FnOnce(&mut Self)>(&mut self,
hash_bodies: bool,
f: F) {
let prev_hash_bodies = self.hash_bodies;
self.hash_bodies = hash_bodies;
f(self);
self.hash_bodies = prev_hash_bodies;
}

#[inline]
pub fn while_hashing_spans<F: FnOnce(&mut Self)>(&mut self,
hash_spans: bool,
f: F) {
let prev_hash_spans = self.hash_spans;
self.hash_spans = hash_spans;
f(self);
self.hash_spans = prev_hash_spans;
}

#[inline]
pub fn with_node_id_hashing_mode<F: FnOnce(&mut Self)>(&mut self,
mode: NodeIdHashingMode,
f: F) {
let prev = self.node_id_hashing_mode;
self.node_id_hashing_mode = mode;
f(self);
self.node_id_hashing_mode = prev;
}

#[inline]
pub fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx> {
self.tcx
}

#[inline]
pub fn def_path_hash(&mut self, def_id: DefId) -> u64 {
self.def_path_hashes.hash(def_id)
}

#[inline]
pub fn hash_spans(&self) -> bool {
self.hash_spans
}

#[inline]
pub fn hash_bodies(&self) -> bool {
self.hash_bodies
}

#[inline]
pub fn codemap(&mut self) -> &mut CachingCodemapView<'tcx> {
&mut self.codemap
}

#[inline]
pub fn is_ignored_attr(&self, name: Symbol) -> bool {
self.ignored_attr_names.binary_search(&name).is_ok()
}

pub fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self,
item_attrs: &[ast::Attribute],
f: F) {
let prev_overflow_checks = self.overflow_checks_enabled;
if attr::contains_name(item_attrs, "rustc_inherit_overflow_checks") {
self.overflow_checks_enabled = true;
}
let prev_hash_node_ids = self.node_id_hashing_mode;
self.node_id_hashing_mode = NodeIdHashingMode::Ignore;

f(self);

self.node_id_hashing_mode = prev_hash_node_ids;
self.overflow_checks_enabled = prev_overflow_checks;
}

#[inline]
pub fn binop_can_panic_at_runtime(&self, binop: hir::BinOp_) -> bool
{
match binop {
hir::BiAdd |
hir::BiSub |
hir::BiMul => self.overflow_checks_enabled,

hir::BiDiv |
hir::BiRem => true,

hir::BiAnd |
hir::BiOr |
hir::BiBitXor |
hir::BiBitAnd |
hir::BiBitOr |
hir::BiShl |
hir::BiShr |
hir::BiEq |
hir::BiLt |
hir::BiLe |
hir::BiNe |
hir::BiGe |
hir::BiGt => false
}
}

#[inline]
pub fn unop_can_panic_at_runtime(&self, unop: hir::UnOp) -> bool
{
match unop {
hir::UnDeref |
hir::UnNot => false,
hir::UnNeg => self.overflow_checks_enabled,
}
}
}


impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ast::NodeId {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'tcx>,
hasher: &mut StableHasher<W>) {
match hcx.node_id_hashing_mode {
NodeIdHashingMode::Ignore => {
// Most NodeIds in the HIR can be ignored, but if there is a
// corresponding entry in the `trait_map` we need to hash that.
// Make sure we don't ignore too much by checking that there is
// no entry in a debug_assert!().
debug_assert!(hcx.tcx.trait_map.get(self).is_none());
}
NodeIdHashingMode::HashDefPath => {
hcx.tcx.hir.definitions().node_to_hir_id(*self).hash_stable(hcx, hasher);
}
NodeIdHashingMode::HashTraitsInScope => {
if let Some(traits) = hcx.tcx.trait_map.get(self) {
// The ordering of the candidates is not fixed. So we hash
// the def-ids and then sort them and hash the collection.
let mut candidates: AccumulateVec<[_; 8]> =
traits.iter()
.map(|&hir::TraitCandidate { def_id, import_id: _ }| {
hcx.def_path_hash(def_id)
})
.collect();
if traits.len() > 1 {
candidates.sort();
}
candidates.hash_stable(hcx, hasher);
}
}
}
}
}

impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for Span {

// Hash a span in a stable way. We can't directly hash the span's BytePos
// fields (that would be similar to hashing pointers, since those are just
// offsets into the CodeMap). Instead, we hash the (file name, line, column)
// triple, which stays the same even if the containing FileMap has moved
// within the CodeMap.
// Also note that we are hashing byte offsets for the column, not unicode
// codepoint offsets. For the purpose of the hash that's sufficient.
// Also, hashing filenames is expensive so we avoid doing it twice when the
// span starts and ends in the same file, which is almost always the case.
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'tcx>,
hasher: &mut StableHasher<W>) {
use syntax_pos::Pos;

if !hcx.hash_spans {
return
}

// If this is not an empty or invalid span, we want to hash the last
// position that belongs to it, as opposed to hashing the first
// position past it.
let span_hi = if self.hi > self.lo {
// We might end up in the middle of a multibyte character here,
// but that's OK, since we are not trying to decode anything at
// this position.
self.hi - ::syntax_pos::BytePos(1)
} else {
self.hi
};

{
let loc1 = hcx.codemap().byte_pos_to_line_and_col(self.lo);
let loc1 = loc1.as_ref()
.map(|&(ref fm, line, col)| (&fm.name[..], line, col.to_usize()))
.unwrap_or(("???", 0, 0));

let loc2 = hcx.codemap().byte_pos_to_line_and_col(span_hi);
let loc2 = loc2.as_ref()
.map(|&(ref fm, line, col)| (&fm.name[..], line, col.to_usize()))
.unwrap_or(("???", 0, 0));

if loc1.0 == loc2.0 {
std_hash::Hash::hash(&0u8, hasher);

std_hash::Hash::hash(loc1.0, hasher);
std_hash::Hash::hash(&loc1.1, hasher);
std_hash::Hash::hash(&loc1.2, hasher);

// Do not hash the file name twice
std_hash::Hash::hash(&loc2.1, hasher);
std_hash::Hash::hash(&loc2.2, hasher);
} else {
std_hash::Hash::hash(&1u8, hasher);

std_hash::Hash::hash(loc1.0, hasher);
std_hash::Hash::hash(&loc1.1, hasher);
std_hash::Hash::hash(&loc1.2, hasher);

std_hash::Hash::hash(loc2.0, hasher);
std_hash::Hash::hash(&loc2.1, hasher);
std_hash::Hash::hash(&loc2.2, hasher);
}
}

if self.ctxt == SyntaxContext::empty() {
0u8.hash_stable(hcx, hasher);
} else {
1u8.hash_stable(hcx, hasher);
self.source_callsite().hash_stable(hcx, hasher);
}
}
}
71 changes: 71 additions & 0 deletions src/librustc/ich/impls_const_math.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// 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 module contains `HashStable` implementations for various data types
//! from `rustc_const_math` in no particular order.

impl_stable_hash_for!(enum ::rustc_const_math::ConstFloat {
F32(val),
F64(val)
});

impl_stable_hash_for!(enum ::rustc_const_math::ConstInt {
I8(val),
I16(val),
I32(val),
I64(val),
I128(val),
Isize(val),
U8(val),
U16(val),
U32(val),
U64(val),
U128(val),
Usize(val)
});

impl_stable_hash_for!(enum ::rustc_const_math::ConstIsize {
Is16(i16),
Is32(i32),
Is64(i64)
});

impl_stable_hash_for!(enum ::rustc_const_math::ConstUsize {
Us16(i16),
Us32(i32),
Us64(i64)
});

impl_stable_hash_for!(enum ::rustc_const_math::ConstMathErr {
NotInRange,
CmpBetweenUnequalTypes,
UnequalTypes(op),
Overflow(op),
ShiftNegative,
DivisionByZero,
RemainderByZero,
UnsignedNegation,
ULitOutOfRange(int_ty),
LitOutOfRange(int_ty)
});

impl_stable_hash_for!(enum ::rustc_const_math::Op {
Add,
Sub,
Mul,
Div,
Rem,
Shr,
Shl,
Neg,
BitAnd,
BitOr,
BitXor
});
Loading