-
Notifications
You must be signed in to change notification settings - Fork 390
Support weak definitions #4414
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
base: master
Are you sure you want to change the base?
Support weak definitions #4414
Conversation
When a symbol only has a weak definition, this definition will be picked. When a symbol has both a weak and a regular definition, the regular definition will be picked instead.
This has been extracted out of rust-lang/rust#134522. |
9284d4c
to
5a433c4
Compare
@@ -138,7 +139,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | |||
Entry::Occupied(e) => e.into_mut(), | |||
Entry::Vacant(e) => { | |||
// Find it if it was not cached. | |||
let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum)> = None; | |||
let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum, bool)> = None; |
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.
Please explain what the bool
means, or use a self-explaining type. It might be worth using a struct instead of a tuple.
if let Some((original_instance, original_cnum, original_is_weak)) = | ||
instance_and_crate | ||
{ | ||
match (is_weak, original_is_weak) { |
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.
match (is_weak, original_is_weak) { | |
// There is more than one definition with this name. What we do now | |
// depends on whether one or both definitions are weak. | |
match (is_weak, original_is_weak) { |
(true, true) | (false, false) => { | ||
// Either both definitions are non-weak or both are weak. In | ||
// either case return an error. For weak definitions we error | ||
// because it is undefined which definition would have been |
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.
// because it is undefined which definition would have been | |
// because it is unspecified which definition would have been |
if let Some((instance, _, _)) = instance_and_crate { | ||
if !matches!(tcx.def_kind(instance.def_id()), DefKind::Fn | DefKind::AssocFn) { | ||
throw_ub_format!( | ||
"attempt to call an exported symbol that is not defined as a function" | ||
); | ||
} | ||
} | ||
|
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.
I guess this logic can live here as well, but is there a specific reason you moved it?
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.
Please rename this to exported_symbol_weak
for better test grouping.
@rustbot author |
When a symbol only has a weak definition, this definition will be picked. When a symbol has both a weak and a regular definition, the regular definition will be picked instead.
In the future the allocator shim may be replaced by weak definitions. This already adds support to simplify things in the future.