diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index d56c816811b3c46d68056e7b662ddba6c08724db..5125ce779ed8e35d450279d132e4d89da282dcf5 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -200,6 +200,8 @@ fn codegen_switchint_terminator( targets: &Vec, ) { 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 703479b74bef8a9d9514a8e1c3fb4ddf24a46a6f..c55bf9858b972450c4cd607ee630221dacb23f38 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -74,7 +74,7 @@ fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { } 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 fd5eca68e21fd5dc24be35b92c4fa4fccd0b2765..b834a734cefc447202d5a0dd2b64636f98fdf637 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 f90fd3b562469edd4420eb9a75e86e9f01b866ef..454d2507e5e2e2bf677d95a1c8f278f2e6f7686f 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 b7f728ec60cfdab9b0b8aa2641c3f24de4ae3d23..e746396e4c684d7e13afb04ef2ac0dd7e75169d1 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -562,7 +562,7 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item<'_>) { 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 3381b95c2a38e1fd9946c29d088ae2c1a6a06a5a..649766547990f264bf5b81fbcdd0705e383bebc6 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 68af22569e35326256533736f0c09f1f08898c5e..e4cc96dd83bfbd751cd4b29b9e1b9bcd1e892b32 100644 --- a/src/librustc_middle/ty/layout.rs +++ b/src/librustc_middle/ty/layout.rs @@ -2159,7 +2159,7 @@ fn pointee_info_at(this: TyAndLayout<'tcx>, cx: &C, offset: Size) -> Option { 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 47110be53b2521ad09b296e7ecf5793122054996..67ad7ee708267968560c9b5b1b97106d5b041ff2 100644 --- a/src/librustc_middle/ty/util.rs +++ b/src/librustc_middle/ty/util.rs @@ -681,11 +681,10 @@ pub fn numeric_min_val(&'tcx self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ty::Const< /// 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 @@ pub fn is_sized(&'tcx self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'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 eb07c7e65f5c98707357de740d06292814224e83..8d7944004c75e2fdf9f1366e4df35fe329ec5185 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 @@ pub(in crate::borrow_check) fn report_use_of_moved_or_uninitialized( 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 70c916a089270dd108cbddfb72dfad01e478a591..a3fc51cad656b0c9f2721f2d53b3b68d21dd527f 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 ceacbbe5139bf3508587b2f9493896961923c1e8..95e193b6253541ac0ddb3ea0efb953ea3cbb5709 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -391,7 +391,7 @@ pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { #[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 cab13d379a2ccead0845ab7735d5ae4aaedf30e9..dffbc969c21b8c645158e7ba7850e59d29df5bb6 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 0f3fbcf8195748e20ee222fe5f8ae850ccbdfb6d..4681079a22ddf4f3ef7abca68251054098c2ed30 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -24,9 +24,10 @@ pub(super) fn eval_terminator( 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 @@ pub(super) fn eval_terminator( 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 15a2e9130a37e91a240c2bbefa4657adac890288..8327affd982ed0f4578d41eded44cf05460e573b 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 936c1a84e142eb9a595c042c016dfe695eac7303..e2893e81a2ce63dc8a0cebdce21ac276ce145957 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -77,7 +77,7 @@ fn in_qualifs(qualifs: &ConstQualifs) -> bool { } 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 7dbb2ebad8b996b0c43b28978368fe60c1b93fa8..9898cde5207780ac582c5e7c899e402bd59968c9 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -282,9 +282,8 @@ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: ), }; 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 @@ fn check_mut_borrowing_layout_constrained_field( // 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 330f6c1640ff493ecd0b9ce443982a6ae22943f7..8bcbcd79ae60b798a49ed22bb6a2221b8599d08e 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -341,7 +341,7 @@ fn validate_candidate(&self, candidate: Candidate) -> Result<(), Unpromotable> { 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 @@ fn validate_rvalue(&self, rvalue: &Rvalue<'tcx>) -> Result<(), Unpromotable> { 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 625f40cd79206313d3f696abb9f494542abc5c79..c5343d9b5d014071e36f89cfacbcf17e02a12a3c 100644 --- a/src/librustc_mir/transform/validate.rs +++ b/src/librustc_mir/transform/validate.rs @@ -90,7 +90,7 @@ fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { 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 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location 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 9a75f3afe8f082bccffe7e60cc0d895c4400f37d..5949fd1e22ce88dbc3effbb1487311d48e738e7f 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 @@ fn expr_as_call_operand( 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 4d97a19f4086bdff11222171efcc635fe3874f4d..6fc447a87f57a7892bfe694846bc568495941f89 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 /// 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 88fb78f85e423add2e3303342314fcd09f6485f5..c8666ba1fd078d58676329565fc6a44f40c16a8f 100644 --- a/src/librustc_passes/intrinsicck.rs +++ b/src/librustc_passes/intrinsicck.rs @@ -214,7 +214,7 @@ fn check_asm_operand_type( // 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 f244785b49d2fdf3dd5e4050543217b5549171e5..dc895ad34a93205017fdd623c22e083b606e9dfa 100644 --- a/src/librustc_trait_selection/infer.rs +++ b/src/librustc_trait_selection/infer.rs @@ -44,7 +44,7 @@ fn type_is_copy_modulo_regions( 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 439bec1702eaed10e2d4dc133a8d5f281246d7cf..7880c09c2ad81a04ad3284ab97fd1b2093a014c9 100644 --- a/src/librustc_ty/needs_drop.rs +++ b/src/librustc_ty/needs_drop.rs @@ -91,7 +91,7 @@ fn next(&mut self) -> Option>> { 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 d80a38819ead0db6ad0441e4d62a31753b372b0d..f7248e7547e27620b766649e48a7514a7a1ad158 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 208265de465adf3a1b81120c1eabe0f7f599a159..f3654ee38716c7c54ab09e65f0230606465ba556 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 { Ok(Stdin) } +} - pub fn read(&self, data: &mut [u8]) -> io::Result { +impl io::Read for Stdin { + fn read(&mut self, data: &mut [u8]) -> io::Result { self.read_vectored(&mut [IoSliceMut::new(data)]) } - pub fn read_vectored(&self, _data: &mut [IoSliceMut<'_>]) -> io::Result { - //ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) }) - // .read(data) + fn read_vectored(&mut self, _data: &mut [IoSliceMut<'_>]) -> io::Result { 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 { Ok(Stdout) } +} - pub fn write(&self, data: &[u8]) -> io::Result { +impl io::Write for Stdout { + fn write(&mut self, data: &[u8]) -> io::Result { let len; unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) } @@ -44,7 +46,7 @@ pub fn write(&self, data: &[u8]) -> io::Result { } } - pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { + fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result { let len; unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) } @@ -57,11 +59,11 @@ pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { } #[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 { Ok(Stderr) } +} - pub fn write(&self, data: &[u8]) -> io::Result { +impl io::Write for Stderr { + fn write(&mut self, data: &[u8]) -> io::Result { let len; unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) } @@ -83,7 +87,7 @@ pub fn write(&self, data: &[u8]) -> io::Result { } } - pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { + fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result { let len; unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) } @@ -96,21 +100,12 @@ pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { } #[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 { - (&*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 9f9e35566ecf59bcbc46291a6deed0558f09740b..78e3911dc4efea33e1edc322a40e54ab7856e2bb 100644 --- a/src/libstd/sys/wasi/stdio.rs +++ b/src/libstd/sys/wasi/stdio.rs @@ -11,22 +11,25 @@ pub fn new() -> io::Result { Ok(Stdin) } - pub fn read(&self, data: &mut [u8]) -> io::Result { + #[inline] + pub fn as_raw_fd(&self) -> u32 { + 0 + } +} + +impl io::Read for Stdin { + fn read(&mut self, data: &mut [u8]) -> io::Result { self.read_vectored(&mut [IoSliceMut::new(data)]) } - pub fn read_vectored(&self, data: &mut [IoSliceMut<'_>]) -> io::Result { + fn read_vectored(&mut self, data: &mut [IoSliceMut<'_>]) -> io::Result { 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 @@ pub fn new() -> io::Result { Ok(Stdout) } - pub fn write(&self, data: &[u8]) -> io::Result { + #[inline] + pub fn as_raw_fd(&self) -> u32 { + 1 + } +} + +impl io::Write for Stdout { + fn write(&mut self, data: &[u8]) -> io::Result { self.write_vectored(&[IoSlice::new(data)]) } - pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { + fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result { 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 @@ pub fn new() -> io::Result { Ok(Stderr) } - pub fn write(&self, data: &[u8]) -> io::Result { - self.write_vectored(&[IoSlice::new(data)]) - } - - pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result { - 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 @@ pub fn as_raw_fd(&self) -> u32 { impl io::Write for Stderr { fn write(&mut self, data: &[u8]) -> io::Result { - (&*self).write(data) + self.write_vectored(&[IoSlice::new(data)]) + } + + fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result { + 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 6115d652b0cea3975ff26d5d60e4d0c92df38d00..f440442ca306279dfb7a0f49bbabb41fc54aabca 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -161,6 +161,8 @@ fn clone(&self) -> Self { 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 @@ fn clone(&self) -> Self { 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 d63139d8052c23a535db8f5bbda2404a18babee5..640c9f3636d4b89262cf19045c0c9d346504ca53 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 0000000000000000000000000000000000000000..576fe1f4c89052e47edd8d3977b3f2250c8d1796 --- /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 0000000000000000000000000000000000000000..83c99db87095179d6f7c906f12b4e6d8c3fdad41 --- /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`, 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 8bd405279c526afd165159f6c7cfab774d4ede03..00d89f550714c4af313a32be92e70a0841f4e2ab 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`, 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 991d129e8f0d612a7d7187abe0d007c5592502b3..1f9bd7a691b520bed9c788980974d3050d14e69d 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 d7bf8a1476817c28892be2a3033f120fb2585301..e097f40f87e47c4b13084141de3e89b840b89232 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 @@ fn check_block(&mut self, cx: &LateContext<'a, 'tcx>, block: &'tcx hir::Block<'_ 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 0b9b7e1b8cc1b3e8e951d2f97dc43ff080390638..93569a04f7a3a23b151b70b28752f912d6cacf23 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 bb257e5a542d98632f9f25c31bac6342c72504b7..230dfd2ebf5661c3dd768225627bc5b4199fd93d 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 @@ fn lint(&self) -> (&'static Lint, &'static str, Span) { } 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 3591972fe082f7d0db4a12878a993059556509b8..d8a73f8054bcaa0dff4509fd060d686b24a89ee2 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 @@ fn check_if_let_some_and_early_return_none(cx: &LateContext<'_, '_>, expr: &Expr 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 60ab19e71f5e4e15b8f9b45ae6cac3fc01f146a5..6d4c6c6ce1ceada7c78195219f454e35374ccc3f 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