about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-06-23 04:03:28 +0000
committerbors <bors@rust-lang.org>2020-06-23 04:03:28 +0000
commit3b1c08c68ccc2c222f84384c836b5e167e2bc241 (patch)
treefbe75cb4169897808d893310d39b9ca806610bd7
parentdcd470fe1be03136a8e1794b7e2cc6179bbd9d92 (diff)
parente97939275697db27b40535b3a14be0f14a6853c2 (diff)
downloadrust-3b1c08c68ccc2c222f84384c836b5e167e2bc241.tar.gz
rust-3b1c08c68ccc2c222f84384c836b5e167e2bc241.zip
Auto merge of #73635 - Dylan-DPC:rollup-b4wbp42, r=Dylan-DPC
Rollup of 7 pull requests

Successful merges:

 - #71756 (add Windows system error codes that should map to io::ErrorKind::TimedOut)
 - #73495 (Converted all platform-specific stdin/stdout/stderr implementations to use io:: traits)
 - #73575 (Fix typo in error_codes doc)
 - #73578 (Make is_freeze and is_copy_modulo_regions take TyCtxtAt)
 - #73586 (switch_ty is redundant)
 - #73600 (Fix spurious 'value moved here in previous iteration of loop' messages)
 - #73610 (Clean up E0699 explanation)

Failed merges:

r? @ghost
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs2
-rw-r--r--src/librustc_codegen_ssa/traits/type_.rs2
-rw-r--r--src/librustc_error_codes/error_codes/E0081.md2
-rw-r--r--src/librustc_error_codes/error_codes/E0699.md6
-rw-r--r--src/librustc_lint/builtin.rs2
-rw-r--r--src/librustc_middle/mir/mod.rs2
-rw-r--r--src/librustc_middle/ty/layout.rs2
-rw-r--r--src/librustc_middle/ty/util.rs14
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs2
-rw-r--r--src/librustc_mir/dataflow/impls/borrowed_locals.rs2
-rw-r--r--src/librustc_mir/interpret/eval_context.rs2
-rw-r--r--src/librustc_mir/interpret/intern.rs2
-rw-r--r--src/librustc_mir/interpret/terminator.rs12
-rw-r--r--src/librustc_mir/shim.rs2
-rw-r--r--src/librustc_mir/transform/check_consts/qualifs.rs2
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs13
-rw-r--r--src/librustc_mir/transform/promote_consts.rs4
-rw-r--r--src/librustc_mir/transform/validate.rs14
-rw-r--r--src/librustc_mir_build/build/expr/as_operand.rs2
-rw-r--r--src/librustc_mir_build/hair/pattern/check_match.rs2
-rw-r--r--src/librustc_passes/intrinsicck.rs2
-rw-r--r--src/librustc_trait_selection/infer.rs2
-rw-r--r--src/librustc_ty/needs_drop.rs2
-rw-r--r--src/libstd/io/error.rs5
-rw-r--r--src/libstd/sys/hermit/stdio.rs39
-rw-r--r--src/libstd/sys/wasi/stdio.rs66
-rw-r--r--src/libstd/sys/windows/c.rs19
-rw-r--r--src/libstd/sys/windows/mod.rs17
-rw-r--r--src/test/ui/moves/issue-46099-move-in-macro.rs15
-rw-r--r--src/test/ui/moves/issue-46099-move-in-macro.stderr14
-rw-r--r--src/test/ui/moves/move-in-guard-2.stderr5
-rw-r--r--src/tools/clippy/clippy_lints/src/functions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/let_if_seq.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_key.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/mod.rs2
37 files changed, 176 insertions, 114 deletions
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index d56c816811b..5125ce779ed 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -200,6 +200,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         targets: &Vec<mir::BasicBlock>,
     ) {
         let discr = self.codegen_operand(&mut bx, &discr);
+        // `switch_ty` is redundant, sanity-check that.
+        assert_eq!(discr.layout.ty, switch_ty);
         if targets.len() == 2 {
             // If there are two targets, emit br instead of switch
             let lltrue = helper.llblock(self, targets[0]);
diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs
index 703479b74be..c55bf9858b9 100644
--- a/src/librustc_codegen_ssa/traits/type_.rs
+++ b/src/librustc_codegen_ssa/traits/type_.rs
@@ -74,7 +74,7 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
     }
 
     fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
-        ty.is_freeze(self.tcx(), ty::ParamEnv::reveal_all(), DUMMY_SP)
+        ty.is_freeze(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all())
     }
 
     fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
