-
Notifications
You must be signed in to change notification settings - Fork 32
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
Fix/reuse helpers #20
Conversation
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.
(hi again @arkivm !)
Nice, I like the use of the never type !
to indicate non-returning functions.
I wonder if something we can have something like unwrap
that instead of panic will call vc_terminate_xxxx
. Consider this code:
let init_frame: PhysFrame = match mem_allocate_frames(init_count) {
Some(f) => f,
None => vc_terminate_svsm_enomem(),
};
can we somehow turn it into:
let init_frame: PhysFrame = mem_allocate_frames(init_count).unwrap_svsm_enomem();
another way is of course to make more and more functions return Result, and use the ?
operator to return early. Then the vc_terminate_xxxx
functions will only be called at the very top level. That will take time...
Thanks for the patches. Please make sure that any changes don't generate new warnings. So whichever patch results in the warning from src/mem/pgtable.rs, make the necessary changes to eliminate the warning in the same patch. |
hi @dubek :)
we can do something like this without much effort. let frame: PhysFrame =
mem_allocate_frames(count as u64).unwrap_or_else(|| vc_terminate_svsm_enomem());
That'd be perfect! This way, we can propagate |
I like this idea but:
I don't think this is very readable. |
633d75a
to
a12a4aa
Compare
The alternative I could think of is to define a trait that would define a function pub trait CustomUnwrap<T> {
fn unwrap_svsm_enomem(self) -> T;
}
impl CustomUnwrap<PhysFrame> for Option<PhysFrame> {
fn unwrap_svsm_enomem(self) -> PhysFrame {
match self {
Some(f) => f,
None => vc_terminate_svsm_enomem(),
}
}
} However, this would cause needless code bloat. otoh, |
Squashed. Ready for review @tlendacky @Zildj1an |
So vc_terminate() is already marked as no-return... why do all the functions where the body only calls vc_terminate() need to be marked that way? Shouldn't rust be able to figure that out? I would say this is more an issue with rust than having to mark all of those other functions as no-return. Thoughts? And if I apply the first patch and build, I get a warning, so it looks like you squashed the wrong patches. |
@arkivm is it possible to do this in a generic way, for every Option and Result? Something like (not sure this is valid syntax): pub trait CustomUnwrap<T> {
fn unwrap_svsm_enomem(self) -> T;
}
impl CustomUnwrap<T> for Option<T> {
fn unwrap_svsm_enomem(self) -> T {
match self {
Some(value) => value,
None => vc_terminate_svsm_enomem(),
}
}
} |
@tlendacky I think that we need to drop the semicolon in: /// Terminate SVSM with generic SVSM reason
#[inline]
pub fn vc_terminate_svsm_general() {
vc_terminate(SVSM_REASON_CODE_SET, SVSM_TERM_GENERAL);
} and then the compiler should complain that the return type of vc_terminate_svsm_general doesn't match the actual "value" returned from the function (which is |
Looks like there is two separate conversations going in parallel here (unwrap options/this PR). @arkivm @dubek I am very interested in the possibility of improving error unwrapping but let us move the conversation to a separate issue. |
I removed the semi-colon(s) and there is no complaining from the compiler. |
hmm, you're right. The following compiles and runs without warnings, even though non-intuitive to me. |
@tlendacky @dubek Valid concern. There are issues in the past, where having a |
You are witnessing the principle of explosion: "From contradiction, anything follows". Thus, from
From fn from_contradiction_an_absolute_unit_follows() {
std::process::exit(random())
} does indeed, as you have already noted, read more to Rust as fn from_contradiction_an_absolute_unit_follows() -> () { and because of the signature for The same thing happens with the example given of For stability reasons, Rust's design has tended to prioritize choices that will lead to the contents of functions not mattering, so that changes inside a function generally won't break someone else's code in the complex software packaging ecosystems of the 21st Century. Global type inference allows every new module you add to potentially break type inference if you have a type system that is complex enough to sometimes require annotations, and my understanding is that this would remain necessarily true even if rustc made its type inference much stronger, because Rust has a type system too complex to be described by a system with fully decidable type inference according to the current understanding of programming language theory. Footnotes |
Thanks @workingjubilee for the thorough explanation. @tlendacky @arkivm As I understand it, we have to make sure we fully specify the declarations of functions: arguments and return types. So we have to state that |
Thank you @workingjubilee for the detailed explanation. @dubek I will revisit this PR to see if some of them can be squashed. |
vc_terminate helpers never return as they internally call `vc_terminate` with a specific return code and reason. Marking all of these as noreturn will allow us use these functions in places where this is part of a match arm. Also fix warning on unused assignments. Technically, the initialized var `pa` is never read, it is just over-written. Changing the return value in the error path function unmasked this warning. Signed-off-by: Vikram Narayanan <vikram186@gmail.com>
Since the vc_terminate helpers are now marked as noreturn, we can use them directly in all places such that the compiler will not complain that the Err path in the match arm is not returning the same value as success path. Signed-off-by: Vikram Narayanan <vikram186@gmail.com>
a12a4aa
to
901b4fc
Compare
Ready for review! |
This looks good to go :) |
Reuse the helpers that are already exported by the vc module for all vc_terminate conditions. Tweak the return code such that the compiler is aware of the noreturn path and not complain that the Err path does not return the same value as the success path.
Signed-off-by: Vikram Narayanan <vikram186@gmail.com>