Skip to content

Rollup of 8 pull requests #50893

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

Merged
merged 26 commits into from
May 20, 2018
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5e30f6b
CheckLoopVisitor: also visit break expressions
est31 May 17, 2018
a8c2332
Removed use of TypeIdHasher in debuginfo and replaced it with StableH…
iancormac84 May 8, 2018
9a746d5
Removed use of TypeIdHasher in symbol hash generation and replaced it…
iancormac84 May 8, 2018
659f164
Removed TypeIdHasher.
iancormac84 May 8, 2018
9041d81
Code structure edits.
iancormac84 May 8, 2018
ef38712
Removed unused imports.
iancormac84 May 8, 2018
6131c0a
Fix more unused imports errors.
iancormac84 May 8, 2018
b79edf0
Added extra hashing step.
iancormac84 May 8, 2018
18b032a
Removed unused import.
iancormac84 May 16, 2018
1839fae
Removed yet another unused import.
iancormac84 May 16, 2018
0349394
Fixed accidental removal of StableHasher declaration.
iancormac84 May 17, 2018
032831d
Update LLVM to 56c931901cfb85cd6f7ed44c7d7520a8de1edf97
nox May 17, 2018
59782f4
in which the unused shorthand field pattern debacle/saga continues
zackmdavis May 18, 2018
cf1f038
Reorder description for snippets in rustdoc documentation
robinkrahl May 18, 2018
8b02488
Fix warning when building stage0 libcore
dlrobertson May 19, 2018
387875d
Update clippy
oli-obk May 19, 2018
9e914cc
Rollup merge of #50531 - iancormac84:merge-typeidhasher-cleanup, r=mi…
kennytm May 19, 2018
ecce274
use if let to avoid potential div by zero
cjkenn May 17, 2018
8d9a87c
remove feature line from test
cjkenn May 19, 2018
fbfce83
Rollup merge of #50827 - nox:llvmup, r=eddyb
kennytm May 19, 2018
611dafc
Rollup merge of #50829 - est31:master, r=estebank
kennytm May 19, 2018
907288c
Rollup merge of #50854 - zackmdavis:and_the_case_of_the_unused_field_…
kennytm May 19, 2018
974396b
Rollup merge of #50858 - robinkrahl:rustdoc-fix-order, r=steveklabnik
kennytm May 19, 2018
9f34c7f
Rollup merge of #50883 - dlrobertson:fix_warning, r=TimNN
kennytm May 19, 2018
e1f031e
Rollup merge of #50819 - cjkenn:cjkenn/div-by-zero, r=kennytm
kennytm May 19, 2018
ada5fee
Rollup merge of #50889 - oli-obk:clippy, r=kennytm
kennytm May 19, 2018
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
28 changes: 25 additions & 3 deletions src/Cargo.lock
Original file line number Diff line number Diff line change
@@ -288,12 +288,12 @@ dependencies = [

[[package]]
name = "clippy"
version = "0.0.200"
version = "0.0.202"
dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy-mini-macro-test 0.2.0",
"clippy_lints 0.0.200",
"clippy_lints 0.0.202",
"compiletest_rs 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -311,6 +311,27 @@ version = "0.2.0"
[[package]]
name = "clippy_lints"
version = "0.0.200"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "clippy_lints"
version = "0.0.202"
dependencies = [
"cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1624,7 +1645,7 @@ version = "0.128.0"
dependencies = [
"cargo 0.29.0",
"cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy_lints 0.0.200",
"clippy_lints 0.0.200 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2978,6 +2999,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
"checksum chrono 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ba5f60682a4c264e7f8d77b82e7788938a76befdf949d4a98026d19099c9d873"
"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
"checksum clippy_lints 0.0.200 (registry+https://github.com/rust-lang/crates.io-index)" = "d2432663f6bdb90255dcf9df5ca504f99b575bb471281591138f62f9d31f863b"
"checksum cmake 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "5cf678ceebedde428000cb3a34465cf3606d1a48da17014948a916deac39da7c"
"checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc"
"checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007"
1 change: 0 additions & 1 deletion src/Cargo.toml
Original file line number Diff line number Diff line change
@@ -64,4 +64,3 @@ cargo = { path = "tools/cargo" }
# RLS depends on `rustfmt` from crates.io, so we put this in a `[patch]` section
# for crates.io
rustfmt-nightly = { path = "tools/rustfmt" }
clippy_lints = { path = "tools/clippy/clippy_lints" }
16 changes: 8 additions & 8 deletions src/doc/rustdoc/src/documentation-tests.md
Original file line number Diff line number Diff line change
@@ -268,10 +268,10 @@ not actually pass as a test.
# fn foo() {}
```

`compile_fail` tells `rustdoc` that the compilation should fail. If it
compiles, then the test will fail. However please note that code failing
with the current Rust release may work in a future release, as new features
are added.
The `no_run` attribute will compile your code, but not run it. This is
important for examples such as "Here's how to retrieve a web page,"
which you would want to ensure compiles, but might be run in a test
environment that has no network access.

```text
/// ```compile_fail
@@ -280,7 +280,7 @@ are added.
/// ```
```

The `no_run` attribute will compile your code, but not run it. This is
important for examples such as "Here's how to retrieve a web page,"
which you would want to ensure compiles, but might be run in a test
environment that has no network access.
`compile_fail` tells `rustdoc` that the compilation should fail. If it
compiles, then the test will fail. However please note that code failing
with the current Rust release may work in a future release, as new features
are added.
1 change: 1 addition & 0 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
@@ -1698,6 +1698,7 @@ impl<T> [T] {
}

/// Function to calculate lenghts of the middle and trailing slice for `align_to{,_mut}`.
#[cfg(not(stage0))]
fn align_to_offsets<U>(&self) -> (usize, usize) {
// What we gonna do about `rest` is figure out what multiple of `U`s we can put in a
// lowest number of `T`s. And how many `T`s we need for each such "multiple".
2 changes: 1 addition & 1 deletion src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
@@ -132,7 +132,7 @@ for ty::RegionKind {
ty::ReLateBound(..) |
ty::ReVar(..) |
ty::ReSkolemized(..) => {
bug!("TypeIdHasher: unexpected region {:?}", *self)
bug!("StableHasher: unexpected region {:?}", *self)
}
}
}
106 changes: 50 additions & 56 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
@@ -117,6 +117,7 @@ use std::io::prelude::*;
use std::io;
use std::rc::Rc;
use syntax::ast::{self, NodeId};
use syntax::ptr::P;
use syntax::symbol::keywords;
use syntax_pos::Span;

@@ -398,72 +399,65 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
lsets.warn_about_unused_args(body, entry_ln);
}

fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
local.pat.each_binding(|_, p_id, sp, path1| {
debug!("adding local variable {}", p_id);
fn add_from_pat<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, pat: &P<hir::Pat>) {
// For struct patterns, take note of which fields used shorthand
// (`x` rather than `x: x`).
//
// FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be
// phased out in favor of `HirId`s; however, we need to match the signature of
// `each_binding`, which uses `NodeIds`.
let mut shorthand_field_ids = NodeSet();
let mut pats = VecDeque::new();
pats.push_back(pat);
while let Some(pat) = pats.pop_front() {
use hir::PatKind::*;
match pat.node {
Binding(_, _, _, ref inner_pat) => {
pats.extend(inner_pat.iter());
}
Struct(_, ref fields, _) => {
for field in fields {
if field.node.is_shorthand {
shorthand_field_ids.insert(field.node.pat.id);
}
}
}
Ref(ref inner_pat, _) |
Box(ref inner_pat) => {
pats.push_back(inner_pat);
}
TupleStruct(_, ref inner_pats, _) |
Tuple(ref inner_pats, _) => {
pats.extend(inner_pats.iter());
}
Slice(ref pre_pats, ref inner_pat, ref post_pats) => {
pats.extend(pre_pats.iter());
pats.extend(inner_pat.iter());
pats.extend(post_pats.iter());
}
_ => {}
}
}

pat.each_binding(|_bm, p_id, _sp, path1| {
let name = path1.node;
ir.add_live_node_for_node(p_id, VarDefNode(sp));
ir.add_live_node_for_node(p_id, VarDefNode(path1.span));
ir.add_variable(Local(LocalInfo {
id: p_id,
name,
is_shorthand: false,
is_shorthand: shorthand_field_ids.contains(&p_id)
}));
});
}

fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
add_from_pat(ir, &local.pat);
intravisit::walk_local(ir, local);
}

fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
for mut pat in &arm.pats {
// For struct patterns, take note of which fields used shorthand
// (`x` rather than `x: x`).
//
// FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be
// phased out in favor of `HirId`s; however, we need to match the signature of
// `each_binding`, which uses `NodeIds`.
let mut shorthand_field_ids = NodeSet();
let mut pats = VecDeque::new();
pats.push_back(pat);
while let Some(pat) = pats.pop_front() {
use hir::PatKind::*;
match pat.node {
Binding(_, _, _, ref inner_pat) => {
pats.extend(inner_pat.iter());
}
Struct(_, ref fields, _) => {
for field in fields {
if field.node.is_shorthand {
shorthand_field_ids.insert(field.node.pat.id);
}
}
}
Ref(ref inner_pat, _) |
Box(ref inner_pat) => {
pats.push_back(inner_pat);
}
TupleStruct(_, ref inner_pats, _) |
Tuple(ref inner_pats, _) => {
pats.extend(inner_pats.iter());
}
Slice(ref pre_pats, ref inner_pat, ref post_pats) => {
pats.extend(pre_pats.iter());
pats.extend(inner_pat.iter());
pats.extend(post_pats.iter());
}
_ => {}
}
}

pat.each_binding(|bm, p_id, _sp, path1| {
debug!("adding local variable {} from match with bm {:?}",
p_id, bm);
let name = path1.node;
ir.add_live_node_for_node(p_id, VarDefNode(path1.span));
ir.add_variable(Local(LocalInfo {
id: p_id,
name: name,
is_shorthand: shorthand_field_ids.contains(&p_id)
}));
})
for pat in &arm.pats {
add_from_pat(ir, pat);
}
intravisit::walk_arm(ir, arm);
}
151 changes: 1 addition & 150 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
@@ -15,23 +15,18 @@ use hir::def_id::DefId;
use hir::map::{DefPathData, Node};
use hir;
use ich::NodeIdHashingMode;
use middle::const_val::ConstVal;
use traits::{self, ObligationCause};
use ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
use ty::fold::TypeVisitor;
use ty::subst::{Substs, UnpackedKind};
use ty::maps::TyCtxtAt;
use ty::TypeVariants::*;
use ty::layout::{Integer, IntegerExt};
use util::common::ErrorReported;
use middle::lang_items;

use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
HashStable};
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use rustc_data_structures::fx::FxHashMap;
use std::{cmp, fmt};
use std::hash::Hash;
use std::intrinsics;
use syntax::ast;
use syntax::attr::{self, SignedInt, UnsignedInt};
use syntax_pos::{Span, DUMMY_SP};
@@ -615,150 +610,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}

pub struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a, W> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
state: StableHasher<W>,
}

impl<'a, 'gcx, 'tcx, W> TypeIdHasher<'a, 'gcx, 'tcx, W>
where W: StableHasherResult
{
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self {
TypeIdHasher { tcx: tcx, state: StableHasher::new() }
}

pub fn finish(self) -> W {
self.state.finish()
}

pub fn hash<T: Hash>(&mut self, x: T) {
x.hash(&mut self.state);
}

fn hash_discriminant_u8<T>(&mut self, x: &T) {
let v = unsafe {
intrinsics::discriminant_value(x)
};
let b = v as u8;
assert_eq!(v, b as u64);
self.hash(b)
}

fn def_id(&mut self, did: DefId) {
// Hash the DefPath corresponding to the DefId, which is independent
// of compiler internal state. We already have a stable hash value of
// all DefPaths available via tcx.def_path_hash(), so we just feed that
// into the hasher.
let hash = self.tcx.def_path_hash(did);
self.hash(hash);
}
}

impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
where W: StableHasherResult
{
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
// Distinguish between the Ty variants uniformly.
self.hash_discriminant_u8(&ty.sty);

match ty.sty {
TyInt(i) => self.hash(i),
TyUint(u) => self.hash(u),
TyFloat(f) => self.hash(f),
TyArray(_, n) => {
self.hash_discriminant_u8(&n.val);
match n.val {
ConstVal::Value(alloc) => self.hash(alloc),
ConstVal::Unevaluated(def_id, _) => self.def_id(def_id),
}
}
TyRawPtr(m) => self.hash(m.mutbl),
TyRef(_, _, mutbl) => self.hash(mutbl),
TyClosure(def_id, _) |
TyGenerator(def_id, _, _) |
TyAnon(def_id, _) |
TyFnDef(def_id, _) => self.def_id(def_id),
TyAdt(d, _) => self.def_id(d.did),
TyForeign(def_id) => self.def_id(def_id),
TyFnPtr(f) => {
self.hash(f.unsafety());
self.hash(f.abi());
self.hash(f.variadic());
self.hash(f.inputs().skip_binder().len());
}
TyDynamic(ref data, ..) => {
if let Some(p) = data.principal() {
self.def_id(p.def_id());
}
for d in data.auto_traits() {
self.def_id(d);
}
}
TyGeneratorWitness(tys) => {
self.hash(tys.skip_binder().len());
}
TyTuple(tys) => {
self.hash(tys.len());
}
TyParam(p) => {
self.hash(p.idx);
self.hash(p.name);
}
TyProjection(ref data) => {
self.def_id(data.item_def_id);
}
TyNever |
TyBool |
TyChar |
TyStr |
TySlice(_) => {}

TyError |
TyInfer(_) => bug!("TypeIdHasher: unexpected type {}", ty)
}

ty.super_visit_with(self)
}

fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
self.hash_discriminant_u8(r);
match *r {
ty::ReErased |
ty::ReStatic |
ty::ReEmpty => {
// No variant fields to hash for these ...
}
ty::ReCanonical(c) => {
self.hash(c);
}
ty::ReLateBound(db, ty::BrAnon(i)) => {
self.hash(db.depth);
self.hash(i);
}
ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, .. }) => {
self.def_id(def_id);
}

ty::ReClosureBound(..) |
ty::ReLateBound(..) |
ty::ReFree(..) |
ty::ReScope(..) |
ty::ReVar(..) |
ty::ReSkolemized(..) => {
bug!("TypeIdHasher: unexpected region {:?}", r)
}
}
false
}

fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, x: &ty::Binder<T>) -> bool {
// Anonymize late-bound regions so that, for example:
// `for<'a, b> fn(&'a &'b T)` and `for<'a, b> fn(&'b &'a T)`
// result in the same TypeId (the two types are equivalent).
self.tcx.anonymize_late_bound_regions(x).super_visit_with(self)
}
}

impl<'a, 'tcx> ty::TyS<'tcx> {
pub fn moves_by_default(&'tcx self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
8 changes: 6 additions & 2 deletions src/librustc_codegen_llvm/abi.rs
Original file line number Diff line number Diff line change
@@ -127,8 +127,12 @@ impl LlvmType for Reg {
impl LlvmType for CastTarget {
fn llvm_type(&self, cx: &CodegenCx) -> Type {
let rest_ll_unit = self.rest.unit.llvm_type(cx);
let rest_count = self.rest.total.bytes() / self.rest.unit.size.bytes();
let rem_bytes = self.rest.total.bytes() % self.rest.unit.size.bytes();
let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 {
(0, 0)
} else {
(self.rest.total.bytes() / self.rest.unit.size.bytes(),
self.rest.total.bytes() % self.rest.unit.size.bytes())
};

if self.prefix.iter().all(|x| x.is_none()) {
// Simplify to a single unit when there is no prefix and size <= unit size
17 changes: 11 additions & 6 deletions src/librustc_codegen_llvm/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
@@ -23,12 +23,11 @@ use llvm::{self, ValueRef};
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
DICompositeType, DILexicalBlock, DIFlags};

use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc::hir::CodegenFnAttrFlags;
use rustc::hir::def::CtorKind;
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
use rustc::ty::fold::TypeVisitor;
use rustc::ty::util::TypeIdHasher;
use rustc::ich::Fingerprint;
use rustc::ich::{Fingerprint, NodeIdHashingMode};
use rustc::ty::Instance;
use common::CodegenCx;
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
@@ -144,9 +143,15 @@ impl<'tcx> TypeMap<'tcx> {

// The hasher we are using to generate the UniqueTypeId. We want
// something that provides more than the 64 bits of the DefaultHasher.
let mut type_id_hasher = TypeIdHasher::<Fingerprint>::new(cx.tcx);
type_id_hasher.visit_ty(type_);
let unique_type_id = type_id_hasher.finish().to_hex();
let mut hasher = StableHasher::<Fingerprint>::new();
let mut hcx = cx.tcx.create_stable_hashing_context();
let type_ = cx.tcx.erase_regions(&type_);
hcx.while_hashing_spans(false, |hcx| {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
type_.hash_stable(hcx, &mut hasher);
});
});
let unique_type_id = hasher.finish().to_hex();

let key = self.unique_id_interner.intern(&unique_type_id);
self.type_to_unique_id.insert(type_, UniqueTypeId(key));
136 changes: 73 additions & 63 deletions src/librustc_codegen_utils/symbol_names.rs
Original file line number Diff line number Diff line change
@@ -97,18 +97,19 @@
//! virtually impossible. Thus, symbol hash generation exclusively relies on
//! DefPaths which are much more robust in the face of changes to the code base.
use rustc::middle::weak_lang_items;
use rustc_mir::monomorphize::Instance;
use rustc_mir::monomorphize::item::{MonoItem, MonoItemExt, InstantiationMode};
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::hir::map as hir_map;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::ty::fold::TypeVisitor;
use rustc::hir::map::definitions::DefPathData;
use rustc::ich::NodeIdHashingMode;
use rustc::middle::weak_lang_items;
use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
use rustc::ty::maps::Providers;
use rustc::ty::subst::Substs;
use rustc::hir::map::definitions::DefPathData;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::util::common::record_time;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_mir::monomorphize::item::{InstantiationMode, MonoItem, MonoItemExt};
use rustc_mir::monomorphize::Instance;

use syntax::attr;
use syntax_pos::symbol::Symbol;
@@ -124,51 +125,60 @@ pub fn provide(providers: &mut Providers) {
};
}

fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn get_symbol_hash<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,

// the DefId of the item this name is for
def_id: DefId,
// the DefId of the item this name is for
def_id: DefId,

// instance this name will be for
instance: Instance<'tcx>,
// instance this name will be for
instance: Instance<'tcx>,

// type of the item, without any generic
// parameters substituted; this is
// included in the hash as a kind of
// safeguard.
item_type: Ty<'tcx>,
// type of the item, without any generic
// parameters substituted; this is
// included in the hash as a kind of
// safeguard.
item_type: Ty<'tcx>,

// values for generic type parameters,
// if any.
substs: &'tcx Substs<'tcx>)
-> u64 {
debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs);
// values for generic type parameters,
// if any.
substs: &'tcx Substs<'tcx>,
) -> u64 {
debug!(
"get_symbol_hash(def_id={:?}, parameters={:?})",
def_id, substs
);

let mut hasher = ty::util::TypeIdHasher::<u64>::new(tcx);
let mut hasher = StableHasher::<u64>::new();
let mut hcx = tcx.create_stable_hashing_context();

record_time(&tcx.sess.perf_stats.symbol_hash_time, || {
// the main symbol name is not necessarily unique; hash in the
// compiler's internal def-path, guaranteeing each symbol has a
// truly unique path
hasher.hash(tcx.def_path_hash(def_id));
tcx.def_path_hash(def_id).hash_stable(&mut hcx, &mut hasher);

// Include the main item-type. Note that, in this case, the
// assertions about `needs_subst` may not hold, but this item-type
// ought to be the same for every reference anyway.
assert!(!item_type.has_erasable_regions());
hasher.visit_ty(item_type);
hcx.while_hashing_spans(false, |hcx| {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
item_type.hash_stable(hcx, &mut hasher);
});
});

// If this is a function, we hash the signature as well.
// This is not *strictly* needed, but it may help in some
// situations, see the `run-make/a-b-a-linker-guard` test.
if let ty::TyFnDef(..) = item_type.sty {
item_type.fn_sig(tcx).visit_with(&mut hasher);
item_type.fn_sig(tcx).hash_stable(&mut hcx, &mut hasher);
}

// also include any type parameters (for generic items)
assert!(!substs.has_erasable_regions());
assert!(!substs.needs_subst());
substs.visit_with(&mut hasher);
substs.hash_stable(&mut hcx, &mut hasher);

let is_generic = substs.types().next().is_some();
let avoid_cross_crate_conflicts =
@@ -194,52 +204,47 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
if !def_id.is_local() && tcx.share_generics() {
// If we are re-using a monomorphization from another crate,
// we have to compute the symbol hash accordingly.
let upstream_monomorphizations =
tcx.upstream_monomorphizations_for(def_id);
let upstream_monomorphizations = tcx.upstream_monomorphizations_for(def_id);

upstream_monomorphizations.and_then(|monos| monos.get(&substs)
.cloned())
.unwrap_or(LOCAL_CRATE)
upstream_monomorphizations
.and_then(|monos| monos.get(&substs).cloned())
.unwrap_or(LOCAL_CRATE)
} else {
LOCAL_CRATE
}
} else {
LOCAL_CRATE
};

hasher.hash(&tcx.original_crate_name(instantiating_crate).as_str()[..]);
hasher.hash(&tcx.crate_disambiguator(instantiating_crate));
(&tcx.original_crate_name(instantiating_crate).as_str()[..])
.hash_stable(&mut hcx, &mut hasher);
(&tcx.crate_disambiguator(instantiating_crate)).hash_stable(&mut hcx, &mut hasher);
}
});

// 64 bits should be enough to avoid collisions.
hasher.finish()
}

fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
-> ty::SymbolName
{
fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName {
let mut buffer = SymbolPathBuffer::new();
item_path::with_forced_absolute_paths(|| {
tcx.push_item_path(&mut buffer, def_id);
});
buffer.into_interned()
}

fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>)
-> ty::SymbolName
{
ty::SymbolName { name: Symbol::intern(&compute_symbol_name(tcx, instance)).as_interned_str() }
fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName {
ty::SymbolName {
name: Symbol::intern(&compute_symbol_name(tcx, instance)).as_interned_str(),
}
}

fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>)
-> String
{
fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> String {
let def_id = instance.def_id();
let substs = instance.substs;

debug!("symbol_name(def_id={:?}, substs={:?})",
def_id, substs);
debug!("symbol_name(def_id={:?}, substs={:?})", def_id, substs);

let node_id = tcx.hir.as_local_node_id(def_id);

@@ -259,7 +264,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
let is_foreign = if let Some(id) = node_id {
match tcx.hir.get(id) {
hir_map::NodeForeignItem(_) => true,
_ => false
_ => false,
}
} else {
tcx.is_foreign_item(def_id)
@@ -296,8 +301,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
loop {
let key = tcx.def_key(ty_def_id);
match key.disambiguated_data.data {
DefPathData::TypeNs(_) |
DefPathData::ValueNs(_) => {
DefPathData::TypeNs(_) | DefPathData::ValueNs(_) => {
instance_ty = tcx.type_of(ty_def_id);
break;
}
@@ -306,8 +310,12 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
// to be a value or type-def or something in there
// *somewhere*
ty_def_id.index = key.parent.unwrap_or_else(|| {
bug!("finding type for {:?}, encountered def-id {:?} with no \
parent", def_id, ty_def_id);
bug!(
"finding type for {:?}, encountered def-id {:?} with no \
parent",
def_id,
ty_def_id
);
});
}
}
@@ -337,14 +345,14 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
// use C++ name-mangling.
struct SymbolPathBuffer {
result: String,
temp_buf: String
temp_buf: String,
}

impl SymbolPathBuffer {
fn new() -> Self {
let mut result = SymbolPathBuffer {
result: String::with_capacity(64),
temp_buf: String::with_capacity(16)
temp_buf: String::with_capacity(16),
};
result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested
result
@@ -353,14 +361,16 @@ impl SymbolPathBuffer {
fn from_interned(symbol: ty::SymbolName) -> Self {
let mut result = SymbolPathBuffer {
result: String::with_capacity(64),
temp_buf: String::with_capacity(16)
temp_buf: String::with_capacity(16),
};
result.result.push_str(&symbol.name.as_str());
result
}

fn into_interned(self) -> ty::SymbolName {
ty::SymbolName { name: Symbol::intern(&self.result).as_interned_str() }
ty::SymbolName {
name: Symbol::intern(&self.result).as_interned_str(),
}
}

fn finish(mut self, hash: u64) -> String {
@@ -379,7 +389,11 @@ impl ItemPathBuffer for SymbolPathBuffer {
fn push(&mut self, text: &str) {
self.temp_buf.clear();
let need_underscore = sanitize(&mut self.temp_buf, text);
let _ = write!(self.result, "{}", self.temp_buf.len() + (need_underscore as usize));
let _ = write!(
self.result,
"{}",
self.temp_buf.len() + (need_underscore as usize)
);
if need_underscore {
self.result.push('_');
}
@@ -410,16 +424,13 @@ pub fn sanitize(result: &mut String, s: &str) -> bool {
'-' | ':' => result.push('.'),

// These are legal symbols
'a' ... 'z'
| 'A' ... 'Z'
| '0' ... '9'
| '_' | '.' | '$' => result.push(c),
'a'...'z' | 'A'...'Z' | '0'...'9' | '_' | '.' | '$' => result.push(c),

_ => {
result.push('$');
for c in c.escape_unicode().skip(1) {
match c {
'{' => {},
'{' => {}
'}' => result.push('$'),
c => result.push(c),
}
@@ -429,7 +440,6 @@ pub fn sanitize(result: &mut String, s: &str) -> bool {
}

// Underscore-qualify anything that didn't start as an ident.
!result.is_empty() &&
result.as_bytes()[0] != '_' as u8 &&
! (result.as_bytes()[0] as char).is_xid_start()
!result.is_empty() && result.as_bytes()[0] != '_' as u8
&& !(result.as_bytes()[0] as char).is_xid_start()
}
2 changes: 2 additions & 0 deletions src/librustc_passes/loops.rs
Original file line number Diff line number Diff line change
@@ -89,6 +89,8 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
self.with_context(LabeledBlock, |v| v.visit_block(&b));
}
hir::ExprBreak(label, ref opt_expr) => {
opt_expr.as_ref().map(|e| self.visit_expr(e));

if self.require_label_in_labeled_block(e.span, &label, "break") {
// If we emitted an error about an unlabeled break in a labeled
// block, we don't need any further checking for this break any more
2 changes: 1 addition & 1 deletion src/rustllvm/llvm-rebuild-trigger
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
# The actual contents of this file do not matter, but to trigger a change on the
# build bots then the contents should be changed so git updates the mtime.
2018-04-05
2018-05-18
33 changes: 33 additions & 0 deletions src/test/ui/issue-50761.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// 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.

// Confirm that we don't accidently divide or mod by zero in llvm_type

// compile-pass

mod a {
pub trait A {}
}

mod b {
pub struct Builder {}

pub fn new() -> Builder {
Builder {}
}

impl Builder {
pub fn with_a(&mut self, _a: fn() -> ::a::A) {}
}
}

pub use self::b::new;

fn main() {}
18 changes: 18 additions & 0 deletions src/test/ui/issue-50802.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2018 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.

#[allow(unreachable_code)]

fn main() {
loop {
break while continue { //~ ERROR E0590
}
}
}
9 changes: 9 additions & 0 deletions src/test/ui/issue-50802.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
--> $DIR/issue-50802.rs:15:21
|
LL | break while continue { //~ ERROR E0590
| ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop

error: aborting due to previous error

For more information about this error, try `rustc --explain E0590`.
Original file line number Diff line number Diff line change
@@ -20,6 +20,11 @@ struct SoulHistory {
endless_and_singing: bool
}

struct LovelyAmbition {
lips: usize,
fire: usize
}

#[derive(Clone, Copy)]
enum Large {
Suit { case: () }
@@ -45,6 +50,10 @@ fn main() {
hours_are_suns = false;
}

let the_spirit = LovelyAmbition { lips: 1, fire: 2 };
let LovelyAmbition { lips, fire } = the_spirit;
println!("{}", lips);

let bag = Large::Suit {
case: ()
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
warning: unused variable: `i_think_continually`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:31:9
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:36:9
|
LL | let i_think_continually = 2;
| ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead
@@ -12,39 +12,39 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
= note: #[warn(unused_variables)] implied by #[warn(unused)]

warning: unused variable: `mut_unused_var`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:13
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:43:13
|
LL | let mut mut_unused_var = 1;
| ^^^^^^^^^^^^^^ help: consider using `_mut_unused_var` instead

warning: unused variable: `var`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:40:14
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:14
|
LL | let (mut var, unused_var) = (1, 2);
| ^^^ help: consider using `_var` instead

warning: unused variable: `unused_var`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:40:19
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:19
|
LL | let (mut var, unused_var) = (1, 2);
| ^^^^^^^^^^ help: consider using `_unused_var` instead

warning: unused variable: `corridors_of_light`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:42:26
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:47:26
|
LL | if let SoulHistory { corridors_of_light,
| ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _`

warning: variable `hours_are_suns` is assigned to, but never used
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:43:30
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:48:30
|
LL | mut hours_are_suns,
| ^^^^^^^^^^^^^^
|
= note: consider using `_hours_are_suns` instead

warning: value assigned to `hours_are_suns` is never read
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:9
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:50:9
|
LL | hours_are_suns = false;
| ^^^^^^^^^^^^^^
@@ -56,44 +56,50 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
| ^^^^^^
= note: #[warn(unused_assignments)] implied by #[warn(unused)]

warning: unused variable: `fire`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:54:32
|
LL | let LovelyAmbition { lips, fire } = the_spirit;
| ^^^^ help: try ignoring the field: `fire: _`

warning: unused variable: `case`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:54:23
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:63:23
|
LL | Large::Suit { case } => {}
| ^^^^ help: try ignoring the field: `case: _`

warning: unused variable: `case`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:59:24
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:68:24
|
LL | &Large::Suit { case } => {}
| ^^^^ help: try ignoring the field: `case: _`

warning: unused variable: `case`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:64:27
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:73:27
|
LL | box Large::Suit { case } => {}
| ^^^^ help: try ignoring the field: `case: _`

warning: unused variable: `case`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:69:24
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:78:24
|
LL | (Large::Suit { case },) => {}
| ^^^^ help: try ignoring the field: `case: _`

warning: unused variable: `case`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:74:24
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:83:24
|
LL | [Large::Suit { case }] => {}
| ^^^^ help: try ignoring the field: `case: _`

warning: unused variable: `case`
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:79:29
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:88:29
|
LL | Tuple(Large::Suit { case }, ()) => {}
| ^^^^ help: try ignoring the field: `case: _`

warning: variable does not need to be mutable
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:9
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:43:9
|
LL | let mut mut_unused_var = 1;
| ----^^^^^^^^^^^^^^
@@ -108,7 +114,7 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
= note: #[warn(unused_mut)] implied by #[warn(unused)]

warning: variable does not need to be mutable
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:40:10
--> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:10
|
LL | let (mut var, unused_var) = (1, 2);
| ----^^^
2 changes: 1 addition & 1 deletion src/tools/clippy