From 58f107ab567a4cbf167151d0cc5dbe7fcf51762e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 26 Jul 2022 04:43:04 +0000 Subject: [PATCH 1/6] Use TraitEngine in more places that don't specifically need FulfillmentCtxt::new_in_snapshot --- .../src/transform/check_consts/qualifs.rs | 4 ++-- .../rustc_trait_selection/src/traits/auto_trait.rs | 2 +- compiler/rustc_trait_selection/src/traits/codegen.rs | 4 ++-- compiler/rustc_trait_selection/src/traits/coherence.rs | 4 ++-- compiler/rustc_trait_selection/src/traits/mod.rs | 2 +- .../rustc_trait_selection/src/traits/specialize/mod.rs | 10 ++++++---- .../src/traits/structural_match.rs | 4 ++-- compiler/rustc_traits/src/implied_outlives_bounds.rs | 5 ++--- compiler/rustc_typeck/src/coherence/builtin.rs | 2 +- compiler/rustc_typeck/src/hir_wf_check.rs | 4 ++-- compiler/rustc_typeck/src/outlives/outlives_bounds.rs | 4 ++-- 11 files changed, 23 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 29464cf8c4e4f..09bb00238d9ec 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -10,7 +10,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty}; use rustc_span::DUMMY_SP; use rustc_trait_selection::traits::{ - self, FulfillmentContext, ImplSource, Obligation, ObligationCause, SelectionContext, + self, ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngineExt, }; use super::ConstCx; @@ -191,7 +191,7 @@ impl Qualif for NeedsNonConstDrop { // If we successfully found one, then select all of the predicates // implied by our const drop impl. - let mut fcx = FulfillmentContext::new(); + let mut fcx = >::new(cx.tcx); for nested in impl_src.nested_obligations() { fcx.register_predicate_obligation(&infcx, nested); } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 5763e6d1b559e..294c81d0b2111 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -205,7 +205,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { // At this point, we already have all of the bounds we need. FulfillmentContext is used // to store all of the necessary region/lifetime bounds in the InferContext, as well as // an additional sanity check. - let mut fulfill = FulfillmentContext::new(); + let mut fulfill = >::new(tcx); fulfill.register_bound(&infcx, full_env, ty, trait_did, ObligationCause::dummy()); let errors = fulfill.select_all_or_error(&infcx); diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs index 5fcaa52d41747..f42f936c516b8 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen.rs @@ -5,7 +5,7 @@ use crate::infer::{DefiningAnchor, TyCtxtInferExt}; use crate::traits::{ - FulfillmentContext, ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, + ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt, Unimplemented, }; use rustc_middle::traits::CodegenObligationError; @@ -55,7 +55,7 @@ pub fn codegen_fulfill_obligation<'tcx>( // Currently, we use a fulfillment context to completely resolve // all nested obligations. This is because they can inform the // inference of the impl's type parameters. - let mut fulfill_cx = FulfillmentContext::new(); + let mut fulfill_cx = >::new(tcx); let impl_source = selection.map(|predicate| { fulfill_cx.register_predicate_obligation(&infcx, predicate); }); diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 9983438233e1e..6fad9f8a5ec96 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -11,7 +11,7 @@ use crate::traits::util::impl_subject_and_oblig; use crate::traits::SkipLeakCheck; use crate::traits::{ self, FulfillmentContext, Normalized, Obligation, ObligationCause, PredicateObligation, - PredicateObligations, SelectionContext, + PredicateObligations, SelectionContext, TraitEngineExt, }; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::Diagnostic; @@ -385,7 +385,7 @@ fn resolve_negative_obligation<'cx, 'tcx>( return false; }; - let mut fulfillment_cx = FulfillmentContext::new(); + let mut fulfillment_cx = >::new(infcx.tcx); fulfillment_cx.register_predicate_obligation(infcx, o); let errors = fulfillment_cx.select_all_or_error(infcx); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 3ef51b0c27abd..ecd6620b44c0d 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -163,7 +163,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>( // The handling of regions in this area of the code is terrible, // see issue #29149. We should be able to improve on this with // NLL. - let mut fulfill_cx = FulfillmentContext::new(); + let mut fulfill_cx = >::new(infcx.tcx); // We can use a dummy node-id here because we won't pay any mind // to region obligations that arise (there shouldn't really be any diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 5f77aae6f221f..28a1cb273a72f 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -14,7 +14,9 @@ use specialization_graph::GraphExt; use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use crate::traits::select::IntercrateAmbiguityCause; -use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine}; +use crate::traits::{ + self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine, TraitEngineExt, +}; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::{struct_span_err, EmissionGuarantee, LintDiagnosticBuilder}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -24,8 +26,8 @@ use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; use rustc_span::{Span, DUMMY_SP}; -use super::util; -use super::{FulfillmentContext, SelectionContext}; +use super::SelectionContext; +use super::{util, FulfillmentContext}; /// Information pertinent to an overlapping impl error. #[derive(Debug)] @@ -207,7 +209,7 @@ fn fulfill_implication<'a, 'tcx>( // (which are packed up in penv) infcx.save_and_restore_in_snapshot_flag(|infcx| { - let mut fulfill_cx = FulfillmentContext::new(); + let mut fulfill_cx = >::new(infcx.tcx); for oblig in obligations.chain(more_obligations) { fulfill_cx.register_predicate_obligation(&infcx, oblig); } diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 6c0b83fbd0304..99dc60c3a2aaf 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -1,6 +1,6 @@ use crate::infer::{InferCtxt, TyCtxtInferExt}; use crate::traits::ObligationCause; -use crate::traits::{self, TraitEngine}; +use crate::traits::{TraitEngine, TraitEngineExt}; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; @@ -78,7 +78,7 @@ fn type_marked_structural<'tcx>( adt_ty: Ty<'tcx>, cause: ObligationCause<'tcx>, ) -> bool { - let mut fulfillment_cx = traits::FulfillmentContext::new(); + let mut fulfillment_cx = >::new(infcx.tcx); // require `#[derive(PartialEq)]` let structural_peq_def_id = infcx.tcx.require_lang_item(LangItem::StructuralPeq, Some(cause.span)); diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 4d4d55de5f457..e3e78f70b15ef 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -14,8 +14,7 @@ use rustc_span::source_map::DUMMY_SP; use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::traits::query::{CanonicalTyGoal, Fallible, NoSolution}; use rustc_trait_selection::traits::wf; -use rustc_trait_selection::traits::FulfillmentContext; -use rustc_trait_selection::traits::TraitEngine; +use rustc_trait_selection::traits::{TraitEngine, TraitEngineExt}; use smallvec::{smallvec, SmallVec}; pub(crate) fn provide(p: &mut Providers) { @@ -52,7 +51,7 @@ fn compute_implied_outlives_bounds<'tcx>( let mut implied_bounds = vec![]; - let mut fulfill_cx = FulfillmentContext::new(); + let mut fulfill_cx = >::new(tcx); while let Some(arg) = wf_args.pop() { if !checked_wf_args.insert(arg) { diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs index d8e42729ff31d..180875f01ded1 100644 --- a/compiler/rustc_typeck/src/coherence/builtin.rs +++ b/compiler/rustc_typeck/src/coherence/builtin.rs @@ -117,7 +117,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { // it is not immediately clear why Copy is not implemented for a field, since // all we point at is the field itself. tcx.infer_ctxt().ignoring_regions().enter(|infcx| { - let mut fulfill_cx = traits::FulfillmentContext::new(); + let mut fulfill_cx = >::new(tcx); fulfill_cx.register_bound( &infcx, param_env, diff --git a/compiler/rustc_typeck/src/hir_wf_check.rs b/compiler/rustc_typeck/src/hir_wf_check.rs index 3dc728271b07a..55c7a15f9bcd1 100644 --- a/compiler/rustc_typeck/src/hir_wf_check.rs +++ b/compiler/rustc_typeck/src/hir_wf_check.rs @@ -7,7 +7,7 @@ use rustc_infer::traits::TraitEngine; use rustc_infer::traits::{ObligationCause, WellFormedLoc}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Region, ToPredicate, TyCtxt, TypeFoldable, TypeFolder}; -use rustc_trait_selection::traits; +use rustc_trait_selection::traits::{self, TraitEngineExt}; pub fn provide(providers: &mut Providers) { *providers = Providers { diagnostic_hir_wf_check, ..*providers }; @@ -66,7 +66,7 @@ fn diagnostic_hir_wf_check<'tcx>( impl<'tcx> Visitor<'tcx> for HirWfCheck<'tcx> { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { self.tcx.infer_ctxt().enter(|infcx| { - let mut fulfill = traits::FulfillmentContext::new(); + let mut fulfill = >::new(self.tcx); let tcx_ty = self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx }); let cause = traits::ObligationCause::new( diff --git a/compiler/rustc_typeck/src/outlives/outlives_bounds.rs b/compiler/rustc_typeck/src/outlives/outlives_bounds.rs index 70b8bcd02208d..229a64650848c 100644 --- a/compiler/rustc_typeck/src/outlives/outlives_bounds.rs +++ b/compiler/rustc_typeck/src/outlives/outlives_bounds.rs @@ -3,7 +3,7 @@ use rustc_middle::ty::{self, Ty}; use rustc_trait_selection::infer::InferCtxt; use rustc_trait_selection::traits::query::type_op::{self, TypeOp, TypeOpOutput}; use rustc_trait_selection::traits::query::NoSolution; -use rustc_trait_selection::traits::{FulfillmentContext, ObligationCause, TraitEngine}; +use rustc_trait_selection::traits::{ObligationCause, TraitEngine, TraitEngineExt}; pub use rustc_middle::traits::query::OutlivesBound; @@ -63,7 +63,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { if let Some(constraints) = constraints { // Instantiation may have produced new inference variables and constraints on those // variables. Process these constraints. - let mut fulfill_cx = FulfillmentContext::new(); + let mut fulfill_cx = >::new(self.tcx); let cause = ObligationCause::misc(span, body_id); for &constraint in &constraints.outlives { let obligation = self.query_outlives_constraint_to_obligation( From 4eee5aaa4e3b2a87e879a44f8ea52ca81f90ea47 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 1 Aug 2022 21:50:21 +0400 Subject: [PATCH 2/6] cleanup code w/ pointers in std a little --- library/core/src/alloc/global.rs | 2 +- library/core/src/ptr/const_ptr.rs | 4 ++-- library/core/src/ptr/mut_ptr.rs | 7 ++++--- library/core/src/slice/iter.rs | 4 ++-- library/core/tests/const_ptr.rs | 6 +++--- library/core/tests/lib.rs | 2 ++ library/std/src/sys/sgx/abi/usercalls/alloc.rs | 2 +- library/std/src/sys/unsupported/alloc.rs | 7 ++++--- 8 files changed, 19 insertions(+), 15 deletions(-) diff --git a/library/core/src/alloc/global.rs b/library/core/src/alloc/global.rs index 887246c600144..6756eecd0e0f8 100644 --- a/library/core/src/alloc/global.rs +++ b/library/core/src/alloc/global.rs @@ -74,7 +74,7 @@ use crate::ptr; /// { /// return null_mut(); /// }; -/// (self.arena.get() as *mut u8).add(allocated) +/// self.arena.get().cast::().add(allocated) /// } /// unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} /// } diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index e0655d68d2cfa..2f2d8329baa46 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1270,8 +1270,8 @@ impl *const T { /// # fn foo(n: usize) { /// # use std::mem::align_of; /// # unsafe { - /// let x = [5u8, 6u8, 7u8, 8u8, 9u8]; - /// let ptr = x.as_ptr().add(n) as *const u8; + /// let x = [5u8, 6, 7, 8, 9]; + /// let ptr = x.as_ptr().add(n); /// let offset = ptr.align_offset(align_of::()); /// if offset < x.len() - n - 1 { /// let u16_ptr = ptr.add(offset) as *const u16; diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index fc3dd2a9b25a9..e932c72ad9860 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1548,12 +1548,13 @@ impl *mut T { /// # fn foo(n: usize) { /// # use std::mem::align_of; /// # unsafe { - /// let x = [5u8, 6u8, 7u8, 8u8, 9u8]; - /// let ptr = x.as_ptr().add(n) as *const u8; + /// let mut x = [5u8, 6, 7, 8, 9]; + /// let ptr = x.as_mut_ptr().add(n); /// let offset = ptr.align_offset(align_of::()); /// if offset < x.len() - n - 1 { - /// let u16_ptr = ptr.add(offset) as *const u16; + /// let u16_ptr = ptr.add(offset) as *mut u16; /// assert_ne!(*u16_ptr, 500); + /// *u16_ptr = 0; /// } else { /// // while the pointer can be aligned via `offset`, it would point /// // outside the allocation diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 76b4a534e5db5..c310ffe091d2c 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -92,7 +92,7 @@ impl<'a, T> Iter<'a, T> { assume(!ptr.is_null()); let end = if mem::size_of::() == 0 { - (ptr as *const u8).wrapping_add(slice.len()) as *const T + ptr.wrapping_byte_add(slice.len()) } else { ptr.add(slice.len()) }; @@ -228,7 +228,7 @@ impl<'a, T> IterMut<'a, T> { assume(!ptr.is_null()); let end = if mem::size_of::() == 0 { - (ptr as *mut u8).wrapping_add(slice.len()) as *mut T + ptr.wrapping_byte_add(slice.len()) } else { ptr.add(slice.len()) }; diff --git a/library/core/tests/const_ptr.rs b/library/core/tests/const_ptr.rs index 152fed803ecdb..d874f08317f61 100644 --- a/library/core/tests/const_ptr.rs +++ b/library/core/tests/const_ptr.rs @@ -3,7 +3,7 @@ const DATA: [u16; 2] = [u16::from_ne_bytes([0x01, 0x23]), u16::from_ne_bytes([0x const fn unaligned_ptr() -> *const u16 { // Since DATA.as_ptr() is aligned to two bytes, adding 1 byte to that produces an unaligned *const u16 - unsafe { (DATA.as_ptr() as *const u8).add(1) as *const u16 } + unsafe { DATA.as_ptr().byte_add(1) } } #[test] @@ -67,7 +67,7 @@ fn write() { const fn write_unaligned() -> [u16; 2] { let mut two_aligned = [0u16; 2]; unsafe { - let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16; + let unaligned_ptr = two_aligned.as_mut_ptr().byte_add(1); ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45])); } two_aligned @@ -91,7 +91,7 @@ fn mut_ptr_write() { const fn write_unaligned() -> [u16; 2] { let mut two_aligned = [0u16; 2]; unsafe { - let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16; + let unaligned_ptr = two_aligned.as_mut_ptr().byte_add(1); unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45])); } two_aligned diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index db94368f6e0cc..df9b1073a0994 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -14,6 +14,7 @@ #![feature(const_maybe_uninit_assume_init_read)] #![feature(const_nonnull_new)] #![feature(const_num_from_num)] +#![feature(const_pointer_byte_offsets)] #![feature(const_ptr_as_ref)] #![feature(const_ptr_read)] #![feature(const_ptr_write)] @@ -74,6 +75,7 @@ #![feature(never_type)] #![feature(unwrap_infallible)] #![feature(result_into_ok_or_err)] +#![feature(pointer_byte_offsets)] #![feature(portable_simd)] #![feature(ptr_metadata)] #![feature(once_cell)] diff --git a/library/std/src/sys/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/sgx/abi/usercalls/alloc.rs index ea24fedd0eb3d..22cbbcf689abd 100644 --- a/library/std/src/sys/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/sgx/abi/usercalls/alloc.rs @@ -115,7 +115,7 @@ pub unsafe trait UserSafe { /// * the pointer is null. /// * the pointed-to range is not in user memory. unsafe fn check_ptr(ptr: *const Self) { - let is_aligned = |p| -> bool { 0 == (p as usize) & (Self::align_of() - 1) }; + let is_aligned = |p| -> bool { 0 == p.addr() & (Self::align_of() - 1) }; assert!(is_aligned(ptr as *const u8)); assert!(is_user_range(ptr as _, mem::size_of_val(unsafe { &*ptr }))); diff --git a/library/std/src/sys/unsupported/alloc.rs b/library/std/src/sys/unsupported/alloc.rs index 8d5d0a2f5ccd1..d715ae45401e6 100644 --- a/library/std/src/sys/unsupported/alloc.rs +++ b/library/std/src/sys/unsupported/alloc.rs @@ -1,15 +1,16 @@ use crate::alloc::{GlobalAlloc, Layout, System}; +use crate::ptr::null_mut; #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { - 0 as *mut u8 + null_mut() } #[inline] unsafe fn alloc_zeroed(&self, _layout: Layout) -> *mut u8 { - 0 as *mut u8 + null_mut() } #[inline] @@ -17,6 +18,6 @@ unsafe impl GlobalAlloc for System { #[inline] unsafe fn realloc(&self, _ptr: *mut u8, _layout: Layout, _new_size: usize) -> *mut u8 { - 0 as *mut u8 + null_mut() } } From 6d6979b74b14b3dead628b5014030265e5c80d09 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 2 Aug 2022 03:51:51 +0400 Subject: [PATCH 3/6] improve documentation of `pointer::align_offset` --- library/core/src/ptr/const_ptr.rs | 17 +++++++++-------- library/core/src/ptr/mut_ptr.rs | 18 ++++++++++-------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 2f2d8329baa46..716f7c6af8f34 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1267,20 +1267,21 @@ impl *const T { /// Accessing adjacent `u8` as `u16` /// /// ``` - /// # fn foo(n: usize) { - /// # use std::mem::align_of; + /// use std::mem::align_of; + /// /// # unsafe { - /// let x = [5u8, 6, 7, 8, 9]; - /// let ptr = x.as_ptr().add(n); + /// let x = [5_u8, 6, 7, 8, 9]; + /// let ptr = x.as_ptr(); /// let offset = ptr.align_offset(align_of::()); - /// if offset < x.len() - n - 1 { - /// let u16_ptr = ptr.add(offset) as *const u16; - /// assert_ne!(*u16_ptr, 500); + /// + /// if offset < x.len() - 1 { + /// let u16_ptr = ptr.add(offset).cast::(); + /// assert!(*u16_ptr == u16::from_ne_bytes([5, 6]) || *u16_ptr == u16::from_ne_bytes([6, 7])); /// } else { /// // while the pointer can be aligned via `offset`, it would point /// // outside the allocation /// } - /// # } } + /// # } /// ``` #[stable(feature = "align_offset", since = "1.36.0")] #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index e932c72ad9860..b8551eeed9e0d 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1545,21 +1545,23 @@ impl *mut T { /// Accessing adjacent `u8` as `u16` /// /// ``` - /// # fn foo(n: usize) { - /// # use std::mem::align_of; + /// use std::mem::align_of; + /// /// # unsafe { - /// let mut x = [5u8, 6, 7, 8, 9]; - /// let ptr = x.as_mut_ptr().add(n); + /// let mut x = [5_u8, 6, 7, 8, 9]; + /// let ptr = x.as_mut_ptr(); /// let offset = ptr.align_offset(align_of::()); - /// if offset < x.len() - n - 1 { - /// let u16_ptr = ptr.add(offset) as *mut u16; - /// assert_ne!(*u16_ptr, 500); + /// + /// if offset < x.len() - 1 { + /// let u16_ptr = ptr.add(offset).cast::(); /// *u16_ptr = 0; /// } else { /// // while the pointer can be aligned via `offset`, it would point /// // outside the allocation /// } - /// # } } + /// + /// assert!(x == [0, 0, 7, 8, 9] || x == [5, 0, 0, 8, 9]); + /// # } /// ``` #[stable(feature = "align_offset", since = "1.36.0")] #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] From 09a3dfc351955999953195aad0706304acf1ef1a Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 2 Aug 2022 13:24:34 -0700 Subject: [PATCH 4/6] rustdoc: use a more compact encoding for source-files.js This reduces the compiler-doc file from 40K to 36K, a 10% reduction in size. --- src/librustdoc/html/render/write_shared.rs | 33 +++++++++++-------- .../html/static/js/source-script.js | 18 ++++++---- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 27ad91d09e064..6fb41ff327916 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -366,13 +366,15 @@ pub(super) fn write_shared( .collect::>(); files.sort_unstable(); let subs = subs.iter().map(|s| s.to_json_string()).collect::>().join(","); - let dirs = - if subs.is_empty() { String::new() } else { format!(",\"dirs\":[{}]", subs) }; + let dirs = if subs.is_empty() && files.is_empty() { + String::new() + } else { + format!(",[{}]", subs) + }; let files = files.join(","); - let files = - if files.is_empty() { String::new() } else { format!(",\"files\":[{}]", files) }; + let files = if files.is_empty() { String::new() } else { format!(",[{}]", files) }; format!( - "{{\"name\":\"{name}\"{dirs}{files}}}", + "[\"{name}\"{dirs}{files}]", name = self.elem.to_str().expect("invalid osstring conversion"), dirs = dirs, files = files @@ -411,18 +413,23 @@ pub(super) fn write_shared( let dst = cx.dst.join(&format!("source-files{}.js", cx.shared.resource_suffix)); let make_sources = || { let (mut all_sources, _krates) = - try_err!(collect(&dst, krate.name(cx.tcx()).as_str(), "sourcesIndex"), &dst); + try_err!(collect_json(&dst, krate.name(cx.tcx()).as_str()), &dst); all_sources.push(format!( - "sourcesIndex[\"{}\"] = {};", + r#""{}":{}"#, &krate.name(cx.tcx()), - hierarchy.to_json_string() + hierarchy + .to_json_string() + // All these `replace` calls are because we have to go through JS string for JSON content. + .replace('\\', r"\\") + .replace('\'', r"\'") + // We need to escape double quotes for the JSON. + .replace("\\\"", "\\\\\"") )); all_sources.sort(); - Ok(format!( - "var sourcesIndex = {{}};\n{}\ncreateSourceSidebar();\n", - all_sources.join("\n") - ) - .into_bytes()) + let mut v = String::from("var sourcesIndex = JSON.parse('{\\\n"); + v.push_str(&all_sources.join(",\\\n")); + v.push_str("\\\n}');\ncreateSourceSidebar();\n"); + Ok(v.into_bytes()) }; write_crate("source-files.js", &make_sources)?; } diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index a6a0b09ef31fe..c45d614293a85 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -12,6 +12,10 @@ const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-path"].value; let oldScrollPosition = 0; +const NAME_OFFSET = 0; +const DIRS_OFFSET = 1; +const FILES_OFFSET = 2; + function closeSidebarIfMobile() { if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) { updateLocalStorage("source-sidebar-show", "false"); @@ -24,15 +28,15 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) { dirEntry.className = "dir-entry"; - fullPath += elem["name"] + "/"; + fullPath += elem[NAME_OFFSET] + "/"; - summary.innerText = elem["name"]; + summary.innerText = elem[NAME_OFFSET]; dirEntry.appendChild(summary); const folders = document.createElement("div"); folders.className = "folders"; - if (elem.dirs) { - for (const dir of elem.dirs) { + if (elem[DIRS_OFFSET]) { + for (const dir of elem[DIRS_OFFSET]) { if (createDirEntry(dir, folders, fullPath, false)) { dirEntry.open = true; hasFoundFile = true; @@ -43,8 +47,8 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) { const files = document.createElement("div"); files.className = "files"; - if (elem.files) { - for (const file_text of elem.files) { + if (elem[FILES_OFFSET]) { + for (const file_text of elem[FILES_OFFSET]) { const file = document.createElement("a"); file.innerText = file_text; file.href = rootPath + "src/" + fullPath + file_text + ".html"; @@ -125,7 +129,7 @@ function createSourceSidebar() { title.innerText = "Files"; sidebar.appendChild(title); Object.keys(sourcesIndex).forEach(key => { - sourcesIndex[key].name = key; + sourcesIndex[key][NAME_OFFSET] = key; hasFoundFile = createDirEntry(sourcesIndex[key], sidebar, "", hasFoundFile); }); From 6f87b7500a3450f41c82dd5eca58460b4ef7a30c Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Wed, 3 Aug 2022 01:54:24 -0700 Subject: [PATCH 5/6] Set llvm configs when building lld --- src/bootstrap/native.rs | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 3347246ea8f6f..4d548dbb63875 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -345,13 +345,6 @@ impl Step for Llvm { cfg.define("LLVM_ENABLE_ZLIB", "OFF"); } - if builder.config.llvm_thin_lto { - cfg.define("LLVM_ENABLE_LTO", "Thin"); - if !target.contains("apple") { - cfg.define("LLVM_ENABLE_LLD", "ON"); - } - } - // This setting makes the LLVM tools link to the dynamic LLVM library, // which saves both memory during parallel links and overall disk space // for the tools. We don't do this on every platform as it doesn't work @@ -463,15 +456,8 @@ impl Step for Llvm { cfg.define("LLVM_VERSION_SUFFIX", suffix); } - if let Some(ref linker) = builder.config.llvm_use_linker { - cfg.define("LLVM_USE_LINKER", linker); - } - - if builder.config.llvm_allow_old_toolchain { - cfg.define("LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN", "YES"); - } - configure_cmake(builder, target, &mut cfg, true, ldflags); + configure_llvm(builder, target, &mut cfg); for (key, val) in &builder.config.llvm_build_config { cfg.define(key, val); @@ -731,6 +717,25 @@ fn configure_cmake( } } +fn configure_llvm(builder: &Builder<'_>, target: TargetSelection, cfg: &mut cmake::Config) { + // ThinLTO is only available when building with LLVM, enabling LLD is required. + // Apple's linker ld64 supports ThinLTO out of the box though, so don't use LLD on Darwin. + if builder.config.llvm_thin_lto { + cfg.define("LLVM_ENABLE_LTO", "Thin"); + if !target.contains("apple") { + cfg.define("LLVM_ENABLE_LLD", "ON"); + } + } + + if let Some(ref linker) = builder.config.llvm_use_linker { + cfg.define("LLVM_USE_LINKER", linker); + } + + if builder.config.llvm_allow_old_toolchain { + cfg.define("LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN", "YES"); + } +} + // Adapted from https://github.com/alexcrichton/cc-rs/blob/fba7feded71ee4f63cfe885673ead6d7b4f2f454/src/lib.rs#L2347-L2365 fn get_var(var_base: &str, host: &str, target: &str) -> Option { let kind = if host == target { "HOST" } else { "TARGET" }; @@ -794,6 +799,7 @@ impl Step for Lld { } configure_cmake(builder, target, &mut cfg, true, ldflags); + configure_llvm(builder, target, &mut cfg); // This is an awful, awful hack. Discovered when we migrated to using // clang-cl to compile LLVM/LLD it turns out that LLD, when built out of @@ -825,10 +831,6 @@ impl Step for Lld { .define("LLVM_CONFIG_PATH", llvm_config_shim) .define("LLVM_INCLUDE_TESTS", "OFF"); - if builder.config.llvm_allow_old_toolchain { - cfg.define("LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN", "YES"); - } - // While we're using this horrible workaround to shim the execution of // llvm-config, let's just pile on more. I can't seem to figure out how // to build LLD as a standalone project and also cross-compile it at the From 1405ce35acbcd61b9da8ab7ded6201639cb83d52 Mon Sep 17 00:00:00 2001 From: b-naber Date: Wed, 3 Aug 2022 11:04:10 +0200 Subject: [PATCH 6/6] fix typo --- compiler/rustc_infer/src/infer/higher_ranked/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index e543ae1fcdab1..4608d3984ac1d 100644 --- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs @@ -16,7 +16,7 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> { /// /// This is implemented by first entering a new universe. /// We then replace all bound variables in `sup` with placeholders, - /// and all bound variables in `sup` with inference vars. + /// and all bound variables in `sub` with inference vars. /// We can then just relate the two resulting types as normal. /// /// Note: this is a subtle algorithm. For a full explanation, please see