From 5e30f6b916826bd8491ad0e115e194e6a935b58c Mon Sep 17 00:00:00 2001 From: est31 Date: Thu, 17 May 2018 13:12:05 +0200 Subject: [PATCH 01/18] CheckLoopVisitor: also visit break expressions Fixes #50802 --- src/librustc_passes/loops.rs | 2 ++ src/test/ui/issue-50802.rs | 18 ++++++++++++++++++ src/test/ui/issue-50802.stderr | 9 +++++++++ 3 files changed, 29 insertions(+) create mode 100644 src/test/ui/issue-50802.rs create mode 100644 src/test/ui/issue-50802.stderr diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index 2368b1aca6948..ac37937509eac 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -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 diff --git a/src/test/ui/issue-50802.rs b/src/test/ui/issue-50802.rs new file mode 100644 index 0000000000000..6342d0757ee53 --- /dev/null +++ b/src/test/ui/issue-50802.rs @@ -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 or the MIT license +// , 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 + } + } +} diff --git a/src/test/ui/issue-50802.stderr b/src/test/ui/issue-50802.stderr new file mode 100644 index 0000000000000..9da2648b376f7 --- /dev/null +++ b/src/test/ui/issue-50802.stderr @@ -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`. From a8c2332cc890ca73911ea0133457b10bf56aefdc Mon Sep 17 00:00:00 2001 From: iancormac84 Date: Tue, 8 May 2018 07:52:01 -0400 Subject: [PATCH 02/18] Removed use of TypeIdHasher in debuginfo and replaced it with StableHasher. Also corrected erroneous mention of TypeIdHasher in implementation of HashStable trait. --- src/librustc/ich/impls_ty.rs | 2 +- src/librustc_codegen_llvm/debuginfo/metadata.rs | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 31dce2a14c2b7..eb672e9ed4b97 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -132,7 +132,7 @@ for ty::RegionKind { ty::ReLateBound(..) | ty::ReVar(..) | ty::ReSkolemized(..) => { - bug!("TypeIdHasher: unexpected region {:?}", *self) + bug!("StableHasher: unexpected region {:?}", *self) } } } diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index ee60711c11d44..4a68ac35deaa0 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -26,9 +26,7 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, 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 +142,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::::new(cx.tcx); - type_id_hasher.visit_ty(type_); - let unique_type_id = type_id_hasher.finish().to_hex(); + let mut hasher = StableHasher::::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)); From 9a746d5c1dad836c615e879b443dbf7ed73123e1 Mon Sep 17 00:00:00 2001 From: iancormac84 Date: Tue, 8 May 2018 07:58:33 -0400 Subject: [PATCH 03/18] Removed use of TypeIdHasher in symbol hash generation and replaced it with StableHasher. --- src/librustc_codegen_utils/symbol_names.rs | 27 +++++++++++----------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 1a62f39ae3d8b..0afb2f7e54b49 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -98,12 +98,13 @@ //! DefPaths which are much more robust in the face of changes to the code base. use rustc::middle::weak_lang_items; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; 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::ich::NodeIdHashingMode; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; -use rustc::ty::fold::TypeVisitor; use rustc::ty::item_path::{self, ItemPathBuffer, RootMode}; use rustc::ty::maps::Providers; use rustc::ty::subst::Substs; @@ -144,31 +145,29 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, -> u64 { debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs); - let mut hasher = ty::util::TypeIdHasher::::new(tcx); + let mut hasher = StableHasher::::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); - - // 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); - } + hcx.while_hashing_spans(false, |hcx| { + hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { + item_type.hash_stable(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 = @@ -207,8 +206,8 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, 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); } }); From 659f164167221ccd9a686dab4fe22bddca471606 Mon Sep 17 00:00:00 2001 From: iancormac84 Date: Tue, 8 May 2018 09:23:36 -0400 Subject: [PATCH 04/18] Removed TypeIdHasher. --- src/librustc/ty/util.rs | 144 ---------------------------------------- 1 file changed, 144 deletions(-) diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index d5532f8f8355a..551825cc3545c 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -615,150 +615,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, -} - -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(&mut self, x: T) { - x.hash(&mut self.state); - } - - fn hash_discriminant_u8(&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>(&mut self, x: &ty::Binder) -> 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>, From 9041d81f7880d1dbd2beee601cbc46d2889f31e6 Mon Sep 17 00:00:00 2001 From: iancormac84 Date: Tue, 8 May 2018 09:38:29 -0400 Subject: [PATCH 05/18] Code structure edits. --- src/librustc_codegen_utils/symbol_names.rs | 118 +++++++++++---------- 1 file changed, 61 insertions(+), 57 deletions(-) diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 0afb2f7e54b49..8ddefdf474fb1 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -97,19 +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_data_structures::stable_hasher::{HashStable, StableHasher}; -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::hir::map::definitions::DefPathData; use rustc::ich::NodeIdHashingMode; -use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; +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; @@ -125,25 +125,29 @@ 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 = StableHasher::::new(); let mut hcx = tcx.create_stable_hashing_context(); @@ -193,12 +197,11 @@ 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 } @@ -206,7 +209,8 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, LOCAL_CRATE }; - (&tcx.original_crate_name(instantiating_crate).as_str()[..]).hash_stable(&mut hcx, &mut hasher); + (&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); } }); @@ -215,9 +219,7 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, 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); @@ -225,20 +227,17 @@ fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) 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); @@ -258,7 +257,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) @@ -295,8 +294,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; } @@ -305,8 +303,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 + ); }); } } @@ -336,14 +338,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 @@ -352,14 +354,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 { @@ -378,7 +382,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('_'); } @@ -409,16 +417,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), } @@ -428,7 +433,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() } From ef38712f87997b87d7ad1aca653d54b47877838a Mon Sep 17 00:00:00 2001 From: iancormac84 Date: Tue, 8 May 2018 10:02:41 -0400 Subject: [PATCH 06/18] Removed unused imports. --- src/librustc/ty/util.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 551825cc3545c..5a745eeab4b80 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -30,8 +30,6 @@ use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, 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}; From 6131c0a98c8dc4739e7985940474f6ae5f0941c3 Mon Sep 17 00:00:00 2001 From: iancormac84 Date: Tue, 8 May 2018 10:58:32 -0400 Subject: [PATCH 07/18] Fix more unused imports errors. --- src/librustc/ty/util.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 5a745eeab4b80..53f82625951ce 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -26,8 +26,7 @@ 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 syntax::ast; From b79edf008f3191e28d96ed98c77fa25533c650d7 Mon Sep 17 00:00:00 2001 From: iancormac84 Date: Tue, 8 May 2018 19:57:45 -0400 Subject: [PATCH 08/18] Added extra hashing step. --- src/librustc_codegen_utils/symbol_names.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 8ddefdf474fb1..2063db6dc5331 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -168,6 +168,13 @@ fn get_symbol_hash<'a, 'tcx>( }); }); + // 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).hash_stable(&mut hcx, &mut hasher); + } + // also include any type parameters (for generic items) assert!(!substs.has_erasable_regions()); assert!(!substs.needs_subst()); From 18b032a96bcc68aa1d78aabb888b07a1fdbee3e6 Mon Sep 17 00:00:00 2001 From: iancormac84 Date: Tue, 15 May 2018 20:27:37 -0400 Subject: [PATCH 09/18] Removed unused import. --- src/librustc/ty/util.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 53f82625951ce..122cd0e707d35 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -15,7 +15,6 @@ 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; From 1839faead079a0f1e0e44e54249567ca27230c1d Mon Sep 17 00:00:00 2001 From: iancormac84 Date: Wed, 16 May 2018 02:29:15 -0400 Subject: [PATCH 10/18] Removed yet another unused import. --- src/librustc/ty/util.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 122cd0e707d35..7cfcbcb86af98 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -17,7 +17,6 @@ use hir; use ich::NodeIdHashingMode; 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::*; From 03493941fb5fa18d592da57530382f5c4b7cf2f9 Mon Sep 17 00:00:00 2001 From: iancormac84 Date: Thu, 17 May 2018 19:43:36 -0400 Subject: [PATCH 11/18] Fixed accidental removal of StableHasher declaration. --- src/librustc_codegen_llvm/debuginfo/metadata.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 4a68ac35deaa0..ae0f6067f4767 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -23,6 +23,7 @@ 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}; From 032831da7882909fc575651bd341acce360143ef Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Thu, 17 May 2018 11:13:04 +0200 Subject: [PATCH 12/18] Update LLVM to 56c931901cfb85cd6f7ed44c7d7520a8de1edf97 This brings in https://github.com/rust-lang/llvm/pull/115, which fixes https://github.com/rust-lang/rust/issues/49873. --- src/llvm | 2 +- src/rustllvm/llvm-rebuild-trigger | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/llvm b/src/llvm index 1abfd0e562cc8..56c931901cfb8 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 1abfd0e562cc8f7a9577d97ee92246699093b954 +Subproject commit 56c931901cfb85cd6f7ed44c7d7520a8de1edf97 diff --git a/src/rustllvm/llvm-rebuild-trigger b/src/rustllvm/llvm-rebuild-trigger index c3fc3e5452c4f..5a0292bb6a16e 100644 --- a/src/rustllvm/llvm-rebuild-trigger +++ b/src/rustllvm/llvm-rebuild-trigger @@ -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 \ No newline at end of file From 59782f4829db1afed5a3d50d03709711b8dd16e0 Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Fri, 18 May 2018 00:07:31 -0700 Subject: [PATCH 13/18] in which the unused shorthand field pattern debacle/saga continues In e4b1a79 (#47922), we corrected erroneous suggestions for unused shorthand field pattern bindings, suggesting `field: _` where the previous suggestion of `_field` wouldn't even have compiled (#47390). Soon, it was revealed that this was insufficient (#50303), and the fix was extended to references, slices, &c. (#50327) But even this proved inadequate, as the erroneous suggestions were still being issued for patterns in local (`let`) bindings (#50804). Here, we yank the shorthand-detection and variable/node registration code into a new common function that can be called while visiting both match arms and `let` bindings. Resolves #50804. --- src/librustc/middle/liveness.rs | 106 +++++++++--------- ...47390-unused-variable-in-struct-pattern.rs | 9 ++ ...0-unused-variable-in-struct-pattern.stderr | 36 +++--- 3 files changed, 80 insertions(+), 71 deletions(-) diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index b39311a74718f..3db8c746713fd 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -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) { + // 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); } diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs index 100fb6d3533f5..bac3f00ffc79d 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs @@ -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: () }; diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr index 992be2c0a2844..a8b0e3e4250ea 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr @@ -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,31 +12,31 @@ 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, | ^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ 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); | ----^^^ From cf1f0385a89a87fbe1ca21bf6fc4fea6bdf36365 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Fri, 18 May 2018 14:09:15 +0200 Subject: [PATCH 14/18] Reorder description for snippets in rustdoc documentation The example code snippets for the `no_run` and `compile_fail` attributes in the rustdoc documentation were followed by the description for the wrong attribute. This patch reorders the descriptions to match the code snippets. --- src/doc/rustdoc/src/documentation-tests.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index 3098587a8a4cc..fd7d1713ca574 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -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. From 8b024888349f2c28b74c6697a33572dbd0d077b0 Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Sat, 19 May 2018 01:13:31 +0000 Subject: [PATCH 15/18] Fix warning when building stage0 libcore When building stage0 a warning will be triggered when compiling libcore due to align_to_offsets not being used. --- src/libcore/slice/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index fdc9aa473e8b8..3b19a401859ee 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1698,6 +1698,7 @@ impl [T] { } /// Function to calculate lenghts of the middle and trailing slice for `align_to{,_mut}`. + #[cfg(not(stage0))] fn align_to_offsets(&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". From 387875dfe360b750da6b857131a25f89d336667d Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Sat, 19 May 2018 13:18:02 +0200 Subject: [PATCH 16/18] Update clippy --- src/Cargo.lock | 28 +++++++++++++++++++++++++--- src/Cargo.toml | 1 - src/tools/clippy | 2 +- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 70e34c34b9996..6472b450f5195 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -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" diff --git a/src/Cargo.toml b/src/Cargo.toml index 1518e8d910fc2..7504b43e20cb3 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -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" } diff --git a/src/tools/clippy b/src/tools/clippy index c658fc8cbcd1f..ebe0b0eed5962 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit c658fc8cbcd1f199edd445a49cb43139ebdc5f02 +Subproject commit ebe0b0eed596243a2839867363cb31d93f0b9754 From ecce274e56e1da80dff66f9d8886c7645f129244 Mon Sep 17 00:00:00 2001 From: cjkenn Date: Wed, 16 May 2018 20:02:01 -0700 Subject: [PATCH 17/18] use if let to avoid potential div by zero remove semicolon -_- Add rem_bytes to conditional to avoid error when performing mod by 0 Add test file to confirm compilation passes. Ensure we don't divide or mod by zero in llvm_type. Include test file from issue. --- src/librustc_codegen_llvm/abi.rs | 8 ++++++-- src/test/ui/issue-50761.rs | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/issue-50761.rs diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 25c598c532c48..221012903d999 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -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 diff --git a/src/test/ui/issue-50761.rs b/src/test/ui/issue-50761.rs new file mode 100644 index 0000000000000..534d483dc42c6 --- /dev/null +++ b/src/test/ui/issue-50761.rs @@ -0,0 +1,35 @@ +// 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 or the MIT license +// , 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 + +#![feature(test)] + +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() {} From 8d9a87c14d9c5abe433444a641282ae1afb0577d Mon Sep 17 00:00:00 2001 From: cjkenn Date: Sat, 19 May 2018 13:01:28 -0700 Subject: [PATCH 18/18] remove feature line from test --- src/test/ui/issue-50761.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/ui/issue-50761.rs b/src/test/ui/issue-50761.rs index 534d483dc42c6..b8a7a089c2313 100644 --- a/src/test/ui/issue-50761.rs +++ b/src/test/ui/issue-50761.rs @@ -12,8 +12,6 @@ // compile-pass -#![feature(test)] - mod a { pub trait A {} }