diff --git a/src/librustc_data_structures/base_n.rs b/src/librustc_data_structures/base_n.rs new file mode 100644 index 0000000000000..bf3e682f86f69 --- /dev/null +++ b/src/librustc_data_structures/base_n.rs @@ -0,0 +1,64 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/// Convert unsigned integers into a string representation with some base. +/// Bases up to and including 36 can be used for case-insensitive things. + +use std::str; + +pub const MAX_BASE: u64 = 64; +const BASE_64: &'static [u8; MAX_BASE as usize] = + b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@$"; + +#[inline] +pub fn push_str(mut n: u64, base: u64, output: &mut String) { + debug_assert!(base >= 2 && base <= MAX_BASE); + let mut s = [0u8; 64]; + let mut index = 0; + + loop { + s[index] = BASE_64[(n % base) as usize]; + index += 1; + n /= base; + + if n == 0 { + break; + } + } + &mut s[0..index].reverse(); + output.push_str(str::from_utf8(&s[0..index]).unwrap()); +} + +#[inline] +pub fn encode(n: u64, base: u64) -> String { + let mut s = String::with_capacity(13); + push_str(n, base, &mut s); + s +} + +#[test] +fn test_encode() { + fn test(n: u64, base: u64) { + assert_eq!(Ok(n), u64::from_str_radix(&encode(n, base)[..], base as u32)); + } + + for base in 2..37 { + test(0, base); + test(1, base); + test(35, base); + test(36, base); + test(37, base); + test(u64::max_value(), base); + + for i in 0 .. 1_000 { + test(i * 983, base); + } + } +} diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 2e4206d2ee1ee..de13b9bf4be10 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -47,6 +47,7 @@ extern crate libc; pub mod array_vec; pub mod accumulate_vec; pub mod small_vec; +pub mod base_n; pub mod bitslice; pub mod blake2b; pub mod bitvec; diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs index ca9c119202322..223200957cb7c 100644 --- a/src/librustc_incremental/persist/fs.rs +++ b/src/librustc_incremental/persist/fs.rs @@ -119,7 +119,7 @@ use rustc::hir::svh::Svh; use rustc::session::Session; use rustc::ty::TyCtxt; use rustc::util::fs as fs_util; -use rustc_data_structures::flock; +use rustc_data_structures::{flock, base_n}; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use std::ffi::OsString; @@ -135,6 +135,12 @@ const DEP_GRAPH_FILENAME: &'static str = "dep-graph.bin"; const WORK_PRODUCTS_FILENAME: &'static str = "work-products.bin"; const METADATA_HASHES_FILENAME: &'static str = "metadata.bin"; +// We encode integers using the following base, so they are shorter than decimal +// or hexadecimal numbers (we want short file and directory names). Since these +// numbers will be used in file names, we choose an encoding that is not +// case-sensitive (as opposed to base64, for example). +const INT_ENCODE_BASE: u64 = 36; + pub fn dep_graph_path(sess: &Session) -> PathBuf { in_incr_comp_dir_sess(sess, DEP_GRAPH_FILENAME) } @@ -327,7 +333,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) { let mut new_sub_dir_name = String::from(&old_sub_dir_name[.. dash_indices[2] + 1]); // Append the svh - new_sub_dir_name.push_str(&encode_base_36(svh.as_u64())); + base_n::push_str(svh.as_u64(), INT_ENCODE_BASE, &mut new_sub_dir_name); // Create the full path let new_path = incr_comp_session_dir.parent().unwrap().join(new_sub_dir_name); @@ -433,7 +439,8 @@ fn generate_session_dir_path(crate_dir: &Path) -> PathBuf { let directory_name = format!("s-{}-{}-working", timestamp, - encode_base_36(random_number as u64)); + base_n::encode(random_number as u64, + INT_ENCODE_BASE)); debug!("generate_session_dir_path: directory_name = {}", directory_name); let directory_path = crate_dir.join(directory_name); debug!("generate_session_dir_path: directory_path = {}", directory_path.display()); @@ -562,27 +569,11 @@ fn extract_timestamp_from_session_dir(directory_name: &str) string_to_timestamp(&directory_name[dash_indices[0]+1 .. dash_indices[1]]) } -const BASE_36: &'static [u8] = b"0123456789abcdefghijklmnopqrstuvwxyz"; - -fn encode_base_36(mut n: u64) -> String { - let mut s = Vec::with_capacity(13); - loop { - s.push(BASE_36[(n % 36) as usize]); - n /= 36; - - if n == 0 { - break; - } - } - s.reverse(); - String::from_utf8(s).unwrap() -} - fn timestamp_to_string(timestamp: SystemTime) -> String { let duration = timestamp.duration_since(UNIX_EPOCH).unwrap(); let micros = duration.as_secs() * 1_000_000 + (duration.subsec_nanos() as u64) / 1000; - encode_base_36(micros) + base_n::encode(micros, INT_ENCODE_BASE) } fn string_to_timestamp(s: &str) -> Result { @@ -629,7 +620,7 @@ pub fn find_metadata_hashes_for(tcx: TyCtxt, cnum: CrateNum) -> Option }; let target_svh = tcx.sess.cstore.crate_hash(cnum); - let target_svh = encode_base_36(target_svh.as_u64()); + let target_svh = base_n::encode(target_svh.as_u64(), INT_ENCODE_BASE); let sub_dir = find_metadata_hashes_iter(&target_svh, dir_entries.filter_map(|e| { e.ok().map(|e| e.file_name().to_string_lossy().into_owned()) @@ -677,7 +668,9 @@ fn crate_path(sess: &Session, let mut hasher = DefaultHasher::new(); crate_disambiguator.hash(&mut hasher); - let crate_name = format!("{}-{}", crate_name, encode_base_36(hasher.finish())); + let crate_name = format!("{}-{}", + crate_name, + base_n::encode(hasher.finish(), INT_ENCODE_BASE)); incr_dir.join(crate_name) } @@ -1049,21 +1042,3 @@ fn test_find_metadata_hashes_iter() None ); } - -#[test] -fn test_encode_base_36() { - fn test(n: u64) { - assert_eq!(Ok(n), u64::from_str_radix(&encode_base_36(n)[..], 36)); - } - - test(0); - test(1); - test(35); - test(36); - test(37); - test(u64::max_value()); - - for i in 0 .. 1_000 { - test(i * 983); - } -} diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index c7cad6455bc30..0c0b7fbf4afea 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -74,7 +74,7 @@ use monomorphize::{self, Instance}; use partitioning::{self, PartitioningStrategy, CodegenUnit}; use symbol_map::SymbolMap; use symbol_names_test; -use trans_item::TransItem; +use trans_item::{TransItem, DefPathBasedNames}; use type_::Type; use type_of; use value::Value; @@ -1004,7 +1004,15 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> { } pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance<'tcx>) { - let _s = StatRecorder::new(ccx, ccx.tcx().item_path_str(instance.def)); + let _s = if ccx.sess().trans_stats() { + let mut instance_name = String::new(); + DefPathBasedNames::new(ccx.tcx(), true, true) + .push_def_path(instance.def, &mut instance_name); + Some(StatRecorder::new(ccx, instance_name)) + } else { + None + }; + // this is an info! to allow collecting monomorphization statistics // and to allow finding the last function before LLVM aborts from // release builds. diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 2728a666556e4..0fc6436e63cd8 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -213,7 +213,7 @@ use glue::{self, DropGlueKind}; use monomorphize::{self, Instance}; use util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; -use trans_item::{TransItem, type_to_string, def_id_to_string}; +use trans_item::{TransItem, DefPathBasedNames}; #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] pub enum TransItemCollectionMode { @@ -1234,3 +1234,21 @@ fn visit_mir_and_promoted<'tcx, V: MirVisitor<'tcx>>(mut visitor: V, mir: &mir:: visitor.visit_mir(promoted); } } + +fn def_id_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId) + -> String { + let mut output = String::new(); + let printer = DefPathBasedNames::new(tcx, false, false); + printer.push_def_path(def_id, &mut output); + output +} + +fn type_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + ty: ty::Ty<'tcx>) + -> String { + let mut output = String::new(); + let printer = DefPathBasedNames::new(tcx, false, false); + printer.push_type_name(ty, &mut output); + output +} diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 3930bcbdd9aea..7657fc7d1c8b0 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -26,6 +26,7 @@ use monomorphize::Instance; use partitioning::CodegenUnit; use trans_item::TransItem; use type_::Type; +use rustc_data_structures::base_n; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt}; use session::config::NoDebugInfo; @@ -700,22 +701,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &self.local_ccxs[self.index] } - /// Get a (possibly) different `CrateContext` from the same - /// `SharedCrateContext`. - pub fn rotate(&'b self) -> CrateContext<'b, 'tcx> { - let (_, index) = - self.local_ccxs - .iter() - .zip(0..self.local_ccxs.len()) - .min_by_key(|&(local_ccx, _idx)| local_ccx.n_llvm_insns.get()) - .unwrap(); - CrateContext { - shared: self.shared, - index: index, - local_ccxs: &self.local_ccxs[..], - } - } - /// Either iterate over only `self`, or iterate over all `CrateContext`s in /// the `SharedCrateContext`. The iterator produces `(ccx, is_origin)` /// pairs, where `is_origin` is `true` if `ccx` is `self` and `false` @@ -975,7 +960,11 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { self.local().local_gen_sym_counter.set(idx + 1); // Include a '.' character, so there can be no accidental conflicts with // user defined names - format!("{}.{}", prefix, idx) + let mut name = String::with_capacity(prefix.len() + 6); + name.push_str(prefix); + name.push_str("."); + base_n::push_str(idx as u64, base_n::MAX_BASE, &mut name); + name } } diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index c5a7dbbcf5480..94a68de7f8670 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -34,6 +34,7 @@ use type_of; use glue; use abi::{Abi, FnType}; use back::symbol_names; +use std::fmt::Write; #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] pub enum TransItem<'tcx> { @@ -307,7 +308,8 @@ impl<'a, 'tcx> TransItem<'tcx> { DropGlueKind::Ty(_) => s.push_str("drop-glue "), DropGlueKind::TyContents(_) => s.push_str("drop-glue-contents "), }; - push_unique_type_name(tcx, dg.ty(), &mut s); + let printer = DefPathBasedNames::new(tcx, false, false); + printer.push_type_name(dg.ty(), &mut s); s } TransItem::Fn(instance) => { @@ -326,7 +328,8 @@ impl<'a, 'tcx> TransItem<'tcx> { -> String { let mut result = String::with_capacity(32); result.push_str(prefix); - push_instance_as_string(tcx, instance, &mut result); + let printer = DefPathBasedNames::new(tcx, false, false); + printer.push_instance_as_string(instance, &mut result); result } } @@ -367,209 +370,219 @@ impl<'a, 'tcx> TransItem<'tcx> { /// Same as `unique_type_name()` but with the result pushed onto the given /// `output` parameter. -pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - t: Ty<'tcx>, - output: &mut String) { - match t.sty { - ty::TyBool => output.push_str("bool"), - ty::TyChar => output.push_str("char"), - ty::TyStr => output.push_str("str"), - ty::TyNever => output.push_str("!"), - ty::TyInt(ast::IntTy::Is) => output.push_str("isize"), - ty::TyInt(ast::IntTy::I8) => output.push_str("i8"), - ty::TyInt(ast::IntTy::I16) => output.push_str("i16"), - ty::TyInt(ast::IntTy::I32) => output.push_str("i32"), - ty::TyInt(ast::IntTy::I64) => output.push_str("i64"), - ty::TyUint(ast::UintTy::Us) => output.push_str("usize"), - ty::TyUint(ast::UintTy::U8) => output.push_str("u8"), - ty::TyUint(ast::UintTy::U16) => output.push_str("u16"), - ty::TyUint(ast::UintTy::U32) => output.push_str("u32"), - ty::TyUint(ast::UintTy::U64) => output.push_str("u64"), - ty::TyFloat(ast::FloatTy::F32) => output.push_str("f32"), - ty::TyFloat(ast::FloatTy::F64) => output.push_str("f64"), - ty::TyAdt(adt_def, substs) => { - push_item_name(tcx, adt_def.did, output); - push_type_params(tcx, substs, &[], output); - }, - ty::TyTuple(component_types) => { - output.push('('); - for &component_type in component_types { - push_unique_type_name(tcx, component_type, output); - output.push_str(", "); - } - if !component_types.is_empty() { - output.pop(); - output.pop(); - } - output.push(')'); - }, - ty::TyBox(inner_type) => { - output.push_str("Box<"); - push_unique_type_name(tcx, inner_type, output); - output.push('>'); - }, - ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => { - output.push('*'); - match mutbl { - hir::MutImmutable => output.push_str("const "), - hir::MutMutable => output.push_str("mut "), - } +pub struct DefPathBasedNames<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + omit_disambiguators: bool, + omit_local_crate_name: bool, +} - push_unique_type_name(tcx, inner_type, output); - }, - ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => { - output.push('&'); - if mutbl == hir::MutMutable { - output.push_str("mut "); - } +impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { + pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, + omit_disambiguators: bool, + omit_local_crate_name: bool) + -> Self { + DefPathBasedNames { + tcx: tcx, + omit_disambiguators: omit_disambiguators, + omit_local_crate_name: omit_local_crate_name, + } + } - push_unique_type_name(tcx, inner_type, output); - }, - ty::TyArray(inner_type, len) => { - output.push('['); - push_unique_type_name(tcx, inner_type, output); - output.push_str(&format!("; {}", len)); - output.push(']'); - }, - ty::TySlice(inner_type) => { - output.push('['); - push_unique_type_name(tcx, inner_type, output); - output.push(']'); - }, - ty::TyTrait(ref trait_data) => { - push_item_name(tcx, trait_data.principal.def_id(), output); - push_type_params(tcx, - trait_data.principal.skip_binder().substs, - &trait_data.projection_bounds, - output); - }, - ty::TyFnDef(.., &ty::BareFnTy{ unsafety, abi, ref sig } ) | - ty::TyFnPtr(&ty::BareFnTy{ unsafety, abi, ref sig } ) => { - if unsafety == hir::Unsafety::Unsafe { - output.push_str("unsafe "); - } + pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String) { + match t.sty { + ty::TyBool => output.push_str("bool"), + ty::TyChar => output.push_str("char"), + ty::TyStr => output.push_str("str"), + ty::TyNever => output.push_str("!"), + ty::TyInt(ast::IntTy::Is) => output.push_str("isize"), + ty::TyInt(ast::IntTy::I8) => output.push_str("i8"), + ty::TyInt(ast::IntTy::I16) => output.push_str("i16"), + ty::TyInt(ast::IntTy::I32) => output.push_str("i32"), + ty::TyInt(ast::IntTy::I64) => output.push_str("i64"), + ty::TyUint(ast::UintTy::Us) => output.push_str("usize"), + ty::TyUint(ast::UintTy::U8) => output.push_str("u8"), + ty::TyUint(ast::UintTy::U16) => output.push_str("u16"), + ty::TyUint(ast::UintTy::U32) => output.push_str("u32"), + ty::TyUint(ast::UintTy::U64) => output.push_str("u64"), + ty::TyFloat(ast::FloatTy::F32) => output.push_str("f32"), + ty::TyFloat(ast::FloatTy::F64) => output.push_str("f64"), + ty::TyAdt(adt_def, substs) => { + self.push_def_path(adt_def.did, output); + self.push_type_params(substs, &[], output); + }, + ty::TyTuple(component_types) => { + output.push('('); + for &component_type in component_types { + self.push_type_name(component_type, output); + output.push_str(", "); + } + if !component_types.is_empty() { + output.pop(); + output.pop(); + } + output.push(')'); + }, + ty::TyBox(inner_type) => { + output.push_str("Box<"); + self.push_type_name(inner_type, output); + output.push('>'); + }, + ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => { + output.push('*'); + match mutbl { + hir::MutImmutable => output.push_str("const "), + hir::MutMutable => output.push_str("mut "), + } - if abi != ::abi::Abi::Rust { - output.push_str("extern \""); - output.push_str(abi.name()); - output.push_str("\" "); - } + self.push_type_name(inner_type, output); + }, + ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => { + output.push('&'); + if mutbl == hir::MutMutable { + output.push_str("mut "); + } - output.push_str("fn("); + self.push_type_name(inner_type, output); + }, + ty::TyArray(inner_type, len) => { + output.push('['); + self.push_type_name(inner_type, output); + write!(output, "; {}", len).unwrap(); + output.push(']'); + }, + ty::TySlice(inner_type) => { + output.push('['); + self.push_type_name(inner_type, output); + output.push(']'); + }, + ty::TyTrait(ref trait_data) => { + self.push_def_path(trait_data.principal.def_id(), output); + self.push_type_params(trait_data.principal.skip_binder().substs, + &trait_data.projection_bounds, + output); + }, + ty::TyFnDef(.., &ty::BareFnTy{ unsafety, abi, ref sig } ) | + ty::TyFnPtr(&ty::BareFnTy{ unsafety, abi, ref sig } ) => { + if unsafety == hir::Unsafety::Unsafe { + output.push_str("unsafe "); + } - let sig = tcx.erase_late_bound_regions_and_normalize(sig); - if !sig.inputs.is_empty() { - for ¶meter_type in &sig.inputs { - push_unique_type_name(tcx, parameter_type, output); - output.push_str(", "); + if abi != ::abi::Abi::Rust { + output.push_str("extern \""); + output.push_str(abi.name()); + output.push_str("\" "); } - output.pop(); - output.pop(); - } - if sig.variadic { - if !sig.inputs.is_empty() { - output.push_str(", ..."); - } else { - output.push_str("..."); + output.push_str("fn("); + + let ty::FnSig { + inputs: sig_inputs, + output: sig_output, + variadic: sig_variadic + } = self.tcx.erase_late_bound_regions_and_normalize(sig); + + if !sig_inputs.is_empty() { + for ¶meter_type in &sig_inputs { + self.push_type_name(parameter_type, output); + output.push_str(", "); + } + output.pop(); + output.pop(); + } + + if sig_variadic { + if !sig_inputs.is_empty() { + output.push_str(", ..."); + } else { + output.push_str("..."); + } } - } - output.push(')'); + output.push(')'); - if !sig.output.is_nil() { - output.push_str(" -> "); - push_unique_type_name(tcx, sig.output, output); + if !sig_output.is_nil() { + output.push_str(" -> "); + self.push_type_name(sig_output, output); + } + }, + ty::TyClosure(def_id, ref closure_substs) => { + self.push_def_path(def_id, output); + let generics = self.tcx.item_generics(self.tcx.closure_base_def_id(def_id)); + let substs = closure_substs.substs.truncate_to(self.tcx, generics); + self.push_type_params(substs, &[], output); + } + ty::TyError | + ty::TyInfer(_) | + ty::TyProjection(..) | + ty::TyParam(_) | + ty::TyAnon(..) => { + bug!("DefPathBasedNames: Trying to create type name for \ + unexpected type: {:?}", t); } - }, - ty::TyClosure(def_id, closure_substs) => { - push_item_name(tcx, def_id, output); - output.push_str("{"); - output.push_str(&format!("{}:{}", def_id.krate, def_id.index.as_usize())); - output.push_str("}"); - let generics = tcx.item_generics(tcx.closure_base_def_id(def_id)); - let substs = closure_substs.substs.truncate_to(tcx, generics); - push_type_params(tcx, substs, &[], output); - } - ty::TyError | - ty::TyInfer(_) | - ty::TyProjection(..) | - ty::TyParam(_) | - ty::TyAnon(..) => { - bug!("debuginfo: Trying to create type name for \ - unexpected type: {:?}", t); } } -} - -fn push_item_name(tcx: TyCtxt, - def_id: DefId, - output: &mut String) { - let def_path = tcx.def_path(def_id); - // some_crate:: - output.push_str(&tcx.crate_name(def_path.krate)); - output.push_str("::"); + pub fn push_def_path(&self, + def_id: DefId, + output: &mut String) { + let def_path = self.tcx.def_path(def_id); - // foo::bar::ItemName:: - for part in tcx.def_path(def_id).data { - output.push_str(&format!("{}[{}]::", - part.data.as_interned_str(), - part.disambiguator)); - } + // some_crate:: + if !(self.omit_local_crate_name && def_id.is_local()) { + output.push_str(&self.tcx.crate_name(def_path.krate)); + output.push_str("::"); + } - // remove final "::" - output.pop(); - output.pop(); -} + // foo::bar::ItemName:: + for part in self.tcx.def_path(def_id).data { + if self.omit_disambiguators { + write!(output, "{}::", part.data.as_interned_str()).unwrap(); + } else { + write!(output, "{}[{}]::", + part.data.as_interned_str(), + part.disambiguator).unwrap(); + } + } -fn push_type_params<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - substs: &Substs<'tcx>, - projections: &[ty::PolyExistentialProjection<'tcx>], - output: &mut String) { - if substs.types().next().is_none() && projections.is_empty() { - return; + // remove final "::" + output.pop(); + output.pop(); } - output.push('<'); - - for type_parameter in substs.types() { - push_unique_type_name(tcx, type_parameter, output); - output.push_str(", "); - } + pub fn push_type_params(&self, + substs: &Substs<'tcx>, + projections: &[ty::PolyExistentialProjection<'tcx>], + output: &mut String) { + if substs.types().next().is_none() && projections.is_empty() { + return; + } - for projection in projections { - let projection = projection.skip_binder(); - let name = &projection.item_name.as_str(); - output.push_str(name); - output.push_str("="); - push_unique_type_name(tcx, projection.ty, output); - output.push_str(", "); - } + output.push('<'); - output.pop(); - output.pop(); + for type_parameter in substs.types() { + self.push_type_name(type_parameter, output); + output.push_str(", "); + } - output.push('>'); -} + for projection in projections { + let projection = projection.skip_binder(); + let name = &projection.item_name.as_str(); + output.push_str(name); + output.push_str("="); + self.push_type_name(projection.ty, output); + output.push_str(", "); + } -fn push_instance_as_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - instance: Instance<'tcx>, - output: &mut String) { - push_item_name(tcx, instance.def, output); - push_type_params(tcx, instance.substs, &[], output); -} + output.pop(); + output.pop(); -pub fn def_id_to_string(tcx: TyCtxt, def_id: DefId) -> String { - let mut output = String::new(); - push_item_name(tcx, def_id, &mut output); - output -} + output.push('>'); + } -pub fn type_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - ty: Ty<'tcx>) - -> String { - let mut output = String::new(); - push_unique_type_name(tcx, ty, &mut output); - output + pub fn push_instance_as_string(&self, + instance: Instance<'tcx>, + output: &mut String) { + self.push_def_path(instance.def, output); + self.push_type_params(instance.substs, &[], output); + } } diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index dc794d5946a69..16d4f97200cb2 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -10,14 +10,12 @@ #![allow(non_camel_case_types)] -use rustc::hir::def_id::DefId; use abi::FnType; use adt; use common::*; use machine; use rustc::ty::{self, Ty, TypeFoldable}; -use rustc::ty::subst::Substs; - +use trans_item::DefPathBasedNames; use type_::Type; use syntax::ast; @@ -282,12 +280,12 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> let n = t.simd_size(cx.tcx()) as u64; Type::vector(&llet, n) } - ty::TyAdt(def, substs) => { + ty::TyAdt(..) => { // Only create the named struct, but don't fill it in. We // fill it in *after* placing it into the type cache. This // avoids creating more than one copy of the enum when one // of the enum's variants refers to the enum itself. - let name = llvm_type_name(cx, def.did, substs); + let name = llvm_type_name(cx, t); adt::incomplete_type_of(cx, t, &name[..]) } @@ -319,21 +317,9 @@ pub fn align_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) layout.align(&cx.tcx().data_layout).abi() as machine::llalign } -fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, - did: DefId, - substs: &Substs<'tcx>) - -> String { - let base = cx.tcx().item_path_str(did); - let strings: Vec = substs.types().map(|t| t.to_string()).collect(); - let tstr = if strings.is_empty() { - base - } else { - format!("{}<{}>", base, strings.join(", ")) - }; - - if did.is_local() { - tstr - } else { - format!("{}.{}", did.krate, tstr) - } +fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> String { + let mut name = String::with_capacity(32); + let printer = DefPathBasedNames::new(cx.tcx(), true, true); + printer.push_type_name(ty, &mut name); + name } diff --git a/src/test/codegen/lifetime_start_end.rs b/src/test/codegen/lifetime_start_end.rs index 81f6cf309da50..e3b35cf355250 100644 --- a/src/test/codegen/lifetime_start_end.rs +++ b/src/test/codegen/lifetime_start_end.rs @@ -27,16 +27,16 @@ pub fn test() { let b = &Some(a); &b; // keep variable in an alloca -// CHECK: [[S_b:%[0-9]+]] = bitcast %"2.std::option::Option"** %b to i8* +// CHECK: [[S_b:%[0-9]+]] = bitcast %"core::option::Option"** %b to i8* // CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S_b]]) -// CHECK: [[S__5:%[0-9]+]] = bitcast %"2.std::option::Option"* %_5 to i8* +// CHECK: [[S__5:%[0-9]+]] = bitcast %"core::option::Option"* %_5 to i8* // CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S__5]]) -// CHECK: [[E__5:%[0-9]+]] = bitcast %"2.std::option::Option"* %_5 to i8* +// CHECK: [[E__5:%[0-9]+]] = bitcast %"core::option::Option"* %_5 to i8* // CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E__5]]) -// CHECK: [[E_b:%[0-9]+]] = bitcast %"2.std::option::Option"** %b to i8* +// CHECK: [[E_b:%[0-9]+]] = bitcast %"core::option::Option"** %b to i8* // CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E_b]]) } diff --git a/src/test/incremental/change_private_fn_cc/struct_point.rs b/src/test/incremental/change_private_fn_cc/struct_point.rs index d6d2b5436ff30..ded87dd27f410 100644 --- a/src/test/incremental/change_private_fn_cc/struct_point.rs +++ b/src/test/incremental/change_private_fn_cc/struct_point.rs @@ -23,10 +23,7 @@ #![rustc_partition_reused(module="struct_point-fn_calls_methods_in_another_impl", cfg="rpass2")] #![rustc_partition_reused(module="struct_point-fn_read_field", cfg="rpass2")] #![rustc_partition_reused(module="struct_point-fn_write_field", cfg="rpass2")] - -// FIXME(#37335) -- should be reused, but an errant Krate edge causes -// it to get translated (at least I *think* this is that same problem) -#![rustc_partition_translated(module="struct_point-fn_make_struct", cfg="rpass2")] +#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")] extern crate point;