diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 3ec27db60c2..c1d8d087eac 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -556,8 +556,8 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> /// create a loop that drops an array: /// /// loop-block: - /// can_go = index < len - /// if can_go then drop-block else succ + /// can_go = index == len + /// if can_go then succ else drop-block /// drop-block: /// ptr = &mut LV[index] /// index = index + 1 @@ -604,13 +604,13 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let loop_block = self.elaborator.patch().new_block(BasicBlockData { statements: vec![ Statement { source_info: self.source_info, kind: StatementKind::Assign( - can_go.clone(), Rvalue::BinaryOp(BinOp::Lt, use_(index), use_(length)) + can_go.clone(), Rvalue::BinaryOp(BinOp::Eq, use_(index), use_(length)) )}, ], is_cleanup: unwind.is_cleanup(), terminator: Some(Terminator { source_info: self.source_info, - kind: TerminatorKind::if_(tcx, use_(can_go), drop_block, succ) + kind: TerminatorKind::if_(tcx, use_(can_go), succ, drop_block) }) }); diff --git a/src/test/run-pass/issue-41888.rs b/src/test/run-pass/issue-41888.rs new file mode 100644 index 00000000000..e145cde039d --- /dev/null +++ b/src/test/run-pass/issue-41888.rs @@ -0,0 +1,43 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { let _ = g(Some(E::F(K))); } + +type R = Result<(), ()>; +struct K; + +enum E { + F(K), // must not be built-in type + #[allow(dead_code)] + G(Box, Box), +} + +fn translate(x: R) -> R { x } + +fn g(mut status: Option) -> R { + loop { + match status { + Some(infix_or_postfix) => match infix_or_postfix { + E::F(_op) => { // <- must be captured by value + match Ok(()) { + Err(err) => return Err(err), + Ok(_) => {}, + }; + } + _ => (), + }, + _ => match translate(Err(())) { + Err(err) => return Err(err), + Ok(_) => {}, + } + } + status = None; + } +}