diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 29987ac44e6f9..fc50d06b33c57 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -404,7 +404,10 @@ impl Vec { /// /// * `ptr` needs to have been previously allocated via [`String`]/`Vec` /// (at least, it's highly likely to be incorrect if it wasn't). - /// * `ptr`'s `T` needs to have the same size and alignment as it was allocated with. + /// * `T` needs to have the same size and alignment as what `ptr` was allocated with. + /// (`T` having a less strict alignment is not sufficient, the alignment really + /// needs to be equal to satsify the [`dealloc`] requirement that memory must be + /// allocated and deallocated with the same layout.) /// * `length` needs to be less than or equal to `capacity`. /// * `capacity` needs to be the capacity that the pointer was allocated with. /// @@ -423,6 +426,7 @@ impl Vec { /// function. /// /// [`String`]: ../../std/string/struct.String.html + /// [`dealloc`]: ../../alloc/alloc/trait.GlobalAlloc.html#tymethod.dealloc /// /// # Examples /// diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 94928211a978a..fca2c3d31d946 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -881,7 +881,8 @@ extern "rust-intrinsic" { /// // clone the vector as we will reuse them later /// let v_clone = v_orig.clone(); /// - /// // Using transmute: this is Undefined Behavior, and a bad idea. + /// // Using transmute: this relies on the unspecified data layout of `Vec`, which is a + /// // bad idea and could cause Undefined Behavior. /// // However, it is no-copy. /// let v_transmuted = unsafe { /// std::mem::transmute::, Vec>>(v_clone) @@ -897,13 +898,14 @@ extern "rust-intrinsic" { /// /// let v_clone = v_orig.clone(); /// - /// // The no-copy, unsafe way, still using transmute, but not UB. - /// // This is equivalent to the original, but safer, and reuses the - /// // same `Vec` internals. Therefore, the new inner type must have the - /// // exact same size, and the same alignment, as the old type. + /// // The no-copy, unsafe way, still using transmute, but not relying on the data layout. + /// // Like the first approach, this reuses the `Vec` internals. + /// // Therefore, the new inner type must have the + /// // exact same size, *and the same alignment*, as the old type. /// // The same caveats exist for this method as transmute, for /// // the original inner type (`&i32`) to the converted inner type - /// // (`Option<&i32>`), so read the nomicon pages linked above. + /// // (`Option<&i32>`), so read the nomicon pages linked above and also + /// // consult the [`from_raw_parts`] documentation. /// let v_from_raw = unsafe { // FIXME Update this when vec_into_raw_parts is stabilized /// // Ensure the original vector is not dropped. @@ -914,6 +916,8 @@ extern "rust-intrinsic" { /// }; /// ``` /// + /// [`from_raw_parts`]: ../../std/vec/struct.Vec.html#method.from_raw_parts + /// /// Implementing `split_at_mut`: /// /// ``` diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 9a4561f286997..1670c8418421f 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2571,11 +2571,13 @@ impl [T] { let (left, rest) = self.split_at_mut(offset); // now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay let (us_len, ts_len) = rest.align_to_offsets::(); + let rest_len = rest.len(); let mut_ptr = rest.as_mut_ptr(); + // We can't use `rest` again after this, that would invalidate its alias `mut_ptr`! ( left, from_raw_parts_mut(mut_ptr as *mut U, us_len), - from_raw_parts_mut(mut_ptr.add(rest.len() - ts_len), ts_len), + from_raw_parts_mut(mut_ptr.add(rest_len - ts_len), ts_len), ) } } diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index cc274b4aecf54..dbab433e33f48 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1570,6 +1570,18 @@ fn test_align_to_empty_mid() { } } +#[test] +fn test_align_to_mut_aliasing() { + let mut val = [1u8, 2, 3, 4, 5]; + // `align_to_mut` used to create `mid` in a way that there was some intermediate + // incorrect aliasing, invalidating the resulting `mid` slice. + let (begin, mid, end) = unsafe { val.align_to_mut::<[u8; 2]>() }; + assert!(begin.len() == 0); + assert!(end.len() == 1); + mid[0] = mid[1]; + assert_eq!(val, [3, 4, 3, 4, 5]) +} + #[test] fn test_slice_partition_dedup_by() { let mut slice: [i32; 9] = [1, -1, 2, 3, 1, -5, 5, -2, 2]; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index befae4195f3b3..f37a94321927b 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2291,13 +2291,13 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> { - let kinds: Vec<_> = ts.into_iter().map(|&t| GenericArg::from(t)).collect(); + let kinds: Vec<_> = ts.iter().map(|&t| GenericArg::from(t)).collect(); self.mk_ty(Tuple(self.intern_substs(&kinds))) } pub fn mk_tup], Ty<'tcx>>>(self, iter: I) -> I::Output { iter.intern_with(|ts| { - let kinds: Vec<_> = ts.into_iter().map(|&t| GenericArg::from(t)).collect(); + let kinds: Vec<_> = ts.iter().map(|&t| GenericArg::from(t)).collect(); self.mk_ty(Tuple(self.intern_substs(&kinds))) }) } diff --git a/src/librustc_builtin_macros/proc_macro_harness.rs b/src/librustc_builtin_macros/proc_macro_harness.rs index b925cad9fdcdc..8c1675ad29dff 100644 --- a/src/librustc_builtin_macros/proc_macro_harness.rs +++ b/src/librustc_builtin_macros/proc_macro_harness.rs @@ -149,7 +149,7 @@ impl<'a> CollectProcMacros<'a> { .span_err(attr.span(), "attribute must be of form: `attributes(foo, bar)`"); &[] }) - .into_iter() + .iter() .filter_map(|attr| { let attr = match attr.meta_item() { Some(meta_item) => meta_item, diff --git a/src/librustc_infer/infer/canonical/query_response.rs b/src/librustc_infer/infer/canonical/query_response.rs index f77faf3d4ab59..77f1c6bf28109 100644 --- a/src/librustc_infer/infer/canonical/query_response.rs +++ b/src/librustc_infer/infer/canonical/query_response.rs @@ -630,7 +630,7 @@ pub fn make_query_region_constraints<'tcx>( assert!(givens.is_empty()); let outlives: Vec<_> = constraints - .into_iter() + .iter() .map(|(k, _)| match *k { // Swap regions because we are going from sub (<=) to outlives // (>=). diff --git a/src/librustc_infer/traits/on_unimplemented.rs b/src/librustc_infer/traits/on_unimplemented.rs index 41201c1c7ae7c..24741462f431c 100644 --- a/src/librustc_infer/traits/on_unimplemented.rs +++ b/src/librustc_infer/traits/on_unimplemented.rs @@ -237,10 +237,8 @@ impl<'tcx> OnUnimplementedDirective { } } - let options: FxHashMap = options - .into_iter() - .filter_map(|(k, v)| v.as_ref().map(|v| (*k, v.to_owned()))) - .collect(); + let options: FxHashMap = + options.iter().filter_map(|(k, v)| v.as_ref().map(|v| (*k, v.to_owned()))).collect(); OnUnimplementedNote { label: label.map(|l| l.format(tcx, trait_ref, &options)), message: message.map(|m| m.format(tcx, trait_ref, &options)), diff --git a/src/librustc_infer/traits/select.rs b/src/librustc_infer/traits/select.rs index 925665763cbe5..1b92c126a15c2 100644 --- a/src/librustc_infer/traits/select.rs +++ b/src/librustc_infer/traits/select.rs @@ -2411,7 +2411,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { types .skip_binder() - .into_iter() + .iter() .flat_map(|ty| { // binder moved -\ let ty: ty::Binder> = ty::Binder::bind(ty); // <----/ diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 4d03f4579fd2e..0282454edcf10 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -739,7 +739,7 @@ impl EarlyLintPass for DeprecatedAttr { } fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: &[ast::Attribute]) { - let mut attrs = attrs.into_iter().peekable(); + let mut attrs = attrs.iter().peekable(); // Accumulate a single span for sugared doc comments. let mut sugared_span: Option = None; diff --git a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs index 27f0c0f1e472a..9451fee499d36 100644 --- a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs @@ -519,7 +519,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } fn add_move_error_details(&self, err: &mut DiagnosticBuilder<'a>, binds_to: &[Local]) { - for (j, local) in binds_to.into_iter().enumerate() { + for (j, local) in binds_to.iter().enumerate() { let bind_to = &self.body.local_decls[*local]; let binding_span = bind_to.source_info.span; diff --git a/src/librustc_mir/dataflow/generic/engine.rs b/src/librustc_mir/dataflow/generic/engine.rs index 371bfa9a6fdb4..d433a4a48d311 100644 --- a/src/librustc_mir/dataflow/generic/engine.rs +++ b/src/librustc_mir/dataflow/generic/engine.rs @@ -419,7 +419,7 @@ impl RustcMirAttrs { let mut ret = RustcMirAttrs::default(); let rustc_mir_attrs = attrs - .into_iter() + .iter() .filter(|attr| attr.check_name(sym::rustc_mir)) .flat_map(|attr| attr.meta_item_list().into_iter().flat_map(|v| v.into_iter())); diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 74d1094f9645e..a7c0efd63b1a8 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -195,7 +195,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { .local_map .get(&place.local) .into_iter() - .flat_map(|bs| bs.into_iter()) + .flat_map(|bs| bs.iter()) .copied(); // If the borrowed place is a local with no projections, all other borrows of this diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 14b8a341e26a0..a035dff9f5a04 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -509,7 +509,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &self, ops: &[mir::Operand<'tcx>], ) -> InterpResult<'tcx, Vec>> { - ops.into_iter().map(|op| self.eval_operand(op, None)).collect() + ops.iter().map(|op| self.eval_operand(op, None)).collect() } // Used when the miri-engine runs into a constant and for extracting information from constants diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 0fa7d6a9b7223..f6a93363dc109 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -401,10 +401,8 @@ fn record_accesses<'tcx>( // We collect this into a `SmallVec` to avoid calling `is_inlining_candidate` in the lock. // FIXME: Call `is_inlining_candidate` when pushing to `neighbors` in `collect_items_rec` // instead to avoid creating this `SmallVec`. - let accesses: SmallVec<[_; 128]> = callees - .into_iter() - .map(|mono_item| (*mono_item, is_inlining_candidate(mono_item))) - .collect(); + let accesses: SmallVec<[_; 128]> = + callees.iter().map(|mono_item| (*mono_item, is_inlining_candidate(mono_item))).collect(); inlining_map.lock_mut().record_accesses(caller, &accesses); } diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index fab55018d3099..4dcbcdcbae4a6 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -644,7 +644,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) { } } - let mut unsafe_blocks: Vec<_> = unsafe_blocks.into_iter().collect(); + let mut unsafe_blocks: Vec<_> = unsafe_blocks.iter().collect(); unsafe_blocks.sort_by_cached_key(|(hir_id, _)| tcx.hir().hir_to_node_id(*hir_id)); let used_unsafe: FxHashSet<_> = unsafe_blocks.iter().flat_map(|&&(id, used)| used.then_some(id)).collect(); diff --git a/src/librustc_mir/transform/uninhabited_enum_branching.rs b/src/librustc_mir/transform/uninhabited_enum_branching.rs index 8f2f2094b1e38..bbaa66f5954cb 100644 --- a/src/librustc_mir/transform/uninhabited_enum_branching.rs +++ b/src/librustc_mir/transform/uninhabited_enum_branching.rs @@ -100,7 +100,7 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching { &mut body.basic_blocks_mut()[bb].terminator_mut().kind { let vals = &*values; - let zipped = vals.iter().zip(targets.into_iter()); + let zipped = vals.iter().zip(targets.iter()); let mut matched_values = Vec::with_capacity(allowed_variants.len()); let mut matched_targets = Vec::with_capacity(allowed_variants.len() + 1); diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index ef4246609da9a..d00d9fc72bfff 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -6,6 +6,7 @@ use crate::maybe_whole; use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, PResult, StashKey}; +use rustc_span::edition::Edition; use rustc_span::source_map::{self, Span}; use rustc_span::symbol::{kw, sym, Symbol}; use syntax::ast::{self, AttrStyle, AttrVec, Attribute, Ident, DUMMY_NODE_ID}; @@ -636,7 +637,7 @@ impl<'a> Parser<'a> { } pub fn parse_trait_item(&mut self) -> PResult<'a, Option>>> { - self.parse_assoc_item(|t| t.span.rust_2018()) + self.parse_assoc_item(|edition| edition >= Edition::Edition2018) } /// Parses associated items. @@ -1380,7 +1381,7 @@ impl<'a> Parser<'a> { /// The parsing configuration used to parse a parameter list (see `parse_fn_params`). /// /// The function decides if, per-parameter `p`, `p` must have a pattern or just a type. -type ReqName = fn(&token::Token) -> bool; +type ReqName = fn(Edition) -> bool; /// Parsing of functions and methods. impl<'a> Parser<'a> { @@ -1536,7 +1537,7 @@ impl<'a> Parser<'a> { let is_name_required = match self.token.kind { token::DotDotDot => false, - _ => req_name(&self.normalized_token), + _ => req_name(self.normalized_token.span.edition()), }; let (pat, ty) = if is_name_required || self.is_named_param() { debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index ef1e99c5a64be..fd84be919d426 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -657,7 +657,7 @@ impl EmbargoVisitor<'tcx> { .map(|module_hir_id| self.tcx.hir().expect_item(module_hir_id)) { if let hir::ItemKind::Mod(m) = &item.kind { - for item_id in m.item_ids.as_ref() { + for item_id in m.item_ids { let item = self.tcx.hir().expect_item(item_id.id); let def_id = self.tcx.hir().local_def_id(item_id.id); if !self.tcx.hygienic_eq(segment.ident, item.ident, def_id) { diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index d08ae3040bda7..b18d4070c24ca 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1426,7 +1426,7 @@ crate fn show_candidates( // we want consistent results across executions, but candidates are produced // by iterating through a hash map, so make sure they are ordered: let mut path_strings: Vec<_> = - candidates.into_iter().map(|c| path_names_to_string(&c.path)).collect(); + candidates.iter().map(|c| path_names_to_string(&c.path)).collect(); path_strings.sort(); path_strings.dedup(); diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 9670fb1e2c465..ad439e3950e13 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -430,7 +430,7 @@ impl Sig for ast::Item { sig.text.push_str(" = "); let ty = match ty { Some(ty) => ty.make(offset + sig.text.len(), id, scx)?, - None => Err("Ty")?, + None => return Err("Ty"), }; sig.text.push_str(&ty.text); sig.text.push(';'); diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs index 31d397f040cb0..320039b7c911a 100644 --- a/src/librustc_span/source_map.rs +++ b/src/librustc_span/source_map.rs @@ -395,7 +395,7 @@ impl SourceMap { .unwrap_or_else(|x| x); let special_chars = end_width_idx - start_width_idx; let non_narrow: usize = f.non_narrow_chars[start_width_idx..end_width_idx] - .into_iter() + .iter() .map(|x| x.width()) .sum(); col.0 - special_chars + non_narrow @@ -413,7 +413,7 @@ impl SourceMap { .binary_search_by_key(&pos, |x| x.pos()) .unwrap_or_else(|x| x); let non_narrow: usize = - f.non_narrow_chars[0..end_width_idx].into_iter().map(|x| x.width()).sum(); + f.non_narrow_chars[0..end_width_idx].iter().map(|x| x.width()).sum(); chpos.0 - end_width_idx + non_narrow }; Loc { file: f, line: 0, col: chpos, col_display } diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs index b77c603da9a74..e0c3dc8a961da 100644 --- a/src/librustc_traits/lowering/mod.rs +++ b/src/librustc_traits/lowering/mod.rs @@ -256,7 +256,7 @@ fn program_clauses_for_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> { // `WellFormed(WC)` let wf_conditions = where_clauses - .into_iter() + .iter() .map(|wc| wc.subst(tcx, bound_vars)) .map(|wc| wc.map_bound(|goal| goal.into_well_formed_goal())); diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index 2ba97055a680a..ec87112b7a8e0 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -239,7 +239,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { .segments .iter() .filter_map(|seg| seg.args.as_ref()) - .map(|generic_args| generic_args.args.as_ref()) + .map(|generic_args| generic_args.args) .find_map(|args| { args.iter() .filter(|arg| arg.is_const()) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8be6bf8f0d38a..e6f59157c8b4b 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2388,9 +2388,9 @@ impl Clean for hir::TypeBindingKind<'_> { hir::TypeBindingKind::Equality { ref ty } => { TypeBindingKind::Equality { ty: ty.clean(cx) } } - hir::TypeBindingKind::Constraint { ref bounds } => TypeBindingKind::Constraint { - bounds: bounds.into_iter().map(|b| b.clean(cx)).collect(), - }, + hir::TypeBindingKind::Constraint { ref bounds } => { + TypeBindingKind::Constraint { bounds: bounds.iter().map(|b| b.clean(cx)).collect() } + } } } } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index ff6431640d33e..ed007fe383c1d 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -738,7 +738,7 @@ impl Markdown<'_> { return String::new(); } let replacer = |_: &str, s: &str| { - if let Some(&(_, ref replace)) = links.into_iter().find(|link| &*link.0 == s) { + if let Some(&(_, ref replace)) = links.iter().find(|link| &*link.0 == s) { Some((replace.clone(), s.to_owned())) } else { None @@ -816,7 +816,7 @@ impl MarkdownSummaryLine<'_> { } let replacer = |_: &str, s: &str| { - if let Some(&(_, ref replace)) = links.into_iter().find(|link| &*link.0 == s) { + if let Some(&(_, ref replace)) = links.iter().find(|link| &*link.0 == s) { Some((replace.clone(), s.to_owned())) } else { None diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index e9ebccb7ec09e..a0a35e4ce4b85 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -670,7 +670,7 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option match *clean_type { clean::ResolvedPath { ref path, .. } => { let segments = &path.segments; - let path_segment = segments.into_iter().last().unwrap_or_else(|| panic!( + let path_segment = segments.iter().last().unwrap_or_else(|| panic!( "get_index_type_name(clean_type: {:?}, accept_generic: {:?}) had length zero path", clean_type, accept_generic )); diff --git a/src/libstd/path.rs b/src/libstd/path.rs index a703cb748e06b..b8361d3e82599 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -2011,7 +2011,7 @@ impl Path { #[stable(feature = "rust1", since = "1.0.0")] pub fn file_name(&self) -> Option<&OsStr> { self.components().next_back().and_then(|p| match p { - Component::Normal(p) => Some(p.as_ref()), + Component::Normal(p) => Some(p), _ => None, }) } diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 68a549158730d..c36e78b1d004e 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -284,7 +284,7 @@ impl Instant { } /// Returns the amount of time elapsed from another instant to this one, - /// or zero duration if that instant is earlier than this one. + /// or zero duration if that instant is later than this one. /// /// # Examples ///