From eb525b0916e0b228000a6d3ddfb57979cd5342f6 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 7 Dec 2018 17:40:23 +0200 Subject: [PATCH] rustc: tie the 'tcx between Print and PrintCx in ty::print. --- .../infer/outlives/free_region_map.rs | 2 +- src/librustc/mir/mod.rs | 2 +- src/librustc/ty/instance.rs | 2 +- src/librustc/ty/mod.rs | 4 +- src/librustc/ty/print.rs | 16 +- src/librustc/ty/structural_impls.rs | 32 ++++ src/librustc/ty/sty.rs | 2 +- src/librustc/ty/subst.rs | 6 +- src/librustc/util/ppaux.rs | 139 ++++++++---------- src/librustc_codegen_llvm/intrinsic.rs | 4 +- 10 files changed, 115 insertions(+), 94 deletions(-) diff --git a/src/librustc/infer/outlives/free_region_map.rs b/src/librustc/infer/outlives/free_region_map.rs index 78353e52ad4..5349e990a77 100644 --- a/src/librustc/infer/outlives/free_region_map.rs +++ b/src/librustc/infer/outlives/free_region_map.rs @@ -91,7 +91,7 @@ fn is_free_or_static(r: Region<'_>) -> bool { impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> { type Lifted = FreeRegionMap<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option> { - self.relation.maybe_map(|&fr| fr.lift_to_tcx(tcx)) + self.relation.maybe_map(|&fr| tcx.lift(&fr)) .map(|relation| FreeRegionMap { relation }) } } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index b04bb5b3d01..bff07de5bcf 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2405,7 +2405,7 @@ fn fmt_tuple(fmt: &mut Formatter<'_>, places: &[Operand<'_>]) -> fmt::Result { AggregateKind::Adt(adt_def, variant, substs, _user_ty, _) => { let variant_def = &adt_def.variants[variant]; - ppaux::parameterized(fmt, substs, variant_def.did, &[])?; + ppaux::parameterized(fmt, variant_def.did, substs)?; match variant_def.ctor_kind { CtorKind::Const => Ok(()), diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index e0b7bbc68e2..0a49dea7ec1 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -175,7 +175,7 @@ pub fn requires_local<'a>( impl<'tcx> fmt::Display for Instance<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ppaux::parameterized(f, self.substs, self.def_id(), &[])?; + ppaux::parameterized(f, self.def_id(), self.substs)?; match self.def { InstanceDef::Item(_) => Ok(()), InstanceDef::VtableShim(_) => { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 23fa81f77df..dbccd60f86b 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1001,7 +1001,7 @@ pub fn const_param(&'tcx self, } /// Bounds on generics. -#[derive(Clone, Default, HashStable)] +#[derive(Clone, Default, Debug, HashStable)] pub struct GenericPredicates<'tcx> { pub parent: Option, pub predicates: Vec<(Predicate<'tcx>, Span)>, @@ -1506,7 +1506,7 @@ pub fn to_opt_type_outlives(&self) -> Option> { /// `[[], [U:Bar]]`. Now if there were some particular reference /// like `Foo`, then the `InstantiatedPredicates` would be `[[], /// [usize:Bar]]`. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct InstantiatedPredicates<'tcx> { pub predicates: Vec>, } diff --git a/src/librustc/ty/print.rs b/src/librustc/ty/print.rs index fb296519d49..a9fffa2ee87 100644 --- a/src/librustc/ty/print.rs +++ b/src/librustc/ty/print.rs @@ -56,32 +56,36 @@ pub(crate) fn prepare_late_bound_region_info(&mut self, value: &ty::Binder } pub trait Print<'tcx> { - fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '_>) -> fmt::Result; - fn print_to_string(&self, cx: &mut PrintCx<'_, '_, '_>) -> String { + fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result; + fn print_to_string(&self, cx: &mut PrintCx<'_, '_, 'tcx>) -> String { let mut result = String::new(); let _ = self.print(&mut result, cx); result } - fn print_display(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '_>) -> fmt::Result { + fn print_display( + &self, + f: &mut F, + cx: &mut PrintCx<'_, '_, 'tcx>, + ) -> fmt::Result { let old_debug = cx.is_debug; cx.is_debug = false; let result = self.print(f, cx); cx.is_debug = old_debug; result } - fn print_display_to_string(&self, cx: &mut PrintCx<'_, '_, '_>) -> String { + fn print_display_to_string(&self, cx: &mut PrintCx<'_, '_, 'tcx>) -> String { let mut result = String::new(); let _ = self.print_display(&mut result, cx); result } - fn print_debug(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '_>) -> fmt::Result { + fn print_debug(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result { let old_debug = cx.is_debug; cx.is_debug = true; let result = self.print(f, cx); cx.is_debug = old_debug; result } - fn print_debug_to_string(&self, cx: &mut PrintCx<'_, '_, '_>) -> String { + fn print_debug_to_string(&self, cx: &mut PrintCx<'_, '_, 'tcx>) -> String { let mut result = String::new(); let _ = self.print_debug(&mut result, cx); result diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index f9eb336a4a3..a19eb1d9545 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -48,7 +48,10 @@ // really meant to be folded. In general, we can only fold a fully // general `Region`. crate::ty::BoundRegion, + crate::ty::Placeholder, crate::ty::ClosureKind, + crate::ty::FreeRegion, + crate::ty::InferTy, crate::ty::IntVarValue, crate::ty::ParamConst, crate::ty::ParamTy, @@ -480,6 +483,13 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option Lift<'tcx> for ty::TypeAndMut<'a> { + type Lifted = ty::TypeAndMut<'tcx>; + ty, mutbl + } +} + BraceStructLiftImpl! { impl<'a, 'tcx> Lift<'tcx> for ty::Instance<'a> { type Lifted = ty::Instance<'tcx>; @@ -494,6 +504,28 @@ impl<'a, 'tcx> Lift<'tcx> for interpret::GlobalId<'a> { } } +// FIXME(eddyb) this is like what some of the macros above generate, +// except that macros *also* generate a foldable impl, which we don't +// want (with it we'd risk bypassing `fold_region` / `fold_const`). +impl<'tcx> Lift<'tcx> for ty::RegionKind { + type Lifted = ty::RegionKind; + fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option { + Some(self.clone()) + } +} + +impl<'a, 'tcx> Lift<'tcx> for ty::LazyConst<'a> { + type Lifted = ty::LazyConst<'tcx>; + fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { + match self { + ty::LazyConst::Evaluated(v) => Some(ty::LazyConst::Evaluated(tcx.lift(v)?)), + ty::LazyConst::Unevaluated(def_id, substs) => { + Some(ty::LazyConst::Unevaluated(*def_id, tcx.lift(substs)?)) + } + } + } +} + BraceStructLiftImpl! { impl<'a, 'tcx> Lift<'tcx> for ty::Const<'a> { type Lifted = ty::Const<'tcx>; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 20acbb5b9c7..0e4b43155d9 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -616,7 +616,7 @@ pub fn principal_def_id(&self) -> Option { #[inline] pub fn projection_bounds<'a>(&'a self) -> - impl Iterator> + 'a { + impl Iterator> + Clone + 'a { self.iter().filter_map(|predicate| { match *predicate { ExistentialPredicate::Projection(p) => Some(p), diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 38be19a71c4..85a05bb9f55 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -140,9 +140,9 @@ impl<'a, 'tcx> Lift<'tcx> for Kind<'a> { fn lift_to_tcx<'cx, 'gcx>(&self, tcx: TyCtxt<'cx, 'gcx, 'tcx>) -> Option { match self.unpack() { - UnpackedKind::Lifetime(lt) => lt.lift_to_tcx(tcx).map(|lt| lt.into()), - UnpackedKind::Type(ty) => ty.lift_to_tcx(tcx).map(|ty| ty.into()), - UnpackedKind::Const(ct) => ct.lift_to_tcx(tcx).map(|ct| ct.into()), + UnpackedKind::Lifetime(lt) => tcx.lift(<).map(|lt| lt.into()), + UnpackedKind::Type(ty) => tcx.lift(&ty).map(|ty| ty.into()), + UnpackedKind::Const(ct) => tcx.lift(&ct).map(|ct| ct.into()), } } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 6d09f72a76b..b56ce0665e9 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -14,6 +14,7 @@ use std::cell::Cell; use std::fmt; +use std::iter; use std::usize; use rustc_target::spec::abi::Abi; @@ -182,7 +183,9 @@ pub fn placeholder_highlight(&self, p: ty::PlaceholderRegion) -> Option { macro_rules! gen_display_debug_body { ( $with:path ) => { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with(|mut cx| $with(self, f, &mut cx)) + PrintCx::with(|mut cx| { + $with(&cx.tcx.lift(self).expect("could not lift for printing"), f, &mut cx) + }) } }; } @@ -215,7 +218,7 @@ impl<$($x)+> Print<'tcx> for $target { fn print( &$self, $f: &mut F, - $cx: &mut PrintCx<'_, '_, '_>, + $cx: &mut PrintCx<'_, '_, 'tcx>, ) -> fmt::Result { if $cx.is_debug $dbg else $disp @@ -227,7 +230,7 @@ impl Print<'tcx> for $target { fn print( &$self, $f: &mut F, - $cx: &mut PrintCx<'_, '_, '_>, + $cx: &mut PrintCx<'_, '_, 'tcx>, ) -> fmt::Result { if $cx.is_debug $dbg else $disp @@ -285,9 +288,9 @@ macro_rules! print { impl PrintCx<'a, 'gcx, 'tcx> { fn fn_sig(&mut self, f: &mut F, - inputs: &[Ty<'_>], + inputs: &[Ty<'tcx>], c_variadic: bool, - output: Ty<'_>) + output: Ty<'tcx>) -> fmt::Result { write!(f, "(")?; let mut inputs = inputs.iter(); @@ -308,12 +311,13 @@ fn fn_sig(&mut self, Ok(()) } - fn parameterized(&mut self, - f: &mut F, - substs: SubstsRef<'_>, - did: DefId, - projections: &[ty::ProjectionPredicate<'_>]) - -> fmt::Result { + fn parameterized( + &mut self, + f: &mut F, + did: DefId, + substs: SubstsRef<'tcx>, + projections: impl Iterator> + Clone, + ) -> fmt::Result { let key = self.tcx.def_key(did); let verbose = self.is_verbose; @@ -411,7 +415,6 @@ fn parameterized(&mut self, *has_default.unwrap_or(&false) }; if has_default { - let substs = self.tcx.lift(&substs).expect("could not lift for printing"); let types = substs.types().rev().skip(child_types); for ((def_id, has_default), actual) in type_params.zip(types) { if !has_default { @@ -428,10 +431,12 @@ fn parameterized(&mut self, print!(f, self, write("{}", self.tcx.item_path_str(path_def_id)))?; let fn_trait_kind = self.tcx.lang_items().fn_trait_kind(path_def_id); - if !verbose && fn_trait_kind.is_some() && projections.len() == 1 { - let projection_ty = projections[0].ty; + if !verbose && fn_trait_kind.is_some() { if let Tuple(ref args) = substs.type_at(1).sty { - return self.fn_sig(f, args, false, projection_ty); + let mut projections = projections.clone(); + if let (Some(proj), None) = (projections.next(), projections.next()) { + return self.fn_sig(f, args, false, proj.ty); + } } } @@ -490,7 +495,7 @@ fn parameterized(&mut self, start_or_continue(f, "<", ", ")?; print!(f, self, write("{}=", - self.tcx.associated_item(projection.projection_ty.item_def_id).ident), + self.tcx.associated_item(projection.item_def_id).ident), print_display(projection.ty))?; } @@ -530,7 +535,7 @@ fn parameterized(&mut self, Ok(()) } - fn in_binder(&mut self, f: &mut F, value: ty::Binder) -> fmt::Result + fn in_binder(&mut self, f: &mut F, value: &ty::Binder) -> fmt::Result where T: Print<'tcx> + TypeFoldable<'tcx>, F: fmt::Write { fn name_by_region_index(index: usize) -> InternedString { @@ -547,7 +552,7 @@ fn name_by_region_index(index: usize) -> InternedString { // the output. We'll probably want to tweak this over time to // decide just how much information to give. if self.binder_depth == 0 { - self.prepare_late_bound_region_info(&value); + self.prepare_late_bound_region_info(value); } let mut empty = true; @@ -562,7 +567,7 @@ fn name_by_region_index(index: usize) -> InternedString { let old_region_index = self.region_index; let mut region_index = old_region_index; - let new_value = self.tcx.replace_late_bound_regions(&value, |br| { + let new_value = self.tcx.replace_late_bound_regions(value, |br| { let _ = start_or_continue(f, "for<", ", "); let br = match br { ty::BrNamed(_, name) => { @@ -604,16 +609,15 @@ fn is_name_used(&self, name: &InternedString) -> bool { } } -pub fn parameterized(f: &mut F, - substs: SubstsRef<'_>, - did: DefId, - projections: &[ty::ProjectionPredicate<'_>]) - -> fmt::Result { - PrintCx::with(|mut cx| cx.parameterized(f, substs, did, projections)) +pub fn parameterized(f: &mut F, did: DefId, substs: SubstsRef<'_>) -> fmt::Result { + PrintCx::with(|mut cx| { + let substs = cx.tcx.lift(&substs).expect("could not lift for printing"); + cx.parameterized(f, did, substs, iter::empty()) + }) } impl<'a, 'tcx, T: Print<'tcx>> Print<'tcx> for &'a T { - fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '_>) -> fmt::Result { + fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, 'tcx>) -> fmt::Result { (*self).print(f, cx) } } @@ -628,16 +632,13 @@ fn print(&self, f: &mut F, cx: &mut PrintCx<'_, '_, '_>) -> fmt:: let mut first = true; if let Some(principal) = self.principal() { - let principal = cx.tcx - .lift(&principal) - .expect("could not lift for printing") - .with_self_ty(cx.tcx, dummy_self); - let projections = self.projection_bounds().map(|p| { - cx.tcx.lift(&p) - .expect("could not lift for printing") - .with_self_ty(cx.tcx, dummy_self) - }).collect::>(); - cx.parameterized(f, principal.substs, principal.def_id, &projections)?; + let principal = principal.with_self_ty(cx.tcx, dummy_self); + cx.parameterized( + f, + principal.def_id, + principal.substs, + self.projection_bounds(), + )?; first = false; } @@ -755,15 +756,15 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { define_print! { ('tcx) ty::ExistentialTraitRef<'tcx>, (self, f, cx) { display { - cx.parameterized(f, self.substs, self.def_id, &[]) - } - debug { let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); - let trait_ref = *cx.tcx.lift(&ty::Binder::bind(*self)) - .expect("could not lift for printing") - .with_self_ty(cx.tcx, dummy_self).skip_binder(); - cx.parameterized(f, trait_ref.substs, trait_ref.def_id, &[]) + let trait_ref = *ty::Binder::bind(*self) + .with_self_ty(cx.tcx, dummy_self) + .skip_binder(); + cx.parameterized(f, trait_ref.def_id, trait_ref.substs, iter::empty()) + } + debug { + self.print_display(f, cx) } } } @@ -957,22 +958,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } -define_print! { - ('tcx) ty::GenericPredicates<'tcx>, (self, f, cx) { - debug { - write!(f, "GenericPredicates({:?})", self.predicates) - } - } -} - -define_print! { - ('tcx) ty::InstantiatedPredicates<'tcx>, (self, f, cx) { - debug { - write!(f, "InstantiatedPredicates({:?})", self.predicates) - } - } -} - define_print! { ('tcx) ty::FnSig<'tcx>, (self, f, cx) { display { @@ -1098,8 +1083,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ] (self, f, cx) { display { - cx.in_binder(f, cx.tcx.lift(self) - .expect("could not lift for printing")) + cx.in_binder(f, self) } } } @@ -1107,7 +1091,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { define_print! { ('tcx) ty::TraitRef<'tcx>, (self, f, cx) { display { - cx.parameterized(f, self.substs, self.def_id, &[]) + cx.parameterized(f, self.def_id, self.substs, iter::empty()) } debug { // when printing out the debug representation, we don't need @@ -1117,7 +1101,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write("<"), print(self.self_ty()), write(" as "))?; - cx.parameterized(f, self.substs, self.def_id, &[])?; + cx.parameterized(f, self.def_id, self.substs, iter::empty())?; write!(f, ">") } } @@ -1166,11 +1150,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, ")") } FnDef(def_id, substs) => { - let substs = cx.tcx.lift(&substs) - .expect("could not lift for printing"); let sig = cx.tcx.fn_sig(def_id).subst(cx.tcx, substs); print!(f, cx, print(sig), write(" {{"))?; - cx.parameterized(f, substs, def_id, &[])?; + cx.parameterized(f, def_id, substs, iter::empty())?; write!(f, "}}") } FnPtr(ref bare_fn) => { @@ -1192,7 +1174,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ty::BoundTyKind::Param(p) => write!(f, "{}", p), } } - Adt(def, substs) => cx.parameterized(f, substs, def.did, &[]), + Adt(def, substs) => cx.parameterized(f, def.did, substs, iter::empty()), Dynamic(data, r) => { let r = r.print_to_string(cx); if !r.is_empty() { @@ -1206,7 +1188,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Ok(()) } } - Foreign(def_id) => parameterized(f, subst::InternalSubsts::empty(), def_id, &[]), + Foreign(def_id) => { + cx.parameterized(f, def_id, subst::InternalSubsts::empty(), iter::empty()) + } Projection(ref data) => data.print(f, cx), UnnormalizedProjection(ref data) => { write!(f, "Unnormalized(")?; @@ -1237,8 +1221,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // by looking up the projections associated with the def_id. - let substs = cx.tcx.lift(&substs) - .expect("could not lift for printing"); let bounds = cx.tcx.predicates_of(def_id).instantiate(cx.tcx, substs); let mut first = true; @@ -1305,8 +1287,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { print!(f, cx, write(" "), print(witness), write("]")) }, GeneratorWitness(types) => { - cx.in_binder(f, cx.tcx.lift(&types) - .expect("could not lift for printing")) + cx.in_binder(f, &types) } Closure(did, substs) => { let upvar_tys = substs.upvar_tys(did, cx.tcx); @@ -1347,8 +1328,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, " closure_kind_ty={:?} closure_sig_ty={:?}", - substs.closure_kind_ty(did, tcx), - substs.closure_sig_ty(did, tcx), + substs.closure_kind_ty(did, cx.tcx), + substs.closure_sig_ty(did, cx.tcx), )?; } @@ -1435,8 +1416,12 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } -define_print! { - ('tcx, T: Print<'tcx> + fmt::Debug, U: Print<'tcx> + fmt::Debug) ty::OutlivesPredicate, +// Similar problem to `Binder`, can't define a generic impl. +define_print_multi! { + [ + ('tcx) ty::OutlivesPredicate, ty::Region<'tcx>>, + ('tcx) ty::OutlivesPredicate, ty::Region<'tcx>> + ] (self, f, cx) { display { print!(f, cx, print(self.0), write(" : "), print(self.1)) @@ -1524,7 +1509,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } ty::Predicate::ConstEvaluatable(def_id, substs) => { write!(f, "the constant `")?; - cx.parameterized(f, substs, def_id, &[])?; + cx.parameterized(f, def_id, substs, iter::empty())?; write!(f, "` can be evaluated") } } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 12edb3a0907..ceb08f94367 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -1903,7 +1903,7 @@ macro_rules! arith { return_error!( "expected element type `{}` of vector type `{}` \ to be a signed or unsigned integer type", - arg_tys[0].simd_type(tcx).sty, arg_tys[0] + arg_tys[0].simd_type(tcx), arg_tys[0] ); } }; @@ -1955,7 +1955,7 @@ fn int_type_width_signed(ty: Ty<'_>, cx: &CodegenCx<'_, '_>) -> Option<(u64, boo // Returns the width of a float Ty // Returns None if the type is not a float -fn float_type_width(ty: Ty) -> Option { +fn float_type_width(ty: Ty<'_>) -> Option { match ty.sty { ty::Float(t) => Some(t.bit_width() as u64), _ => None, -- 2.44.0