From 0ff8f0b5782e736f75be6f36765791164d9f0db7 Mon Sep 17 00:00:00 2001 From: Alex <58638691+Alex-Velez@users.noreply.github.com> Date: Sun, 14 Aug 2022 21:06:01 -0500 Subject: [PATCH 01/20] Update src/test/assembly/x86_64-floating-point-clamp.rs Simple Clamp Function I thought this was more robust and easier to read. I also allowed this function to return early in order to skip the extra bound check (I'm sure the difference is negligible). I'm not sure if there was a reason for binding `self` to `x`; if so, please correct me. Simple Clamp Function for f64 I thought this was more robust and easier to read. I also allowed this function to return early in order to skip the extra bound check (I'm sure the difference is negligible). I'm not sure if there was a reason for binding `self` to `x`; if so, please correct me. Floating point clamp test f32 clamp using mut self f64 clamp using mut self Update library/core/src/num/f32.rs Update f64.rs Update x86_64-floating-point-clamp.rs Update src/test/assembly/x86_64-floating-point-clamp.rs Update x86_64-floating-point-clamp.rs Co-Authored-By: scottmcm --- library/core/src/num/f32.rs | 13 +++++----- library/core/src/num/f64.rs | 13 +++++----- .../assembly/x86_64-floating-point-clamp.rs | 25 +++++++++++++++++++ 3 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 src/test/assembly/x86_64-floating-point-clamp.rs diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 6548ad2e514f..f485e4591213 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1282,15 +1282,14 @@ impl f32 { #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "clamp", since = "1.50.0")] #[inline] - pub fn clamp(self, min: f32, max: f32) -> f32 { + pub fn clamp(mut self, min: f32, max: f32) -> f32 { assert!(min <= max); - let mut x = self; - if x < min { - x = min; + if self < min { + self = min; } - if x > max { - x = max; + if self > max { + self = max; } - x + self } } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 75c92c2f8834..3d385e3888a8 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1280,15 +1280,14 @@ impl f64 { #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "clamp", since = "1.50.0")] #[inline] - pub fn clamp(self, min: f64, max: f64) -> f64 { + pub fn clamp(mut self, min: f64, max: f64) -> f64 { assert!(min <= max); - let mut x = self; - if x < min { - x = min; + if self < min { + self = min; } - if x > max { - x = max; + if self > max { + self = max; } - x + self } } diff --git a/src/test/assembly/x86_64-floating-point-clamp.rs b/src/test/assembly/x86_64-floating-point-clamp.rs new file mode 100644 index 000000000000..3388b0e1abd7 --- /dev/null +++ b/src/test/assembly/x86_64-floating-point-clamp.rs @@ -0,0 +1,25 @@ +// Floating-point clamp is designed to be implementable as max+min, +// so check to make sure that's what it's actually emitting. + +// assembly-output: emit-asm +// compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel +// only-x86_64 + +// CHECK-LABEL: clamp_demo: +#[no_mangle] +pub fn clamp_demo(a: f32, x: f32, y: f32) -> f32 { + // CHECK: maxss + // CHECK: minss + a.clamp(x, y) +} + +// CHECK-LABEL: clamp12_demo: +#[no_mangle] +pub fn clamp12_demo(a: f32) -> f32 { + // CHECK-NEXT: movss xmm1 + // CHECK-NEXT: maxss xmm1, xmm0 + // CHECK-NEXT: movss xmm0 + // CHECK-NEXT: minss xmm0, xmm1 + // CHECK-NEXT: ret + a.clamp(1.0, 2.0) +} From 302689fa7bbfc9b24b0bc73db41f7fce5586987c Mon Sep 17 00:00:00 2001 From: Alex <58638691+Alex-Velez@users.noreply.github.com> Date: Tue, 16 Aug 2022 20:39:22 -0500 Subject: [PATCH 02/20] Update src/test/assembly/x86_64-floating-point-clamp.rs Co-authored-by: scottmcm --- src/test/assembly/x86_64-floating-point-clamp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/assembly/x86_64-floating-point-clamp.rs b/src/test/assembly/x86_64-floating-point-clamp.rs index 3388b0e1abd7..4493791a5769 100644 --- a/src/test/assembly/x86_64-floating-point-clamp.rs +++ b/src/test/assembly/x86_64-floating-point-clamp.rs @@ -16,7 +16,7 @@ pub fn clamp_demo(a: f32, x: f32, y: f32) -> f32 { // CHECK-LABEL: clamp12_demo: #[no_mangle] pub fn clamp12_demo(a: f32) -> f32 { - // CHECK-NEXT: movss xmm1 + // CHECK: movss xmm1 // CHECK-NEXT: maxss xmm1, xmm0 // CHECK-NEXT: movss xmm0 // CHECK-NEXT: minss xmm0, xmm1 From 5e1730fd17145fd9db5c042b127e2f400c83738a Mon Sep 17 00:00:00 2001 From: ltdk Date: Wed, 17 Aug 2022 02:01:32 -0400 Subject: [PATCH 03/20] Make slice::reverse const --- library/core/src/slice/mod.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index e79d47c9f98c..361862cdd525 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -674,8 +674,9 @@ impl [T] { /// assert!(v == [3, 2, 1]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_reverse", issue = "none")] #[inline] - pub fn reverse(&mut self) { + pub const fn reverse(&mut self) { let half_len = self.len() / 2; let Range { start, end } = self.as_mut_ptr_range(); @@ -698,9 +699,9 @@ impl [T] { revswap(front_half, back_half, half_len); #[inline] - fn revswap(a: &mut [T], b: &mut [T], n: usize) { - debug_assert_eq!(a.len(), n); - debug_assert_eq!(b.len(), n); + const fn revswap(a: &mut [T], b: &mut [T], n: usize) { + debug_assert!(a.len() == n); + debug_assert!(b.len() == n); // Because this function is first compiled in isolation, // this check tells LLVM that the indexing below is @@ -708,8 +709,10 @@ impl [T] { // lengths of the slices are known -- it's removed. let (a, b) = (&mut a[..n], &mut b[..n]); - for i in 0..n { + let mut i = 0; + while i < n { mem::swap(&mut a[i], &mut b[n - 1 - i]); + i += 1; } } } From 934d259b8ca1237c3fb50be21b8bba5ec8e6a7ce Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 19 Aug 2022 14:35:15 +0200 Subject: [PATCH 04/20] Fix invalid comparison for Class::Decoration in `is_equal_to` --- src/librustdoc/html/highlight.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 9d8ee52a3faf..944cf0885124 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -291,8 +291,8 @@ impl Class { match (self, other) { (Self::Self_(_), Self::Self_(_)) | (Self::Macro(_), Self::Macro(_)) - | (Self::Ident(_), Self::Ident(_)) - | (Self::Decoration(_), Self::Decoration(_)) => true, + | (Self::Ident(_), Self::Ident(_)) => true, + (Self::Decoration(c1), Self::Decoration(c2)) => c1 == c2, (x, y) => x == y, } } From 7d2083c58ea9208c456b0bef177d87665e8c8a4f Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 7 Apr 2022 11:16:37 +0200 Subject: [PATCH 05/20] small mir typeck cleanup --- compiler/rustc_borrowck/src/type_check/canonical.rs | 7 ++++--- .../rustc_borrowck/src/type_check/free_region_relations.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 6cfe5efb6888..451b82c5c187 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -90,12 +90,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { locations: Locations, category: ConstraintCategory<'tcx>, ) { - self.prove_predicates( - Some(ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { + self.prove_predicate( + ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: ty::BoundConstness::NotConst, polarity: ty::ImplPolarity::Positive, - }))), + })) + .to_predicate(self.tcx()), locations, category, ); diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 74655369faf0..bb28622edf93 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -268,7 +268,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { // } // impl Foo for () { // type Bar = (); - // fn foo(&self) ->&() {} + // fn foo(&self) -> &() {} // } // ``` // Both &Self::Bar and &() are WF diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 7bf7f7357bf4..bb2e773189c0 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1911,7 +1911,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } - &Rvalue::NullaryOp(_, ty) => { + &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { let trait_ref = ty::TraitRef { def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), substs: tcx.mk_substs_trait(ty, &[]), From 56b5ec83f2ade19fc601ad44a7366d3e5215401a Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 7 Apr 2022 11:28:31 +0200 Subject: [PATCH 06/20] move `type_check_internal` into `type_check` --- compiler/rustc_borrowck/src/type_check/mod.rs | 139 +++++++----------- 1 file changed, 53 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index bb2e773189c0..293d847ec9ab 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -178,97 +178,15 @@ pub(crate) fn type_check<'mir, 'tcx>( upvars, }; - let opaque_type_values = type_check_internal( - infcx, - param_env, - body, - promoted, - ®ion_bound_pairs, - implicit_region_bound, - &mut borrowck_context, - |mut cx| { - debug!("inside extra closure of type_check_internal"); - cx.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output); - liveness::generate( - &mut cx, - body, - elements, - flow_inits, - move_data, - location_table, - use_polonius, - ); - - translate_outlives_facts(&mut cx); - let opaque_type_values = - infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); - - opaque_type_values - .into_iter() - .map(|(opaque_type_key, decl)| { - cx.fully_perform_op( - Locations::All(body.span), - ConstraintCategory::OpaqueType, - CustomTypeOp::new( - |infcx| { - infcx.register_member_constraints( - param_env, - opaque_type_key, - decl.hidden_type.ty, - decl.hidden_type.span, - ); - Ok(InferOk { value: (), obligations: vec![] }) - }, - || "opaque_type_map".to_string(), - ), - ) - .unwrap(); - let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); - trace!( - "finalized opaque type {:?} to {:#?}", - opaque_type_key, - hidden_type.ty.kind() - ); - if hidden_type.has_infer_types_or_consts() { - infcx.tcx.sess.delay_span_bug( - decl.hidden_type.span, - &format!("could not resolve {:#?}", hidden_type.ty.kind()), - ); - hidden_type.ty = infcx.tcx.ty_error(); - } - - (opaque_type_key, (hidden_type, decl.origin)) - }) - .collect() - }, - ); - - MirTypeckResults { constraints, universal_region_relations, opaque_type_values } -} - -#[instrument( - skip(infcx, body, promoted, region_bound_pairs, borrowck_context, extra), - level = "debug" -)] -fn type_check_internal<'a, 'tcx, R>( - infcx: &'a InferCtxt<'a, 'tcx>, - param_env: ty::ParamEnv<'tcx>, - body: &'a Body<'tcx>, - promoted: &'a IndexVec>, - region_bound_pairs: &'a RegionBoundPairs<'tcx>, - implicit_region_bound: ty::Region<'tcx>, - borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, - extra: impl FnOnce(TypeChecker<'a, 'tcx>) -> R, -) -> R { - debug!("body: {:#?}", body); let mut checker = TypeChecker::new( infcx, body, param_env, - region_bound_pairs, + ®ion_bound_pairs, implicit_region_bound, - borrowck_context, + &mut borrowck_context, ); + let errors_reported = { let mut verifier = TypeVerifier::new(&mut checker, promoted); verifier.visit_body(&body); @@ -280,7 +198,56 @@ fn type_check_internal<'a, 'tcx, R>( checker.typeck_mir(body); } - extra(checker) + checker.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output); + liveness::generate( + &mut checker, + body, + elements, + flow_inits, + move_data, + location_table, + use_polonius, + ); + + translate_outlives_facts(&mut checker); + let opaque_type_values = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); + + let opaque_type_values = opaque_type_values + .into_iter() + .map(|(opaque_type_key, decl)| { + checker + .fully_perform_op( + Locations::All(body.span), + ConstraintCategory::OpaqueType, + CustomTypeOp::new( + |infcx| { + infcx.register_member_constraints( + param_env, + opaque_type_key, + decl.hidden_type.ty, + decl.hidden_type.span, + ); + Ok(InferOk { value: (), obligations: vec![] }) + }, + || "opaque_type_map".to_string(), + ), + ) + .unwrap(); + let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); + trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind()); + if hidden_type.has_infer_types_or_consts() { + infcx.tcx.sess.delay_span_bug( + decl.hidden_type.span, + &format!("could not resolve {:#?}", hidden_type.ty.kind()), + ); + hidden_type.ty = infcx.tcx.ty_error(); + } + + (opaque_type_key, (hidden_type, decl.origin)) + }) + .collect(); + + MirTypeckResults { constraints, universal_region_relations, opaque_type_values } } fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) { From 07e41fb54c3d06afb1c100e945f2eae2233ff270 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Fri, 19 Aug 2022 14:37:53 +0000 Subject: [PATCH 07/20] update test for LLVM change LLVM commit https://github.com/llvm/llvm-project/commit/c2a38887932e3a46aa3bee35f3f5568ac68282f4 updates the PIC level version selection. This updates the rust tests to work under both the old and new behaviors. Detected by our experimental rust + llvm @ HEAD bot: https://buildkite.com/llvm-project/rust-llvm-integrate-prototype/builds/12829#0182b368-a405-47a2-b3da-9c79cb907bfe/701-709 --- src/test/codegen/pic-relocation-model.rs | 2 +- src/test/codegen/pie-relocation-model.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/codegen/pic-relocation-model.rs b/src/test/codegen/pic-relocation-model.rs index 6e1d5a6c3f27..bcfe2f9af50b 100644 --- a/src/test/codegen/pic-relocation-model.rs +++ b/src/test/codegen/pic-relocation-model.rs @@ -13,4 +13,4 @@ pub fn call_foreign_fn() -> u8 { // CHECK: declare zeroext i8 @foreign_fn() extern "C" {fn foreign_fn() -> u8;} -// CHECK: !{i32 7, !"PIC Level", i32 2} +// CHECK: !{i32 {{[78]}}, !"PIC Level", i32 2} diff --git a/src/test/codegen/pie-relocation-model.rs b/src/test/codegen/pie-relocation-model.rs index a843202a94f8..ec44edc06677 100644 --- a/src/test/codegen/pie-relocation-model.rs +++ b/src/test/codegen/pie-relocation-model.rs @@ -18,5 +18,5 @@ pub fn call_foreign_fn() -> u8 { // CHECK: declare zeroext i8 @foreign_fn() extern "C" {fn foreign_fn() -> u8;} -// CHECK: !{i32 7, !"PIC Level", i32 2} +// CHECK: !{i32 {{[78]}}, !"PIC Level", i32 2} // CHECK: !{i32 7, !"PIE Level", i32 2} From 8b7b1f773a4d97b9567eb5998b5e59a718ece9d7 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Wed, 17 Aug 2022 13:07:17 -0700 Subject: [PATCH 08/20] Minor syntax and formatting update to doc comment The comment is on find_vtable_types_for_unsizing, but there is another unrelated typo fix as well. --- compiler/rustc_monomorphize/src/collector.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 96bbf5802e73..82ef16a7f72f 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -128,7 +128,7 @@ //! #### Unsizing Casts //! A subtle way of introducing neighbor edges is by casting to a trait object. //! Since the resulting fat-pointer contains a reference to a vtable, we need to -//! instantiate all object-save methods of the trait, as we need to store +//! instantiate all object-safe methods of the trait, as we need to store //! pointers to these functions even if they never get called anywhere. This can //! be seen as a special case of taking a function reference. //! @@ -1044,10 +1044,12 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> /// them. /// /// For example, the source type might be `&SomeStruct` and the target type -/// might be `&SomeTrait` in a cast like: +/// might be `&dyn SomeTrait` in a cast like: /// +/// ```rust,ignore (not real code) /// let src: &SomeStruct = ...; -/// let target = src as &SomeTrait; +/// let target = src as &dyn SomeTrait; +/// ``` /// /// Then the output of this function would be (SomeStruct, SomeTrait) since for /// constructing the `target` fat-pointer we need the vtable for that pair. @@ -1068,8 +1070,10 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> /// for the pair of `T` (which is a trait) and the concrete type that `T` was /// originally coerced from: /// +/// ```rust,ignore (not real code) /// let src: &ComplexStruct = ...; -/// let target = src as &ComplexStruct; +/// let target = src as &ComplexStruct; +/// ``` /// /// Again, we want this `find_vtable_types_for_unsizing()` to provide the pair /// `(SomeStruct, SomeTrait)`. From ae2b1dbc8915c2a41bc3555cceb65a07c0032b05 Mon Sep 17 00:00:00 2001 From: ltdk Date: Fri, 19 Aug 2022 20:38:32 -0400 Subject: [PATCH 09/20] Tracking issue for const_reverse --- library/core/src/slice/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 361862cdd525..75c7c4d5581d 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -674,7 +674,7 @@ impl [T] { /// assert!(v == [3, 2, 1]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_reverse", issue = "none")] + #[rustc_const_unstable(feature = "const_reverse", issue = "100784")] #[inline] pub const fn reverse(&mut self) { let half_len = self.len() / 2; From 042e0d02d74862796e9716abee07455b5e885151 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 19 Aug 2022 17:27:22 +0200 Subject: [PATCH 10/20] Merge "EnterSpan" events to reduce code blocks DOM size --- src/librustdoc/html/highlight.rs | 91 ++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 23 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 944cf0885124..562a5933025f 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -141,7 +141,7 @@ fn write_pending_elems( if !done { // We only want to "open" the tag ourselves if we have more than one pending and if the current // parent tag is not the same as our pending content. - let open_tag_ourselves = pending_elems.len() > 1; + let open_tag_ourselves = pending_elems.len() > 1 && current_class.is_some(); let close_tag = if open_tag_ourselves { enter_span(out, current_class.unwrap(), &href_context) } else { @@ -158,6 +158,18 @@ fn write_pending_elems( *current_class = None; } +fn handle_exit_span( + out: &mut Buffer, + href_context: &Option>, + pending_elems: &mut Vec<(&str, Option)>, + closing_tags: &mut Vec<(&str, Class)>, +) { + let class = closing_tags.last().expect("ExitSpan without EnterSpan").1; + // We flush everything just in case... + write_pending_elems(out, href_context, pending_elems, &mut Some(class), closing_tags); + exit_span(out, closing_tags.pop().expect("ExitSpan without EnterSpan").0); +} + /// Check if two `Class` can be merged together. In the following rules, "unclassified" means `None` /// basically (since it's `Option`). The following rules apply: /// @@ -171,7 +183,7 @@ fn can_merge(class1: Option, class2: Option, text: &str) -> bool { (Some(c1), Some(c2)) => c1.is_equal_to(c2), (Some(Class::Ident(_)), None) | (None, Some(Class::Ident(_))) => true, (Some(_), None) | (None, Some(_)) => text.trim().is_empty(), - _ => false, + (None, None) => true, } } @@ -196,6 +208,9 @@ fn write_code( let src = src.replace("\r\n", "\n"); // It contains the closing tag and the associated `Class`. let mut closing_tags: Vec<(&'static str, Class)> = Vec::new(); + // This is used because we don't automatically generate the closing tag on `ExitSpan` in + // case an `EnterSpan` event with the same class follows. + let mut pending_exit_span: Option = None; // The following two variables are used to group HTML elements with same `class` attributes // to reduce the DOM size. let mut current_class: Option = None; @@ -211,9 +226,21 @@ fn write_code( .highlight(&mut |highlight| { match highlight { Highlight::Token { text, class } => { + // If we received a `ExitSpan` event and then have a non-compatible `Class`, we + // need to close the ``. + if let Some(pending) = pending_exit_span && + !can_merge(Some(pending), class, text) { + handle_exit_span( + out, + &href_context, + &mut pending_elems, + &mut closing_tags, + ); + pending_exit_span = None; + current_class = class.map(Class::dummy); // If the two `Class` are different, time to flush the current content and start // a new one. - if !can_merge(current_class, class, text) { + } else if !can_merge(current_class, class, text) { write_pending_elems( out, &href_context, @@ -228,30 +255,48 @@ fn write_code( pending_elems.push((text, class)); } Highlight::EnterSpan { class } => { - // We flush everything just in case... - write_pending_elems( - out, - &href_context, - &mut pending_elems, - &mut current_class, - &closing_tags, - ); - closing_tags.push((enter_span(out, class, &href_context), class)) + let mut should_add = true; + if pending_exit_span.is_some() { + if !can_merge(Some(class), pending_exit_span, "") { + handle_exit_span(out, &href_context, &mut pending_elems, &mut closing_tags); + } else { + should_add = false; + } + } else { + // We flush everything just in case... + write_pending_elems( + out, + &href_context, + &mut pending_elems, + &mut current_class, + &closing_tags, + ); + } + current_class = None; + pending_exit_span = None; + if should_add { + let closing_tag = enter_span(out, class, &href_context); + closing_tags.push((closing_tag, class)); + } } Highlight::ExitSpan => { - // We flush everything just in case... - write_pending_elems( - out, - &href_context, - &mut pending_elems, - &mut current_class, - &closing_tags, - ); - exit_span(out, closing_tags.pop().expect("ExitSpan without EnterSpan").0) + current_class = None; + pending_exit_span = + Some(closing_tags.last().as_ref().expect("ExitSpan without EnterSpan").1); } }; }); - write_pending_elems(out, &href_context, &mut pending_elems, &mut current_class, &closing_tags); + if pending_exit_span.is_some() { + handle_exit_span(out, &href_context, &mut pending_elems, &mut closing_tags); + } else { + write_pending_elems( + out, + &href_context, + &mut pending_elems, + &mut current_class, + &closing_tags, + ); + } } fn write_footer(out: &mut Buffer, playground_button: Option<&str>) { @@ -761,7 +806,7 @@ impl<'a> Classifier<'a> { TokenKind::CloseBracket => { if self.in_attribute { self.in_attribute = false; - sink(Highlight::Token { text: "]", class: Some(Class::Attribute) }); + sink(Highlight::Token { text: "]", class: None }); sink(Highlight::ExitSpan); return; } From f5b5d867d5954c2a843f6a3db338ea86fafd66b1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 19 Aug 2022 18:16:02 +0200 Subject: [PATCH 11/20] Update rustdoc tests --- .../html/highlight/fixtures/decorations.html | 4 ++-- .../html/highlight/fixtures/sample.html | 15 ++++++++------- src/librustdoc/html/highlight/fixtures/sample.rs | 1 + src/test/rustdoc/issue-41783.codeblock.html | 4 ++-- src/test/rustdoc/issue-41783.rs | 6 ++++-- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/html/highlight/fixtures/decorations.html b/src/librustdoc/html/highlight/fixtures/decorations.html index 218489787215..f73e7c1fe769 100644 --- a/src/librustdoc/html/highlight/fixtures/decorations.html +++ b/src/librustdoc/html/highlight/fixtures/decorations.html @@ -1,2 +1,2 @@ -let x = 1; -let y = 2; \ No newline at end of file +let x = 1; +let y = 2; \ No newline at end of file diff --git a/src/librustdoc/html/highlight/fixtures/sample.html b/src/librustdoc/html/highlight/fixtures/sample.html index ae2650528eb7..4a5a3cf609cd 100644 --- a/src/librustdoc/html/highlight/fixtures/sample.html +++ b/src/librustdoc/html/highlight/fixtures/sample.html @@ -8,12 +8,13 @@ .lifetime { color: #B76514; } .question-mark { color: #ff9011; } -
#![crate_type = "lib"]
+
#![crate_type = "lib"]
 
-use std::path::{Path, PathBuf};
+use std::path::{Path, PathBuf};
 
-#[cfg(target_os = "linux")]
-fn main() -> () {
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "windows")]
+fn main() -> () {
     let foo = true && false || true;
     let _: *const () = 0;
     let _ = &foo;
@@ -22,8 +23,8 @@
     mac!(foo, &mut bar);
     assert!(self.length < N && index <= self.length);
     ::std::env::var("gateau").is_ok();
-    #[rustfmt::skip]
-    let s:std::path::PathBuf = std::path::PathBuf::new();
+    #[rustfmt::skip]
+    let s:std::path::PathBuf = std::path::PathBuf::new();
     let mut s = String::new();
 
     match &s {
@@ -31,7 +32,7 @@
     }
 }
 
-macro_rules! bar {
+macro_rules! bar {
     ($foo:tt) => {};
 }
 
diff --git a/src/librustdoc/html/highlight/fixtures/sample.rs b/src/librustdoc/html/highlight/fixtures/sample.rs index fbfdc6767337..ef85b566cb3c 100644 --- a/src/librustdoc/html/highlight/fixtures/sample.rs +++ b/src/librustdoc/html/highlight/fixtures/sample.rs @@ -3,6 +3,7 @@ use std::path::{Path, PathBuf}; #[cfg(target_os = "linux")] +#[cfg(target_os = "windows")] fn main() -> () { let foo = true && false || true; let _: *const () = 0; diff --git a/src/test/rustdoc/issue-41783.codeblock.html b/src/test/rustdoc/issue-41783.codeblock.html index b919935e4b47..89987491d1b4 100644 --- a/src/test/rustdoc/issue-41783.codeblock.html +++ b/src/test/rustdoc/issue-41783.codeblock.html @@ -1,5 +1,5 @@ # single ## double ### triple -#[outer] -#![inner] \ No newline at end of file +#[outer] +#![inner]
diff --git a/src/test/rustdoc/issue-41783.rs b/src/test/rustdoc/issue-41783.rs index d67716028799..87267a750c61 100644 --- a/src/test/rustdoc/issue-41783.rs +++ b/src/test/rustdoc/issue-41783.rs @@ -1,8 +1,10 @@ // @has issue_41783/struct.Foo.html // @!hasraw - 'space' // @!hasraw - 'comment' -// @hasraw - '#[outer]' -// @hasraw - '#![inner]' +// @hasraw - '#[outer]' +// @!hasraw - '#[outer]' +// @hasraw - '#![inner]' +// @!hasraw - '#![inner]' // @snapshot 'codeblock' - '//*[@class="rustdoc-toggle top-doc"]/*[@class="docblock"]//pre/code' /// ```no_run From 4c89c2886d9d915db3e11a9f87a188cada9dd457 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 19 Aug 2022 21:35:09 +0200 Subject: [PATCH 12/20] Clean up highlight `` merge code --- src/librustdoc/html/highlight.rs | 239 +++++++++++++++---------------- 1 file changed, 118 insertions(+), 121 deletions(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 562a5933025f..4a12d74ddef5 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -111,65 +111,6 @@ fn write_header(out: &mut Buffer, class: &str, extra_content: Option) { write!(out, ""); } -/// Write all the pending elements sharing a same (or at mergeable) `Class`. -/// -/// If there is a "parent" (if a `EnterSpan` event was encountered) and the parent can be merged -/// with the elements' class, then we simply write the elements since the `ExitSpan` event will -/// close the tag. -/// -/// Otherwise, if there is only one pending element, we let the `string` function handle both -/// opening and closing the tag, otherwise we do it into this function. -fn write_pending_elems( - out: &mut Buffer, - href_context: &Option>, - pending_elems: &mut Vec<(&str, Option)>, - current_class: &mut Option, - closing_tags: &[(&str, Class)], -) { - if pending_elems.is_empty() { - return; - } - let mut done = false; - if let Some((_, parent_class)) = closing_tags.last() { - if can_merge(*current_class, Some(*parent_class), "") { - for (text, class) in pending_elems.iter() { - string(out, Escape(text), *class, &href_context, false); - } - done = true; - } - } - if !done { - // We only want to "open" the tag ourselves if we have more than one pending and if the current - // parent tag is not the same as our pending content. - let open_tag_ourselves = pending_elems.len() > 1 && current_class.is_some(); - let close_tag = if open_tag_ourselves { - enter_span(out, current_class.unwrap(), &href_context) - } else { - "" - }; - for (text, class) in pending_elems.iter() { - string(out, Escape(text), *class, &href_context, !open_tag_ourselves); - } - if open_tag_ourselves { - exit_span(out, close_tag); - } - } - pending_elems.clear(); - *current_class = None; -} - -fn handle_exit_span( - out: &mut Buffer, - href_context: &Option>, - pending_elems: &mut Vec<(&str, Option)>, - closing_tags: &mut Vec<(&str, Class)>, -) { - let class = closing_tags.last().expect("ExitSpan without EnterSpan").1; - // We flush everything just in case... - write_pending_elems(out, href_context, pending_elems, &mut Some(class), closing_tags); - exit_span(out, closing_tags.pop().expect("ExitSpan without EnterSpan").0); -} - /// Check if two `Class` can be merged together. In the following rules, "unclassified" means `None` /// basically (since it's `Option`). The following rules apply: /// @@ -187,6 +128,87 @@ fn can_merge(class1: Option, class2: Option, text: &str) -> bool { } } +/// This type is used as a conveniency to prevent having to pass all its fields as arguments into +/// the various functions (which became its methods). +struct TokenHandler<'a, 'b, 'c, 'd, 'e> { + out: &'a mut Buffer, + /// It contains the closing tag and the associated `Class`. + closing_tags: Vec<(&'static str, Class)>, + /// This is used because we don't automatically generate the closing tag on `ExitSpan` in + /// case an `EnterSpan` event with the same class follows. + pending_exit_span: Option, + /// `current_class` and `pending_elems` are used to group HTML elements with same `class` + /// attributes to reduce the DOM size. + current_class: Option, + /// We need to keep the `Class` for each element because it could contain a `Span` which is + /// used to generate links. + pending_elems: Vec<(&'b str, Option)>, + href_context: Option>, +} + +impl<'a, 'b, 'c, 'd, 'e> TokenHandler<'a, 'b, 'c, 'd, 'e> { + fn handle_exit_span(&mut self) { + // We can't get the last `closing_tags` element using `pop()` because `closing_tags` is + // being used in `write_pending_elems`. + let class = self.closing_tags.last().expect("ExitSpan without EnterSpan").1; + // We flush everything just in case... + self.write_pending_elems(Some(class)); + + exit_span(self.out, self.closing_tags.pop().expect("ExitSpan without EnterSpan").0); + self.pending_exit_span = None; + } + + /// Write all the pending elements sharing a same (or at mergeable) `Class`. + /// + /// If there is a "parent" (if a `EnterSpan` event was encountered) and the parent can be merged + /// with the elements' class, then we simply write the elements since the `ExitSpan` event will + /// close the tag. + /// + /// Otherwise, if there is only one pending element, we let the `string` function handle both + /// opening and closing the tag, otherwise we do it into this function. + /// + /// It returns `true` if `current_class` must be set to `None` afterwards. + fn write_pending_elems(&mut self, current_class: Option) -> bool { + if self.pending_elems.is_empty() { + return false; + } + if let Some((_, parent_class)) = self.closing_tags.last() && + can_merge(current_class, Some(*parent_class), "") + { + for (text, class) in self.pending_elems.iter() { + string(self.out, Escape(text), *class, &self.href_context, false); + } + } else { + // We only want to "open" the tag ourselves if we have more than one pending and if the + // current parent tag is not the same as our pending content. + let close_tag = if self.pending_elems.len() > 1 && current_class.is_some() { + Some(enter_span(self.out, current_class.unwrap(), &self.href_context)) + } else { + None + }; + for (text, class) in self.pending_elems.iter() { + string(self.out, Escape(text), *class, &self.href_context, close_tag.is_none()); + } + if let Some(close_tag) = close_tag { + exit_span(self.out, close_tag); + } + } + self.pending_elems.clear(); + true + } +} + +impl<'a, 'b, 'c, 'd, 'e> Drop for TokenHandler<'a, 'b, 'c, 'd, 'e> { + /// When leaving, we need to flush all pending data to not have missing content. + fn drop(&mut self) { + if self.pending_exit_span.is_some() { + self.handle_exit_span(); + } else { + self.write_pending_elems(self.current_class); + } + } +} + /// Convert the given `src` source code into HTML by adding classes for highlighting. /// /// This code is used to render code blocks (in the documentation) as well as the source code pages. @@ -206,21 +228,18 @@ fn write_code( ) { // This replace allows to fix how the code source with DOS backline characters is displayed. let src = src.replace("\r\n", "\n"); - // It contains the closing tag and the associated `Class`. - let mut closing_tags: Vec<(&'static str, Class)> = Vec::new(); - // This is used because we don't automatically generate the closing tag on `ExitSpan` in - // case an `EnterSpan` event with the same class follows. - let mut pending_exit_span: Option = None; - // The following two variables are used to group HTML elements with same `class` attributes - // to reduce the DOM size. - let mut current_class: Option = None; - // We need to keep the `Class` for each element because it could contain a `Span` which is - // used to generate links. - let mut pending_elems: Vec<(&str, Option)> = Vec::new(); + let mut token_handler = TokenHandler { + out, + closing_tags: Vec::new(), + pending_exit_span: None, + current_class: None, + pending_elems: Vec::new(), + href_context, + }; Classifier::new( &src, - href_context.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP), + token_handler.href_context.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP), decoration_info, ) .highlight(&mut |highlight| { @@ -228,75 +247,53 @@ fn write_code( Highlight::Token { text, class } => { // If we received a `ExitSpan` event and then have a non-compatible `Class`, we // need to close the ``. - if let Some(pending) = pending_exit_span && + let need_current_class_update = if let Some(pending) = token_handler.pending_exit_span && !can_merge(Some(pending), class, text) { - handle_exit_span( - out, - &href_context, - &mut pending_elems, - &mut closing_tags, - ); - pending_exit_span = None; - current_class = class.map(Class::dummy); + token_handler.handle_exit_span(); + true // If the two `Class` are different, time to flush the current content and start // a new one. - } else if !can_merge(current_class, class, text) { - write_pending_elems( - out, - &href_context, - &mut pending_elems, - &mut current_class, - &closing_tags, - ); - current_class = class.map(Class::dummy); - } else if current_class.is_none() { - current_class = class.map(Class::dummy); + } else if !can_merge(token_handler.current_class, class, text) { + token_handler.write_pending_elems(token_handler.current_class); + true + } else { + token_handler.current_class.is_none() + }; + + if need_current_class_update { + token_handler.current_class = class.map(Class::dummy); } - pending_elems.push((text, class)); + token_handler.pending_elems.push((text, class)); } Highlight::EnterSpan { class } => { let mut should_add = true; - if pending_exit_span.is_some() { - if !can_merge(Some(class), pending_exit_span, "") { - handle_exit_span(out, &href_context, &mut pending_elems, &mut closing_tags); - } else { + if let Some(pending_exit_span) = token_handler.pending_exit_span { + if class.is_equal_to(pending_exit_span) { should_add = false; + } else { + token_handler.handle_exit_span(); } } else { // We flush everything just in case... - write_pending_elems( - out, - &href_context, - &mut pending_elems, - &mut current_class, - &closing_tags, - ); + if token_handler.write_pending_elems(token_handler.current_class) { + token_handler.current_class = None; + } } - current_class = None; - pending_exit_span = None; if should_add { - let closing_tag = enter_span(out, class, &href_context); - closing_tags.push((closing_tag, class)); + let closing_tag = enter_span(token_handler.out, class, &token_handler.href_context); + token_handler.closing_tags.push((closing_tag, class)); } + + token_handler.current_class = None; + token_handler.pending_exit_span = None; } Highlight::ExitSpan => { - current_class = None; - pending_exit_span = - Some(closing_tags.last().as_ref().expect("ExitSpan without EnterSpan").1); + token_handler.current_class = None; + token_handler.pending_exit_span = + Some(token_handler.closing_tags.last().as_ref().expect("ExitSpan without EnterSpan").1); } }; }); - if pending_exit_span.is_some() { - handle_exit_span(out, &href_context, &mut pending_elems, &mut closing_tags); - } else { - write_pending_elems( - out, - &href_context, - &mut pending_elems, - &mut current_class, - &closing_tags, - ); - } } fn write_footer(out: &mut Buffer, playground_button: Option<&str>) { From 7ab8e0cbe4c6e7617fe43a44467c463fad3b010e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 20 Aug 2022 14:24:05 +0200 Subject: [PATCH 13/20] Extend decoration test to detect regressions --- src/librustdoc/html/highlight/fixtures/decorations.html | 4 +++- src/librustdoc/html/highlight/tests.rs | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/highlight/fixtures/decorations.html b/src/librustdoc/html/highlight/fixtures/decorations.html index f73e7c1fe769..ebf29f9cb3a9 100644 --- a/src/librustdoc/html/highlight/fixtures/decorations.html +++ b/src/librustdoc/html/highlight/fixtures/decorations.html @@ -1,2 +1,4 @@ let x = 1; -let y = 2; \ No newline at end of file +let y = 2; +let z = 3; +let a = 4; \ No newline at end of file diff --git a/src/librustdoc/html/highlight/tests.rs b/src/librustdoc/html/highlight/tests.rs index 4861a8ad32da..a5e633df4344 100644 --- a/src/librustdoc/html/highlight/tests.rs +++ b/src/librustdoc/html/highlight/tests.rs @@ -69,9 +69,12 @@ fn test_union_highlighting() { fn test_decorations() { create_default_session_globals_then(|| { let src = "let x = 1; -let y = 2;"; +let y = 2; +let z = 3; +let a = 4;"; let mut decorations = FxHashMap::default(); - decorations.insert("example", vec![(0, 10)]); + decorations.insert("example", vec![(0, 10), (11, 21)]); + decorations.insert("example2", vec![(22, 32)]); let mut html = Buffer::new(); write_code(&mut html, src, None, Some(DecorationInfo(decorations))); From 0c3ed968a2117dcd532abf8ed58a8ce49a7bc742 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 20 Aug 2022 21:07:13 +0200 Subject: [PATCH 14/20] Add `/build-rust-analyzer/` to .gitignore To avoid rust-analyzer and rustc having to wait for each other, the dev guide mentions using another build directory for RA. We should also put this into the .gitignore, just like the normal `build`. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a6625ac2ac4a..b16fb6341c2e 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ no_llvm_build /llvm/ /mingw-build/ /build/ +/build-rust-analyzer/ /dist/ /unicode-downloads /target From 03146471b58be8a0f9133064ea503252e60f7466 Mon Sep 17 00:00:00 2001 From: scottmcm Date: Sat, 20 Aug 2022 21:08:56 +0000 Subject: [PATCH 15/20] Allow other directives before the `ret` --- src/test/assembly/x86_64-floating-point-clamp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/assembly/x86_64-floating-point-clamp.rs b/src/test/assembly/x86_64-floating-point-clamp.rs index 4493791a5769..0f3b465d08d4 100644 --- a/src/test/assembly/x86_64-floating-point-clamp.rs +++ b/src/test/assembly/x86_64-floating-point-clamp.rs @@ -20,6 +20,6 @@ pub fn clamp12_demo(a: f32) -> f32 { // CHECK-NEXT: maxss xmm1, xmm0 // CHECK-NEXT: movss xmm0 // CHECK-NEXT: minss xmm0, xmm1 - // CHECK-NEXT: ret + // CHECK: ret a.clamp(1.0, 2.0) } From e4720e1cf26b6a9804615f79dc6ff1a006399cf1 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 19 Aug 2022 13:33:06 +0400 Subject: [PATCH 16/20] Replace most uses of `pointer::offset` with `add` and `sub` --- compiler/rustc_arena/src/lib.rs | 2 +- .../example/alloc_system.rs | 2 +- .../rustc_codegen_gcc/example/alloc_system.rs | 2 +- compiler/rustc_serialize/src/serialize.rs | 2 +- library/alloc/src/alloc/tests.rs | 2 +- .../alloc/src/collections/vec_deque/mod.rs | 4 +-- library/alloc/src/slice.rs | 6 ++-- library/alloc/src/vec/in_place_collect.rs | 2 +- library/alloc/src/vec/into_iter.rs | 6 ++-- library/alloc/src/vec/mod.rs | 6 ++-- library/alloc/src/vec/spec_extend.rs | 2 +- library/alloc/tests/str.rs | 10 +++--- library/core/src/slice/mod.rs | 2 +- library/core/src/slice/sort.rs | 36 +++++++++---------- library/core/src/str/validations.rs | 4 +-- library/panic_abort/src/android.rs | 2 +- library/panic_unwind/src/dwarf/eh.rs | 2 +- library/std/src/os/unix/net/addr.rs | 2 +- .../std/src/sys/sgx/abi/usercalls/tests.rs | 4 +-- library/std/src/sys/windows/alloc.rs | 4 +-- library/std/src/sys/windows/fs.rs | 6 ++-- library/std/src/sys/windows/os.rs | 6 ++-- 22 files changed, 57 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 6529f11100d2..daf67217e64a 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -217,7 +217,7 @@ impl TypedArena { } else { let ptr = self.ptr.get(); // Advance the pointer. - self.ptr.set(self.ptr.get().offset(1)); + self.ptr.set(self.ptr.get().add(1)); // Write into uninitialized memory. ptr::write(ptr, object); &mut *ptr diff --git a/compiler/rustc_codegen_cranelift/example/alloc_system.rs b/compiler/rustc_codegen_cranelift/example/alloc_system.rs index cf95c89bc315..50261c193973 100644 --- a/compiler/rustc_codegen_cranelift/example/alloc_system.rs +++ b/compiler/rustc_codegen_cranelift/example/alloc_system.rs @@ -94,7 +94,7 @@ mod platform { struct Header(*mut u8); const HEAP_ZERO_MEMORY: DWORD = 0x00000008; unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header { - &mut *(ptr as *mut Header).offset(-1) + &mut *(ptr as *mut Header).sub(1) } unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 { let aligned = ptr.add(align - (ptr as usize & (align - 1))); diff --git a/compiler/rustc_codegen_gcc/example/alloc_system.rs b/compiler/rustc_codegen_gcc/example/alloc_system.rs index 5f66ca67f2d4..89661918d05a 100644 --- a/compiler/rustc_codegen_gcc/example/alloc_system.rs +++ b/compiler/rustc_codegen_gcc/example/alloc_system.rs @@ -156,7 +156,7 @@ mod platform { struct Header(*mut u8); const HEAP_ZERO_MEMORY: DWORD = 0x00000008; unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header { - &mut *(ptr as *mut Header).offset(-1) + &mut *(ptr as *mut Header).sub(1) } unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 { let aligned = ptr.add(align - (ptr as usize & (align - 1))); diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index 36585b8d77e0..9bd5550038fc 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -273,7 +273,7 @@ impl> Decodable for Vec { unsafe { let ptr: *mut T = vec.as_mut_ptr(); for i in 0..len { - std::ptr::write(ptr.offset(i as isize), Decodable::decode(d)); + std::ptr::write(ptr.add(i), Decodable::decode(d)); } vec.set_len(len); } diff --git a/library/alloc/src/alloc/tests.rs b/library/alloc/src/alloc/tests.rs index 7d560964d85b..b2f0194599b2 100644 --- a/library/alloc/src/alloc/tests.rs +++ b/library/alloc/src/alloc/tests.rs @@ -15,7 +15,7 @@ fn allocate_zeroed() { let end = i.add(layout.size()); while i < end { assert_eq!(*i, 0); - i = i.offset(1); + i = i.add(1); } Global.deallocate(ptr.as_non_null_ptr(), layout); } diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 4d895d83745b..57ab74e01590 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2447,8 +2447,8 @@ impl VecDeque { let mut right_offset = 0; for i in left_edge..right_edge { right_offset = (i - left_edge) % (cap - right_edge); - let src: isize = (right_edge + right_offset) as isize; - ptr::swap(buf.add(i), buf.offset(src)); + let src = right_edge + right_offset; + ptr::swap(buf.add(i), buf.add(src)); } let n_ops = right_edge - left_edge; left_edge += n_ops; diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 63d4d9452900..5733124ec756 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -1024,7 +1024,7 @@ where // Consume the greater side. // If equal, prefer the right run to maintain stability. unsafe { - let to_copy = if is_less(&*right.offset(-1), &*left.offset(-1)) { + let to_copy = if is_less(&*right.sub(1), &*left.sub(1)) { decrement_and_get(left) } else { decrement_and_get(right) @@ -1038,12 +1038,12 @@ where unsafe fn get_and_increment(ptr: &mut *mut T) -> *mut T { let old = *ptr; - *ptr = unsafe { ptr.offset(1) }; + *ptr = unsafe { ptr.add(1) }; old } unsafe fn decrement_and_get(ptr: &mut *mut T) -> *mut T { - *ptr = unsafe { ptr.offset(-1) }; + *ptr = unsafe { ptr.sub(1) }; *ptr } diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs index 55dcb84ad16f..b211421b2027 100644 --- a/library/alloc/src/vec/in_place_collect.rs +++ b/library/alloc/src/vec/in_place_collect.rs @@ -267,7 +267,7 @@ where // one slot in the underlying storage will have been freed up and we can immediately // write back the result. unsafe { - let dst = dst_buf.offset(i as isize); + let dst = dst_buf.add(i); debug_assert!(dst as *const _ <= end, "InPlaceIterable contract violation"); ptr::write(dst, self.__iterator_get_unchecked(i)); // Since this executes user code which can panic we have to bump the pointer diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 1b483e3fc779..e02ad391a595 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -160,7 +160,7 @@ impl Iterator for IntoIter { Some(unsafe { mem::zeroed() }) } else { let old = self.ptr; - self.ptr = unsafe { self.ptr.offset(1) }; + self.ptr = unsafe { self.ptr.add(1) }; Some(unsafe { ptr::read(old) }) } @@ -272,7 +272,7 @@ impl DoubleEndedIterator for IntoIter { // Make up a value of this ZST. Some(unsafe { mem::zeroed() }) } else { - self.end = unsafe { self.end.offset(-1) }; + self.end = unsafe { self.end.sub(1) }; Some(unsafe { ptr::read(self.end) }) } @@ -288,7 +288,7 @@ impl DoubleEndedIterator for IntoIter { } } else { // SAFETY: same as for advance_by() - self.end = unsafe { self.end.offset(step_size.wrapping_neg() as isize) }; + self.end = unsafe { self.end.sub(step_size) }; } let to_drop = ptr::slice_from_raw_parts_mut(self.end as *mut T, step_size); // SAFETY: same as for advance_by() diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index fa9f2131c0c1..3251e6240d8a 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1393,7 +1393,7 @@ impl Vec { if index < len { // Shift everything over to make space. (Duplicating the // `index`th element into two consecutive places.) - ptr::copy(p, p.offset(1), len - index); + ptr::copy(p, p.add(1), len - index); } else if index == len { // No elements need shifting. } else { @@ -1455,7 +1455,7 @@ impl Vec { ret = ptr::read(ptr); // Shift everything down to fill in that spot. - ptr::copy(ptr.offset(1), ptr, len - index - 1); + ptr::copy(ptr.add(1), ptr, len - index - 1); } self.set_len(len - 1); ret @@ -2408,7 +2408,7 @@ impl Vec { // Write all elements except the last one for _ in 1..n { ptr::write(ptr, value.next()); - ptr = ptr.offset(1); + ptr = ptr.add(1); // Increment the length in every step in case next() panics local_len.increment_len(1); } diff --git a/library/alloc/src/vec/spec_extend.rs b/library/alloc/src/vec/spec_extend.rs index 506ee0ecfa27..1ea9c827afd7 100644 --- a/library/alloc/src/vec/spec_extend.rs +++ b/library/alloc/src/vec/spec_extend.rs @@ -39,7 +39,7 @@ where let mut local_len = SetLenOnDrop::new(&mut self.len); iterator.for_each(move |element| { ptr::write(ptr, element); - ptr = ptr.offset(1); + ptr = ptr.add(1); // Since the loop executes user code which can panic we have to bump the pointer // after each step. // NB can't overflow since we would have had to alloc the address space diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs index 7379569dd68f..e30329aa1cb6 100644 --- a/library/alloc/tests/str.rs +++ b/library/alloc/tests/str.rs @@ -1010,11 +1010,11 @@ fn test_as_bytes_fail() { fn test_as_ptr() { let buf = "hello".as_ptr(); unsafe { - assert_eq!(*buf.offset(0), b'h'); - assert_eq!(*buf.offset(1), b'e'); - assert_eq!(*buf.offset(2), b'l'); - assert_eq!(*buf.offset(3), b'l'); - assert_eq!(*buf.offset(4), b'o'); + assert_eq!(*buf.add(0), b'h'); + assert_eq!(*buf.add(1), b'e'); + assert_eq!(*buf.add(2), b'l'); + assert_eq!(*buf.add(3), b'l'); + assert_eq!(*buf.add(4), b'o'); } } diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index e79d47c9f98c..f98a279c02f4 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2921,7 +2921,7 @@ impl [T] { let prev_ptr_write = ptr.add(next_write - 1); if !same_bucket(&mut *ptr_read, &mut *prev_ptr_write) { if next_read != next_write { - let ptr_write = prev_ptr_write.offset(1); + let ptr_write = prev_ptr_write.add(1); mem::swap(&mut *ptr_read, &mut *ptr_write); } next_write += 1; diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs index 6a201834b8e6..8b025da2a46e 100644 --- a/library/core/src/slice/sort.rs +++ b/library/core/src/slice/sort.rs @@ -326,8 +326,8 @@ where unsafe { // Branchless comparison. *end_l = i as u8; - end_l = end_l.offset(!is_less(&*elem, pivot) as isize); - elem = elem.offset(1); + end_l = end_l.add(!is_less(&*elem, pivot) as usize); + elem = elem.add(1); } } } @@ -352,9 +352,9 @@ where // Plus, `block_r` was asserted to be less than `BLOCK` and `elem` will therefore at most be pointing to the beginning of the slice. unsafe { // Branchless comparison. - elem = elem.offset(-1); + elem = elem.sub(1); *end_r = i as u8; - end_r = end_r.offset(is_less(&*elem, pivot) as isize); + end_r = end_r.add(is_less(&*elem, pivot) as usize); } } } @@ -365,12 +365,12 @@ where if count > 0 { macro_rules! left { () => { - l.offset(*start_l as isize) + l.add(*start_l as usize) }; } macro_rules! right { () => { - r.offset(-(*start_r as isize) - 1) + r.sub((*start_r as usize) + 1) }; } @@ -398,16 +398,16 @@ where ptr::copy_nonoverlapping(right!(), left!(), 1); for _ in 1..count { - start_l = start_l.offset(1); + start_l = start_l.add(1); ptr::copy_nonoverlapping(left!(), right!(), 1); - start_r = start_r.offset(1); + start_r = start_r.add(1); ptr::copy_nonoverlapping(right!(), left!(), 1); } ptr::copy_nonoverlapping(&tmp, right!(), 1); mem::forget(tmp); - start_l = start_l.offset(1); - start_r = start_r.offset(1); + start_l = start_l.add(1); + start_r = start_r.add(1); } } @@ -420,7 +420,7 @@ where // safe. Otherwise, the debug assertions in the `is_done` case guarantee that // `width(l, r) == block_l + block_r`, namely, that the block sizes have been adjusted to account // for the smaller number of remaining elements. - l = unsafe { l.offset(block_l as isize) }; + l = unsafe { l.add(block_l) }; } if start_r == end_r { @@ -428,7 +428,7 @@ where // SAFETY: Same argument as [block-width-guarantee]. Either this is a full block `2*BLOCK`-wide, // or `block_r` has been adjusted for the last handful of elements. - r = unsafe { r.offset(-(block_r as isize)) }; + r = unsafe { r.sub(block_r) }; } if is_done { @@ -457,9 +457,9 @@ where // - `offsets_l` contains valid offsets into `v` collected during the partitioning of // the last block, so the `l.offset` calls are valid. unsafe { - end_l = end_l.offset(-1); - ptr::swap(l.offset(*end_l as isize), r.offset(-1)); - r = r.offset(-1); + end_l = end_l.sub(1); + ptr::swap(l.add(*end_l as usize), r.sub(1)); + r = r.sub(1); } } width(v.as_mut_ptr(), r) @@ -470,9 +470,9 @@ where while start_r < end_r { // SAFETY: See the reasoning in [remaining-elements-safety]. unsafe { - end_r = end_r.offset(-1); - ptr::swap(l, r.offset(-(*end_r as isize) - 1)); - l = l.offset(1); + end_r = end_r.sub(1); + ptr::swap(l, r.sub((*end_r as usize) + 1)); + l = l.add(1); } } width(v.as_mut_ptr(), l) diff --git a/library/core/src/str/validations.rs b/library/core/src/str/validations.rs index 04bc665233e3..2acef432f206 100644 --- a/library/core/src/str/validations.rs +++ b/library/core/src/str/validations.rs @@ -216,12 +216,12 @@ pub(super) const fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { // SAFETY: since `align - index` and `ascii_block_size` are // multiples of `usize_bytes`, `block = ptr.add(index)` is // always aligned with a `usize` so it's safe to dereference - // both `block` and `block.offset(1)`. + // both `block` and `block.add(1)`. unsafe { let block = ptr.add(index) as *const usize; // break if there is a nonascii byte let zu = contains_nonascii(*block); - let zv = contains_nonascii(*block.offset(1)); + let zv = contains_nonascii(*block.add(1)); if zu || zv { break; } diff --git a/library/panic_abort/src/android.rs b/library/panic_abort/src/android.rs index 18bb932f10ea..0fd824f8a458 100644 --- a/library/panic_abort/src/android.rs +++ b/library/panic_abort/src/android.rs @@ -42,7 +42,7 @@ pub(crate) unsafe fn android_set_abort_message(payload: *mut &mut dyn BoxMeUp) { return; // allocation failure } copy_nonoverlapping(msg.as_ptr(), buf as *mut u8, msg.len()); - buf.offset(msg.len() as isize).write(0); + buf.add(msg.len()).write(0); let func = transmute::(func_addr); func(buf); diff --git a/library/panic_unwind/src/dwarf/eh.rs b/library/panic_unwind/src/dwarf/eh.rs index 7394feab82f2..9aa966b5063b 100644 --- a/library/panic_unwind/src/dwarf/eh.rs +++ b/library/panic_unwind/src/dwarf/eh.rs @@ -75,7 +75,7 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result let call_site_encoding = reader.read::(); let call_site_table_length = reader.read_uleb128(); - let action_table = reader.ptr.offset(call_site_table_length as isize); + let action_table = reader.ptr.add(call_site_table_length as usize); let ip = context.ip; if !USING_SJLJ_EXCEPTIONS { diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 9aeae4b2cae6..bb313c7597b6 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -329,7 +329,7 @@ impl SocketAddr { crate::ptr::copy_nonoverlapping( namespace.as_ptr(), - addr.sun_path.as_mut_ptr().offset(1) as *mut u8, + addr.sun_path.as_mut_ptr().add(1) as *mut u8, namespace.len(), ); let len = (sun_path_offset(&addr) + 1 + namespace.len()) as libc::socklen_t; diff --git a/library/std/src/sys/sgx/abi/usercalls/tests.rs b/library/std/src/sys/sgx/abi/usercalls/tests.rs index cbf7d7d54f7a..598ad5a083cc 100644 --- a/library/std/src/sys/sgx/abi/usercalls/tests.rs +++ b/library/std/src/sys/sgx/abi/usercalls/tests.rs @@ -17,12 +17,12 @@ fn test_copy_function() { dst.copy_from_enclave(&[0u8; 100]); // Copy src[0..size] to dst + offset - unsafe { copy_to_userspace(src.as_ptr(), dst.as_mut_ptr().offset(offset), size) }; + unsafe { copy_to_userspace(src.as_ptr(), dst.as_mut_ptr().add(offset), size) }; // Verify copy for byte in 0..size { unsafe { - assert_eq!(*dst.as_ptr().offset(offset + byte as isize), src[byte as usize]); + assert_eq!(*dst.as_ptr().add(offset + byte), src[byte as usize]); } } } diff --git a/library/std/src/sys/windows/alloc.rs b/library/std/src/sys/windows/alloc.rs index fdc81cdea7de..fe00c08aa6a9 100644 --- a/library/std/src/sys/windows/alloc.rs +++ b/library/std/src/sys/windows/alloc.rs @@ -168,7 +168,7 @@ unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 { // SAFETY: Because the size and alignment of a header is <= `MIN_ALIGN` and `aligned` // is aligned to at least `MIN_ALIGN` and has at least `MIN_ALIGN` bytes of padding before // it, it is safe to write a header directly before it. - unsafe { ptr::write((aligned as *mut Header).offset(-1), Header(ptr)) }; + unsafe { ptr::write((aligned as *mut Header).sub(1), Header(ptr)) }; // SAFETY: The returned pointer does not point to the to the start of an allocated block, // but there is a header readable directly before it containing the location of the start @@ -213,7 +213,7 @@ unsafe impl GlobalAlloc for System { // SAFETY: Because of the contract of `System`, `ptr` is guaranteed to be non-null // and have a header readable directly before it. - unsafe { ptr::read((ptr as *mut Header).offset(-1)).0 } + unsafe { ptr::read((ptr as *mut Header).sub(1)).0 } } }; diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index aed082b3e0ab..1361b9c90c02 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -512,7 +512,7 @@ impl File { )); } }; - let subst_ptr = path_buffer.offset(subst_off as isize); + let subst_ptr = path_buffer.add(subst_off.into()); let mut subst = slice::from_raw_parts(subst_ptr, subst_len as usize); // Absolute paths start with an NT internal namespace prefix `\??\` // We should not let it leak through. @@ -1345,10 +1345,10 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> { let v = br"\??\"; let v = v.iter().map(|x| *x as u16); for c in v.chain(original.as_os_str().encode_wide()) { - *buf.offset(i) = c; + *buf.add(i) = c; i += 1; } - *buf.offset(i) = 0; + *buf.add(i) = 0; i += 1; (*db).ReparseTag = c::IO_REPARSE_TAG_MOUNT_POINT; (*db).ReparseTargetMaximumLength = (i * 2) as c::WORD; diff --git a/library/std/src/sys/windows/os.rs b/library/std/src/sys/windows/os.rs index bcac996c024e..352337ba3223 100644 --- a/library/std/src/sys/windows/os.rs +++ b/library/std/src/sys/windows/os.rs @@ -99,11 +99,11 @@ impl Iterator for Env { } let p = self.cur as *const u16; let mut len = 0; - while *p.offset(len) != 0 { + while *p.add(len) != 0 { len += 1; } - let s = slice::from_raw_parts(p, len as usize); - self.cur = self.cur.offset(len + 1); + let s = slice::from_raw_parts(p, len); + self.cur = self.cur.add(len + 1); // Windows allows environment variables to start with an equals // symbol (in any other position, this is the separator between From 3ba393465f262c68e7a2972ea18bc5547cf61340 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 19 Aug 2022 13:33:46 +0400 Subject: [PATCH 17/20] Make some docs nicer wrt pointer offsets --- library/alloc/src/ffi/c_str.rs | 6 +++--- library/alloc/src/vec/mod.rs | 8 ++++---- library/core/src/intrinsics.rs | 2 +- library/core/src/sync/atomic.rs | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index ae61b1f1e8ed..be21d8c722d7 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -436,9 +436,9 @@ impl CString { /// /// unsafe { /// assert_eq!(b'f', *ptr as u8); - /// assert_eq!(b'o', *ptr.offset(1) as u8); - /// assert_eq!(b'o', *ptr.offset(2) as u8); - /// assert_eq!(b'\0', *ptr.offset(3) as u8); + /// assert_eq!(b'o', *ptr.add(1) as u8); + /// assert_eq!(b'o', *ptr.add(2) as u8); + /// assert_eq!(b'\0', *ptr.add(3) as u8); /// /// // retake pointer to free memory /// let _ = CString::from_raw(ptr); diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index fa9f2131c0c1..fe4dcafe14c3 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -542,8 +542,8 @@ impl Vec { /// /// unsafe { /// // Overwrite memory with 4, 5, 6 - /// for i in 0..len as isize { - /// ptr::write(p.offset(i), 4 + i); + /// for i in 0..len { + /// ptr::write(p.add(i), 4 + i); /// } /// /// // Put everything back together into a Vec @@ -702,8 +702,8 @@ impl Vec { /// /// unsafe { /// // Overwrite memory with 4, 5, 6 - /// for i in 0..len as isize { - /// ptr::write(p.offset(i), 4 + i); + /// for i in 0..len { + /// ptr::write(p.add(i), 4 + i); /// } /// /// // Put everything back together into a Vec diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 15467e0191db..3c2a2418aadc 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2211,7 +2211,7 @@ pub(crate) fn is_nonoverlapping(src: *const T, dst: *const T, count: usize) - /// unsafe { /// // The call to offset is always safe because `Vec` will never /// // allocate more than `isize::MAX` bytes. -/// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize); +/// let dst_ptr = dst.as_mut_ptr().add(dst_len); /// let src_ptr = src.as_ptr(); /// /// // Truncate `src` without dropping its contents. We do this first, diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 40ca9abd6bdc..21ac9c5c7e3c 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -1555,7 +1555,7 @@ impl AtomicPtr { /// previous pointer. /// /// This is equivalent to using [`wrapping_add`] and [`cast`] to atomically - /// perform `ptr = ptr.cast::().wrapping_add(val).cast::()`. + /// perform `ptr = ptr.wrapping_byte_add(val)`. /// /// `fetch_byte_add` takes an [`Ordering`] argument which describes the /// memory ordering of this operation. All ordering modes are possible. Note @@ -1592,7 +1592,7 @@ impl AtomicPtr { /// previous pointer. /// /// This is equivalent to using [`wrapping_sub`] and [`cast`] to atomically - /// perform `ptr = ptr.cast::().wrapping_sub(val).cast::()`. + /// perform `ptr = ptr.wrapping_byte_sub(val)`. /// /// `fetch_byte_sub` takes an [`Ordering`] argument which describes the /// memory ordering of this operation. All ordering modes are possible. Note From b2625e24b95b5077a1ec59ad6ac667939eb6521f Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 21 Aug 2022 06:36:11 +0400 Subject: [PATCH 18/20] fix nitpicks from review --- library/core/src/intrinsics.rs | 2 +- library/core/src/sync/atomic.rs | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 3c2a2418aadc..3d7b875eac15 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2209,7 +2209,7 @@ pub(crate) fn is_nonoverlapping(src: *const T, dst: *const T, count: usize) - /// dst.reserve(src_len); /// /// unsafe { -/// // The call to offset is always safe because `Vec` will never +/// // The call to add is always safe because `Vec` will never /// // allocate more than `isize::MAX` bytes. /// let dst_ptr = dst.as_mut_ptr().add(dst_len); /// let src_ptr = src.as_ptr(); diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 21ac9c5c7e3c..3c96290fc537 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -1554,7 +1554,7 @@ impl AtomicPtr { /// Offsets the pointer's address by adding `val` *bytes*, returning the /// previous pointer. /// - /// This is equivalent to using [`wrapping_add`] and [`cast`] to atomically + /// This is equivalent to using [`wrapping_byte_add`] to atomically /// perform `ptr = ptr.wrapping_byte_add(val)`. /// /// `fetch_byte_add` takes an [`Ordering`] argument which describes the @@ -1565,8 +1565,7 @@ impl AtomicPtr { /// **Note**: This method is only available on platforms that support atomic /// operations on [`AtomicPtr`]. /// - /// [`wrapping_add`]: pointer::wrapping_add - /// [`cast`]: pointer::cast + /// [`wrapping_byte_add`]: pointer::wrapping_byte_add /// /// # Examples /// @@ -1591,7 +1590,7 @@ impl AtomicPtr { /// Offsets the pointer's address by subtracting `val` *bytes*, returning the /// previous pointer. /// - /// This is equivalent to using [`wrapping_sub`] and [`cast`] to atomically + /// This is equivalent to using [`wrapping_byte_sub`] to atomically /// perform `ptr = ptr.wrapping_byte_sub(val)`. /// /// `fetch_byte_sub` takes an [`Ordering`] argument which describes the @@ -1602,8 +1601,7 @@ impl AtomicPtr { /// **Note**: This method is only available on platforms that support atomic /// operations on [`AtomicPtr`]. /// - /// [`wrapping_sub`]: pointer::wrapping_sub - /// [`cast`]: pointer::cast + /// [`wrapping_byte_sub`]: pointer::wrapping_byte_sub /// /// # Examples /// From 7abbfa8c415bf964e007713c786d57b48c40701d Mon Sep 17 00:00:00 2001 From: Nelson Chen Date: Sun, 21 Aug 2022 01:56:26 -0700 Subject: [PATCH 19/20] Make doc for stdin field of process consistent The other fields use this format and example. --- library/std/src/process.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/std/src/process.rs b/library/std/src/process.rs index d6cba7e7598f..d91d4fa64caa 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -169,15 +169,15 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; pub struct Child { pub(crate) handle: imp::Process, - /// The handle for writing to the child's standard input (stdin), if it has - /// been captured. To avoid partially moving - /// the `child` and thus blocking yourself from calling - /// functions on `child` while using `stdin`, - /// you might find it helpful: + /// The handle for writing to the child's standard input (stdin), if it + /// has been captured. You might find it helpful to do /// /// ```compile_fail,E0425 /// let stdin = child.stdin.take().unwrap(); /// ``` + /// + /// to avoid partially moving the `child` and thus blocking yourself from calling + /// functions on `child` while using `stdin`. #[stable(feature = "process", since = "1.0.0")] pub stdin: Option, From c835d9c0d2049c1a664dab080fde9be1ceec334b Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Sun, 21 Aug 2022 09:17:09 -0400 Subject: [PATCH 20/20] ADD - diagnostic lints to rustc_transmute Module is complete because it has zero diagnostics. --- compiler/rustc_transmute/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index cfc7c752a6bd..32e6cb9c64f7 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -7,6 +7,8 @@ result_into_ok_or_err )] #![allow(dead_code, unused_variables)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate tracing;