From f2b9b2d13bb14dd80d5bacbbb63d9d5cc6003a35 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Thu, 23 May 2019 13:48:27 -0500 Subject: [PATCH] move DefPathBasedNames to ty::print::obsolete --- src/librustc/ty/print/mod.rs | 1 + src/librustc/ty/print/obsolete.rs | 286 ++++++++++++++++++++ src/librustc_codegen_llvm/type_of.rs | 2 +- src/librustc_codegen_ssa/base.rs | 1 + src/librustc_mir/monomorphize/collector.rs | 3 +- src/librustc_mir/monomorphize/item.rs | 300 +-------------------- 6 files changed, 296 insertions(+), 297 deletions(-) create mode 100644 src/librustc/ty/print/obsolete.rs diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index 53d4466cfef68..a3986f7c055e6 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashSet; // `pretty` is a separate module only for organization. mod pretty; +pub mod obsolete; pub use self::pretty::*; pub trait Print<'gcx, 'tcx, P> { diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc/ty/print/obsolete.rs new file mode 100644 index 0000000000000..85d338699b0e0 --- /dev/null +++ b/src/librustc/ty/print/obsolete.rs @@ -0,0 +1,286 @@ +//! Allows for producing a unique string key for a mono item. +//! These keys are used by the handwritten auto-tests, so they need to be +//! predictable and human-readable. +//! +//! Note: A lot of this could looks very similar to what's already in `ty::print`. +//! FIXME(eddyb) implement a custom `PrettyPrinter` for this. + +use rustc::hir::def_id::DefId; +use rustc::mir::interpret::ConstValue; +use rustc::ty::subst::SubstsRef; +use rustc::ty::{self, ClosureSubsts, Const, GeneratorSubsts, Instance, Ty, TyCtxt}; +use rustc::{bug, hir}; +use std::fmt::Write; +use std::iter; +use syntax::ast; + +/// Same as `unique_type_name()` but with the result pushed onto the given +/// `output` parameter. +pub struct DefPathBasedNames<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + omit_disambiguators: bool, + omit_local_crate_name: bool, +} + +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, omit_disambiguators, omit_local_crate_name } + } + + // Pushes the type name of the specified type to the provided string. + // If `debug` is true, printing normally unprintable types is allowed + // (e.g. `ty::GeneratorWitness`). This parameter should only be set when + // this method is being used for logging purposes (e.g. with `debug!` or `info!`) + // When being used for codegen purposes, `debug` should be set to `false` + // in order to catch unexpected types that should never end up in a type name. + pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) { + match t.sty { + ty::Bool => output.push_str("bool"), + ty::Char => output.push_str("char"), + ty::Str => output.push_str("str"), + ty::Never => output.push_str("!"), + ty::Int(ast::IntTy::Isize) => output.push_str("isize"), + ty::Int(ast::IntTy::I8) => output.push_str("i8"), + ty::Int(ast::IntTy::I16) => output.push_str("i16"), + ty::Int(ast::IntTy::I32) => output.push_str("i32"), + ty::Int(ast::IntTy::I64) => output.push_str("i64"), + ty::Int(ast::IntTy::I128) => output.push_str("i128"), + ty::Uint(ast::UintTy::Usize) => output.push_str("usize"), + ty::Uint(ast::UintTy::U8) => output.push_str("u8"), + ty::Uint(ast::UintTy::U16) => output.push_str("u16"), + ty::Uint(ast::UintTy::U32) => output.push_str("u32"), + ty::Uint(ast::UintTy::U64) => output.push_str("u64"), + ty::Uint(ast::UintTy::U128) => output.push_str("u128"), + ty::Float(ast::FloatTy::F32) => output.push_str("f32"), + ty::Float(ast::FloatTy::F64) => output.push_str("f64"), + ty::Adt(adt_def, substs) => { + self.push_def_path(adt_def.did, output); + self.push_generic_params(substs, iter::empty(), output, debug); + } + ty::Tuple(component_types) => { + output.push('('); + for &component_type in component_types { + self.push_type_name(component_type.expect_ty(), output, debug); + output.push_str(", "); + } + if !component_types.is_empty() { + output.pop(); + output.pop(); + } + output.push(')'); + } + ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl }) => { + output.push('*'); + match mutbl { + hir::MutImmutable => output.push_str("const "), + hir::MutMutable => output.push_str("mut "), + } + + self.push_type_name(inner_type, output, debug); + } + ty::Ref(_, inner_type, mutbl) => { + output.push('&'); + if mutbl == hir::MutMutable { + output.push_str("mut "); + } + + self.push_type_name(inner_type, output, debug); + } + ty::Array(inner_type, len) => { + output.push('['); + self.push_type_name(inner_type, output, debug); + write!(output, "; {}", len.unwrap_usize(self.tcx)).unwrap(); + output.push(']'); + } + ty::Slice(inner_type) => { + output.push('['); + self.push_type_name(inner_type, output, debug); + output.push(']'); + } + ty::Dynamic(ref trait_data, ..) => { + if let Some(principal) = trait_data.principal() { + self.push_def_path(principal.def_id(), output); + self.push_generic_params( + principal.skip_binder().substs, + trait_data.projection_bounds(), + output, + debug, + ); + } else { + output.push_str("dyn '_"); + } + } + ty::Foreign(did) => self.push_def_path(did, output), + ty::FnDef(..) | ty::FnPtr(_) => { + let sig = t.fn_sig(self.tcx); + if sig.unsafety() == hir::Unsafety::Unsafe { + output.push_str("unsafe "); + } + + let abi = sig.abi(); + if abi != ::rustc_target::spec::abi::Abi::Rust { + output.push_str("extern \""); + output.push_str(abi.name()); + output.push_str("\" "); + } + + output.push_str("fn("); + + let sig = + self.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); + + if !sig.inputs().is_empty() { + for ¶meter_type in sig.inputs() { + self.push_type_name(parameter_type, output, debug); + output.push_str(", "); + } + output.pop(); + output.pop(); + } + + if sig.c_variadic { + if !sig.inputs().is_empty() { + output.push_str(", ..."); + } else { + output.push_str("..."); + } + } + + output.push(')'); + + if !sig.output().is_unit() { + output.push_str(" -> "); + self.push_type_name(sig.output(), output, debug); + } + } + ty::Generator(def_id, GeneratorSubsts { ref substs }, _) + | ty::Closure(def_id, ClosureSubsts { ref substs }) => { + self.push_def_path(def_id, output); + let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id)); + let substs = substs.truncate_to(self.tcx, generics); + self.push_generic_params(substs, iter::empty(), output, debug); + } + ty::Error + | ty::Bound(..) + | ty::Infer(_) + | ty::Placeholder(..) + | ty::UnnormalizedProjection(..) + | ty::Projection(..) + | ty::Param(_) + | ty::GeneratorWitness(_) + | ty::Opaque(..) => { + if debug { + output.push_str(&format!("`{:?}`", t)); + } else { + bug!( + "DefPathBasedNames: trying to create type name for unexpected type: {:?}", + t, + ); + } + } + } + } + + // Pushes the the name of the specified const to the provided string. + // If `debug` is true, usually-unprintable consts (such as `Infer`) will be printed, + // as well as the unprintable types of constants (see `push_type_name` for more details). + pub fn push_const_name(&self, c: &Const<'tcx>, output: &mut String, debug: bool) { + match c.val { + ConstValue::Scalar(..) | ConstValue::Slice { .. } | ConstValue::ByRef(..) => { + // FIXME(const_generics): we could probably do a better job here. + write!(output, "{:?}", c).unwrap() + } + _ => { + if debug { + write!(output, "{:?}", c).unwrap() + } else { + bug!( + "DefPathBasedNames: trying to create const name for unexpected const: {:?}", + c, + ); + } + } + } + output.push_str(": "); + self.push_type_name(c.ty, output, debug); + } + + pub fn push_def_path(&self, def_id: DefId, output: &mut String) { + let def_path = self.tcx.def_path(def_id); + + // some_crate:: + if !(self.omit_local_crate_name && def_id.is_local()) { + output.push_str(&self.tcx.crate_name(def_path.krate).as_str()); + output.push_str("::"); + } + + // 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(); + } + } + + // remove final "::" + output.pop(); + output.pop(); + } + + fn push_generic_params( + &self, + substs: SubstsRef<'tcx>, + projections: I, + output: &mut String, + debug: bool, + ) where + I: Iterator>, + { + let mut projections = projections.peekable(); + if substs.non_erasable_generics().next().is_none() && projections.peek().is_none() { + return; + } + + output.push('<'); + + for type_parameter in substs.types() { + self.push_type_name(type_parameter, output, debug); + output.push_str(", "); + } + + for projection in projections { + let projection = projection.skip_binder(); + let name = &self.tcx.associated_item(projection.item_def_id).ident.as_str(); + output.push_str(name); + output.push_str("="); + self.push_type_name(projection.ty, output, debug); + output.push_str(", "); + } + + for const_parameter in substs.consts() { + self.push_const_name(const_parameter, output, debug); + output.push_str(", "); + } + + output.pop(); + output.pop(); + + output.push('>'); + } + + pub fn push_instance_as_string( + &self, + instance: Instance<'tcx>, + output: &mut String, + debug: bool, + ) { + self.push_def_path(instance.def_id(), output); + self.push_generic_params(instance.substs, iter::empty(), output, debug); + } +} diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index 800bf505125d6..7a82fd731f604 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -4,7 +4,7 @@ use crate::type_::Type; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::layout::{self, Align, LayoutOf, FnTypeExt, PointeeInfo, Size, TyLayout}; use rustc_target::abi::{FloatTy, TyLayoutMethods}; -use rustc_mir::monomorphize::item::DefPathBasedNames; +use rustc::ty::print::obsolete::DefPathBasedNames; use rustc_codegen_ssa::traits::*; use std::fmt::Write; diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 2f134e6e358b6..fc3d0712fca5a 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -24,6 +24,7 @@ use rustc::mir::mono::{CodegenUnitNameBuilder, CodegenUnit}; use rustc::ty::{self, Ty, TyCtxt, Instance}; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; use rustc::ty::query::Providers; +use rustc::ty::print::obsolete::DefPathBasedNames; use rustc::middle::cstore::{self, LinkagePreference}; use rustc::util::common::{time, print_time_passes_entry}; use rustc::session::config::{self, EntryFnType, Lto}; diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index b808f64b0077f..2fc42098669ea 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -182,6 +182,7 @@ use rustc::mir::interpret::{AllocId, ConstValue}; use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem}; use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind, Instance}; +use rustc::ty::print::obsolete::DefPathBasedNames; use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc::session::config::EntryFnType; use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind}; @@ -193,7 +194,7 @@ use crate::monomorphize; use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; use rustc::util::common::time; -use crate::monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMode}; +use crate::monomorphize::item::{MonoItemExt, InstantiationMode}; use rustc_data_structures::bit_set::GrowableBitSet; use rustc_data_structures::sync::{MTRef, MTLock, ParallelIterator, par_iter}; diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index c685283b3dc0a..d60d0fe9114d3 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -1,14 +1,11 @@ -use rustc::hir; -use rustc::hir::def_id::{DefId, LOCAL_CRATE}; -use rustc::mir::interpret::ConstValue; +use rustc::hir::def_id::LOCAL_CRATE; use rustc::mir::mono::MonoItem; use rustc::session::config::OptLevel; -use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts, Instance}; -use rustc::ty::subst::{SubstsRef, InternalSubsts}; -use syntax::ast; +use rustc::ty::{self, TyCtxt, Instance}; +use rustc::ty::subst::InternalSubsts; +use rustc::ty::print::obsolete::DefPathBasedNames; use syntax::attr::InlineAttr; -use std::fmt::{self, Write}; -use std::iter; +use std::fmt; use rustc::mir::mono::Linkage; use syntax_pos::symbol::InternedString; use syntax::source_map::Span; @@ -206,290 +203,3 @@ impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { self } } - -//=----------------------------------------------------------------------------- -// MonoItem String Keys -//=----------------------------------------------------------------------------- - -// The code below allows for producing a unique string key for a mono item. -// These keys are used by the handwritten auto-tests, so they need to be -// predictable and human-readable. -// -// Note: A lot of this could looks very similar to what's already in `ty::print`. -// FIXME(eddyb) implement a custom `PrettyPrinter` for this. - -/// Same as `unique_type_name()` but with the result pushed onto the given -/// `output` parameter. -pub struct DefPathBasedNames<'a, 'tcx: 'a> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, - omit_disambiguators: bool, - omit_local_crate_name: bool, -} - -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, - omit_disambiguators, - omit_local_crate_name, - } - } - - // Pushes the type name of the specified type to the provided string. - // If `debug` is true, printing normally unprintable types is allowed - // (e.g. `ty::GeneratorWitness`). This parameter should only be set when - // this method is being used for logging purposes (e.g. with `debug!` or `info!`) - // When being used for codegen purposes, `debug` should be set to `false` - // in order to catch unexpected types that should never end up in a type name. - pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) { - match t.sty { - ty::Bool => output.push_str("bool"), - ty::Char => output.push_str("char"), - ty::Str => output.push_str("str"), - ty::Never => output.push_str("!"), - ty::Int(ast::IntTy::Isize) => output.push_str("isize"), - ty::Int(ast::IntTy::I8) => output.push_str("i8"), - ty::Int(ast::IntTy::I16) => output.push_str("i16"), - ty::Int(ast::IntTy::I32) => output.push_str("i32"), - ty::Int(ast::IntTy::I64) => output.push_str("i64"), - ty::Int(ast::IntTy::I128) => output.push_str("i128"), - ty::Uint(ast::UintTy::Usize) => output.push_str("usize"), - ty::Uint(ast::UintTy::U8) => output.push_str("u8"), - ty::Uint(ast::UintTy::U16) => output.push_str("u16"), - ty::Uint(ast::UintTy::U32) => output.push_str("u32"), - ty::Uint(ast::UintTy::U64) => output.push_str("u64"), - ty::Uint(ast::UintTy::U128) => output.push_str("u128"), - ty::Float(ast::FloatTy::F32) => output.push_str("f32"), - ty::Float(ast::FloatTy::F64) => output.push_str("f64"), - ty::Adt(adt_def, substs) => { - self.push_def_path(adt_def.did, output); - self.push_generic_params(substs, iter::empty(), output, debug); - }, - ty::Tuple(component_types) => { - output.push('('); - for &component_type in component_types { - self.push_type_name(component_type.expect_ty(), output, debug); - output.push_str(", "); - } - if !component_types.is_empty() { - output.pop(); - output.pop(); - } - output.push(')'); - }, - ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => { - output.push('*'); - match mutbl { - hir::MutImmutable => output.push_str("const "), - hir::MutMutable => output.push_str("mut "), - } - - self.push_type_name(inner_type, output, debug); - }, - ty::Ref(_, inner_type, mutbl) => { - output.push('&'); - if mutbl == hir::MutMutable { - output.push_str("mut "); - } - - self.push_type_name(inner_type, output, debug); - }, - ty::Array(inner_type, len) => { - output.push('['); - self.push_type_name(inner_type, output, debug); - write!(output, "; {}", len.unwrap_usize(self.tcx)).unwrap(); - output.push(']'); - }, - ty::Slice(inner_type) => { - output.push('['); - self.push_type_name(inner_type, output, debug); - output.push(']'); - }, - ty::Dynamic(ref trait_data, ..) => { - if let Some(principal) = trait_data.principal() { - self.push_def_path(principal.def_id(), output); - self.push_generic_params( - principal.skip_binder().substs, - trait_data.projection_bounds(), - output, - debug - ); - } else { - output.push_str("dyn '_"); - } - }, - ty::Foreign(did) => self.push_def_path(did, output), - ty::FnDef(..) | - ty::FnPtr(_) => { - let sig = t.fn_sig(self.tcx); - if sig.unsafety() == hir::Unsafety::Unsafe { - output.push_str("unsafe "); - } - - let abi = sig.abi(); - if abi != ::rustc_target::spec::abi::Abi::Rust { - output.push_str("extern \""); - output.push_str(abi.name()); - output.push_str("\" "); - } - - output.push_str("fn("); - - let sig = self.tcx.normalize_erasing_late_bound_regions( - ty::ParamEnv::reveal_all(), - &sig, - ); - - if !sig.inputs().is_empty() { - for ¶meter_type in sig.inputs() { - self.push_type_name(parameter_type, output, debug); - output.push_str(", "); - } - output.pop(); - output.pop(); - } - - if sig.c_variadic { - if !sig.inputs().is_empty() { - output.push_str(", ..."); - } else { - output.push_str("..."); - } - } - - output.push(')'); - - if !sig.output().is_unit() { - output.push_str(" -> "); - self.push_type_name(sig.output(), output, debug); - } - }, - ty::Generator(def_id, GeneratorSubsts { ref substs }, _) | - ty::Closure(def_id, ClosureSubsts { ref substs }) => { - self.push_def_path(def_id, output); - let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id)); - let substs = substs.truncate_to(self.tcx, generics); - self.push_generic_params(substs, iter::empty(), output, debug); - } - ty::Error | - ty::Bound(..) | - ty::Infer(_) | - ty::Placeholder(..) | - ty::UnnormalizedProjection(..) | - ty::Projection(..) | - ty::Param(_) | - ty::GeneratorWitness(_) | - ty::Opaque(..) => { - if debug { - output.push_str(&format!("`{:?}`", t)); - } else { - bug!( - "DefPathBasedNames: trying to create type name for unexpected type: {:?}", - t, - ); - } - } - } - } - - // Pushes the the name of the specified const to the provided string. - // If `debug` is true, usually-unprintable consts (such as `Infer`) will be printed, - // as well as the unprintable types of constants (see `push_type_name` for more details). - pub fn push_const_name(&self, c: &Const<'tcx>, output: &mut String, debug: bool) { - match c.val { - ConstValue::Scalar(..) | ConstValue::Slice { .. } | ConstValue::ByRef(..) => { - // FIXME(const_generics): we could probably do a better job here. - write!(output, "{:?}", c).unwrap() - } - _ => { - if debug { - write!(output, "{:?}", c).unwrap() - } else { - bug!( - "DefPathBasedNames: trying to create const name for unexpected const: {:?}", - c, - ); - } - } - } - output.push_str(": "); - self.push_type_name(c.ty, output, debug); - } - - pub fn push_def_path(&self, - def_id: DefId, - output: &mut String) { - let def_path = self.tcx.def_path(def_id); - - // some_crate:: - if !(self.omit_local_crate_name && def_id.is_local()) { - output.push_str(&self.tcx.crate_name(def_path.krate).as_str()); - output.push_str("::"); - } - - // 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(); - } - } - - // remove final "::" - output.pop(); - output.pop(); - } - - fn push_generic_params( - &self, - substs: SubstsRef<'tcx>, - projections: I, - output: &mut String, - debug: bool, - ) where I: Iterator> { - let mut projections = projections.peekable(); - if substs.non_erasable_generics().next().is_none() && projections.peek().is_none() { - return; - } - - output.push('<'); - - for type_parameter in substs.types() { - self.push_type_name(type_parameter, output, debug); - output.push_str(", "); - } - - for projection in projections { - let projection = projection.skip_binder(); - let name = &self.tcx.associated_item(projection.item_def_id).ident.as_str(); - output.push_str(name); - output.push_str("="); - self.push_type_name(projection.ty, output, debug); - output.push_str(", "); - } - - for const_parameter in substs.consts() { - self.push_const_name(const_parameter, output, debug); - output.push_str(", "); - } - - output.pop(); - output.pop(); - - output.push('>'); - } - - pub fn push_instance_as_string(&self, - instance: Instance<'tcx>, - output: &mut String, - debug: bool) { - self.push_def_path(instance.def_id(), output); - self.push_generic_params(instance.substs, iter::empty(), output, debug); - } -}