diff --git a/src/librustc_error_codes/error_codes/E0081.md b/src/librustc_error_codes/error_codes/E0081.md
index fd5eca68e21..b834a734cef 100644
--- a/src/librustc_error_codes/error_codes/E0081.md
+++ b/src/librustc_error_codes/error_codes/E0081.md
@@ -1,4 +1,4 @@
-A discrimant value is present more than once.
+A discriminant value is present more than once.
 
 Erroneous code example:
 
diff --git a/src/librustc_error_codes/error_codes/E0699.md b/src/librustc_error_codes/error_codes/E0699.md
index f90fd3b5624..454d2507e5e 100644
--- a/src/librustc_error_codes/error_codes/E0699.md
+++ b/src/librustc_error_codes/error_codes/E0699.md
@@ -1,14 +1,16 @@
 A method was called on a raw pointer whose inner type wasn't completely known.
 
-For example, you may have done something like:
+Erroneous code example:
 
-```compile_fail
+```compile_fail,edition2018,E0699
 # #![deny(warnings)]
+# fn main() {
 let foo = &1;
 let bar = foo as *const _;
 if bar.is_null() {
     // ...
 }
+# }
 ```
 
 Here, the type of `bar` isn't known; it could be a pointer to anything. Instead,
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index b7f728ec60c..e746396e4c6 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -562,7 +562,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations {
             return;
         }
         let param_env = ty::ParamEnv::empty();
-        if ty.is_copy_modulo_regions(cx.tcx, param_env, item.span) {
+        if ty.is_copy_modulo_regions(cx.tcx.at(item.span), param_env) {
             return;
         }
         if can_type_implement_copy(cx.tcx, param_env, ty).is_ok() {
diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs
index 3381b95c2a3..64976654799 100644
--- a/src/librustc_middle/mir/mod.rs
+++ b/src/librustc_middle/mir/mod.rs
@@ -1075,6 +1075,8 @@ pub enum TerminatorKind<'tcx> {
         discr: Operand<'tcx>,
 
         /// The type of value being tested.
+        /// This is always the same as the type of `discr`.
+        /// FIXME: remove this redundant information. Currently, it is relied on by pretty-printing.
         switch_ty: Ty<'tcx>,
 
         /// Possible values. The locations to branch to in each case
diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs
index 68af22569e3..e4cc96dd83b 100644
--- a/src/librustc_middle/ty/layout.rs
+++ b/src/librustc_middle/ty/layout.rs
@@ -2159,7 +2159,7 @@ where
 
             ty::Ref(_, ty, mt) if offset.bytes() == 0 => {
                 let tcx = cx.tcx();
-                let is_freeze = ty.is_freeze(tcx, cx.param_env(), DUMMY_SP);
+                let is_freeze = ty.is_freeze(tcx.at(DUMMY_SP), cx.param_env());
                 let kind = match mt {
                     hir::Mutability::Not => {
                         if is_freeze {
diff --git a/src/librustc_middle/ty/util.rs b/src/librustc_middle/ty/util.rs
index 47110be53b2..67ad7ee7082 100644
--- a/src/librustc_middle/ty/util.rs
+++ b/src/librustc_middle/ty/util.rs
@@ -681,11 +681,10 @@ impl<'tcx> ty::TyS<'tcx> {
     /// winds up being reported as an error during NLL borrow check.
     pub fn is_copy_modulo_regions(
         &'tcx self,
-        tcx: TyCtxt<'tcx>,
+        tcx_at: TyCtxtAt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
-        span: Span,
     ) -> bool {
-        tcx.at(span).is_copy_raw(param_env.and(self))
+        tcx_at.is_copy_raw(param_env.and(self))
     }
 
     /// Checks whether values of this type `T` have a size known at
@@ -706,13 +705,8 @@ impl<'tcx> ty::TyS<'tcx> {
     /// that the `Freeze` trait is not exposed to end users and is
     /// effectively an implementation detail.
     // FIXME: use `TyCtxtAt` instead of separate `Span`.
-    pub fn is_freeze(
-        &'tcx self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-        span: Span,
-    ) -> bool {
-        self.is_trivially_freeze() || tcx.at(span).is_freeze_raw(param_env.and(self))
+    pub fn is_freeze(&'tcx self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
+        self.is_trivially_freeze() || tcx_at.is_freeze_raw(param_env.and(self))
     }
 
     /// Fast path helper for testing if a type is `Freeze`.
diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
index eb07c7e65f5..8d7944004c7 100644
--- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
@@ -138,7 +138,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
                 let move_msg = if move_spans.for_closure() { " into closure" } else { "" };
 
-                if span == move_span {
+                if location == move_out.source {
                     err.span_label(
                         span,
                         format!("value moved{} here, in previous iteration of loop", move_msg),
diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
index 70c916a0892..a3fc51cad65 100644
--- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs
+++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
@@ -233,7 +233,7 @@ impl MutBorrow<'mir, 'tcx> {
     ///
     /// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
     fn shared_borrow_allows_mutation(&self, place: Place<'tcx>) -> bool {
-        !place.ty(self.body, self.tcx).ty.is_freeze(self.tcx, self.param_env, DUMMY_SP)
+        !place.ty(self.body, self.tcx).ty.is_freeze(self.tcx.at(DUMMY_SP), self.param_env)
     }
 }
 
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index ceacbbe5139..95e193b6253 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -391,7 +391,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
     #[inline]
     pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
-        ty.is_freeze(*self.tcx, self.param_env, self.tcx.span)
+        ty.is_freeze(self.tcx, self.param_env)
     }
 
     pub fn load_mir(
diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index cab13d379a2..dffbc969c21 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -111,7 +111,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>(
     if let InternMode::Static(mutability) = mode {
         // For this, we need to take into account `UnsafeCell`. When `ty` is `None`, we assume
         // no interior mutability.
-        let frozen = ty.map_or(true, |ty| ty.is_freeze(*ecx.tcx, ecx.param_env, ecx.tcx.span));
+        let frozen = ty.map_or(true, |ty| ty.is_freeze(ecx.tcx, ecx.param_env));
         // For statics, allocation mutability is the combination of the place mutability and
         // the type mutability.
         // The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere.
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 0f3fbcf8195..4681079a22d 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -24,9 +24,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
             Goto { target } => self.go_to_block(target),
 
-            SwitchInt { ref discr, ref values, ref targets, .. } => {
+            SwitchInt { ref discr, ref values, ref targets, switch_ty } => {
                 let discr = self.read_immediate(self.eval_operand(discr, None)?)?;
                 trace!("SwitchInt({:?})", *discr);
+                assert_eq!(discr.layout.ty, switch_ty);
 
                 // Branch to the `otherwise` case by default, if no match is found.
                 assert!(!targets.is_empty());
@@ -50,14 +51,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.go_to_block(target_block);
             }
 
-            Call {
-                ref func,
-                ref args,
-                destination,
-                ref cleanup,
-                from_hir_call: _from_hir_call,
-                fn_span: _,
-            } => {
+            Call { ref func, ref args, destination, ref cleanup, from_hir_call: _, fn_span: _ } => {
                 let old_stack = self.frame_idx();
                 let old_loc = self.frame().loc;
                 let func = self.eval_operand(func, None)?;
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 15a2e9130a3..8327affd982 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -327,7 +327,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -
     let param_env = tcx.param_env(def_id);
 
     let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);
-    let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env, builder.span);
+    let is_copy = self_ty.is_copy_modulo_regions(tcx.at(builder.span), param_env);
 
     let dest = Place::return_place();
     let src = tcx.mk_place_deref(Place::from(Local::new(1 + 0)));
diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs
index 936c1a84e14..e2893e81a2c 100644
--- a/src/librustc_mir/transform/check_consts/qualifs.rs
+++ b/src/librustc_mir/transform/check_consts/qualifs.rs
@@ -77,7 +77,7 @@ impl Qualif for HasMutInterior {
     }
 
     fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
-        !ty.is_freeze(cx.tcx, cx.param_env, DUMMY_SP)
+        !ty.is_freeze(cx.tcx.at(DUMMY_SP), cx.param_env)
     }
 
     fn in_adt_inherently(cx: &ConstCx<'_, 'tcx>, adt: &'tcx AdtDef, _: SubstsRef<'tcx>) -> bool {
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 7dbb2ebad8b..9898cde5207 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -282,9 +282,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                                 ),
                             };
                             if !elem_ty.is_copy_modulo_regions(
-                                self.tcx,
+                                self.tcx.at(self.source_info.span),
                                 self.param_env,
-                                self.source_info.span,
                             ) {
                                 self.require_unsafe(
                                     "assignment to non-`Copy` union field",
@@ -459,11 +458,11 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
 
                             // Check `is_freeze` as late as possible to avoid cycle errors
                             // with opaque types.
-                            } else if !place.ty(self.body, self.tcx).ty.is_freeze(
-                                self.tcx,
-                                self.param_env,
-                                self.source_info.span,
-                            ) {
+                            } else if !place
+                                .ty(self.body, self.tcx)
+                                .ty
+                                .is_freeze(self.tcx.at(self.source_info.span), self.param_env)
+                            {
                                 (
                                     "borrow of layout constrained field with interior \
                                         mutability",
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 330f6c1640f..8bcbcd79ae6 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -341,7 +341,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                                     Place::ty_from(place.local, proj_base, self.body, self.tcx)
                                         .projection_ty(self.tcx, elem)
                                         .ty;
-                                if ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) {
+                                if ty.is_freeze(self.tcx.at(DUMMY_SP), self.param_env) {
                                     has_mut_interior = false;
                                     break;
                                 }
@@ -678,7 +678,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                         let ty = Place::ty_from(place.local, proj_base, self.body, self.tcx)
                             .projection_ty(self.tcx, elem)
                             .ty;
-                        if ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) {
+                        if ty.is_freeze(self.tcx.at(DUMMY_SP), self.param_env) {
                             has_mut_interior = false;
                             break;
                         }
diff --git a/src/librustc_mir/transform/validate.rs b/src/librustc_mir/transform/validate.rs
index 625f40cd792..c5343d9b5d0 100644
--- a/src/librustc_mir/transform/validate.rs
+++ b/src/librustc_mir/transform/validate.rs
@@ -90,7 +90,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             let ty = place.ty(&self.body.local_decls, self.tcx).ty;
             let span = self.body.source_info(location).span;
 
-            if !ty.is_copy_modulo_regions(self.tcx, self.param_env, span) {
+            if !ty.is_copy_modulo_regions(self.tcx.at(span), self.param_env) {
                 self.fail(location, format!("`Operand::Copy` with non-`Copy` type {}", ty));
             }
         }
@@ -121,7 +121,17 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             TerminatorKind::Goto { target } => {
                 self.check_edge(location, *target, EdgeKind::Normal);
             }
-            TerminatorKind::SwitchInt { targets, values, .. } => {
+            TerminatorKind::SwitchInt { targets, values, switch_ty, discr } => {
+                let ty = discr.ty(&self.body.local_decls, self.tcx);
+                if ty != *switch_ty {
+                    self.fail(
+                        location,
+                        format!(
+                            "encountered `SwitchInt` terminator with type mismatch: {:?} != {:?}",
+                            ty, switch_ty,
+                        ),
+                    );
+                }
                 if targets.len() != values.len() + 1 {
                     self.fail(
                         location,
diff --git a/src/librustc_mir_build/build/expr/as_operand.rs b/src/librustc_mir_build/build/expr/as_operand.rs
index 9a75f3afe8f..5949fd1e22c 100644
--- a/src/librustc_mir_build/build/expr/as_operand.rs
+++ b/src/librustc_mir_build/build/expr/as_operand.rs
@@ -172,7 +172,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
             if !ty.is_sized(tcx.at(span), param_env) {
                 // !sized means !copy, so this is an unsized move
-                assert!(!ty.is_copy_modulo_regions(tcx, param_env, span));
+                assert!(!ty.is_copy_modulo_regions(tcx.at(span), param_env));
 
                 // As described above, detect the case where we are passing a value of unsized
                 // type, and that value is coming from the deref of a box.
diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs
index 4d97a19f408..6fc447a87f5 100644
--- a/src/librustc_mir_build/hair/pattern/check_match.rs
+++ b/src/librustc_mir_build/hair/pattern/check_match.rs
@@ -579,7 +579,7 @@ fn maybe_point_at_variant(ty: Ty<'_>, patterns: &[super::Pat<'_>]) -> Vec<Span>
 
 /// Check if a by-value binding is by-value. That is, check if the binding's type is not `Copy`.
 fn is_binding_by_move(cx: &MatchVisitor<'_, '_>, hir_id: HirId, span: Span) -> bool {
-    !cx.tables.node_type(hir_id).is_copy_modulo_regions(cx.tcx, cx.param_env, span)
+    !cx.tables.node_type(hir_id).is_copy_modulo_regions(cx.tcx.at(span), cx.param_env)
 }
 
 /// Check the legality of legality of by-move bindings.
diff --git a/src/librustc_passes/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs
index 88fb78f85e4..c8666ba1fd0 100644
--- a/src/librustc_passes/intrinsicck.rs
+++ b/src/librustc_passes/intrinsicck.rs
@@ -214,7 +214,7 @@ impl ExprVisitor<'tcx> {
 
         // Check that the type implements Copy. The only case where this can
         // possibly fail is for SIMD types which don't #[derive(Copy)].
-        if !ty.is_copy_modulo_regions(self.tcx, self.param_env, DUMMY_SP) {
+        if !ty.is_copy_modulo_regions(self.tcx.at(DUMMY_SP), self.param_env) {
             let msg = "arguments for inline assembly must be copyable";
             let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
             err.note(&format!("`{}` does not implement the Copy trait", ty));
diff --git a/src/librustc_trait_selection/infer.rs b/src/librustc_trait_selection/infer.rs
index f244785b49d..dc895ad34a9 100644
--- a/src/librustc_trait_selection/infer.rs
+++ b/src/librustc_trait_selection/infer.rs
@@ -44,7 +44,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
         let ty = self.resolve_vars_if_possible(&ty);
 
         if !(param_env, ty).needs_infer() {
-            return ty.is_copy_modulo_regions(self.tcx, param_env, span);
+            return ty.is_copy_modulo_regions(self.tcx.at(span), param_env);
         }
 
         let copy_def_id = self.tcx.require_lang_item(lang_items::CopyTraitLangItem, None);
diff --git a/src/librustc_ty/needs_drop.rs b/src/librustc_ty/needs_drop.rs
index 439bec1702e..7880c09c2ad 100644
--- a/src/librustc_ty/needs_drop.rs
+++ b/src/librustc_ty/needs_drop.rs
@@ -91,7 +91,7 @@ where
 
             for component in components {
                 match component.kind {
-                    _ if component.is_copy_modulo_regions(tcx, self.param_env, DUMMY_SP) => (),
+                    _ if component.is_copy_modulo_regions(tcx.at(DUMMY_SP), self.param_env) => (),
 
                     ty::Closure(_, substs) => {
                         for upvar_ty in substs.as_closure().upvar_tys() {
diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs
index d80a38819ea..f7248e7547e 100644
--- a/src/libstd/io/error.rs
+++ b/src/libstd/io/error.rs
@@ -160,6 +160,11 @@ pub enum ErrorKind {
     #[stable(feature = "rust1", since = "1.0.0")]
     Interrupted,
     /// Any I/O error not part of this list.
+    ///
+    /// Errors that are `Other` now may move to a different or a new
+    /// [`ErrorKind`] variant in the future. It is not recommended to match
+    /// an error against `Other` and to expect any additional characteristics,
+    /// e.g., a specific [`Error::raw_os_error`] return value.
     #[stable(feature = "rust1", since = "1.0.0")]
     Other,
 
diff --git a/src/libstd/sys/hermit/stdio.rs b/src/libstd/sys/hermit/stdio.rs
index 208265de465..f3654ee3871 100644
--- a/src/libstd/sys/hermit/stdio.rs
+++ b/src/libstd/sys/hermit/stdio.rs
@@ -10,19 +10,19 @@ impl Stdin {
     pub fn new() -> io::Result<Stdin> {
         Ok(Stdin)
     }
+}
 
-    pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
+impl io::Read for Stdin {
+    fn read(&mut self, data: &mut [u8]) -> io::Result<usize> {
         self.read_vectored(&mut [IoSliceMut::new(data)])
     }
 
-    pub fn read_vectored(&self, _data: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        //ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) })
-        //    .read(data)
+    fn read_vectored(&mut self, _data: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         Ok(0)
     }
 
     #[inline]
-    pub fn is_read_vectored(&self) -> bool {
+    fn is_read_vectored(&self) -> bool {
         true
     }
 }
@@ -31,8 +31,10 @@ impl Stdout {
     pub fn new() -> io::Result<Stdout> {
         Ok(Stdout)
     }
+}
 
-    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+impl io::Write for Stdout {
+    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
         let len;
 
         unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }
@@ -44,7 +46,7 @@ impl Stdout {
         }
     }
 
-    pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
+    fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
         let len;
 
         unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }
@@ -57,11 +59,11 @@ impl Stdout {
     }
 
     #[inline]
-    pub fn is_write_vectored(&self) -> bool {
+    fn is_write_vectored(&self) -> bool {
         true
     }
 
-    pub fn flush(&self) -> io::Result<()> {
+    fn flush(&mut self) -> io::Result<()> {
         Ok(())
     }
 }
@@ -70,8 +72,10 @@ impl Stderr {
     pub fn new() -> io::Result<Stderr> {
         Ok(Stderr)
     }
+}
 
-    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+impl io::Write for Stderr {
+    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
         let len;
 
         unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }
@@ -83,7 +87,7 @@ impl Stderr {
         }
     }
 
-    pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
+    fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
         let len;
 
         unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }
@@ -96,21 +100,12 @@ impl Stderr {
     }
 
     #[inline]
-    pub fn is_write_vectored(&self) -> bool {
+    fn is_write_vectored(&self) -> bool {
         true
     }
 
-    pub fn flush(&self) -> io::Result<()> {
-        Ok(())
-    }
-}
-
-impl io::Write for Stderr {
-    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
-        (&*self).write(data)
-    }
     fn flush(&mut self) -> io::Result<()> {
-        (&*self).flush()
+        Ok(())
     }
 }
 
diff --git a/src/libstd/sys/wasi/stdio.rs b/src/libstd/sys/wasi/stdio.rs
index 9f9e35566ec..78e3911dc4e 100644
--- a/src/libstd/sys/wasi/stdio.rs
+++ b/src/libstd/sys/wasi/stdio.rs
@@ -11,22 +11,25 @@ impl Stdin {
         Ok(Stdin)
     }
 
-    pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
+    #[inline]
+    pub fn as_raw_fd(&self) -> u32 {
+        0
+    }
+}
+
+impl io::Read for Stdin {
+    fn read(&mut self, data: &mut [u8]) -> io::Result<usize> {
         self.read_vectored(&mut [IoSliceMut::new(data)])
     }
 
-    pub fn read_vectored(&self, data: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+    fn read_vectored(&mut self, data: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
         ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).read(data)
     }
 
     #[inline]
-    pub fn is_read_vectored(&self) -> bool {
+    fn is_read_vectored(&self) -> bool {
         true
     }
-
-    pub fn as_raw_fd(&self) -> u32 {
-        0
-    }
 }
 
 impl Stdout {
@@ -34,26 +37,28 @@ impl Stdout {
         Ok(Stdout)
     }
 
-    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+    #[inline]
+    pub fn as_raw_fd(&self) -> u32 {
+        1
+    }
+}
+
+impl io::Write for Stdout {
+    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
         self.write_vectored(&[IoSlice::new(data)])
     }
 
-    pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
+    fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
         ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).write(data)
     }
 
     #[inline]
-    pub fn is_write_vectored(&self) -> bool {
+    fn is_write_vectored(&self) -> bool {
         true
     }
-
-    pub fn flush(&self) -> io::Result<()> {
+    fn flush(&mut self) -> io::Result<()> {
         Ok(())
     }
-
-    pub fn as_raw_fd(&self) -> u32 {
-        1
-    }
 }
 
 impl Stderr {
@@ -61,23 +66,7 @@ impl Stderr {
         Ok(Stderr)
     }
 
-    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
-        self.write_vectored(&[IoSlice::new(data)])
-    }
-
-    pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
-        ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).write(data)
-    }
-
     #[inline]
-    pub fn is_write_vectored(&self) -> bool {
-        true
-    }
-
-    pub fn flush(&self) -> io::Result<()> {
-        Ok(())
-    }
-
     pub fn as_raw_fd(&self) -> u32 {
         2
     }
@@ -85,11 +74,20 @@ impl Stderr {
 
 impl io::Write for Stderr {
     fn write(&mut self, data: &[u8]) -> io::Result<usize> {
-        (&*self).write(data)
+        self.write_vectored(&[IoSlice::new(data)])
+    }
+
+    fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
+        ManuallyDrop::new(unsafe { WasiFd::from_raw(self.as_raw_fd()) }).write(data)
+    }
+
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
     }
 
     fn flush(&mut self) -> io::Result<()> {
-        (&*self).flush()
+        Ok(())
     }
 }
 
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index 6115d652b0c..f440442ca30 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -161,6 +161,8 @@ pub const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
 
 pub const PROGRESS_CONTINUE: DWORD = 0;
 
+// List of Windows system error codes with descriptions:
+// https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes#system-error-codes
 pub const ERROR_FILE_NOT_FOUND: DWORD = 2;
 pub const ERROR_PATH_NOT_FOUND: DWORD = 3;
 pub const ERROR_ACCESS_DENIED: DWORD = 5;
@@ -171,13 +173,26 @@ pub const ERROR_FILE_EXISTS: DWORD = 80;
 pub const ERROR_INVALID_PARAMETER: DWORD = 87;
 pub const ERROR_BROKEN_PIPE: DWORD = 109;
 pub const ERROR_CALL_NOT_IMPLEMENTED: DWORD = 120;
+pub const ERROR_SEM_TIMEOUT: DWORD = 121;
 pub const ERROR_INSUFFICIENT_BUFFER: DWORD = 122;
 pub const ERROR_ALREADY_EXISTS: DWORD = 183;
-pub const ERROR_NO_DATA: DWORD = 232;
 pub const ERROR_ENVVAR_NOT_FOUND: DWORD = 203;
+pub const ERROR_NO_DATA: DWORD = 232;
+pub const ERROR_DRIVER_CANCEL_TIMEOUT: DWORD = 594;
 pub const ERROR_OPERATION_ABORTED: DWORD = 995;
 pub const ERROR_IO_PENDING: DWORD = 997;
-pub const ERROR_TIMEOUT: DWORD = 0x5B4;
+pub const ERROR_SERVICE_REQUEST_TIMEOUT: DWORD = 1053;
+pub const ERROR_COUNTER_TIMEOUT: DWORD = 1121;
+pub const ERROR_TIMEOUT: DWORD = 1460;
+pub const ERROR_RESOURCE_CALL_TIMED_OUT: DWORD = 5910;
+pub const ERROR_CTX_MODEM_RESPONSE_TIMEOUT: DWORD = 7012;
+pub const ERROR_CTX_CLIENT_QUERY_TIMEOUT: DWORD = 7040;
+pub const FRS_ERR_SYSVOL_POPULATE_TIMEOUT: DWORD = 8014;
+pub const ERROR_DS_TIMELIMIT_EXCEEDED: DWORD = 8226;
+pub const DNS_ERROR_RECORD_TIMED_OUT: DWORD = 9705;
+pub const ERROR_IPSEC_IKE_TIMED_OUT: DWORD = 13805;
+pub const ERROR_RUNLEVEL_SWITCH_TIMEOUT: DWORD = 15402;
+pub const ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT: DWORD = 15403;
 
 pub const E_NOTIMPL: HRESULT = 0x80004001u32 as HRESULT;
 
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index d63139d8052..640c9f3636d 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -61,7 +61,22 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
         c::ERROR_FILE_NOT_FOUND => return ErrorKind::NotFound,
         c::ERROR_PATH_NOT_FOUND => return ErrorKind::NotFound,
         c::ERROR_NO_DATA => return ErrorKind::BrokenPipe,
-        c::ERROR_OPERATION_ABORTED => return ErrorKind::TimedOut,
+        c::ERROR_SEM_TIMEOUT
+        | c::WAIT_TIMEOUT
+        | c::ERROR_DRIVER_CANCEL_TIMEOUT
+        | c::ERROR_OPERATION_ABORTED
+        | c::ERROR_SERVICE_REQUEST_TIMEOUT
+        | c::ERROR_COUNTER_TIMEOUT
+        | c::ERROR_TIMEOUT
+        | c::ERROR_RESOURCE_CALL_TIMED_OUT
+        | c::ERROR_CTX_MODEM_RESPONSE_TIMEOUT
+        | c::ERROR_CTX_CLIENT_QUERY_TIMEOUT
+        | c::FRS_ERR_SYSVOL_POPULATE_TIMEOUT
+        | c::ERROR_DS_TIMELIMIT_EXCEEDED
+        | c::DNS_ERROR_RECORD_TIMED_OUT
+        | c::ERROR_IPSEC_IKE_TIMED_OUT
+        | c::ERROR_RUNLEVEL_SWITCH_TIMEOUT
+        | c::ERROR_RUNLEVEL_SWITCH_AGENT_TIMEOUT => return ErrorKind::TimedOut,
         _ => {}
     }
 
diff --git a/src/test/ui/moves/issue-46099-move-in-macro.rs b/src/test/ui/moves/issue-46099-move-in-macro.rs
new file mode 100644
index 00000000000..576fe1f4c89
--- /dev/null
+++ b/src/test/ui/moves/issue-46099-move-in-macro.rs
@@ -0,0 +1,15 @@
+// Regression test for issue #46099
+// Tests that we don't emit spurious
+// 'value moved in previous iteration of loop' message
+
+macro_rules! test {
+    ($v:expr) => {{
+        drop(&$v);
+        $v
+    }}
+}
+
+fn main() {
+    let b = Box::new(true);
+    test!({b}); //~ ERROR use of moved value
+}
diff --git a/src/test/ui/moves/issue-46099-move-in-macro.stderr b/src/test/ui/moves/issue-46099-move-in-macro.stderr
new file mode 100644
index 00000000000..83c99db8709
--- /dev/null
+++ b/src/test/ui/moves/issue-46099-move-in-macro.stderr
@@ -0,0 +1,14 @@
+error[E0382]: use of moved value: `b`
+  --> $DIR/issue-46099-move-in-macro.rs:14:12
+   |
+LL |     let b = Box::new(true);
+   |         - move occurs because `b` has type `std::boxed::Box<bool>`, which does not implement the `Copy` trait
+LL |     test!({b});
+   |            ^
+   |            |
+   |            value moved here
+   |            value used here after move
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/moves/move-in-guard-2.stderr b/src/test/ui/moves/move-in-guard-2.stderr
index 8bd405279c5..00d89f55071 100644
--- a/src/test/ui/moves/move-in-guard-2.stderr
+++ b/src/test/ui/moves/move-in-guard-2.stderr
@@ -5,7 +5,10 @@ LL |     let x: Box<_> = box 1;
    |         - move occurs because `x` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
 ...
 LL |         (_, 2) if take(x) => (),
-   |                        ^ value moved here, in previous iteration of loop
+   |                        ^
+   |                        |
+   |                        value moved here
+   |                        value used here after move
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/clippy_lints/src/functions.rs b/src/tools/clippy/clippy_lints/src/functions.rs
index 991d129e8f0..1f9bd7a691b 100644
--- a/src/tools/clippy/clippy_lints/src/functions.rs
+++ b/src/tools/clippy/clippy_lints/src/functions.rs
@@ -513,7 +513,7 @@ fn is_mutable_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>, span: Span,
         // primitive types are never mutable
         ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false,
         ty::Adt(ref adt, ref substs) => {
-            tys.insert(adt.did) && !ty.is_freeze(cx.tcx, cx.param_env, span)
+            tys.insert(adt.did) && !ty.is_freeze(cx.tcx.at(span), cx.param_env)
                 || KNOWN_WRAPPER_TYS.iter().any(|path| match_def_path(cx, adt.did, path))
                     && substs.types().any(|ty| is_mutable_ty(cx, ty, span, tys))
         },
diff --git a/src/tools/clippy/clippy_lints/src/let_if_seq.rs b/src/tools/clippy/clippy_lints/src/let_if_seq.rs
index d7bf8a14768..e097f40f87e 100644
--- a/src/tools/clippy/clippy_lints/src/let_if_seq.rs
+++ b/src/tools/clippy/clippy_lints/src/let_if_seq.rs
@@ -74,9 +74,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq {
                     let span = stmt.span.to(if_.span);
 
                     let has_interior_mutability = !cx.tables.node_type(canonical_id).is_freeze(
-                        cx.tcx,
+                        cx.tcx.at(span),
                         cx.param_env,
-                        span
                     );
                     if has_interior_mutability { return; }
 
diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs
index 0b9b7e1b8cc..93569a04f7a 100644
--- a/src/tools/clippy/clippy_lints/src/mut_key.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_key.rs
@@ -118,7 +118,7 @@ fn is_mutable_type<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>, span: Spa
             size.try_eval_usize(cx.tcx, cx.param_env).map_or(true, |u| u != 0) && is_mutable_type(cx, inner_ty, span)
         },
         Tuple(..) => ty.tuple_fields().any(|ty| is_mutable_type(cx, ty, span)),
-        Adt(..) => cx.tcx.layout_of(cx.param_env.and(ty)).is_ok() && !ty.is_freeze(cx.tcx, cx.param_env, span),
+        Adt(..) => cx.tcx.layout_of(cx.param_env.and(ty)).is_ok() && !ty.is_freeze(cx.tcx.at(span), cx.param_env),
         _ => false,
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index bb257e5a542..230dfd2ebf5 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -110,7 +110,7 @@ impl Source {
 }
 
 fn verify_ty_bound<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>, source: Source) {
-    if ty.is_freeze(cx.tcx, cx.param_env, DUMMY_SP) || is_copy(cx, ty) {
+    if ty.is_freeze(cx.tcx.at(DUMMY_SP), cx.param_env) || is_copy(cx, ty) {
         // An `UnsafeCell` is `!Copy`, and an `UnsafeCell` is also the only type which
         // is `!Freeze`, thus if our type is `Copy` we can be sure it must be `Freeze`
         // as well.
diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs
index 3591972fe08..d8a73f8054b 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark.rs
@@ -137,7 +137,7 @@ impl QuestionMark {
     fn moves_by_default(cx: &LateContext<'_, '_>, expression: &Expr<'_>) -> bool {
         let expr_ty = cx.tables.expr_ty(expression);
 
-        !expr_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, expression.span)
+        !expr_ty.is_copy_modulo_regions(cx.tcx.at(expression.span), cx.param_env)
     }
 
     fn is_option(cx: &LateContext<'_, '_>, expression: &Expr<'_>) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs
index 60ab19e71f5..6d4c6c6ce1c 100644
--- a/src/tools/clippy/clippy_lints/src/utils/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs
@@ -891,7 +891,7 @@ pub fn type_is_unsafe_function<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx
 }
 
 pub fn is_copy<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
-    ty.is_copy_modulo_regions(cx.tcx, cx.param_env, DUMMY_SP)
+    ty.is_copy_modulo_regions(cx.tcx.at(DUMMY_SP), cx.param_env)
 }
 
 /// Checks if an expression is constructing a tuple-like enum variant or struct