Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the rust toolchain to nightly-2022-05-03 #1181

Merged
merged 6 commits into from
May 12, 2022

Conversation

celinval
Copy link
Contributor

Description of changes:

Update the rust toolchain to nightly-2022-05-03. There were many issues that had to be fixed to upgrade the toolchain. I split the changes into the following commits:

  1. Fix compilation (usually due to API changes).
  2. Fix handling of Box due to changes in its internal representation (Implement core::ptr::Unique on top of NonNull rust-lang/rust#96010).
  3. Implement new statement kind (Deinit).
  4. Fix discriminant handling. The constant conversion to i64 was panicking and the niche_value conversion was also triggering an overflow error. I disabled the conversion checks for now and simplified the entire logic.

Resolved issues:

Resolves #1162

Call-outs:

This change disables conversion checks. I am open to discussion, but I think this check is too strict and it was rather complicating our codegen logic. I propose to instrument casting later based on user configuration.

Testing:

  • How is this change tested? Old tests

  • Is this a refactor change? No

Checklist

  • Each commit message has a non-empty body, explaining why the change was made
  • Methods or procedures are documented
  • Regression or unit tests are included, or existing tests cover the modified code
  • My PR is restricted to a single feature or bugfix

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

@celinval celinval requested a review from a team as a code owner May 10, 2022 03:54
Copy link
Contributor

@tedinski tedinski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than the subtleties of the discriminant change it looks good, should get a second approval from someone on that.

wrapping_sub(&niche_val, *niche_start)
};

// Compute relative discriminant value (`niche_val - niche_start`).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there Rust documentation to point to here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope... I can point to the code where I derived this comment from though.

// No need to subtract.
expr.clone()
} else {
let unsigned = Type::unsigned_int(expr.typ().width().unwrap());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this a helper function on the type?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, this will turn ssize_t into uint64_t instead of size_t. It would be nice to handle the CInt types specially here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok... let me create a helper function in the bindings crate to deal with different types.

let layout = self.layout_of(dst_mir_ty);
if layout.is_zst() || self.ignore_var_ty(dst_mir_ty) {
// We ignore assignment for all zero size types
// Ignore generators too for now:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to ignore generators?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we don't codegen them and they end up with size 0 despite what their layout says.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, I changed the check to see if the size of the destination is 0, which today will exclude generators. The first check might be redundant now, but I guess it doesn't hurt for now.

// We ignore assignment for all zero size types
// Ignore generators too for now:
// https://github.com/model-checking/kani/issues/416
Stmt::skip(Location::none())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No location available?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can probably fix that. Let me see. I just took this code from the way we handle assignment.

@@ -1263,7 +1263,7 @@ impl<'tcx> GotocCtx<'tcx> {
_ => unreachable!(),
};

let rustc_target::abi::Scalar { value: prim_type, .. } = element;
let prim_type = element.primitive();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's cleaner :)

impl<'tcx> GotocCtx<'tcx> {
/// Dereference a boxed type `std::boxed::Box<T>` to get a `*T`.
///
/// WARNING: This is based on a manual inspection of how boxed types are currently
/// a) implemented by the rust standard library
/// b) codegenned by Kani.
/// If either of those change, this will almost certainly stop working.
pub fn deref_box(&self, e: Expr) -> Expr {
pub fn deref_box(&self, box_expr: Expr) -> Expr {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the comment below need to be updated?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep

@@ -102,14 +102,17 @@ impl<'tcx> GotocCtx<'tcx> {
}
}

/// Members traverse path to get to the raw pointer of a box (b.0.pointer.pointer).
const RAW_PTR_FROM_BOX: [&str; 3] = ["0", "pointer", "pointer"];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clever

expr.clone()
} else {
let unsigned = Type::unsigned_int(expr.typ().width().unwrap());
let constant = Expr::int_constant(constant as i64, unsigned.clone());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there a cast to i64?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might be leftover from previous attempts... :)

// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
// Check niche optimization for mix of option, tuple and nonnull.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't seem accurate (don't see a tuple, and nonnull should perhaps be nonzero).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it is outdated

@celinval
Copy link
Contributor Author

@zhassan-aws @danielsn would you like to take a look at the new revision? Cheers!

/// Convert type to its unsigned counterpart if possible.
/// For types that are already unsigned, this will return self.
/// Note: This will expand any typedef.
pub fn to_unsigned(&self) -> Option<Self> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

This compiles but regression is failing due to unimplemented statement.
Box<T> now users NonNull<T> instead of raw pointer.
We codegen an assignment to non-det value per documentation. See more
information here:
 - rust-lang/rust#95125
After the merge, the previous wrapping sub logic was triggering a panic
due to u128 -> i64 conversion. There were also other overflow issues
when trying to convert the `niche_value` to unsigned.

For now, I'm disabling the coversion check which I believe is too
strict. We should consider implementing a more flexible check later that
can be controlled by the user without affecting the internal compiler
codegen.
 - Improve comments.
 - Remove wrong cast to i64.
 - Fix statement location.
 - Create util function to create unsigned type.
pub fn to_unsigned(&self) -> Option<Self> {
let concrete = self.unwrap_typedef();
match concrete {
CInteger(CIntType::SSizeT) => Some(CInteger(CIntType::SizeT)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't there some other types that could go here too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could include Bool which would be a no-op and I could handle CBitField but I noticed that we don't handle that in neither signed() or unsigned() so we should probably add some logic there too. For us to add support to Char we would need access to the machine model. Is there any other type you would like to see?

Let me know what you prefer and I can add that as a follow up PR.

Copy link
Contributor

@danielsn danielsn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had one comment but it is a minor one.

@celinval celinval merged commit d0b74ca into model-checking:main May 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sprint 2022-05-17: Update rust toolchain version
4 participants