From d09f5a4cebde8666bff023928e7a8dc4dd8d708c Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Tue, 2 Nov 2021 10:04:59 -0700 Subject: [PATCH] Fix panic due to wrong intrinsic arguments (#533) (#610) During codegen of function calls, we were ignoring argument of Unit type. This was causing a failure due to missing arguments when an intrinsic or closure was being called with an '()' as an argument. This change modifies how we deal with Unit types during function definition and function call. --- .../rustc_codegen_rmc/src/codegen/statement.rs | 16 +++++----------- compiler/rustc_codegen_rmc/src/codegen/typ.rs | 1 - src/test/rmc/Iterator/try_fold.rs | 9 +++++++++ 3 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 src/test/rmc/Iterator/try_fold.rs diff --git a/compiler/rustc_codegen_rmc/src/codegen/statement.rs b/compiler/rustc_codegen_rmc/src/codegen/statement.rs index 3dd73220d369d..564bebaf601e1 100644 --- a/compiler/rustc_codegen_rmc/src/codegen/statement.rs +++ b/compiler/rustc_codegen_rmc/src/codegen/statement.rs @@ -271,18 +271,14 @@ impl<'tcx> GotocCtx<'tcx> { // Therefore, we have to project out the corresponding fields when we detect // an invocation of a closure. // - // Note: In some cases, the enviroment struct has type FnDef, so we skip it in + // Note: In some cases, the environment struct has type FnDef, so we skip it in // ignore_var_ty. So the tuple is always the last arg, but it might be in the // first or the second position. + // Note 2: For empty closures, the only argument needed is the environment struct. if fargs.len() > 0 { let tupe = fargs.remove(fargs.len() - 1); let tupled_args: Vec = match self.operand_ty(last_mir_arg.unwrap()).kind() { ty::Tuple(tupled_args) => { - // The tuple needs to be added back for type checking even if empty - if tupled_args.is_empty() { - fargs.push(tupe); - return; - } tupled_args.iter().map(|s| self.codegen_ty(s.expect_ty())).collect() } _ => unreachable!("Argument to function with Abi::RustCall is not a tuple"), @@ -290,11 +286,9 @@ impl<'tcx> GotocCtx<'tcx> { // Unwrap as needed for (i, t) in tupled_args.iter().enumerate() { - if !t.is_unit() { - // Access the tupled parameters through the `member` operation - let index_param = tupe.clone().member(&i.to_string(), &self.symbol_table); - fargs.push(index_param); - } + // Access the tupled parameters through the `member` operation + let index_param = tupe.clone().member(&i.to_string(), &self.symbol_table); + fargs.push(index_param); } } } diff --git a/compiler/rustc_codegen_rmc/src/codegen/typ.rs b/compiler/rustc_codegen_rmc/src/codegen/typ.rs index a4e2a4157618e..875f8375729ed 100644 --- a/compiler/rustc_codegen_rmc/src/codegen/typ.rs +++ b/compiler/rustc_codegen_rmc/src/codegen/typ.rs @@ -1238,7 +1238,6 @@ impl<'tcx> GotocCtx<'tcx> { /// Whether a variable of type ty should be ignored as a parameter to a function pub fn ignore_var_ty(&self, ty: Ty<'tcx>) -> bool { match ty.kind() { - ty::Tuple(substs) if substs.is_empty() => true, ty::FnDef(_, _) => true, _ => false, } diff --git a/src/test/rmc/Iterator/try_fold.rs b/src/test/rmc/Iterator/try_fold.rs new file mode 100644 index 0000000000000..783d7f16f42b7 --- /dev/null +++ b/src/test/rmc/Iterator/try_fold.rs @@ -0,0 +1,9 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// cbmc-flags: --unwind 3 + +pub fn main() { + let arr = [(1, 2), (2, 2)]; + let result = arr.iter().try_fold((), |acc, &i| Some(())); + assert_ne!(result, None, "This should succeed"); +}