提交 3b1c08c6 编写于 作者: B bors

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
......@@ -200,6 +200,8 @@ fn codegen_switchint_terminator(
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]);
......
......@@ -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 {
......
A discrimant value is present more than once.
A discriminant value is present more than once.
Erroneous code example:
......
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,
......
......@@ -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() {
......
......@@ -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
......
......@@ -2159,7 +2159,7 @@ fn pointee_info_at(this: TyAndLayout<'tcx>, cx: &C, offset: Size) -> Option<Poin
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 {
......
......@@ -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`.
......
......@@ -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),
......
......@@ -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)
}
}
......
......@@ -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(
......
......@@ -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.
......
......@@ -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)?;
......
......@@ -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)));
......
......@@ -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 {
......
......@@ -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",
......
......@@ -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;
}
......
......@@ -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,
......
......@@ -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.
......
......@@ -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.
......
......@@ -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));
......
......@@ -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);
......
......@@ -91,7 +91,7 @@ fn next(&mut self) -> Option<NeedsDropResult<Ty<'tcx>>> {
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() {
......
......@@ -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,
......
......@@ -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 @@ pub fn write(&self, data: &[u8]) -> io::Result<usize> {
}
}
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 @@ pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
}
#[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 @@ pub fn write(&self, data: &[u8]) -> io::Result<usize> {
}
}
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 @@ pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
}
#[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(())
}
}
......
......@@ -11,22 +11,25 @@ pub fn new() -> io::Result<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 @@ pub fn new() -> io::Result<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 @@ pub fn new() -> io::Result<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 @@ pub fn as_raw_fd(&self) -> u32 {
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(())
}
}
......
......@@ -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;
......
......@@ -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,
_ => {}
}
......
// 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
}
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`.
......@@ -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
......
......@@ -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))
},
......
......@@ -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; }
......
......@@ -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,
}
}
......@@ -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.
......
......@@ -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 {
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册