Skip to content

Commit

Permalink
Fix panic due to wrong intrinsic arguments (rust-lang#533) (rust-lang…
Browse files Browse the repository at this point in the history
…#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.
  • Loading branch information
celinval authored and tedinski committed Nov 2, 2021
1 parent e5c5acd commit d09f5a4
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 12 deletions.
16 changes: 5 additions & 11 deletions compiler/rustc_codegen_rmc/src/codegen/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,30 +271,24 @@ 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<Type> = 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"),
};

// 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);
}
}
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_codegen_rmc/src/codegen/typ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down
9 changes: 9 additions & 0 deletions src/test/rmc/Iterator/try_fold.rs
Original file line number Diff line number Diff line change
@@ -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");
}

0 comments on commit d09f5a4

Please sign in to comment.