From 9c3dc7e8721c03e1e033895f327ff71f8fd400b4 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 1 Feb 2018 00:00:38 +0200 Subject: [PATCH 1/3] rustc: prefer ParamEnvAnd and LayoutCx over tuples for LayoutOf. --- src/librustc/lint/context.rs | 2 +- src/librustc/ty/layout.rs | 171 ++++++++++++--------- src/librustc_const_eval/eval.rs | 3 +- src/librustc_lint/types.rs | 4 +- src/librustc_mir/interpret/eval_context.rs | 2 +- src/librustc_mir/transform/inline.rs | 3 +- src/librustc_trans/context.rs | 3 +- src/librustc_typeck/check/mod.rs | 3 +- 8 files changed, 107 insertions(+), 84 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 5336c1944e8c4..929d5e7ec62bb 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -631,7 +631,7 @@ impl<'a, 'tcx> LayoutOf> for &'a LateContext<'a, 'tcx> { type TyLayout = Result, LayoutError<'tcx>>; fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { - (self.tcx, self.param_env.reveal_all()).layout_of(ty) + self.tcx.layout_of(self.param_env.and(ty)) } } diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 69d07eafdca7a..63b91ff110161 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -895,7 +895,8 @@ fn layout_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } tcx.layout_depth.set(depth+1); - let layout = LayoutDetails::compute_uncached(tcx, param_env, ty); + let cx = LayoutCx { tcx, param_env }; + let layout = cx.layout_raw_uncached(ty); tcx.layout_depth.set(depth); layout @@ -908,13 +909,18 @@ pub fn provide(providers: &mut ty::maps::Providers) { }; } -impl<'a, 'tcx> LayoutDetails { - fn compute_uncached(tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ty::ParamEnv<'tcx>, - ty: Ty<'tcx>) - -> Result<&'tcx Self, LayoutError<'tcx>> { - let cx = (tcx, param_env); - let dl = cx.data_layout(); +#[derive(Copy, Clone)] +pub struct LayoutCx<'tcx, C> { + pub tcx: C, + pub param_env: ty::ParamEnv<'tcx> +} + +impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { + fn layout_raw_uncached(self, ty: Ty<'tcx>) + -> Result<&'tcx LayoutDetails, LayoutError<'tcx>> { + let tcx = self.tcx; + let param_env = self.param_env; + let dl = self.data_layout(); let scalar_unit = |value: Primitive| { let bits = value.size(dl).bits(); assert!(bits <= 128); @@ -924,7 +930,7 @@ impl<'a, 'tcx> LayoutDetails { } }; let scalar = |value: Primitive| { - tcx.intern_layout(LayoutDetails::scalar(cx, scalar_unit(value))) + tcx.intern_layout(LayoutDetails::scalar(self, scalar_unit(value))) }; let scalar_pair = |a: Scalar, b: Scalar| { let align = a.value.align(dl).max(b.value.align(dl)).max(dl.aggregate_align); @@ -1158,13 +1164,13 @@ impl<'a, 'tcx> LayoutDetails { Ok(match ty.sty { // Basic scalars. ty::TyBool => { - tcx.intern_layout(LayoutDetails::scalar(cx, Scalar { + tcx.intern_layout(LayoutDetails::scalar(self, Scalar { value: Int(I8, false), valid_range: 0..=1 })) } ty::TyChar => { - tcx.intern_layout(LayoutDetails::scalar(cx, Scalar { + tcx.intern_layout(LayoutDetails::scalar(self, Scalar { value: Int(I32, false), valid_range: 0..=0x10FFFF })) @@ -1180,7 +1186,7 @@ impl<'a, 'tcx> LayoutDetails { ty::TyFnPtr(_) => { let mut ptr = scalar_unit(Pointer); ptr.valid_range.start = 1; - tcx.intern_layout(LayoutDetails::scalar(cx, ptr)) + tcx.intern_layout(LayoutDetails::scalar(self, ptr)) } // The never type. @@ -1198,13 +1204,13 @@ impl<'a, 'tcx> LayoutDetails { let pointee = tcx.normalize_associated_type_in_env(&pointee, param_env); if pointee.is_sized(tcx, param_env, DUMMY_SP) { - return Ok(tcx.intern_layout(LayoutDetails::scalar(cx, data_ptr))); + return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr))); } let unsized_part = tcx.struct_tail(pointee); let metadata = match unsized_part.sty { ty::TyForeign(..) => { - return Ok(tcx.intern_layout(LayoutDetails::scalar(cx, data_ptr))); + return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr))); } ty::TySlice(_) | ty::TyStr => { scalar_unit(Int(dl.ptr_sized_integer(), false)) @@ -1230,7 +1236,7 @@ impl<'a, 'tcx> LayoutDetails { } } - let element = cx.layout_of(element)?; + let element = self.layout_of(element)?; let count = count.val.to_const_int().unwrap().to_u64().unwrap(); let size = element.size.checked_mul(count, dl) .ok_or(LayoutError::SizeOverflow(ty))?; @@ -1247,7 +1253,7 @@ impl<'a, 'tcx> LayoutDetails { }) } ty::TySlice(element) => { - let element = cx.layout_of(element)?; + let element = self.layout_of(element)?; tcx.intern_layout(LayoutDetails { variants: Variants::Single { index: 0 }, fields: FieldPlacement::Array { @@ -1289,14 +1295,14 @@ impl<'a, 'tcx> LayoutDetails { // Tuples, generators and closures. ty::TyGenerator(def_id, ref substs, _) => { let tys = substs.field_tys(def_id, tcx); - univariant(&tys.map(|ty| cx.layout_of(ty)).collect::, _>>()?, + univariant(&tys.map(|ty| self.layout_of(ty)).collect::, _>>()?, &ReprOptions::default(), StructKind::AlwaysSized)? } ty::TyClosure(def_id, ref substs) => { let tys = substs.upvar_tys(def_id, tcx); - univariant(&tys.map(|ty| cx.layout_of(ty)).collect::, _>>()?, + univariant(&tys.map(|ty| self.layout_of(ty)).collect::, _>>()?, &ReprOptions::default(), StructKind::AlwaysSized)? } @@ -1308,13 +1314,13 @@ impl<'a, 'tcx> LayoutDetails { StructKind::MaybeUnsized }; - univariant(&tys.iter().map(|ty| cx.layout_of(ty)).collect::, _>>()?, + univariant(&tys.iter().map(|ty| self.layout_of(ty)).collect::, _>>()?, &ReprOptions::default(), kind)? } // SIMD vector types. ty::TyAdt(def, ..) if def.repr.simd() => { - let element = cx.layout_of(ty.simd_type(tcx))?; + let element = self.layout_of(ty.simd_type(tcx))?; let count = ty.simd_size(tcx) as u64; assert!(count > 0); let scalar = match element.abi { @@ -1350,7 +1356,7 @@ impl<'a, 'tcx> LayoutDetails { // Cache the field layouts. let variants = def.variants.iter().map(|v| { v.fields.iter().map(|field| { - cx.layout_of(field.ty(tcx, substs)) + self.layout_of(field.ty(tcx, substs)) }).collect::, _>>() }).collect::, _>>()?; @@ -1430,7 +1436,7 @@ impl<'a, 'tcx> LayoutDetails { let mut st = univariant_uninterned(&variants[v], &def.repr, kind)?; st.variants = Variants::Single { index: v }; // Exclude 0 from the range of a newtype ABI NonZero. - if Some(def.did) == cx.tcx().lang_items().non_zero() { + if Some(def.did) == self.tcx.lang_items().non_zero() { match st.abi { Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => { @@ -1482,7 +1488,7 @@ impl<'a, 'tcx> LayoutDetails { let count = (niche_variants.end - niche_variants.start + 1) as u128; for (field_index, field) in variants[i].iter().enumerate() { let (offset, niche, niche_start) = - match field.find_niche(cx, count)? { + match field.find_niche(self, count)? { Some(niche) => niche, None => continue }; @@ -1687,56 +1693,49 @@ impl<'a, 'tcx> LayoutDetails { /// This is invoked by the `layout_raw` query to record the final /// layout of each type. #[inline] - fn record_layout_for_printing(tcx: TyCtxt<'a, 'tcx, 'tcx>, - ty: Ty<'tcx>, - param_env: ty::ParamEnv<'tcx>, - layout: TyLayout<'tcx>) { + fn record_layout_for_printing(self, layout: TyLayout<'tcx>) { // If we are running with `-Zprint-type-sizes`, record layouts for // dumping later. Ignore layouts that are done with non-empty // environments or non-monomorphic layouts, as the user only wants // to see the stuff resulting from the final trans session. if - !tcx.sess.opts.debugging_opts.print_type_sizes || - ty.has_param_types() || - ty.has_self_ty() || - !param_env.caller_bounds.is_empty() + !self.tcx.sess.opts.debugging_opts.print_type_sizes || + layout.ty.has_param_types() || + layout.ty.has_self_ty() || + !self.param_env.caller_bounds.is_empty() { return; } - Self::record_layout_for_printing_outlined(tcx, ty, param_env, layout) + self.record_layout_for_printing_outlined(layout) } - fn record_layout_for_printing_outlined(tcx: TyCtxt<'a, 'tcx, 'tcx>, - ty: Ty<'tcx>, - param_env: ty::ParamEnv<'tcx>, - layout: TyLayout<'tcx>) { - let cx = (tcx, param_env); + fn record_layout_for_printing_outlined(self, layout: TyLayout<'tcx>) { // (delay format until we actually need it) let record = |kind, opt_discr_size, variants| { - let type_desc = format!("{:?}", ty); - tcx.sess.code_stats.borrow_mut().record_type_size(kind, - type_desc, - layout.align, - layout.size, - opt_discr_size, - variants); + let type_desc = format!("{:?}", layout.ty); + self.tcx.sess.code_stats.borrow_mut().record_type_size(kind, + type_desc, + layout.align, + layout.size, + opt_discr_size, + variants); }; - let adt_def = match ty.sty { + let adt_def = match layout.ty.sty { ty::TyAdt(ref adt_def, _) => { - debug!("print-type-size t: `{:?}` process adt", ty); + debug!("print-type-size t: `{:?}` process adt", layout.ty); adt_def } ty::TyClosure(..) => { - debug!("print-type-size t: `{:?}` record closure", ty); + debug!("print-type-size t: `{:?}` record closure", layout.ty); record(DataTypeKind::Closure, None, vec![]); return; } _ => { - debug!("print-type-size t: `{:?}` skip non-nominal", ty); + debug!("print-type-size t: `{:?}` skip non-nominal", layout.ty); return; } }; @@ -1748,7 +1747,7 @@ impl<'a, 'tcx> LayoutDetails { layout: TyLayout<'tcx>| { let mut min_size = Size::from_bytes(0); let field_info: Vec<_> = flds.iter().enumerate().map(|(i, &name)| { - match layout.field(cx, i) { + match layout.field(self, i) { Err(err) => { bug!("no layout found for field {}: `{:?}`", name, err); } @@ -1808,18 +1807,18 @@ impl<'a, 'tcx> LayoutDetails { Variants::NicheFilling { .. } | Variants::Tagged { .. } => { debug!("print-type-size `{:#?}` adt general variants def {}", - ty, adt_def.variants.len()); + layout.ty, adt_def.variants.len()); let variant_infos: Vec<_> = adt_def.variants.iter().enumerate().map(|(i, variant_def)| { let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect(); build_variant_info(Some(variant_def.name), &fields, - layout.for_variant(cx, i)) + layout.for_variant(self, i)) }) .collect(); record(adt_kind.into(), match layout.variants { - Variants::Tagged { ref discr, .. } => Some(discr.value.size(tcx)), + Variants::Tagged { ref discr, .. } => Some(discr.value.size(self)), _ => None }, variant_infos); } @@ -1855,7 +1854,7 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> { assert!(!ty.has_infer_types()); // First try computing a static layout. - let err = match (tcx, param_env).layout_of(ty) { + let err = match tcx.layout_of(param_env.and(ty)) { Ok(layout) => { return Ok(SizeSkeleton::Known(layout.size)); } @@ -2001,15 +2000,15 @@ impl<'a, 'gcx, 'tcx> HasTyCtxt<'gcx> for TyCtxt<'a, 'gcx, 'tcx> { } } -impl<'a, 'gcx, 'tcx, T: Copy> HasDataLayout for (TyCtxt<'a, 'gcx, 'tcx>, T) { +impl<'tcx, T: HasDataLayout> HasDataLayout for LayoutCx<'tcx, T> { fn data_layout(&self) -> &TargetDataLayout { - self.0.data_layout() + self.tcx.data_layout() } } -impl<'a, 'gcx, 'tcx, T: Copy> HasTyCtxt<'gcx> for (TyCtxt<'a, 'gcx, 'tcx>, T) { +impl<'gcx, 'tcx, T: HasTyCtxt<'gcx>> HasTyCtxt<'gcx> for LayoutCx<'tcx, T> { fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'gcx> { - self.0.tcx() + self.tcx.tcx() } } @@ -2042,17 +2041,15 @@ pub trait LayoutOf { fn layout_of(self, ty: T) -> Self::TyLayout; } -impl<'a, 'tcx> LayoutOf> for (TyCtxt<'a, 'tcx, 'tcx>, ty::ParamEnv<'tcx>) { +impl<'a, 'tcx> LayoutOf> for LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { type TyLayout = Result, LayoutError<'tcx>>; /// Computes the layout of a type. Note that this implicitly /// executes in "reveal all" mode. - #[inline] fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { - let (tcx, param_env) = self; - - let ty = tcx.normalize_associated_type_in_env(&ty, param_env.reveal_all()); - let details = tcx.layout_raw(param_env.reveal_all().and(ty))?; + let param_env = self.param_env.reveal_all(); + let ty = self.tcx.normalize_associated_type_in_env(&ty, param_env); + let details = self.tcx.layout_raw(param_env.and(ty))?; let layout = TyLayout { ty, details @@ -2064,24 +2061,21 @@ impl<'a, 'tcx> LayoutOf> for (TyCtxt<'a, 'tcx, 'tcx>, ty::ParamEnv<'tcx // completed, to avoid problems around recursive structures // and the like. (Admitedly, I wasn't able to reproduce a problem // here, but it seems like the right thing to do. -nmatsakis) - LayoutDetails::record_layout_for_printing(tcx, ty, param_env, layout); + self.record_layout_for_printing(layout); Ok(layout) } } -impl<'a, 'tcx> LayoutOf> for (ty::maps::TyCtxtAt<'a, 'tcx, 'tcx>, - ty::ParamEnv<'tcx>) { +impl<'a, 'tcx> LayoutOf> for LayoutCx<'tcx, ty::maps::TyCtxtAt<'a, 'tcx, 'tcx>> { type TyLayout = Result, LayoutError<'tcx>>; /// Computes the layout of a type. Note that this implicitly /// executes in "reveal all" mode. - #[inline] fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { - let (tcx_at, param_env) = self; - - let ty = tcx_at.tcx.normalize_associated_type_in_env(&ty, param_env.reveal_all()); - let details = tcx_at.layout_raw(param_env.reveal_all().and(ty))?; + let param_env = self.param_env.reveal_all(); + let ty = self.tcx.normalize_associated_type_in_env(&ty, param_env.reveal_all()); + let details = self.tcx.layout_raw(param_env.reveal_all().and(ty))?; let layout = TyLayout { ty, details @@ -2093,12 +2087,45 @@ impl<'a, 'tcx> LayoutOf> for (ty::maps::TyCtxtAt<'a, 'tcx, 'tcx>, // completed, to avoid problems around recursive structures // and the like. (Admitedly, I wasn't able to reproduce a problem // here, but it seems like the right thing to do. -nmatsakis) - LayoutDetails::record_layout_for_printing(tcx_at.tcx, ty, param_env, layout); + let cx = LayoutCx { + tcx: *self.tcx, + param_env: self.param_env + }; + cx.record_layout_for_printing(layout); Ok(layout) } } +// Helper (inherent) `layout_of` methods to avoid pushing `LayoutCx` to users. +impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { + /// Computes the layout of a type. Note that this implicitly + /// executes in "reveal all" mode. + #[inline] + pub fn layout_of(self, param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) + -> Result, LayoutError<'tcx>> { + let cx = LayoutCx { + tcx: self, + param_env: param_env_and_ty.param_env + }; + cx.layout_of(param_env_and_ty.value) + } +} + +impl<'a, 'tcx> ty::maps::TyCtxtAt<'a, 'tcx, 'tcx> { + /// Computes the layout of a type. Note that this implicitly + /// executes in "reveal all" mode. + #[inline] + pub fn layout_of(self, param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) + -> Result, LayoutError<'tcx>> { + let cx = LayoutCx { + tcx: self, + param_env: param_env_and_ty.param_env + }; + cx.layout_of(param_env_and_ty.value) + } +} + impl<'a, 'tcx> TyLayout<'tcx> { pub fn for_variant(&self, cx: C, variant_index: usize) -> Self where C: LayoutOf> + HasTyCtxt<'tcx>, diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 418bd4b5effc6..1d2813e4f6704 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -17,7 +17,6 @@ use rustc::hir::map::blocks::FnLikeNode; use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::DefId; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::ty::layout::LayoutOf; use rustc::ty::util::IntTypeExt; use rustc::ty::subst::{Substs, Subst}; use rustc::util::common::ErrorReported; @@ -313,7 +312,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>, if tcx.fn_sig(def_id).abi() == Abi::RustIntrinsic { let layout_of = |ty: Ty<'tcx>| { let ty = tcx.erase_regions(&ty); - (tcx.at(e.span), cx.param_env).layout_of(ty).map_err(|err| { + tcx.at(e.span).layout_of(cx.param_env.and(ty)).map_err(|err| { ConstEvalErr { span: e.span, kind: LayoutError(err) } }) }; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index e0999db6e3e66..e7e4119b9999b 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -437,8 +437,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { // repr(transparent) types are allowed to have arbitrary ZSTs, not just // PhantomData -- skip checking all ZST fields if def.repr.transparent() { - let is_zst = (cx, cx.param_env(field.did)) - .layout_of(field_ty) + let is_zst = cx + .layout_of(cx.param_env(field.did).and(field_ty)) .map(|layout| layout.is_zst()) .unwrap_or(false); if is_zst { diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index baec0fea50f1e..02fcb69fef5ac 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -172,7 +172,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> LayoutOf> for &'a EvalContext<'a, 'tcx type TyLayout = EvalResult<'tcx, TyLayout<'tcx>>; fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { - (self.tcx, self.param_env).layout_of(ty) + self.tcx.layout_of(self.param_env.and(ty)) .map_err(|layout| EvalErrorKind::Layout(layout).into()) } } diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 43ee75d1e2ba2..ceea97e3ed3b0 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -19,7 +19,6 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc::mir::*; use rustc::mir::visit::*; use rustc::ty::{self, Instance, Ty, TyCtxt, TypeFoldable}; -use rustc::ty::layout::LayoutOf; use rustc::ty::subst::{Subst,Substs}; use std::collections::VecDeque; @@ -655,7 +654,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> Option { - (tcx, param_env).layout_of(ty).ok().map(|layout| layout.size.bytes()) + tcx.layout_of(param_env.and(ty)).ok().map(|layout| layout.size.bytes()) } fn subst_and_normalize<'a, 'tcx: 'a>( diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 06b8d9ff7b306..a285e5f263ab7 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -464,8 +464,7 @@ impl<'a, 'tcx> LayoutOf> for &'a CodegenCx<'a, 'tcx> { type TyLayout = TyLayout<'tcx>; fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { - (self.tcx, ty::ParamEnv::empty(traits::Reveal::All)) - .layout_of(ty) + self.tcx.layout_of(ty::ParamEnv::empty(traits::Reveal::All).and(ty)) .unwrap_or_else(|e| match e { LayoutError::SizeOverflow(_) => self.sess().fatal(&e.to_string()), _ => bug!("failed to get layout for `{}`: {}", ty, e) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 483dd345286d4..e4023b4d9590b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -100,7 +100,6 @@ use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc::ty::fold::TypeFoldable; use rustc::ty::maps::Providers; use rustc::ty::util::{Representability, IntTypeExt}; -use rustc::ty::layout::LayoutOf; use errors::{DiagnosticBuilder, DiagnosticId}; use require_c_abi_if_variadic; @@ -1551,7 +1550,7 @@ fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: De let field_infos: Vec<_> = adt.non_enum_variant().fields.iter().map(|field| { let ty = field.ty(tcx, Substs::identity_for_item(tcx, field.did)); let param_env = tcx.param_env(field.did); - let layout = (tcx, param_env).layout_of(ty); + let layout = tcx.layout_of(param_env.and(ty)); // We are currently checking the type this field came from, so it must be local let span = tcx.hir.span_if_local(field.did).unwrap(); let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false); From e1f04c04dffc1615fde9dd1e51d27bcc5275cdb2 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Sun, 28 Jan 2018 15:50:03 -0700 Subject: [PATCH 2/3] Disable ThinLTO for dist builds. Dist builds should always be as fast as we can make them, and since those run on CI we don't care quite as much for the build being somewhat slower. As such, we don't automatically enable ThinLTO on builds for the dist builders. --- config.toml.example | 5 +++++ src/bootstrap/builder.rs | 21 +++++++++++++++------ src/bootstrap/config.rs | 5 +++++ src/bootstrap/configure.py | 1 + src/ci/run.sh | 1 + 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/config.toml.example b/config.toml.example index 9ca0f563d0af1..75cab74258b6b 100644 --- a/config.toml.example +++ b/config.toml.example @@ -235,6 +235,11 @@ # compiler. #codegen-units = 1 +# Whether to enable ThinLTO (and increase the codegen units to either a default +# or the configured value). On by default. If we want the fastest possible +# compiler, we should disable this. +#thinlto = true + # Whether or not debug assertions are enabled for the compiler and standard # library. Also enables compilation of debug! and trace! logging macros. #debug-assertions = false diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 780513dd94394..bf7b1015a4921 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -509,10 +509,6 @@ impl<'a> Builder<'a> { }) .env("TEST_MIRI", self.config.test_miri.to_string()) .env("RUSTC_ERROR_METADATA_DST", self.extended_error_dir()); - if let Some(n) = self.config.rust_codegen_units { - cargo.env("RUSTC_CODEGEN_UNITS", n.to_string()); - } - if let Some(host_linker) = self.build.linker(compiler.host) { cargo.env("RUSTC_HOST_LINKER", host_linker); @@ -679,6 +675,13 @@ impl<'a> Builder<'a> { if self.is_very_verbose() { cargo.arg("-v"); } + + // This must be kept before the thinlto check, as we set codegen units + // to 1 forcibly there. + if let Some(n) = self.config.rust_codegen_units { + cargo.env("RUSTC_CODEGEN_UNITS", n.to_string()); + } + if self.config.rust_optimize { // FIXME: cargo bench does not accept `--release` if cmd != "bench" { @@ -686,11 +689,17 @@ impl<'a> Builder<'a> { } if self.config.rust_codegen_units.is_none() && - self.build.is_rust_llvm(compiler.host) - { + self.build.is_rust_llvm(compiler.host) && + self.config.rust_thinlto { cargo.env("RUSTC_THINLTO", "1"); + } else if self.config.rust_codegen_units.is_none() { + // Generally, if ThinLTO has been disabled for some reason, we + // want to set the codegen units to 1. However, we shouldn't do + // this if the option was specifically set by the user. + cargo.env("RUSTC_CODEGEN_UNITS", "1"); } } + if self.config.locked_deps { cargo.arg("--locked"); } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 0da04bebac513..be8910120ee19 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -81,6 +81,7 @@ pub struct Config { // rust codegen options pub rust_optimize: bool, pub rust_codegen_units: Option, + pub rust_thinlto: bool, pub rust_debug_assertions: bool, pub rust_debuginfo: bool, pub rust_debuginfo_lines: bool, @@ -261,6 +262,7 @@ impl Default for StringOrBool { struct Rust { optimize: Option, codegen_units: Option, + thinlto: Option, debug_assertions: Option, debuginfo: Option, debuginfo_lines: Option, @@ -412,6 +414,7 @@ impl Config { // Store off these values as options because if they're not provided // we'll infer default values for them later + let mut thinlto = None; let mut llvm_assertions = None; let mut debuginfo_lines = None; let mut debuginfo_only_std = None; @@ -455,6 +458,7 @@ impl Config { optimize = rust.optimize; ignore_git = rust.ignore_git; debug_jemalloc = rust.debug_jemalloc; + thinlto = rust.thinlto; set(&mut config.rust_optimize_tests, rust.optimize_tests); set(&mut config.rust_debuginfo_tests, rust.debuginfo_tests); set(&mut config.codegen_tests, rust.codegen_tests); @@ -539,6 +543,7 @@ impl Config { "stable" | "beta" | "nightly" => true, _ => false, }; + config.rust_thinlto = thinlto.unwrap_or(true); config.rust_debuginfo_lines = debuginfo_lines.unwrap_or(default); config.rust_debuginfo_only_std = debuginfo_only_std.unwrap_or(default); diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index bc6f666d0012f..d51752a12d9e5 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -70,6 +70,7 @@ def v(*args): # Optimization and debugging options. These may be overridden by the release # channel, etc. o("optimize", "rust.optimize", "build optimized rust code") +o("thinlto", "rust.thinlto", "build Rust with ThinLTO enabled") o("optimize-llvm", "llvm.optimize", "build optimized LLVM") o("llvm-assertions", "llvm.assertions", "build LLVM with assertions") o("debug-assertions", "rust.debug-assertions", "build with debugging assertions") diff --git a/src/ci/run.sh b/src/ci/run.sh index dab385c09649c..02480c6937de1 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -46,6 +46,7 @@ export RUST_RELEASE_CHANNEL=nightly if [ "$DEPLOY$DEPLOY_ALT" != "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp" + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-thinlto" if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions" From cec82c1bfe373785e0bad93c557ce7db17a4048d Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 1 Feb 2018 18:56:48 +1300 Subject: [PATCH 3/3] Update RLS and Rustfmt --- src/Cargo.lock | 56 +++++++++++++++++++++++------------------------ src/tools/rls | 2 +- src/tools/rustfmt | 2 +- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index d26098903eec5..fc89cc4ea9ee3 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1618,7 +1618,7 @@ version = "0.1.0" [[package]] name = "rls" -version = "0.124.0" +version = "0.125.0" dependencies = [ "cargo 0.26.0", "env_logger 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1635,7 +1635,7 @@ dependencies = [ "rls-rustc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-vfs 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfmt-nightly 0.3.6", + "rustfmt-nightly 0.3.8", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1723,7 +1723,7 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_cratesio_shim" -version = "12.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1732,57 +1732,57 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_data_structures" -version = "12.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-rustc_errors" -version = "12.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-ap-rustc_data_structures 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-serialize" -version = "12.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-ap-syntax" -version = "12.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_errors 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_cratesio_shim 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-syntax_pos" -version = "12.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-ap-rustc_data_structures 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2207,7 +2207,7 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "0.3.6" +version = "0.3.8" dependencies = [ "cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2219,8 +2219,8 @@ dependencies = [ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_errors 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3068,12 +3068,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rls-rustc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "85cfb9dde19e313da3e47738008f8a472e470cc42d910b71595a9238494701f2" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" "checksum rls-vfs 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ffd34691a510938bb67fe0444fb363103c73ffb31c121d1e16bc92d8945ea8ff" -"checksum rustc-ap-rustc_cratesio_shim 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1a51c10af5abd5d698b7e3487e869e6d15f6feb04cbedb5c792e2824f9d845e" -"checksum rustc-ap-rustc_data_structures 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1aa227490501072780d57f74b1164d361833ff8e172f817da0da2cdf2e4280cc" -"checksum rustc-ap-rustc_errors 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "21ff6c6e13ac4fc04b7d4d398828b024c4b6577045cb3175b33d35fea35ff6d0" -"checksum rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b4e7f51e298675c2bf830f7265621a8936fb09e63b825b58144cbaac969e604" -"checksum rustc-ap-syntax 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8bf5639869ba2f7fa581939cd217cb71a85506b82ad0ea520614fb0dceb2386c" -"checksum rustc-ap-syntax_pos 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1c020cdb7379e1c733ae0a311ae47c748337ba584d2dd7b7f53baaae78de6f8b" +"checksum rustc-ap-rustc_cratesio_shim 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ad5e562044ea78a6764dd75ae8afe4b21fde49f4548024b5fdf6345c21fb524" +"checksum rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c0d65325492aba7db72899e3edbab34d39af98c42ab7c7e450c9a288ffe4ad" +"checksum rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "87d4ab2e06a671b5b5c5b0359dac346f164c99d059dce6a22feb08f2f56bd182" +"checksum rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e0745fa445ff41c4b6699936cf35ce3ca49502377dd7b3929c829594772c3a7b" +"checksum rustc-ap-syntax 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82efedabe30f393161e11214a9130edfa01ad476372d1c6f3fec1f8d30488c9d" +"checksum rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9de2e927e280c75b8efab9c5f591ad31082d5d2c4c562c68fdba2ee77286b0" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" diff --git a/src/tools/rls b/src/tools/rls index 511321ae1c2fa..dee42bda8156a 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 511321ae1c2fa3f0e334885fecf406dd6c882836 +Subproject commit dee42bda8156a28ead609080e27b02173bb9c29e diff --git a/src/tools/rustfmt b/src/tools/rustfmt index e0e3e22248cd1..346238f49740d 160000 --- a/src/tools/rustfmt +++ b/src/tools/rustfmt @@ -1 +1 @@ -Subproject commit e0e3e22248cd14ebbe0253e9720261a0328bfc59 +Subproject commit 346238f49740d6c98102a6a59811b1625c73a9d7