Skip to content

Commit 8c55d6e

Browse files
authored
Clippy updates (#672)
* Run a more exhasutive clippy check Signed-off-by: Mark Rossett <marosset@microsoft.com> * Updating dep_rust.yaml to run clippy and other code checks as a seperate job Signed-off-by: Mark Rossett <marosset@microsoft.com> * Fix clippy warnings for hyperlight-guest Signed-off-by: Mark Rossett <marosset@microsoft.com> * More clippy fixes for hyperlight_guest_bin Signed-off-by: Mark Rossett <marosset@microsoft.com> --------- Signed-off-by: Mark Rossett <marosset@microsoft.com>
1 parent 39df600 commit 8c55d6e

File tree

11 files changed

+196
-56
lines changed

11 files changed

+196
-56
lines changed

.github/workflows/dep_rust.yml

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,49 @@ defaults:
3131
shell: bash
3232

3333
jobs:
34+
code-checks:
35+
if: ${{ inputs.docs_only == 'false' }}
36+
timeout-minutes: 60
37+
strategy:
38+
fail-fast: true
39+
matrix:
40+
hypervisor: ['hyperv-ws2025', kvm]
41+
config: [debug, release]
42+
runs-on: ${{ fromJson(
43+
format('["self-hosted", "{0}", "X64", "1ES.Pool=hld-{1}-amd"]',
44+
(matrix.hypervisor == 'hyperv-ws2025') && 'Windows' || 'Linux',
45+
matrix.hypervisor == 'hyperv-ws2025' && 'win2025' || 'kvm')) }}
46+
steps:
47+
- uses: actions/checkout@v4
48+
49+
- uses: hyperlight-dev/ci-setup-workflow@v1.5.0
50+
with:
51+
rust-toolchain: "1.85"
52+
env:
53+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54+
55+
# Does not check for updated Cargo.lock files for test rust guests as this causes an issue with this checkwhen deoendabot updates dependencies in common crates
56+
- name: Ensure up-to-date Cargo.lock
57+
run: |
58+
cargo fetch --locked
59+
60+
- name: fmt
61+
run: just fmt-check
62+
63+
- name: clippy
64+
if: ${{ (runner.os == 'Windows' )}}
65+
run: |
66+
just clippy ${{ matrix.config }}
67+
just clippy-guests ${{ matrix.config }}
68+
69+
- name: clippy exhaustive check
70+
if: ${{ (runner.os == 'Linux' )}}
71+
run: |
72+
just clippy-exhaustive ${{ matrix.config }}
73+
74+
- name: Verify MSRV
75+
run: ./dev/verify-msrv.sh hyperlight-host hyperlight-guest hyperlight-guest-bin hyperlight-common
76+
3477
build:
3578
if: ${{ inputs.docs_only == 'false' }}
3679
timeout-minutes: 60
@@ -61,19 +104,6 @@ jobs:
61104
env:
62105
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63106

64-
- name: fmt
65-
run: just fmt-check
66-
67-
- name: clippy
68-
run: |
69-
just clippy ${{ matrix.config }}
70-
just clippy-guests ${{ matrix.config }}
71-
72-
# Does not check for updated Cargo.lock files for test rust guests as this causes an issue with this checkwhen deoendabot updates dependencies in common crates
73-
- name: Ensure up-to-date Cargo.lock
74-
run: |
75-
cargo fetch --locked
76-
77107
- name: Get gh action service name
78108
if: ${{ (runner.os == 'Windows' )}}
79109
run: (Get-Service actions.runner.*) | Foreach { $_.Name, $_.UserName, $_.ServiceType }
@@ -93,9 +123,6 @@ jobs:
93123
- name: Build
94124
run: just build ${{ matrix.config }}
95125

96-
- name: Verify MSRV
97-
run: ./dev/verify-msrv.sh hyperlight-host hyperlight-guest hyperlight-guest-bin hyperlight-common
98-
99126
- name: Run Rust tests
100127
env:
101128
CARGO_TERM_COLOR: always

Justfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,19 @@ clippy-apply-fix-unix:
176176
clippy-apply-fix-windows:
177177
cargo clippy --target x86_64-pc-windows-msvc --fix --all
178178

179+
# Run clippy with feature combinations for all packages
180+
clippy-exhaustive target=default-target: (witguest-wit)
181+
./hack/clippy-package-features.sh hyperlight-host {{ target }}
182+
./hack/clippy-package-features.sh hyperlight-guest {{ target }}
183+
./hack/clippy-package-features.sh hyperlight-guest-bin {{ target }}
184+
./hack/clippy-package-features.sh hyperlight-common {{ target }}
185+
./hack/clippy-package-features.sh hyperlight-testing {{ target }}
186+
just clippy-guests {{ target }}
187+
188+
# Test a specific package with all feature combinations
189+
clippy-package package target=default-target: (witguest-wit)
190+
./hack/clippy-package-features.sh {{ package }} {{ target }}
191+
179192
# Verify Minimum Supported Rust Version
180193
verify-msrv:
181194
./dev/verify-msrv.sh hyperlight-host hyperlight-guest hyperlight-guest-lib hyperlight-common

hack/clippy-package-features.sh

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
# Check for required arguments
6+
if [[ $# -lt 2 ]]; then
7+
echo "Usage: $0 <package> <target>" >&2
8+
echo "Example: $0 hyperlight-host debug" >&2
9+
exit 1
10+
fi
11+
12+
PACKAGE="$1"
13+
TARGET="$2"
14+
15+
# Convert target for cargo profile
16+
PROFILE=$([ "$TARGET" = "debug" ] && echo "dev" || echo "$TARGET")
17+
18+
# Required features needed so the rust packages can compile
19+
if [[ "$PACKAGE" == "hyperlight-host" ]]; then
20+
REQUIRED_FEATURES=("kvm" "mshv3")
21+
elif [[ "$PACKAGE" == "hyperlight-guest-bin" ]]; then
22+
REQUIRED_FEATURES=("printf")
23+
else
24+
REQUIRED_FEATURES=()
25+
fi
26+
27+
# Get all features for the package (excluding default and required features)
28+
# Always exclude "default", and exclude any required features using jq
29+
features=$(cargo metadata --format-version 1 --no-deps | jq -r --arg pkg "$PACKAGE" '.packages[] | select(.name == $pkg) | .features | keys[] | select(. != "default" and (IN($ARGS.positional[])|not))' --args "${REQUIRED_FEATURES[@]}" || true)
30+
31+
# Convert required features array to comma-separated string for cargo
32+
if [[ ${#REQUIRED_FEATURES[@]} -gt 0 ]]; then
33+
required_features_str=$(IFS=,; echo "${REQUIRED_FEATURES[*]}")
34+
else
35+
required_features_str=""
36+
fi
37+
38+
# Test with minimal features
39+
if [[ ${#REQUIRED_FEATURES[@]} -gt 0 ]]; then
40+
echo "Testing $PACKAGE with required features only ($required_features_str)..."
41+
(set -x; cargo clippy -p "$PACKAGE" --all-targets --no-default-features --features "$required_features_str" --profile="$PROFILE" -- -D warnings)
42+
else
43+
echo "Testing $PACKAGE with no features..."
44+
(set -x; cargo clippy -p "$PACKAGE" --all-targets --no-default-features --profile="$PROFILE" -- -D warnings)
45+
fi
46+
47+
echo "Testing $PACKAGE with default features..."
48+
(set -x; cargo clippy -p "$PACKAGE" --all-targets --profile="$PROFILE" -- -D warnings)
49+
50+
# Test each additional feature individually
51+
for feature in $features; do
52+
if [[ ${#REQUIRED_FEATURES[@]} -gt 0 ]]; then
53+
echo "Testing $PACKAGE with feature: $required_features_str,$feature"
54+
(set -x; cargo clippy -p "$PACKAGE" --all-targets --no-default-features --features "$required_features_str,$feature" --profile="$PROFILE" -- -D warnings)
55+
else
56+
echo "Testing $PACKAGE with feature: $feature"
57+
(set -x; cargo clippy -p "$PACKAGE" --all-targets --no-default-features --features "$feature" --profile="$PROFILE" -- -D warnings)
58+
fi
59+
done
60+
61+
# Test all features together
62+
if [[ -n "$features" ]]; then
63+
all_features=$(echo $features | tr '\n' ',' | sed 's/,$//')
64+
if [[ ${#REQUIRED_FEATURES[@]} -gt 0 ]]; then
65+
echo "Testing $PACKAGE with all features: $required_features_str,$all_features"
66+
(set -x; cargo clippy -p "$PACKAGE" --all-targets --no-default-features --features "$required_features_str,$all_features" --profile="$PROFILE" -- -D warnings)
67+
else
68+
echo "Testing $PACKAGE with all features: $all_features"
69+
(set -x; cargo clippy -p "$PACKAGE" --all-targets --no-default-features --features "$all_features" --profile="$PROFILE" -- -D warnings)
70+
fi
71+
fi

src/hyperlight_guest/src/guest_handle/handle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use hyperlight_common::mem::HyperlightPEB;
2525
///
2626
/// Guests are expected to initialize this and store it. For example, you
2727
/// could store it in a global variable.
28-
#[derive(Debug, Clone, Copy)]
28+
#[derive(Debug, Clone, Copy, Default)]
2929
pub struct GuestHandle {
3030
peb: Option<*mut HyperlightPEB>,
3131
}

src/hyperlight_guest/src/guest_handle/host_comm.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ impl GuestHandle {
4141
let user_memory_region_size = unsafe { (*peb_ptr).init_data.size };
4242

4343
if num > user_memory_region_size {
44-
return Err(HyperlightGuestError::new(
44+
Err(HyperlightGuestError::new(
4545
ErrorCode::GuestError,
4646
format!(
4747
"Requested {} bytes from user memory, but only {} bytes are available",
4848
num, user_memory_region_size
4949
),
50-
));
50+
))
5151
} else {
5252
let user_memory_region_slice =
5353
unsafe { core::slice::from_raw_parts(user_memory_region_ptr, num as usize) };
@@ -142,7 +142,7 @@ impl GuestHandle {
142142
/// Write an error to the shared output data buffer.
143143
pub fn write_error(&self, error_code: ErrorCode, message: Option<&str>) {
144144
let guest_error: GuestError = GuestError::new(
145-
error_code.clone(),
145+
error_code,
146146
message.map_or("".to_string(), |m| m.to_string()),
147147
);
148148
let guest_error_buffer: Vec<u8> = (&guest_error)

src/hyperlight_guest_bin/src/exceptions/handler.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode;
2121
use hyperlight_common::outb::Exception;
2222
use hyperlight_guest::exit::abort_with_code_and_message;
2323

24-
use crate::paging;
25-
2624
/// See AMD64 Architecture Programmer's Manual, Volume 2
2725
/// §8.9.3 Interrupt Stack Frame, pp. 283--284
2826
/// Figure 8-14: Long-Mode Stack After Interrupt---Same Privilege,
@@ -56,9 +54,9 @@ const _: () = assert!(size_of::<Context>() == 152 + 512);
5654

5755
// TODO: This will eventually need to end up in a per-thread context,
5856
// when there are threads.
59-
pub static handlers: [core::sync::atomic::AtomicU64; 31] =
57+
pub static HANDLERS: [core::sync::atomic::AtomicU64; 31] =
6058
[const { core::sync::atomic::AtomicU64::new(0) }; 31];
61-
type handler_t = fn(n: u64, info: *mut ExceptionInfo, ctx: *mut Context, pf_addr: u64) -> bool;
59+
pub type HandlerT = fn(n: u64, info: *mut ExceptionInfo, ctx: *mut Context, pf_addr: u64) -> bool;
6260

6361
/// Exception handler
6462
#[unsafe(no_mangle)]
@@ -89,15 +87,12 @@ pub extern "C" fn hl_exception_handler(
8987
// vectors (0-31)
9088
if exception_number < 31 {
9189
let handler =
92-
handlers[exception_number as usize].load(core::sync::atomic::Ordering::Acquire);
90+
HANDLERS[exception_number as usize].load(core::sync::atomic::Ordering::Acquire);
9391
if handler != 0
9492
&& unsafe {
95-
core::mem::transmute::<_, handler_t>(handler)(
96-
exception_number,
97-
exn_info,
98-
ctx,
99-
page_fault_address,
100-
)
93+
core::mem::transmute::<u64, fn(u64, *mut ExceptionInfo, *mut Context, u64) -> bool>(
94+
handler,
95+
)(exception_number, exn_info, ctx, page_fault_address)
10196
}
10297
{
10398
return;

src/hyperlight_guest_bin/src/exceptions/idtr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub(crate) unsafe fn load_idt() {
4949

5050
// Use &raw mut to get a mutable raw pointer, then dereference it
5151
// this is to avoid the clippy warning "shared reference to mutable static"
52+
#[allow(clippy::deref_addrof)]
5253
let idtr = &mut *(&raw mut IDTR);
5354
idtr.init(expected_base, idt_size as u16);
5455
idtr.load();

src/hyperlight_guest_bin/src/guest_function/call.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub(crate) fn call_guest_function(function_call: FunctionCall) -> Result<Vec<u8>
4242
// Find the function definition for the function call.
4343
// Use &raw const to get an immutable reference to the static HashMap
4444
// this is to avoid the clippy warning "shared reference to mutable static"
45+
#[allow(clippy::deref_addrof)]
4546
if let Some(registered_function_definition) =
4647
unsafe { (*(&raw const REGISTERED_GUEST_FUNCTIONS)).get(&function_call.function_name) }
4748
{
@@ -90,7 +91,7 @@ fn internal_dispatch_function() -> Result<()> {
9091
.expect("Function call deserialization failed");
9192

9293
let result_vec = call_guest_function(function_call).inspect_err(|e| {
93-
handle.write_error(e.kind.clone(), Some(e.message.as_str()));
94+
handle.write_error(e.kind, Some(e.message.as_str()));
9495
})?;
9596

9697
handle.push_shared_output_data(result_vec)

src/hyperlight_guest_bin/src/host_comm.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ pub fn print_output_with_host_print(function_call: &FunctionCall) -> Result<Vec<
101101
pub unsafe extern "C" fn _putchar(c: c_char) {
102102
let handle = unsafe { GUEST_HANDLE };
103103
let char = c as u8;
104-
let mut message_buffer = unsafe { &mut MESSAGE_BUFFER };
104+
let message_buffer = unsafe { &mut MESSAGE_BUFFER };
105105

106106
// Extend buffer capacity if it's empty (like `with_capacity` in lazy_static).
107107
// TODO: replace above Vec::new() with Vec::with_capacity once it's stable in const contexts.
@@ -113,12 +113,12 @@ pub unsafe extern "C" fn _putchar(c: c_char) {
113113

114114
if message_buffer.len() == BUFFER_SIZE || char == b'\0' {
115115
let str = if char == b'\0' {
116-
CStr::from_bytes_until_nul(&message_buffer)
116+
CStr::from_bytes_until_nul(message_buffer)
117117
.expect("No null byte in buffer")
118118
.to_string_lossy()
119119
.into_owned()
120120
} else {
121-
String::from_utf8(mem::take(&mut message_buffer))
121+
String::from_utf8(mem::take(message_buffer))
122122
.expect("Failed to convert buffer to string")
123123
};
124124

src/hyperlight_guest_bin/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ pub extern "C" fn entrypoint(peb_address: u64, seed: u64, ops: u64, max_log_leve
104104
#[allow(static_mut_refs)]
105105
let peb_ptr = GUEST_HANDLE.peb().unwrap();
106106

107-
let srand_seed = ((peb_address << 8 ^ seed >> 4) >> 32) as u32;
107+
let srand_seed = (((peb_address << 8) ^ (seed >> 4)) >> 32) as u32;
108108

109109
// Set the seed for the random number generator for C code using rand;
110110
srand(srand_seed);

0 commit comments

Comments
 (0)