diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index a4c3be1d17745..13442c3164928 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -1,6 +1,5 @@ use crate::FnCtxt; use rustc_ast::util::parser::PREC_POSTFIX; -use rustc_data_structures::fx::FxHashMap; use rustc_errors::MultiSpan; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; @@ -13,15 +12,13 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::middle::stability::EvalResult; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder}; -use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; -use rustc_middle::ty::relate::TypeRelation; -use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeVisitableExt}; +use rustc_middle::ty::fold::BottomUpFolder; +use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeFoldable}; use rustc_span::symbol::{sym, Symbol}; -use rustc_span::{BytePos, Span}; +use rustc_span::{BytePos, Span, DUMMY_SP}; use rustc_target::abi::FieldIdx; use rustc_trait_selection::infer::InferCtxtExt as _; -use rustc_trait_selection::traits::error_reporting::method_chain::CollectAllMismatches; use rustc_trait_selection::traits::ObligationCause; use super::method::probe; @@ -62,9 +59,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || self.suggest_into(err, expr, expr_ty, expected) || self.suggest_floating_point_literal(err, expr, expected) || self.suggest_null_ptr_for_literal_zero_given_to_ptr_arg(err, expr, expected) - || self.note_result_coercion(err, expr, expected, expr_ty); + || self.suggest_coercing_result_via_try_operator(err, expr, expected, expr_ty); + if !suggested { - self.point_at_expr_source_of_inferred_type(err, expr, expr_ty, expected, expr.span); + self.note_source_of_type_mismatch_constraint( + err, + expr, + TypeMismatchSource::Ty(expected), + ); } } @@ -218,37 +220,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (expected, Some(err)) } - pub fn point_at_expr_source_of_inferred_type( + /// Notes the point at which a variable is constrained to some type incompatible + /// with some expectation given by `source`. + pub fn note_source_of_type_mismatch_constraint( &self, err: &mut Diagnostic, expr: &hir::Expr<'_>, - found: Ty<'tcx>, - expected: Ty<'tcx>, - mismatch_span: Span, + source: TypeMismatchSource<'tcx>, ) -> bool { - let map = self.tcx.hir(); + let hir = self.tcx.hir(); let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind else { return false; }; let [hir::PathSegment { ident, args: None, .. }] = p.segments else { return false; }; - let hir::def::Res::Local(hir_id) = p.res else { return false; }; - let Some(hir::Node::Pat(pat)) = map.find(hir_id) else { return false; }; - let Some(hir::Node::Local(hir::Local { - ty: None, - init: Some(init), - .. - })) = map.find_parent(pat.hir_id) else { return false; }; - let Some(ty) = self.node_ty_opt(init.hir_id) else { return false; }; - if ty.is_closure() || init.span.overlaps(expr.span) || pat.span.from_expansion() { - return false; - } + let hir::def::Res::Local(local_hir_id) = p.res else { return false; }; + let hir::Node::Pat(pat) = hir.get(local_hir_id) else { return false; }; + let (init_ty_hir_id, init) = match hir.get_parent(pat.hir_id) { + hir::Node::Local(hir::Local { ty: Some(ty), init, .. }) => (ty.hir_id, *init), + hir::Node::Local(hir::Local { init: Some(init), .. }) => (init.hir_id, Some(*init)), + _ => return false, + }; + let Some(init_ty) = self.node_ty_opt(init_ty_hir_id) else { return false; }; // Locate all the usages of the relevant binding. - struct FindExprs<'hir> { + struct FindExprs<'tcx> { hir_id: hir::HirId, - uses: Vec<&'hir hir::Expr<'hir>>, + uses: Vec<&'tcx hir::Expr<'tcx>>, } - impl<'v> Visitor<'v> for FindExprs<'v> { - fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + impl<'tcx> Visitor<'tcx> for FindExprs<'tcx> { + fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = ex.kind && let hir::def::Res::Local(hir_id) = path.res && hir_id == self.hir_id @@ -259,180 +258,205 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - let mut expr_finder = FindExprs { hir_id, uses: vec![] }; - let id = map.get_parent_item(hir_id); - let hir_id: hir::HirId = id.into(); - - let Some(node) = map.find(hir_id) else { return false; }; - let Some(body_id) = node.body_id() else { return false; }; - let body = map.body(body_id); + let mut expr_finder = FindExprs { hir_id: local_hir_id, uses: init.into_iter().collect() }; + let body = + hir.body(hir.maybe_body_owned_by(self.body_id).expect("expected item to have body")); expr_finder.visit_expr(body.value); - // Hack to make equality checks on types with inference variables and regions useful. - let mut eraser = BottomUpFolder { + + use rustc_infer::infer::type_variable::*; + use rustc_middle::infer::unify_key::*; + // Replaces all of the variables in the given type with a fresh inference variable. + let mut fudger = BottomUpFolder { tcx: self.tcx, + ty_op: |ty| { + if let ty::Infer(infer) = ty.kind() { + match infer { + ty::InferTy::TyVar(_) => self.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::MiscVariable, + span: DUMMY_SP, + }), + ty::InferTy::IntVar(_) => self.next_int_var(), + ty::InferTy::FloatVar(_) => self.next_float_var(), + _ => bug!(), + } + } else { + ty + } + }, lt_op: |_| self.tcx.lifetimes.re_erased, - ct_op: |c| c, - ty_op: |t| match *t.kind() { - ty::Infer(ty::TyVar(_)) => self.tcx.mk_ty_var(ty::TyVid::from_u32(0)), - ty::Infer(ty::IntVar(_)) => self.tcx.mk_int_var(ty::IntVid { index: 0 }), - ty::Infer(ty::FloatVar(_)) => self.tcx.mk_float_var(ty::FloatVid { index: 0 }), - _ => t, + ct_op: |ct| { + if let ty::ConstKind::Infer(_) = ct.kind() { + self.next_const_var( + ct.ty(), + ConstVariableOrigin { + kind: ConstVariableOriginKind::MiscVariable, + span: DUMMY_SP, + }, + ) + } else { + ct + } }, }; - let mut prev = eraser.fold_ty(ty); - let mut prev_span: Option = None; - - for binding in expr_finder.uses { - // In every expression where the binding is referenced, we will look at that - // expression's type and see if it is where the incorrect found type was fully - // "materialized" and point at it. We will also try to provide a suggestion there. - if let Some(hir::Node::Expr(expr) - | hir::Node::Stmt(hir::Stmt { - kind: hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr), - .. - })) = &map.find_parent(binding.hir_id) - && let hir::ExprKind::MethodCall(segment, rcvr, args, _span) = expr.kind - && rcvr.hir_id == binding.hir_id - && let Some(def_id) = self.typeck_results.borrow().type_dependent_def_id(expr.hir_id) - { - // We special case methods, because they can influence inference through the - // call's arguments and we can provide a more explicit span. - let sig = self.tcx.fn_sig(def_id).subst_identity(); - let def_self_ty = sig.input(0).skip_binder(); - let param_tys = sig.inputs().skip_binder().iter().skip(1); - // If there's an arity mismatch, pointing out the call as the source of an inference - // can be misleading, so we skip it. - if param_tys.len() != args.len() { - continue; - } - let rcvr_ty = self.node_ty(rcvr.hir_id); - // Get the evaluated type *after* calling the method call, so that the influence - // of the arguments can be reflected in the receiver type. The receiver - // expression has the type *before* this analysis is done. - let ty = match self.lookup_probe_for_diagnostic( - segment.ident, - rcvr_ty, - expr, - probe::ProbeScope::TraitsInScope, - None, - ) { - Ok(pick) => eraser.fold_ty(pick.self_ty), - Err(_) => rcvr_ty, + + let expected_ty = match source { + TypeMismatchSource::Ty(expected_ty) => expected_ty, + // Try to deduce what the possible value of `expr` would be if the + // incompatible arg were compatible. For example, given `Vec` + // and `vec.push(1u32)`, we ideally want to deduce that the type of + // `vec` *should* have been `Vec`. This will allow us to then + // run the subsequent code with this expectation, finding out exactly + // when this type diverged from our expectation. + TypeMismatchSource::Arg { call_expr, incompatible_arg: idx } => { + let hir::ExprKind::MethodCall(segment, _, args, _) = call_expr.kind else { + return false; }; - // Remove one layer of references to account for `&mut self` and - // `&self`, so that we can compare it against the binding. - let (ty, def_self_ty) = match (ty.kind(), def_self_ty.kind()) { - (ty::Ref(_, ty, a), ty::Ref(_, self_ty, b)) if a == b => (*ty, *self_ty), - _ => (ty, def_self_ty), + let Some(arg_ty) = self.node_ty_opt(args[idx].hir_id) else { + return false; }; - let mut param_args = FxHashMap::default(); - let mut param_expected = FxHashMap::default(); - let mut param_found = FxHashMap::default(); - if self.can_eq(self.param_env, ty, found) { - // We only point at the first place where the found type was inferred. - for (param_ty, arg) in param_tys.zip(args) { - if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() { - // We found an argument that references a type parameter in `Self`, - // so we assume that this is the argument that caused the found - // type, which we know already because of `can_eq` above was first - // inferred in this method call. - let arg_ty = self.node_ty(arg.hir_id); - if !arg.span.overlaps(mismatch_span) { - err.span_label( - arg.span, - &format!( - "this is of type `{arg_ty}`, which causes `{ident}` to be \ - inferred as `{ty}`", - ), - ); - } - param_args.insert(param_ty, (arg, arg_ty)); - } - } + let possible_rcvr_ty = expr_finder.uses.iter().find_map(|binding| { + let possible_rcvr_ty = self.node_ty_opt(binding.hir_id)?; + // Fudge the receiver, so we can do new inference on it. + let possible_rcvr_ty = possible_rcvr_ty.fold_with(&mut fudger); + let method = self + .lookup_method( + possible_rcvr_ty, + segment, + DUMMY_SP, + call_expr, + binding, + args, + ) + .ok()?; + // Unify the method signature with our incompatible arg, to + // do inference in the *opposite* direction and to find out + // what our ideal rcvr ty would look like. + let _ = self + .at(&ObligationCause::dummy(), self.param_env) + .eq(DefineOpaqueTypes::No, method.sig.inputs()[idx + 1], arg_ty) + .ok()?; + self.select_obligations_where_possible(|errs| { + // Yeet the errors, we're already reporting errors. + errs.clear(); + }); + Some(self.resolve_vars_if_possible(possible_rcvr_ty)) + }); + if let Some(rcvr_ty) = possible_rcvr_ty { + rcvr_ty + } else { + return false; } + } + }; - // Here we find, for a type param `T`, the type that `T` is in the current - // method call *and* in the original expected type. That way, we can see if we - // can give any structured suggestion for the function argument. - let mut c = CollectAllMismatches { - infcx: &self.infcx, - param_env: self.param_env, - errors: vec![], + // If our expected_ty does not equal init_ty, then it *began* as incompatible. + // No need to note in this case... + if !self.can_eq(self.param_env, expected_ty, init_ty.fold_with(&mut fudger)) { + return false; + } + + for window in expr_finder.uses.windows(2) { + // Bindings always update their recorded type after the fact, so we + // need to look at the *following* usage's type to see when the + // binding became incompatible. + let [binding, next_usage] = *window else { continue; }; + + // Don't go past the binding (always gonna be a nonsense label if so) + if binding.hir_id == expr.hir_id { + break; + } + + let Some(next_use_ty) = self.node_ty_opt(next_usage.hir_id) else { continue; }; + + // If the type is not constrained in a way making it not possible to + // equate with `expected_ty` by this point, skip. + if self.can_eq(self.param_env, expected_ty, next_use_ty.fold_with(&mut fudger)) { + continue; + } + + if let hir::Node::Expr(parent_expr) = hir.get_parent(binding.hir_id) + && let hir::ExprKind::MethodCall(segment, rcvr, args, _) = parent_expr.kind + && rcvr.hir_id == binding.hir_id + { + // If our binding became incompatible while it was a receiver + // to a method call, we may be able to make a better guess to + // the source of a type mismatch. + let Some(rcvr_ty) = self.node_ty_opt(rcvr.hir_id) else { continue; }; + let rcvr_ty = rcvr_ty.fold_with(&mut fudger); + let Ok(method) = + self.lookup_method(rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr, args) + else { + continue; }; - let _ = c.relate(def_self_ty, ty); - for error in c.errors { - if let TypeError::Sorts(error) = error { - param_found.insert(error.expected, error.found); - } - } - c.errors = vec![]; - let _ = c.relate(def_self_ty, expected); - for error in c.errors { - if let TypeError::Sorts(error) = error { - param_expected.insert(error.expected, error.found); - } - } - for (param, (arg, arg_ty)) in param_args.iter() { - let Some(expected) = param_expected.get(param) else { continue; }; - let Some(found) = param_found.get(param) else { continue; }; - if !self.can_eq(self.param_env, *arg_ty, *found) { continue; } - self.emit_coerce_suggestions(err, arg, *found, *expected, None, None); - } - let ty = eraser.fold_ty(ty); - if ty.references_error() { - break; - } - if ty != prev - && param_args.is_empty() - && self.can_eq(self.param_env, ty, found) + let ideal_rcvr_ty = rcvr_ty.fold_with(&mut fudger); + let ideal_method = self + .lookup_method(ideal_rcvr_ty, segment, DUMMY_SP, parent_expr, rcvr, args) + .ok() + .and_then(|method| { + let _ = self.at(&ObligationCause::dummy(), self.param_env) + .eq(DefineOpaqueTypes::No, ideal_rcvr_ty, expected_ty) + .ok()?; + Some(method) + }); + + // Find what argument caused our rcvr to become incompatible + // with the expected ty. + for (idx, (expected_arg_ty, arg_expr)) in + std::iter::zip(&method.sig.inputs()[1..], args).enumerate() { - // We only point at the first place where the found type was inferred. - if !segment.ident.span.overlaps(mismatch_span) { + let Some(arg_ty) = self.node_ty_opt(arg_expr.hir_id) else { continue; }; + let arg_ty = arg_ty.fold_with(&mut fudger); + let _ = self.try_coerce( + arg_expr, + arg_ty, + *expected_arg_ty, + AllowTwoPhase::No, + None, + ); + self.select_obligations_where_possible(|errs| { + // Yeet the errors, we're already reporting errors. + errs.clear(); + }); + // If our rcvr, after inference due to unifying the signature + // with the expected argument type, is still compatible with + // the rcvr, then it must've not been the source of blame. + if self.can_eq(self.param_env, rcvr_ty, expected_ty) { + continue; + } + err.span_label(arg_expr.span, format!("this argument has type `{arg_ty}`...")); err.span_label( - segment.ident.span, - with_forced_trimmed_paths!(format!( - "here the type of `{ident}` is inferred to be `{ty}`", - )), - );} - break; - } else if !param_args.is_empty() { - break; - } - prev = ty; - } else { - let ty = eraser.fold_ty(self.node_ty(binding.hir_id)); - if ty.references_error() { - break; - } - if ty != prev - && let Some(span) = prev_span - && self.can_eq(self.param_env, ty, found) - { - // We only point at the first place where the found type was inferred. - // We use the *previous* span because if the type is known *here* it means - // it was *evaluated earlier*. We don't do this for method calls because we - // evaluate the method's self type eagerly, but not in any other case. - if !span.overlaps(mismatch_span) { - err.span_label( - span, - with_forced_trimmed_paths!(format!( - "here the type of `{ident}` is inferred to be `{ty}`", - )), + binding.span, + format!("... which causes `{ident}` to have type `{next_use_ty}`"), + ); + // Using our "ideal" method signature, suggest a fix to this + // blame arg, if possible. Don't do this if we're coming from + // arg mismatch code, because we'll possibly suggest a mutually + // incompatible fix at the original mismatch site. + if matches!(source, TypeMismatchSource::Ty(_)) + && let Some(ideal_method) = ideal_method + { + self.emit_type_mismatch_suggestions( + err, + arg_expr, + arg_ty, + self.resolve_vars_if_possible(ideal_method.sig.inputs()[idx + 1]), + None, + None, ); } - break; + return true; } - prev = ty; - } - if binding.hir_id == expr.hir_id { - // Do not look at expressions that come after the expression we were originally - // evaluating and had a type error. - break; } - prev_span = Some(binding.span); + err.span_label( + binding.span, + format!("here the type of `{ident}` is inferred to be `{next_use_ty}`"), + ); + return true; } - true + + // We must've not found something that constrained the expr. + false } fn annotate_expected_due_to_let_ty( @@ -708,7 +732,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - pub(crate) fn note_result_coercion( + pub(crate) fn suggest_coercing_result_via_try_operator( &self, err: &mut Diagnostic, expr: &hir::Expr<'tcx>, @@ -2094,3 +2118,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } + +pub enum TypeMismatchSource<'tcx> { + /// Expected the binding to have the given type, but it was found to have + /// a different type. Find out when that type first became incompatible. + Ty(Ty<'tcx>), + /// When we fail during method argument checking, try to find out if a previous + /// expression has constrained the method's receiver in a way that makes the + /// argument's type incompatible. + Arg { call_expr: &'tcx hir::Expr<'tcx>, incompatible_arg: usize }, +} diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index a009ae5d44eb1..ea1b52daaa5e5 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -472,7 +472,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err_code: &str, fn_def_id: Option, call_span: Span, - call_expr: &hir::Expr<'tcx>, + call_expr: &'tcx hir::Expr<'tcx>, ) { // Next, let's construct the error let (error_span, full_call_span, call_name, is_method) = match &call_expr.kind { @@ -807,24 +807,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { full_call_span, format!("arguments to this {} are incorrect", call_name), ); - if let (Some(callee_ty), hir::ExprKind::MethodCall(_, rcvr, _, _)) = - (callee_ty, &call_expr.kind) + + if let hir::ExprKind::MethodCall(_, rcvr, _, _) = call_expr.kind + && provided_idx.as_usize() == expected_idx.as_usize() { - // Type that would have accepted this argument if it hadn't been inferred earlier. - // FIXME: We leave an inference variable for now, but it'd be nice to get a more - // specific type to increase the accuracy of the diagnostic. - let expected = self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: full_call_span, - }); - self.point_at_expr_source_of_inferred_type( + self.note_source_of_type_mismatch_constraint( &mut err, rcvr, - expected, - callee_ty, - provided_arg_span, + crate::demand::TypeMismatchSource::Arg { + call_expr, + incompatible_arg: provided_idx.as_usize(), + }, ); } + // Call out where the function is defined self.label_fn_like( &mut err, diff --git a/library/alloc/benches/btree/map.rs b/library/alloc/benches/btree/map.rs index 1f6b87fb0e40f..ec1b0a8eba039 100644 --- a/library/alloc/benches/btree/map.rs +++ b/library/alloc/benches/btree/map.rs @@ -1,5 +1,4 @@ use std::collections::BTreeMap; -use std::iter::Iterator; use std::ops::RangeBounds; use std::vec::Vec; diff --git a/library/alloc/benches/vec.rs b/library/alloc/benches/vec.rs index 663f6b9dd1c9c..c1d3e1bdfe79d 100644 --- a/library/alloc/benches/vec.rs +++ b/library/alloc/benches/vec.rs @@ -1,5 +1,5 @@ use rand::RngCore; -use std::iter::{repeat, FromIterator}; +use std::iter::repeat; use test::{black_box, Bencher}; #[bench] diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 09041bb119bb7..7f88327bf190a 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -150,16 +150,13 @@ use core::any::Any; use core::async_iter::AsyncIterator; use core::borrow; use core::cmp::Ordering; -use core::convert::{From, TryFrom}; use core::error::Error; use core::fmt; use core::future::Future; use core::hash::{Hash, Hasher}; -#[cfg(not(no_global_oom_handling))] -use core::iter::FromIterator; -use core::iter::{FusedIterator, Iterator}; +use core::iter::FusedIterator; use core::marker::Tuple; -use core::marker::{Unpin, Unsize}; +use core::marker::Unsize; use core::mem; use core::ops::{ CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver, diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index bc86125c7c33c..8aa4d342e6e37 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -144,7 +144,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use core::fmt; -use core::iter::{FromIterator, FusedIterator, InPlaceIterable, SourceIter, TrustedLen}; +use core::iter::{FusedIterator, InPlaceIterable, SourceIter, TrustedLen}; use core::mem::{self, swap, ManuallyDrop}; use core::num::NonZeroUsize; use core::ops::{Deref, DerefMut}; @@ -263,7 +263,6 @@ mod tests; /// more detailed analysis. /// /// [`core::cmp::Reverse`]: core::cmp::Reverse -/// [`Ord`]: core::cmp::Ord /// [`Cell`]: core::cell::Cell /// [`RefCell`]: core::cell::RefCell /// [push]: BinaryHeap::push @@ -1418,7 +1417,6 @@ impl FusedIterator for Iter<'_, T> {} /// (provided by the [`IntoIterator`] trait). See its documentation for more. /// /// [`into_iter`]: BinaryHeap::into_iter -/// [`IntoIterator`]: core::iter::IntoIterator #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct IntoIter { diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index da675379cd58b..abd5f17137ec2 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -3,7 +3,7 @@ use core::borrow::Borrow; use core::cmp::Ordering; use core::fmt::{self, Debug}; use core::hash::{Hash, Hasher}; -use core::iter::{FromIterator, FusedIterator}; +use core::iter::FusedIterator; use core::marker::PhantomData; use core::mem::{self, ManuallyDrop}; use core::ops::{Bound, Index, RangeBounds}; @@ -420,7 +420,6 @@ impl<'a, K: 'a, V: 'a> Default for IterMut<'a, K, V> { /// (provided by the [`IntoIterator`] trait). See its documentation for more. /// /// [`into_iter`]: IntoIterator::into_iter -/// [`IntoIterator`]: core::iter::IntoIterator #[stable(feature = "rust1", since = "1.0.0")] #[rustc_insignificant_dtor] pub struct IntoIter< @@ -650,7 +649,7 @@ impl BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] pub fn clear(&mut self) { // avoid moving the allocator - mem::drop(BTreeMap { + drop(BTreeMap { root: mem::replace(&mut self.root, None), length: mem::replace(&mut self.length, 0), alloc: self.alloc.clone(), diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 4311f21c925cd..da00d83bdbb57 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -9,8 +9,7 @@ use crate::testing::ord_chaos::{Cyclic3, Governed, Governor}; use crate::testing::rng::DeterministicRng; use crate::vec::Vec; use std::cmp::Ordering; -use std::convert::TryFrom; -use std::iter::{self, FromIterator}; +use std::iter; use std::mem; use std::ops::Bound::{self, Excluded, Included, Unbounded}; use std::ops::RangeBounds; diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index a7cb3948aa112..232a017314e5e 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -4,7 +4,7 @@ use core::cmp::Ordering::{self, Equal, Greater, Less}; use core::cmp::{max, min}; use core::fmt::{self, Debug}; use core::hash::{Hash, Hasher}; -use core::iter::{FromIterator, FusedIterator, Peekable}; +use core::iter::{FusedIterator, Peekable}; use core::mem::ManuallyDrop; use core::ops::{BitAnd, BitOr, BitXor, RangeBounds, Sub}; @@ -30,7 +30,6 @@ use crate::alloc::{Allocator, Global}; /// Iterators returned by [`BTreeSet::iter`] produce their items in order, and take worst-case /// logarithmic and amortized constant time per item returned. /// -/// [`Ord`]: core::cmp::Ord /// [`Cell`]: core::cell::Cell /// [`RefCell`]: core::cell::RefCell /// @@ -147,7 +146,6 @@ impl fmt::Debug for Iter<'_, T> { /// (provided by the [`IntoIterator`] trait). See its documentation for more. /// /// [`into_iter`]: BTreeSet#method.into_iter -/// [`IntoIterator`]: core::iter::IntoIterator #[stable(feature = "rust1", since = "1.0.0")] #[derive(Debug)] pub struct IntoIter< diff --git a/library/alloc/src/collections/btree/set/tests.rs b/library/alloc/src/collections/btree/set/tests.rs index 7b8d41a603176..a7c839d77ed4c 100644 --- a/library/alloc/src/collections/btree/set/tests.rs +++ b/library/alloc/src/collections/btree/set/tests.rs @@ -4,7 +4,6 @@ use crate::testing::rng::DeterministicRng; use crate::vec::Vec; use std::cmp::Ordering; use std::hash::{Hash, Hasher}; -use std::iter::FromIterator; use std::ops::Bound::{Excluded, Included}; use std::panic::{catch_unwind, AssertUnwindSafe}; diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 080a4a14eda6e..1743a155c5abf 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -15,7 +15,7 @@ use core::cmp::Ordering; use core::fmt; use core::hash::{Hash, Hasher}; -use core::iter::{FromIterator, FusedIterator}; +use core::iter::FusedIterator; use core::marker::PhantomData; use core::mem; use core::ptr::NonNull; @@ -130,7 +130,6 @@ impl fmt::Debug for IterMut<'_, T> { /// (provided by the [`IntoIterator`] trait). See its documentation for more. /// /// [`into_iter`]: LinkedList::into_iter -/// [`IntoIterator`]: core::iter::IntoIterator #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs index e2b40f7912e0f..d9e274df0f5f2 100644 --- a/library/alloc/src/collections/vec_deque/into_iter.rs +++ b/library/alloc/src/collections/vec_deque/into_iter.rs @@ -12,7 +12,6 @@ use super::VecDeque; /// (provided by the [`IntoIterator`] trait). See its documentation for more. /// /// [`into_iter`]: VecDeque::into_iter -/// [`IntoIterator`]: core::iter::IntoIterator #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter< diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 05dbcdc904e05..8916b42eda05e 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -10,7 +10,7 @@ use core::cmp::{self, Ordering}; use core::fmt; use core::hash::{Hash, Hasher}; -use core::iter::{repeat_n, repeat_with, ByRefSized, FromIterator}; +use core::iter::{repeat_n, repeat_with, ByRefSized}; use core::mem::{ManuallyDrop, SizedTypeProperties}; use core::ops::{Index, IndexMut, Range, RangeBounds}; use core::ptr; diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 3751f2a245456..dfd30d99cf041 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -4,7 +4,6 @@ use core::alloc::LayoutError; use core::cmp; use core::intrinsics; use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; -use core::ops::Drop; use core::ptr::{self, NonNull, Unique}; use core::slice; diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 1e9cf404f77ea..cf93a40496fdf 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -15,7 +15,7 @@ //! //! [`Rc`] uses non-atomic reference counting. This means that overhead is very //! low, but an [`Rc`] cannot be sent between threads, and consequently [`Rc`] -//! does not implement [`Send`][send]. As a result, the Rust compiler +//! does not implement [`Send`]. As a result, the Rust compiler //! will check *at compile time* that you are not sending [`Rc`]s between //! threads. If you need multi-threaded, atomic reference counting, use //! [`sync::Arc`][arc]. @@ -232,7 +232,6 @@ //! [clone]: Clone::clone //! [`Cell`]: core::cell::Cell //! [`RefCell`]: core::cell::RefCell -//! [send]: core::marker::Send //! [arc]: crate::sync::Arc //! [`Deref`]: core::ops::Deref //! [downgrade]: Rc::downgrade @@ -251,13 +250,12 @@ use core::any::Any; use core::borrow; use core::cell::Cell; use core::cmp::Ordering; -use core::convert::{From, TryFrom}; use core::fmt; use core::hash::{Hash, Hasher}; use core::intrinsics::abort; #[cfg(not(no_global_oom_handling))] use core::iter; -use core::marker::{self, PhantomData, Unpin, Unsize}; +use core::marker::{PhantomData, Unsize}; #[cfg(not(no_global_oom_handling))] use core::mem::size_of_val; use core::mem::{self, align_of_val_raw, forget}; @@ -321,7 +319,7 @@ pub struct Rc { } #[stable(feature = "rust1", since = "1.0.0")] -impl !marker::Send for Rc {} +impl !Send for Rc {} // Note that this negative impl isn't strictly necessary for correctness, // as `Rc` transitively contains a `Cell`, which is itself `!Sync`. @@ -329,7 +327,7 @@ impl !marker::Send for Rc {} // having an explicit negative impl is nice for documentation purposes // and results in nicer error messages. #[stable(feature = "rust1", since = "1.0.0")] -impl !marker::Sync for Rc {} +impl !Sync for Rc {} #[stable(feature = "catch_unwind", since = "1.9.0")] impl UnwindSafe for Rc {} @@ -1060,7 +1058,7 @@ impl Rc { #[inline] #[stable(feature = "rc_mutate_strong_count", since = "1.53.0")] pub unsafe fn decrement_strong_count(ptr: *const T) { - unsafe { mem::drop(Rc::from_raw(ptr)) }; + unsafe { drop(Rc::from_raw(ptr)) }; } /// Returns `true` if there are no other `Rc` or [`Weak`] pointers to @@ -1496,7 +1494,7 @@ impl Rc<[T]> { /// /// Behavior is undefined should the size be wrong. #[cfg(not(no_global_oom_handling))] - unsafe fn from_iter_exact(iter: impl iter::Iterator, len: usize) -> Rc<[T]> { + unsafe fn from_iter_exact(iter: impl Iterator, len: usize) -> Rc<[T]> { // Panic guard while cloning T elements. // In the event of a panic, elements that have been written // into the new RcBox will be dropped, then the memory freed. @@ -2088,7 +2086,7 @@ impl TryFrom> for Rc<[T; N]> { #[cfg(not(no_global_oom_handling))] #[stable(feature = "shared_from_iter", since = "1.37.0")] -impl iter::FromIterator for Rc<[T]> { +impl FromIterator for Rc<[T]> { /// Takes each element in the `Iterator` and collects it into an `Rc<[T]>`. /// /// # Performance characteristics @@ -2127,7 +2125,7 @@ impl iter::FromIterator for Rc<[T]> { /// let evens: Rc<[u8]> = (0..10).collect(); // Just a single allocation happens here. /// # assert_eq!(&*evens, &*(0..10).collect::>()); /// ``` - fn from_iter>(iter: I) -> Self { + fn from_iter>(iter: I) -> Self { ToRcSlice::to_rc_slice(iter.into_iter()) } } @@ -2204,9 +2202,9 @@ pub struct Weak { } #[stable(feature = "rc_weak", since = "1.4.0")] -impl !marker::Send for Weak {} +impl !Send for Weak {} #[stable(feature = "rc_weak", since = "1.4.0")] -impl !marker::Sync for Weak {} +impl !Sync for Weak {} #[unstable(feature = "coerce_unsized", issue = "18598")] impl, U: ?Sized> CoerceUnsized> for Weak {} diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index c1cd3c74ab676..be41919b9dc23 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -45,9 +45,9 @@ use core::error::Error; use core::fmt; use core::hash; -use core::iter::FusedIterator; #[cfg(not(no_global_oom_handling))] -use core::iter::{from_fn, FromIterator}; +use core::iter::from_fn; +use core::iter::FusedIterator; #[cfg(not(no_global_oom_handling))] use core::ops::Add; #[cfg(not(no_global_oom_handling))] diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 150924851d21d..5bfe537bc830f 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -11,14 +11,13 @@ use core::any::Any; use core::borrow; use core::cmp::Ordering; -use core::convert::{From, TryFrom}; use core::fmt; use core::hash::{Hash, Hasher}; use core::hint; use core::intrinsics::abort; #[cfg(not(no_global_oom_handling))] use core::iter; -use core::marker::{PhantomData, Unpin, Unsize}; +use core::marker::{PhantomData, Unsize}; #[cfg(not(no_global_oom_handling))] use core::mem::size_of_val; use core::mem::{self, align_of_val_raw}; @@ -188,8 +187,6 @@ macro_rules! acquire { /// [mutex]: ../../std/sync/struct.Mutex.html /// [rwlock]: ../../std/sync/struct.RwLock.html /// [atomic]: core::sync::atomic -/// [`Send`]: core::marker::Send -/// [`Sync`]: core::marker::Sync /// [deref]: core::ops::Deref /// [downgrade]: Arc::downgrade /// [upgrade]: Weak::upgrade @@ -1241,7 +1238,7 @@ impl Arc { #[inline] #[stable(feature = "arc_mutate_strong_count", since = "1.51.0")] pub unsafe fn decrement_strong_count(ptr: *const T) { - unsafe { mem::drop(Arc::from_raw(ptr)) }; + unsafe { drop(Arc::from_raw(ptr)) }; } #[inline] @@ -1404,7 +1401,7 @@ impl Arc<[T]> { /// /// Behavior is undefined should the size be wrong. #[cfg(not(no_global_oom_handling))] - unsafe fn from_iter_exact(iter: impl iter::Iterator, len: usize) -> Arc<[T]> { + unsafe fn from_iter_exact(iter: impl Iterator, len: usize) -> Arc<[T]> { // Panic guard while cloning T elements. // In the event of a panic, elements that have been written // into the new ArcInner will be dropped, then the memory freed. @@ -2818,7 +2815,7 @@ impl TryFrom> for Arc<[T; N]> { #[cfg(not(no_global_oom_handling))] #[stable(feature = "shared_from_iter", since = "1.37.0")] -impl iter::FromIterator for Arc<[T]> { +impl FromIterator for Arc<[T]> { /// Takes each element in the `Iterator` and collects it into an `Arc<[T]>`. /// /// # Performance characteristics @@ -2857,7 +2854,7 @@ impl iter::FromIterator for Arc<[T]> { /// let evens: Arc<[u8]> = (0..10).collect(); // Just a single allocation happens here. /// # assert_eq!(&*evens, &*(0..10).collect::>()); /// ``` - fn from_iter>(iter: I) -> Self { + fn from_iter>(iter: I) -> Self { ToArcSlice::to_arc_slice(iter.into_iter()) } } diff --git a/library/alloc/src/vec/cow.rs b/library/alloc/src/vec/cow.rs index 64943a273c9a5..2c799605b7b67 100644 --- a/library/alloc/src/vec/cow.rs +++ b/library/alloc/src/vec/cow.rs @@ -1,5 +1,4 @@ use crate::borrow::Cow; -use core::iter::FromIterator; use super::Vec; diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 6a05f70e43747..02faf8e638948 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -108,7 +108,7 @@ impl IntoIter { /// ``` /// # let mut into_iter = Vec::::with_capacity(10).into_iter(); /// let mut into_iter = std::mem::replace(&mut into_iter, Vec::new().into_iter()); - /// (&mut into_iter).for_each(core::mem::drop); + /// (&mut into_iter).for_each(drop); /// std::mem::forget(into_iter); /// ``` /// diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 9f0111db4524c..3736a6e0b0ecb 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -56,12 +56,9 @@ #[cfg(not(no_global_oom_handling))] use core::cmp; use core::cmp::Ordering; -use core::convert::TryFrom; use core::fmt; use core::hash::{Hash, Hasher}; use core::iter; -#[cfg(not(no_global_oom_handling))] -use core::iter::FromIterator; use core::marker::PhantomData; use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; use core::ops::{self, Index, IndexMut, Range, RangeBounds}; @@ -2990,7 +2987,7 @@ impl<'a, T: Copy + 'a, A: Allocator + 'a> Extend<&'a T> for Vec { } } -/// Implements comparison of vectors, [lexicographically](core::cmp::Ord#lexicographical-comparison). +/// Implements comparison of vectors, [lexicographically](Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for Vec { #[inline] @@ -3002,7 +2999,7 @@ impl PartialOrd for Vec { #[stable(feature = "rust1", since = "1.0.0")] impl Eq for Vec {} -/// Implements ordering of vectors, [lexicographically](core::cmp::Ord#lexicographical-comparison). +/// Implements ordering of vectors, [lexicographically](Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] impl Ord for Vec { #[inline] diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 5b5f55d0e65b0..55331475aff2a 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -231,7 +231,8 @@ pub trait PartialEq { } } -/// Derive macro generating an impl of the trait `PartialEq`. +/// Derive macro generating an impl of the trait [`PartialEq`]. +/// The behavior of this macro is described in detail [here](PartialEq#derivable). #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics, structural_match)] @@ -297,7 +298,7 @@ pub trait Eq: PartialEq { fn assert_receiver_is_total_eq(&self) {} } -/// Derive macro generating an impl of the trait `Eq`. +/// Derive macro generating an impl of the trait [`Eq`]. #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics, derive_eq, structural_match, no_coverage)] @@ -859,7 +860,8 @@ pub trait Ord: Eq + PartialOrd { } } -/// Derive macro generating an impl of the trait `Ord`. +/// Derive macro generating an impl of the trait [`Ord`]. +/// The behavior of this macro is described in detail [here](Ord#derivable). #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics)] @@ -1138,7 +1140,8 @@ pub trait PartialOrd: PartialEq { } } -/// Derive macro generating an impl of the trait `PartialOrd`. +/// Derive macro generating an impl of the trait [`PartialOrd`]. +/// The behavior of this macro is described in detail [here](PartialOrd#derivable). #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics)] diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs index d9d62eb759e69..45498a54b25dc 100644 --- a/library/core/src/intrinsics/mir.rs +++ b/library/core/src/intrinsics/mir.rs @@ -247,7 +247,7 @@ //! - The exception is the last arm, which must be `_ => basic_block` and corresponds to the //! otherwise branch. //! - [`Call`] has an associated function as well. The third argument of this function is a normal -//! function call expresion, for example `my_other_function(a, 5)`. +//! function call expression, for example `my_other_function(a, 5)`. //! #![unstable( diff --git a/library/core/src/iter/sources/repeat_with.rs b/library/core/src/iter/sources/repeat_with.rs index 3f34105a3e071..d3cd74a448375 100644 --- a/library/core/src/iter/sources/repeat_with.rs +++ b/library/core/src/iter/sources/repeat_with.rs @@ -19,7 +19,6 @@ use crate::ops::Try; /// please open a GitHub issue explaining your use case. /// /// [`repeat()`]: crate::iter::repeat -/// [`DoubleEndedIterator`]: crate::iter::DoubleEndedIterator /// /// # Examples /// diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index f3d1e45f4fb6a..02877604248df 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -764,7 +764,6 @@ pub trait Iterator { /// more idiomatic to use [`for`] than `map()`. /// /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for - /// [`FnMut`]: crate::ops::FnMut /// /// # Examples /// diff --git a/library/core/src/net/parser.rs b/library/core/src/net/parser.rs index a08d2792d0456..b9a1924d66898 100644 --- a/library/core/src/net/parser.rs +++ b/library/core/src/net/parser.rs @@ -9,7 +9,7 @@ use crate::fmt; use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; use crate::str::FromStr; -trait ReadNumberHelper: crate::marker::Sized { +trait ReadNumberHelper: Sized { const ZERO: Self; fn checked_mul(&self, other: u32) -> Option; fn checked_add(&self, other: u32) -> Option; diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 0d385c9d18744..06fbe083ca13d 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -15,14 +15,10 @@ use crate::panic::Location; /// use std::panic; /// /// panic::set_hook(Box::new(|panic_info| { -/// if let Some(s) = panic_info.payload().downcast_ref::<&str>() { -/// println!("panic occurred: {s:?}"); -/// } else { -/// println!("panic occurred"); -/// } +/// println!("panic occurred: {panic_info}"); /// })); /// -/// panic!("Normal panic"); +/// panic!("critical system failure"); /// ``` #[lang = "panic_info"] #[stable(feature = "panic_hooks", since = "1.10.0")] diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 51e6947a9c25a..3df990e5dd9fe 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -577,7 +577,6 @@ impl Copy for () { /// [`is_null`]: pointer::is_null /// [`offset`]: pointer::offset #[doc = concat!("[`into_raw`]: ", include_str!("../primitive_docs/box_into_raw.md"))] -/// [`drop`]: mem::drop /// [`write`]: ptr::write #[stable(feature = "rust1", since = "1.0.0")] mod prim_pointer {} @@ -1026,7 +1025,6 @@ mod prim_str {} /// * [`UnwindSafe`] /// * [`RefUnwindSafe`] /// -/// [`Unpin`]: marker::Unpin /// [`UnwindSafe`]: panic::UnwindSafe /// [`RefUnwindSafe`]: panic::RefUnwindSafe /// @@ -1405,10 +1403,6 @@ mod prim_ref {} /// /// *See also the traits [`Fn`], [`FnMut`], and [`FnOnce`].* /// -/// [`Fn`]: ops::Fn -/// [`FnMut`]: ops::FnMut -/// [`FnOnce`]: ops::FnOnce -/// /// Function pointers are pointers that point to *code*, not data. They can be called /// just like functions. Like references, function pointers are, among other things, assumed to /// not be null, so if you want to pass a function pointer over FFI and be able to accommodate null diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs index 2333f60a8889b..07fd96f929586 100644 --- a/library/core/src/slice/sort.rs +++ b/library/core/src/slice/sort.rs @@ -1486,7 +1486,7 @@ where } /// Finds a streak of presorted elements starting at the beginning of the slice. Returns the first -/// value that is not part of said streak, and a bool denoting wether the streak was reversed. +/// value that is not part of said streak, and a bool denoting whether the streak was reversed. /// Streaks can be increasing or decreasing. fn find_streak(v: &[T], is_less: &mut F) -> (usize, bool) where diff --git a/library/core/src/str/pattern.rs b/library/core/src/str/pattern.rs index 19da6d2fbecbc..e3a464a1c51a9 100644 --- a/library/core/src/str/pattern.rs +++ b/library/core/src/str/pattern.rs @@ -1891,7 +1891,7 @@ unsafe fn small_slice_eq(x: &[u8], y: &[u8]) -> bool { // SAFETY: Via the conditional above, we know that both `px` and `py` // have the same length, so `px < pxend` implies that `py < pyend`. - // Thus, derefencing both `px` and `py` in the loop below is safe. + // Thus, dereferencing both `px` and `py` in the loop below is safe. // // Moreover, we set `pxend` and `pyend` to be 4 bytes before the actual // end of `px` and `py`. Thus, the final dereference outside of the diff --git a/library/core/src/sync/exclusive.rs b/library/core/src/sync/exclusive.rs index 301ad41c96634..3f3e19c55d4ba 100644 --- a/library/core/src/sync/exclusive.rs +++ b/library/core/src/sync/exclusive.rs @@ -69,9 +69,6 @@ use core::task::{Context, Poll}; /// for any value. This is a parallel with the fact that /// `&` and `&mut` references together can be thought of as a _compile-time_ /// version of a read-write lock. -/// -/// -/// [`Sync`]: core::marker::Sync #[unstable(feature = "exclusive_wrapper", issue = "98407")] #[doc(alias = "SyncWrapper")] #[doc(alias = "SyncCell")] diff --git a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs index adf0fcbeae2bd..b5ba198e5041b 100644 --- a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs @@ -257,7 +257,7 @@ where } } -impl core::convert::From> for Simd +impl From> for Simd where T: MaskElement, LaneCount: SupportedLaneCount, diff --git a/library/proc_macro/src/bridge/fxhash.rs b/library/proc_macro/src/bridge/fxhash.rs index 17bd0a1b33646..f4e9054419721 100644 --- a/library/proc_macro/src/bridge/fxhash.rs +++ b/library/proc_macro/src/bridge/fxhash.rs @@ -5,8 +5,6 @@ //! on the `rustc_hash` crate. use std::collections::HashMap; -use std::convert::TryInto; -use std::default::Default; use std::hash::BuildHasherDefault; use std::hash::Hasher; use std::mem::size_of; diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 938935771d64e..9d081c8b842d5 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -47,7 +47,7 @@ use std::cmp::Ordering; use std::ops::RangeBounds; use std::path::PathBuf; use std::str::FromStr; -use std::{error, fmt, iter}; +use std::{error, fmt}; /// Determines whether proc_macro has been made accessible to the currently /// running program. @@ -310,7 +310,7 @@ impl ConcatStreamsHelper { /// Collects a number of token trees into a single stream. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] -impl iter::FromIterator for TokenStream { +impl FromIterator for TokenStream { fn from_iter>(trees: I) -> Self { let iter = trees.into_iter(); let mut builder = ConcatTreesHelper::new(iter.size_hint().0); @@ -322,7 +322,7 @@ impl iter::FromIterator for TokenStream { /// A "flattening" operation on token streams, collects token trees /// from multiple token streams into a single stream. #[stable(feature = "proc_macro_lib", since = "1.15.0")] -impl iter::FromIterator for TokenStream { +impl FromIterator for TokenStream { fn from_iter>(streams: I) -> Self { let iter = streams.into_iter(); let mut builder = ConcatStreamsHelper::new(iter.size_hint().0); diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 742c4cc7c5539..3afc8287ecc00 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1446,7 +1446,6 @@ impl<'a, K, V> IterMut<'a, K, V> { /// (provided by the [`IntoIterator`] trait). See its documentation for more. /// /// [`into_iter`]: IntoIterator::into_iter -/// [`IntoIterator`]: crate::iter::IntoIterator /// /// # Example /// diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 837a18bff6087..ac906e682d5f0 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -1272,7 +1272,6 @@ pub struct Iter<'a, K: 'a> { /// (provided by the [`IntoIterator`] trait). See its documentation for more. /// /// [`into_iter`]: IntoIterator::into_iter -/// [`IntoIterator`]: crate::iter::IntoIterator /// /// # Examples /// diff --git a/library/std/src/collections/mod.rs b/library/std/src/collections/mod.rs index 23ed577ea609a..42f738acb9f7b 100644 --- a/library/std/src/collections/mod.rs +++ b/library/std/src/collections/mod.rs @@ -398,8 +398,6 @@ //! // ...but the key hasn't changed. b is still "baz", not "xyz". //! assert_eq!(map.keys().next().unwrap().b, "baz"); //! ``` -//! -//! [IntoIterator]: crate::iter::IntoIterator "iter::IntoIterator" #![stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 80ed34157e6dc..5c0541d3caf33 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -6,7 +6,6 @@ use crate::cmp; use crate::collections::TryReserveError; use crate::fmt; use crate::hash::{Hash, Hasher}; -use crate::iter::Extend; use crate::ops; use crate::rc::Rc; use crate::str::FromStr; diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 1cedd6eedfaf9..34c0ce9dcf848 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -11,7 +11,6 @@ mod repr_unpacked; #[cfg(not(target_pointer_width = "64"))] use repr_unpacked::Repr; -use crate::convert::From; use crate::error; use crate::fmt; use crate::result; diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index 203c490fa29a6..43842bee992a7 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -1678,7 +1678,7 @@ mod super_keyword {} /// below `Iterator` is a **supertrait** and `ThreeIterator` is a **subtrait**: /// /// ```rust -/// trait ThreeIterator: std::iter::Iterator { +/// trait ThreeIterator: Iterator { /// fn next_three(&mut self) -> Option<[Self::Item; 3]>; /// } /// ``` diff --git a/library/std/src/path.rs b/library/std/src/path.rs index dbc18f7827e60..8014ba992eaf8 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -78,7 +78,7 @@ use crate::fmt; use crate::fs; use crate::hash::{Hash, Hasher}; use crate::io; -use crate::iter::{self, FusedIterator}; +use crate::iter::FusedIterator; use crate::ops::{self, Deref}; use crate::rc::Rc; use crate::str::FromStr; @@ -450,26 +450,26 @@ impl<'a> PrefixComponent<'a> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a> cmp::PartialEq for PrefixComponent<'a> { +impl<'a> PartialEq for PrefixComponent<'a> { #[inline] fn eq(&self, other: &PrefixComponent<'a>) -> bool { - cmp::PartialEq::eq(&self.parsed, &other.parsed) + self.parsed == other.parsed } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a> cmp::PartialOrd for PrefixComponent<'a> { +impl<'a> PartialOrd for PrefixComponent<'a> { #[inline] fn partial_cmp(&self, other: &PrefixComponent<'a>) -> Option { - cmp::PartialOrd::partial_cmp(&self.parsed, &other.parsed) + PartialOrd::partial_cmp(&self.parsed, &other.parsed) } } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::Ord for PrefixComponent<'_> { +impl Ord for PrefixComponent<'_> { #[inline] fn cmp(&self, other: &Self) -> cmp::Ordering { - cmp::Ord::cmp(&self.parsed, &other.parsed) + Ord::cmp(&self.parsed, &other.parsed) } } @@ -988,7 +988,7 @@ impl<'a> DoubleEndedIterator for Components<'a> { impl FusedIterator for Components<'_> {} #[stable(feature = "rust1", since = "1.0.0")] -impl<'a> cmp::PartialEq for Components<'a> { +impl<'a> PartialEq for Components<'a> { #[inline] fn eq(&self, other: &Components<'a>) -> bool { let Components { path: _, front: _, back: _, has_physical_root: _, prefix: _ } = self; @@ -1015,10 +1015,10 @@ impl<'a> cmp::PartialEq for Components<'a> { } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::Eq for Components<'_> {} +impl Eq for Components<'_> {} #[stable(feature = "rust1", since = "1.0.0")] -impl<'a> cmp::PartialOrd for Components<'a> { +impl<'a> PartialOrd for Components<'a> { #[inline] fn partial_cmp(&self, other: &Components<'a>) -> Option { Some(compare_components(self.clone(), other.clone())) @@ -1026,7 +1026,7 @@ impl<'a> cmp::PartialOrd for Components<'a> { } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::Ord for Components<'_> { +impl Ord for Components<'_> { #[inline] fn cmp(&self, other: &Self) -> cmp::Ordering { compare_components(self.clone(), other.clone()) @@ -1741,7 +1741,7 @@ impl FromStr for PathBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl> iter::FromIterator

for PathBuf { +impl> FromIterator

for PathBuf { fn from_iter>(iter: I) -> PathBuf { let mut buf = PathBuf::new(); buf.extend(iter); @@ -1750,7 +1750,7 @@ impl> iter::FromIterator

for PathBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl> iter::Extend

for PathBuf { +impl> Extend

for PathBuf { fn extend>(&mut self, iter: I) { iter.into_iter().for_each(move |p| self.push(p.as_ref())); } @@ -1904,7 +1904,7 @@ impl ToOwned for Path { } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::PartialEq for PathBuf { +impl PartialEq for PathBuf { #[inline] fn eq(&self, other: &PathBuf) -> bool { self.components() == other.components() @@ -1919,10 +1919,10 @@ impl Hash for PathBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::Eq for PathBuf {} +impl Eq for PathBuf {} #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::PartialOrd for PathBuf { +impl PartialOrd for PathBuf { #[inline] fn partial_cmp(&self, other: &PathBuf) -> Option { Some(compare_components(self.components(), other.components())) @@ -1930,7 +1930,7 @@ impl cmp::PartialOrd for PathBuf { } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::Ord for PathBuf { +impl Ord for PathBuf { #[inline] fn cmp(&self, other: &PathBuf) -> cmp::Ordering { compare_components(self.components(), other.components()) @@ -3025,7 +3025,7 @@ impl fmt::Display for Display<'_> { } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::PartialEq for Path { +impl PartialEq for Path { #[inline] fn eq(&self, other: &Path) -> bool { self.components() == other.components() @@ -3084,10 +3084,10 @@ impl Hash for Path { } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::Eq for Path {} +impl Eq for Path {} #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::PartialOrd for Path { +impl PartialOrd for Path { #[inline] fn partial_cmp(&self, other: &Path) -> Option { Some(compare_components(self.components(), other.components())) @@ -3095,7 +3095,7 @@ impl cmp::PartialOrd for Path { } #[stable(feature = "rust1", since = "1.0.0")] -impl cmp::Ord for Path { +impl Ord for Path { #[inline] fn cmp(&self, other: &Path) -> cmp::Ordering { compare_components(self.components(), other.components()) diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs index c314bbbb68e57..1b29c887d2100 100644 --- a/library/std/src/prelude/mod.rs +++ b/library/std/src/prelude/mod.rs @@ -34,7 +34,7 @@ //! marker traits that indicate fundamental properties of types. //! * [std::ops]::{[Drop], [Fn], [FnMut], [FnOnce]}, various //! operations for both destructors and overloading `()`. -//! * [std::mem]::[drop][mem::drop], a convenience function for explicitly +//! * [std::mem]::[drop], a convenience function for explicitly //! dropping a value. //! * [std::boxed]::[Box], a way to allocate values on the heap. //! * [std::borrow]::[ToOwned], the conversion trait that defines @@ -66,7 +66,6 @@ //! * [std::convert]::{[TryFrom], [TryInto]}, //! * [std::iter]::[FromIterator]. //! -//! [mem::drop]: crate::mem::drop //! [std::borrow]: crate::borrow //! [std::boxed]: crate::boxed //! [std::clone]: crate::clone @@ -86,9 +85,6 @@ //! [std::slice]: crate::slice //! [std::string]: crate::string //! [std::vec]: mod@crate::vec -//! [TryFrom]: crate::convert::TryFrom -//! [TryInto]: crate::convert::TryInto -//! [FromIterator]: crate::iter::FromIterator //! [`to_owned`]: crate::borrow::ToOwned::to_owned //! [book-closures]: ../../book/ch13-01-closures.html //! [book-dtor]: ../../book/ch15-03-drop.html diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 51e6947a9c25a..3df990e5dd9fe 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -577,7 +577,6 @@ impl Copy for () { /// [`is_null`]: pointer::is_null /// [`offset`]: pointer::offset #[doc = concat!("[`into_raw`]: ", include_str!("../primitive_docs/box_into_raw.md"))] -/// [`drop`]: mem::drop /// [`write`]: ptr::write #[stable(feature = "rust1", since = "1.0.0")] mod prim_pointer {} @@ -1026,7 +1025,6 @@ mod prim_str {} /// * [`UnwindSafe`] /// * [`RefUnwindSafe`] /// -/// [`Unpin`]: marker::Unpin /// [`UnwindSafe`]: panic::UnwindSafe /// [`RefUnwindSafe`]: panic::RefUnwindSafe /// @@ -1405,10 +1403,6 @@ mod prim_ref {} /// /// *See also the traits [`Fn`], [`FnMut`], and [`FnOnce`].* /// -/// [`Fn`]: ops::Fn -/// [`FnMut`]: ops::FnMut -/// [`FnOnce`]: ops::FnOnce -/// /// Function pointers are pointers that point to *code*, not data. They can be called /// just like functions. Like references, function pointers are, among other things, assumed to /// not be null, so if you want to pass a function pointer over FFI and be able to accommodate null diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 80d73084c4f01..0ab72f7ea7a6d 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -652,10 +652,19 @@ impl Command { self } - /// Inserts or updates an environment variable mapping. + /// Inserts or updates an explicit environment variable mapping. /// - /// Note that environment variable names are case-insensitive (but case-preserving) on Windows, - /// and case-sensitive on all other platforms. + /// This method allows you to add an environment variable mapping to the spawned process or + /// overwrite a previously set value. You can use [`Command::envs`] to set multiple environment + /// variables simultaneously. + /// + /// Child processes will inherit environment variables from their parent process by default. + /// Environment variables explicitly set using [`Command::env`] take precedence over inherited + /// variables. You can disable environment variable inheritance entirely using + /// [`Command::env_clear`] or for a single key using [`Command::env_remove`]. + /// + /// Note that environment variable names are case-insensitive (but + /// case-preserving) on Windows and case-sensitive on all other platforms. /// /// # Examples /// @@ -679,7 +688,19 @@ impl Command { self } - /// Adds or updates multiple environment variable mappings. + /// Inserts or updates multiple explicit environment variable mappings. + /// + /// This method allows you to add multiple environment variable mappings to the spawned process + /// or overwrite previously set values. You can use [`Command::env`] to set a single environment + /// variable. + /// + /// Child processes will inherit environment variables from their parent process by default. + /// Environment variables explicitly set using [`Command::envs`] take precedence over inherited + /// variables. You can disable environment variable inheritance entirely using + /// [`Command::env_clear`] or for a single key using [`Command::env_remove`]. + /// + /// Note that environment variable names are case-insensitive (but case-preserving) on Windows + /// and case-sensitive on all other platforms. /// /// # Examples /// @@ -716,7 +737,18 @@ impl Command { self } - /// Removes an environment variable mapping. + /// Removes an explicitly set environment variable and prevents inheriting it from a parent + /// process. + /// + /// This method will remove the explicit value of an environment variable set via + /// [`Command::env`] or [`Command::envs`]. In addition, it will prevent the spawned child + /// process from inheriting that environment variable from its parent process. + /// + /// After calling [`Command::env_remove`], the value associated with its key from + /// [`Command::get_envs`] will be [`None`]. + /// + /// To clear all explicitly set environment variables and disable all environment variable + /// inheritance, you can use [`Command::env_clear`]. /// /// # Examples /// @@ -736,7 +768,17 @@ impl Command { self } - /// Clears the entire environment map for the child process. + /// Clears all explicitly set environment variables and prevents inheriting any parent process + /// environment variables. + /// + /// This method will remove all explicitly added environment variables set via [`Command::env`] + /// or [`Command::envs`]. In addition, it will prevent the spawned child process from inheriting + /// any environment variable from its parent process. + /// + /// After calling [`Command::env_remove`], the iterator from [`Command::get_envs`] will be + /// empty. + /// + /// You can use [`Command::env_remove`] to clear a single mapping. /// /// # Examples /// @@ -988,17 +1030,21 @@ impl Command { CommandArgs { inner: self.inner.get_args() } } - /// Returns an iterator of the environment variables that will be set when - /// the process is spawned. + /// Returns an iterator of the environment variables explicitly set for the child process. + /// + /// Environment variables explicitly set using [`Command::env`], [`Command::envs`], and + /// [`Command::env_remove`] can be retrieved with this method. + /// + /// Note that this output does not include environment variables inherited from the parent + /// process. /// - /// Each element is a tuple `(&OsStr, Option<&OsStr>)`, where the first - /// value is the key, and the second is the value, which is [`None`] if - /// the environment variable is to be explicitly removed. + /// Each element is a tuple key/value pair `(&OsStr, Option<&OsStr>)`. A [`None`] value + /// indicates its key was explicitly removed via [`Command::env_remove`]. The associated key for + /// the [`None`] value will no longer inherit from its parent process. /// - /// This only includes environment variables explicitly set with - /// [`Command::env`], [`Command::envs`], and [`Command::env_remove`]. It - /// does not include environment variables that will be inherited by the - /// child process. + /// An empty iterator can indicate that no explicit mappings were added or that + /// [`Command::env_clear`] was called. After calling [`Command::env_clear`], the child process + /// will not inherit any environment variables from its parent process. /// /// # Examples /// diff --git a/library/std/src/sys/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/sgx/abi/usercalls/alloc.rs index 0d934318c22a4..01505e94487b2 100644 --- a/library/std/src/sys/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/sgx/abi/usercalls/alloc.rs @@ -3,7 +3,6 @@ use crate::arch::asm; use crate::cell::UnsafeCell; use crate::cmp; -use crate::convert::TryInto; use crate::mem; use crate::ops::{CoerceUnsized, Deref, DerefMut, Index, IndexMut}; use crate::ptr::{self, NonNull}; diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 21ec1b5133df3..abef170dd5a64 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -1893,7 +1893,7 @@ mod remove_dir_impl { // file descriptor is automatically closed by libc::closedir() now, so give up ownership let new_parent_fd = dir_fd.into_raw_fd(); // a valid root is not needed because we do not call any functions involving the full path - // of the DirEntrys. + // of the `DirEntry`s. let dummy_root = PathBuf::new(); let inner = InnerReadDir { dirp, root: dummy_root }; Ok((ReadDir::new(inner), new_parent_fd)) diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs index 8d5b540212a17..d310be6c7a1eb 100644 --- a/library/std/src/sys/unix/futex.rs +++ b/library/std/src/sys/unix/futex.rs @@ -273,8 +273,6 @@ pub mod zircon { #[cfg(target_os = "fuchsia")] pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option) -> bool { - use crate::convert::TryFrom; - // Sleep forever if the timeout is longer than fits in a i64. let deadline = timeout .and_then(|d| { diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index 1c44058aff79d..a345af76fa217 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -7,7 +7,6 @@ mod tests; use crate::os::unix::prelude::*; -use crate::convert::TryFrom; use crate::error::Error as StdError; use crate::ffi::{CStr, CString, OsStr, OsString}; use crate::fmt; diff --git a/library/std/src/sys/unix/process/process_fuchsia.rs b/library/std/src/sys/unix/process/process_fuchsia.rs index d4c7e58b34d2e..e45c380a0bb84 100644 --- a/library/std/src/sys/unix/process/process_fuchsia.rs +++ b/library/std/src/sys/unix/process/process_fuchsia.rs @@ -166,7 +166,6 @@ impl Process { } pub fn wait(&mut self) -> io::Result { - use crate::default::Default; use crate::sys::process::zircon::*; let mut proc_info: zx_info_process_t = Default::default(); @@ -199,7 +198,6 @@ impl Process { } pub fn try_wait(&mut self) -> io::Result> { - use crate::default::Default; use crate::sys::process::zircon::*; let mut proc_info: zx_info_process_t = Default::default(); diff --git a/library/std/src/sys/windows/c/errors.rs b/library/std/src/sys/windows/c/errors.rs index 23dcc119db9f6..ad8da19b6daa8 100644 --- a/library/std/src/sys/windows/c/errors.rs +++ b/library/std/src/sys/windows/c/errors.rs @@ -12,7 +12,7 @@ pub const ERROR_RESOURCE_CALL_TIMED_OUT: DWORD = 5910; pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: DWORD = 8014; pub const DNS_ERROR_RECORD_TIMED_OUT: DWORD = 9705; -// The followiung list was obtained from +// The following list was obtained from // `/usr/x86_64-w64-mingw32/include/winerror.h` // in the Debian package // mingw-w64_6.0.0-3_all.deb diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs index eb427dbda2393..cb24caa1e8a60 100644 --- a/library/std/src/sys_common/net.rs +++ b/library/std/src/sys_common/net.rs @@ -2,7 +2,6 @@ mod tests; use crate::cmp; -use crate::convert::{TryFrom, TryInto}; use crate::fmt; use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut}; use crate::mem; diff --git a/library/std/src/sys_common/thread_parking/id.rs b/library/std/src/sys_common/thread_parking/id.rs index 575988ec760c7..15042fc3beecb 100644 --- a/library/std/src/sys_common/thread_parking/id.rs +++ b/library/std/src/sys_common/thread_parking/id.rs @@ -79,7 +79,7 @@ impl Parker { park_timeout(dur, self.state.as_ptr().addr()); // Swap to ensure that we observe all state changes with acquire // ordering, even if the state has been changed after the timeout - // occured. + // occurred. self.state.swap(EMPTY, Acquire); } } diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index 9fb31ed7663d0..e76d6716b94fe 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -219,14 +219,14 @@ pub fn assert_test_result(result: T) -> Result<(), String> { struct FilteredTests { tests: Vec<(TestId, TestDescAndFn)>, - benchs: Vec<(TestId, TestDescAndFn)>, + benches: Vec<(TestId, TestDescAndFn)>, next_id: usize, } impl FilteredTests { fn add_bench(&mut self, desc: TestDesc, testfn: TestFn) { let test = TestDescAndFn { desc, testfn }; - self.benchs.push((TestId(self.next_id), test)); + self.benches.push((TestId(self.next_id), test)); self.next_id += 1; } fn add_test(&mut self, desc: TestDesc, testfn: TestFn) { @@ -245,7 +245,7 @@ impl FilteredTests { self.add_test(desc, testfn); } fn total_len(&self) -> usize { - self.tests.len() + self.benchs.len() + self.tests.len() + self.benches.len() } } @@ -290,7 +290,7 @@ where let tests_len = tests.len(); - let mut filtered = FilteredTests { tests: Vec::new(), benchs: Vec::new(), next_id: 0 }; + let mut filtered = FilteredTests { tests: Vec::new(), benches: Vec::new(), next_id: 0 }; for test in filter_tests(opts, tests) { let mut desc = test.desc; @@ -457,7 +457,7 @@ where if opts.bench_benchmarks { // All benchmarks run at the end, in serial. - for (id, b) in filtered.benchs { + for (id, b) in filtered.benches { let event = TestEvent::TeWait(b.desc.clone()); notify_about_test_event(event)?; let join_handle = run_test(opts, false, id, b, run_strategy, tx.clone()); diff --git a/src/bootstrap/cache.rs b/src/bootstrap/cache.rs index 05f25af68ea8f..5376c4ec9c325 100644 --- a/src/bootstrap/cache.rs +++ b/src/bootstrap/cache.rs @@ -1,9 +1,8 @@ use std::any::{Any, TypeId}; use std::borrow::Borrow; use std::cell::RefCell; -use std::cmp::{Ord, Ordering, PartialOrd}; +use std::cmp::Ordering; use std::collections::HashMap; -use std::convert::AsRef; use std::fmt; use std::hash::{Hash, Hasher}; use std::marker::PhantomData; diff --git a/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md b/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md index 36bc312b9c99a..eb2285ef90646 100644 --- a/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md +++ b/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md @@ -103,6 +103,13 @@ macro_rules! foo { } ``` +There is one case where the disambiguation will be performed automatically: if an intra doc +link is resolved at the same time as a trait and as a derive proc-macro. In this case, it'll +always generate a link to the trait and not emit a "missing disambiguation" warning. A good +example of this case is when you link to the `Clone` trait: there is also a `Clone` +proc-macro but it ignores it in this case. If you want to link to the proc-macro, you can +use the `macro@` disambiguator. + ## Warnings, re-exports, and scoping Links are resolved in the scope of the module where the item is defined, even diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6ceba1b1f8e22..5fa0c120fba10 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -35,7 +35,6 @@ use rustc_span::{self, ExpnKind}; use std::borrow::Cow; use std::collections::hash_map::Entry; use std::collections::BTreeMap; -use std::default::Default; use std::hash::Hash; use std::mem; use thin_vec::ThinVec; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index e34ece9264cfb..6d2ce9e2833f4 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1,6 +1,5 @@ use std::borrow::Cow; use std::cell::RefCell; -use std::default::Default; use std::hash::Hash; use std::path::PathBuf; use std::rc::Rc; @@ -980,7 +979,7 @@ pub(crate) trait NestedAttributesExt { /// Returns `true` if the attribute list contains a specific `word` fn has_word(self, word: Symbol) -> bool where - Self: std::marker::Sized, + Self: Sized, { ::get_word_attr(self, word).is_some() } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 512c5c85d6a49..1be4f364eadeb 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -1,5 +1,4 @@ use std::collections::BTreeMap; -use std::convert::TryFrom; use std::ffi::OsStr; use std::fmt; use std::path::PathBuf; diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index fd81a21f5a994..00aadb8e82aeb 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -36,7 +36,6 @@ use rustc_span::{Span, Symbol}; use once_cell::sync::Lazy; use std::borrow::Cow; use std::collections::VecDeque; -use std::default::Default; use std::fmt::Write; use std::ops::{ControlFlow, Range}; use std::str; diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 1e3cd2668506f..463184acaa14f 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -38,7 +38,6 @@ pub(crate) use self::context::*; pub(crate) use self::span_map::{collect_spans_and_sources, LinkFromSrc}; use std::collections::VecDeque; -use std::default::Default; use std::fmt::{self, Write}; use std::fs; use std::iter::Peekable; diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 08a0e1c377ef8..f5b4a3f5abd65 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -59,7 +59,7 @@ pub(crate) fn build_index<'tcx>( // `sort_unstable_by_key` produces lifetime errors let k1 = (&k1.path, k1.name.as_str(), &k1.ty, &k1.parent); let k2 = (&k2.path, k2.name.as_str(), &k2.ty, &k2.parent); - std::cmp::Ord::cmp(&k1, &k2) + Ord::cmp(&k1, &k2) }); // Set up alias indexes. diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index c39caf73a9367..cd6509607d561 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -4,7 +4,6 @@ #![allow(rustc::default_hash_types)] -use std::convert::From; use std::fmt; use rustc_ast::ast; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 60c98cc3831bd..4a88dc5254de6 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -69,7 +69,6 @@ extern crate test; #[cfg(feature = "jemalloc")] extern crate jemalloc_sys; -use std::default::Default; use std::env::{self, VarError}; use std::io::{self, IsTerminal}; use std::process; diff --git a/src/tools/bump-stage0/src/main.rs b/src/tools/bump-stage0/src/main.rs index f530a4d73d360..b007f9a22c36f 100644 --- a/src/tools/bump-stage0/src/main.rs +++ b/src/tools/bump-stage0/src/main.rs @@ -2,7 +2,6 @@ use anyhow::{Context, Error}; use curl::easy::Easy; use indexmap::IndexMap; use std::collections::HashMap; -use std::convert::TryInto; const PATH: &str = "src/stage0.json"; const COMPILER_COMPONENTS: &[&str] = &["rustc", "rust-std", "cargo"]; diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs index 7e5b4d810ba93..197e9a9965f7d 100644 --- a/src/tools/tidy/src/bins.rs +++ b/src/tools/tidy/src/bins.rs @@ -57,8 +57,8 @@ mod os_impl { match fs::File::create(&path) { Ok(file) => { let exec = is_executable(&path).unwrap_or(false); - std::mem::drop(file); - std::fs::remove_file(&path).expect("Deleted temp file"); + drop(file); + fs::remove_file(&path).expect("Deleted temp file"); // If the file is executable, then we assume that this // filesystem does not track executability, so skip this check. return if exec { Unsupported } else { Supported }; diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index d40c4ad0711cf..6fd41e833624f 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -31,7 +31,6 @@ //! this in the long term. use crate::walk::{filter_dirs, walk}; -use std::iter::Iterator; use std::path::Path; // Paths that may contain platform-specific code. diff --git a/src/tools/unicode-table-generator/src/raw_emitter.rs b/src/tools/unicode-table-generator/src/raw_emitter.rs index 890ff986c2be0..7547b49ab2a54 100644 --- a/src/tools/unicode-table-generator/src/raw_emitter.rs +++ b/src/tools/unicode-table-generator/src/raw_emitter.rs @@ -1,6 +1,5 @@ use crate::fmt_list; use std::collections::{BTreeMap, BTreeSet, HashMap}; -use std::convert::TryFrom; use std::fmt::{self, Write}; use std::ops::Range; diff --git a/src/tools/unicode-table-generator/src/skiplist.rs b/src/tools/unicode-table-generator/src/skiplist.rs index 6e439968c3bfd..9b613a94c5795 100644 --- a/src/tools/unicode-table-generator/src/skiplist.rs +++ b/src/tools/unicode-table-generator/src/skiplist.rs @@ -1,6 +1,5 @@ use crate::fmt_list; use crate::raw_emitter::RawEmitter; -use std::convert::TryInto; use std::fmt::Write as _; use std::ops::Range; diff --git a/tests/ui/hygiene/panic-location.run.stderr b/tests/ui/hygiene/panic-location.run.stderr index 1c6a7b02f8e77..a7252a4002770 100644 --- a/tests/ui/hygiene/panic-location.run.stderr +++ b/tests/ui/hygiene/panic-location.run.stderr @@ -1,2 +1,2 @@ -thread 'main' panicked at 'capacity overflow', library/alloc/src/raw_vec.rs:525:5 +thread 'main' panicked at 'capacity overflow', library/alloc/src/raw_vec.rs:524:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/tests/ui/type/type-check/assignment-in-if.stderr b/tests/ui/type/type-check/assignment-in-if.stderr index de133e5599cf9..9f4558adab150 100644 --- a/tests/ui/type/type-check/assignment-in-if.stderr +++ b/tests/ui/type/type-check/assignment-in-if.stderr @@ -67,9 +67,6 @@ LL | x == 5 error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:44:18 | -LL | if y = (Foo { foo: x }) { - | - here the type of `x` is inferred to be `usize` -... LL | if x == x && x = x && x == x { | ------ ^ expected `bool`, found `usize` | | @@ -78,9 +75,6 @@ LL | if x == x && x = x && x == x { error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:44:22 | -LL | if y = (Foo { foo: x }) { - | - here the type of `x` is inferred to be `usize` -... LL | if x == x && x = x && x == x { | ^ expected `bool`, found `usize` @@ -98,9 +92,6 @@ LL | if x == x && x == x && x == x { error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:51:28 | -LL | if y = (Foo { foo: x }) { - | - here the type of `x` is inferred to be `usize` -... LL | if x == x && x == x && x = x { | ---------------- ^ expected `bool`, found `usize` | | diff --git a/tests/ui/type/type-check/point-at-inference-3.fixed b/tests/ui/type/type-check/point-at-inference-3.fixed index edd4adf8bd256..15a3b580568d6 100644 --- a/tests/ui/type/type-check/point-at-inference-3.fixed +++ b/tests/ui/type/type-check/point-at-inference-3.fixed @@ -2,7 +2,8 @@ fn main() { let mut v = Vec::new(); v.push(0i32); - //~^ NOTE this is of type `i32`, which causes `v` to be inferred as `Vec` + //~^ NOTE this argument has type `i32`... + //~| NOTE ... which causes `v` to have type `Vec` v.push(0); v.push(1i32); //~ ERROR mismatched types //~^ NOTE expected `i32`, found `u32` diff --git a/tests/ui/type/type-check/point-at-inference-3.rs b/tests/ui/type/type-check/point-at-inference-3.rs index 49d7b50075bbc..a48c4f9862f75 100644 --- a/tests/ui/type/type-check/point-at-inference-3.rs +++ b/tests/ui/type/type-check/point-at-inference-3.rs @@ -2,7 +2,8 @@ fn main() { let mut v = Vec::new(); v.push(0i32); - //~^ NOTE this is of type `i32`, which causes `v` to be inferred as `Vec` + //~^ NOTE this argument has type `i32`... + //~| NOTE ... which causes `v` to have type `Vec` v.push(0); v.push(1u32); //~ ERROR mismatched types //~^ NOTE expected `i32`, found `u32` diff --git a/tests/ui/type/type-check/point-at-inference-3.stderr b/tests/ui/type/type-check/point-at-inference-3.stderr index 2c4907ed263ba..238764812364c 100644 --- a/tests/ui/type/type-check/point-at-inference-3.stderr +++ b/tests/ui/type/type-check/point-at-inference-3.stderr @@ -1,8 +1,10 @@ error[E0308]: mismatched types - --> $DIR/point-at-inference-3.rs:7:12 + --> $DIR/point-at-inference-3.rs:8:12 | LL | v.push(0i32); - | ---- this is of type `i32`, which causes `v` to be inferred as `Vec` + | - ---- this argument has type `i32`... + | | + | ... which causes `v` to have type `Vec` ... LL | v.push(1u32); | ---- ^^^^ expected `i32`, found `u32` diff --git a/tests/ui/type/type-check/point-at-inference-4.rs b/tests/ui/type/type-check/point-at-inference-4.rs index aea9b2c6c14ee..3deb234c2751e 100644 --- a/tests/ui/type/type-check/point-at-inference-4.rs +++ b/tests/ui/type/type-check/point-at-inference-4.rs @@ -11,8 +11,11 @@ fn main() { let s = S(None); s.infer(0i32); //~^ ERROR this method takes 2 arguments but 1 argument was supplied + //~| NOTE this argument has type `i32`... + //~| NOTE ... which causes `s` to have type `S` //~| NOTE an argument is missing //~| HELP provide the argument + //~| HELP change the type of the numeric literal from `i32` to `u32` let t: S = s; //~^ ERROR mismatched types //~| NOTE expected `S`, found `S` diff --git a/tests/ui/type/type-check/point-at-inference-4.stderr b/tests/ui/type/type-check/point-at-inference-4.stderr index 28833d2ed1c92..5f7bb8b9367ec 100644 --- a/tests/ui/type/type-check/point-at-inference-4.stderr +++ b/tests/ui/type/type-check/point-at-inference-4.stderr @@ -15,8 +15,13 @@ LL | s.infer(0i32, /* b */); | ~~~~~~~~~~~~~~~ error[E0308]: mismatched types - --> $DIR/point-at-inference-4.rs:16:24 + --> $DIR/point-at-inference-4.rs:19:24 | +LL | s.infer(0i32); + | - ---- this argument has type `i32`... + | | + | ... which causes `s` to have type `S` +... LL | let t: S = s; | --------- ^ expected `S`, found `S` | | @@ -24,6 +29,10 @@ LL | let t: S = s; | = note: expected struct `S` found struct `S` +help: change the type of the numeric literal from `i32` to `u32` + | +LL | s.infer(0u32); + | ~~~ error: aborting due to 2 previous errors diff --git a/tests/ui/type/type-check/point-at-inference.stderr b/tests/ui/type/type-check/point-at-inference.stderr index a76b4f90c734b..5fc94d4d1b6ba 100644 --- a/tests/ui/type/type-check/point-at-inference.stderr +++ b/tests/ui/type/type-check/point-at-inference.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/point-at-inference.rs:12:9 | LL | foo.push(i); - | - this is of type `&{integer}`, which causes `foo` to be inferred as `Vec<&{integer}>` + | --- - this argument has type `&{integer}`... + | | + | ... which causes `foo` to have type `Vec<&{integer}>` ... LL | bar(foo); | --- ^^^ expected `Vec`, found `Vec<&{integer}>` diff --git a/tests/ui/typeck/bad-type-in-vec-contains.stderr b/tests/ui/typeck/bad-type-in-vec-contains.stderr index 0e03388d2d58c..72533ab1fa37f 100644 --- a/tests/ui/typeck/bad-type-in-vec-contains.stderr +++ b/tests/ui/typeck/bad-type-in-vec-contains.stderr @@ -7,7 +7,6 @@ LL | primes.contains(3); | | expected `&_`, found integer | | help: consider borrowing here: `&3` | arguments to this method are incorrect - | here the type of `primes` is inferred to be `[_]` | = note: expected reference `&_` found type `{integer}` diff --git a/tests/ui/typeck/bad-type-in-vec-push.stderr b/tests/ui/typeck/bad-type-in-vec-push.stderr index ae46050c91be2..1d5337260fa0a 100644 --- a/tests/ui/typeck/bad-type-in-vec-push.stderr +++ b/tests/ui/typeck/bad-type-in-vec-push.stderr @@ -1,8 +1,6 @@ error[E0308]: mismatched types --> $DIR/bad-type-in-vec-push.rs:11:17 | -LL | vector.sort(); - | ------ here the type of `vector` is inferred to be `Vec<_>` LL | result.push(vector); | ---- ^^^^^^ expected integer, found `Vec<_>` | | diff --git a/tests/ui/typeck/issue-107775.stderr b/tests/ui/typeck/issue-107775.stderr index 9ee9c022c6e8c..b97e74b7e53fa 100644 --- a/tests/ui/typeck/issue-107775.stderr +++ b/tests/ui/typeck/issue-107775.stderr @@ -2,9 +2,9 @@ error[E0308]: mismatched types --> $DIR/issue-107775.rs:35:16 | LL | map.insert(1, Struct::do_something); - | - -------------------- this is of type `fn(u8) -> Pin + Send>> {::do_something::<'_>}`, which causes `map` to be inferred as `HashMap<{integer}, fn(u8) -> Pin + Send>> {::do_something::<'_>}>` - | | - | this is of type `{integer}`, which causes `map` to be inferred as `HashMap<{integer}, fn(u8) -> Pin + Send>> {::do_something::<'_>}>` + | --- -------------------- this argument has type `fn(u8) -> Pin + Send>> {::do_something::<'_>}`... + | | + | ... which causes `map` to have type `HashMap<{integer}, fn(u8) -> Pin + Send>> {::do_something::<'_>}>` LL | Self { map } | ^^^ expected `HashMap Pin<...>>`, found `HashMap<{integer}, ...>` |