-
Notifications
You must be signed in to change notification settings - Fork 101
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
Drop for dynamic objects #402
Drop for dynamic objects #402
Conversation
db28d0b
to
bb160fc
Compare
let type_from_mir = ctx.codegen_ty(t); | ||
if expr_ty != type_from_mir { Some((expr_ty, type_from_mir)) } else { None } | ||
} | ||
TypeOrVariant::Variant(_) => None, //TODO, what to do here? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to create an issue for this ? Not sure if this is tracked somewhere..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
15388e3
to
671b741
Compare
format!("drop_in_place for {}", drop_sym_name).as_str(), | ||
trait_fn_ty, | ||
Location::none(), | ||
"https://github.com/model-checking/rmc/issues/202", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the right link? #202
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.readable_instance_name(drop_instance), | ||
); | ||
Type::void_pointer().null().cast_to(trait_fn_ty) | ||
self.codegen_unimplemented( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this typecheck? We want a pointer to an unimplemented function, and instead we're getting an unimplemented function that returns a fn pointer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does type check, we cast to the same type in the if
case. I don't think we have any unit tests that hit this, only the standard library regression.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue is that this code is called in a constructor, so it will always fail at CBMC time (which is sound, but not helpful). I think what we want is to make a function whose body is unimplemented
, and put a pointer to that function into the vtable.
let instance = Instance::resolve_drop_in_place(self.tcx, loc_ty); | ||
if let Some(hk) = self.hooks.hook_applies(self.tcx, instance) { | ||
let drop_instance = Instance::resolve_drop_in_place(self.tcx, loc_ty); | ||
if let Some(hk) = self.hooks.hook_applies(self.tcx, drop_instance) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need the hook here? Or could we just move its logic inside the regular codegen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without it, we fail on:
failures:
[expected] expected/replace-hashmap/main.rs
[expected] expected/replace-vec/main.rs
} | ||
_ => { | ||
// Non-virtual, direct drop call | ||
assert!(!matches!(drop_instance.def, InstanceDef::Virtual(_, _))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we assert this above? Would that be a better check than matching on loc_ty.kind()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conditional doesn't work as a check, because asserting the inverse in the dynamic case fails whenever the instance def is InstanceDef::DropGlue
instead of ::Virtual
. This structure also matches how the Cranelift backend handles this case.
let func = self.codegen_func_expr(drop_instance, None); | ||
let place = self.codegen_place(location); | ||
let arg = if let Some(fat_ptr) = place.fat_ptr_goto_expr { | ||
// Drop takes the fat pointer if it exists |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be in the case of dropping a slice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've also seen it be a fat pointer to a nested dynamic object.
let _nested: Box<dyn Send> = Box::new(x); | ||
} | ||
unsafe { | ||
assert!(CELL == 2); // Should fail |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use the expect_fail
macro
Description of changes:
RMC does not current codegen calls to drop for dynamic objects. This PR does that, inserting vtable calls as necessary.
Resolved issues:
Resolves #66
Should also resolve #435
Call-outs:
SizeAndAlignOfDst
tests. This patch has a workaround to insert acodegen_unimplemented
call in the case that drop fails to typecheck, which maintains soundness (the current implementation is not sound because it does not call drop at all).Testing:
Existing plus 7 new regressions.
Not really.
Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.