Skip to content

Commit 4e81e3b

Browse files
authored
Merge branch 'main' into rawvecchallenge
2 parents c3ed50a + 02a7a8c commit 4e81e3b

File tree

447 files changed

+13017
-8248
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

447 files changed

+13017
-8248
lines changed

.github/workflows/kani-metrics.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ jobs:
2626
python-version: '3.x'
2727

2828
- name: Compute Kani Metrics
29-
run: ./scripts/run-kani.sh --run metrics --path ${{github.workspace}}
29+
run: |
30+
./scripts/run-kani.sh --run metrics --with-autoharness --path ${{github.workspace}}
31+
rm kani-list.json
3032
3133
- name: Create Pull Request
3234
uses: peter-evans/create-pull-request@v7

.github/workflows/kani.yml

Lines changed: 222 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,193 @@ jobs:
5353
- name: Run Kani Verification
5454
run: head/scripts/run-kani.sh --path ${{github.workspace}}/head
5555

56+
kani_autoharness:
57+
name: Verify std library using autoharness
58+
runs-on: ${{ matrix.os }}
59+
strategy:
60+
matrix:
61+
os: [ubuntu-latest, macos-latest]
62+
include:
63+
- os: ubuntu-latest
64+
base: ubuntu
65+
- os: macos-latest
66+
base: macos
67+
fail-fast: false
68+
69+
steps:
70+
# Step 1: Check out the repository
71+
- name: Checkout Repository
72+
uses: actions/checkout@v4
73+
with:
74+
submodules: true
75+
76+
# Step 2: Run Kani autoharness on the std library for selected functions.
77+
# Uses "--include-pattern" to make sure we do not try to run across all
78+
# possible functions as that may take a lot longer than expected. Instead,
79+
# explicitly list all functions (or prefixes thereof) the proofs of which
80+
# are known to pass.
81+
- name: Run Kani Verification
82+
run: |
83+
scripts/run-kani.sh --run autoharness --kani-args \
84+
--include-pattern alloc::layout::Layout::from_size_align \
85+
--include-pattern ascii::ascii_char::AsciiChar::from_u8 \
86+
--include-pattern char::convert::from_u32_unchecked \
87+
--include-pattern "num::nonzero::NonZero::<i8>::count_ones" \
88+
--include-pattern "num::nonzero::NonZero::<i16>::count_ones" \
89+
--include-pattern "num::nonzero::NonZero::<i32>::count_ones" \
90+
--include-pattern "num::nonzero::NonZero::<i64>::count_ones" \
91+
--include-pattern "num::nonzero::NonZero::<i128>::count_ones" \
92+
--include-pattern "num::nonzero::NonZero::<isize>::count_ones" \
93+
--include-pattern "num::nonzero::NonZero::<u8>::count_ones" \
94+
--include-pattern "num::nonzero::NonZero::<u16>::count_ones" \
95+
--include-pattern "num::nonzero::NonZero::<u32>::count_ones" \
96+
--include-pattern "num::nonzero::NonZero::<u64>::count_ones" \
97+
--include-pattern "num::nonzero::NonZero::<u128>::count_ones" \
98+
--include-pattern "num::nonzero::NonZero::<usize>::count_ones" \
99+
--include-pattern "num::nonzero::NonZero::<i8>::rotate_" \
100+
--include-pattern "num::nonzero::NonZero::<i16>::rotate_" \
101+
--include-pattern "num::nonzero::NonZero::<i32>::rotate_" \
102+
--include-pattern "num::nonzero::NonZero::<i64>::rotate_" \
103+
--include-pattern "num::nonzero::NonZero::<i128>::rotate_" \
104+
--include-pattern "num::nonzero::NonZero::<isize>::rotate_" \
105+
--include-pattern "num::nonzero::NonZero::<u8>::rotate_" \
106+
--include-pattern "num::nonzero::NonZero::<u16>::rotate_" \
107+
--include-pattern "num::nonzero::NonZero::<u32>::rotate_" \
108+
--include-pattern "num::nonzero::NonZero::<u64>::rotate_" \
109+
--include-pattern "num::nonzero::NonZero::<u128>::rotate_" \
110+
--include-pattern "num::nonzero::NonZero::<usize>::rotate_" \
111+
--include-pattern ptr::align_offset::mod_inv \
112+
--include-pattern ptr::alignment::Alignment::as_nonzero \
113+
--include-pattern ptr::alignment::Alignment::as_usize \
114+
--include-pattern ptr::alignment::Alignment::log2 \
115+
--include-pattern ptr::alignment::Alignment::mask \
116+
--include-pattern ptr::alignment::Alignment::new \
117+
--include-pattern ptr::alignment::Alignment::new_unchecked \
118+
--include-pattern time::Duration::from_micros \
119+
--include-pattern time::Duration::from_millis \
120+
--include-pattern time::Duration::from_nanos \
121+
--include-pattern time::Duration::from_secs \
122+
--exclude-pattern time::Duration::from_secs_f \
123+
--include-pattern unicode::unicode_data::conversions::to_ \
124+
--exclude-pattern ::precondition_check \
125+
--harness-timeout 10m \
126+
--default-unwind 1000 \
127+
--jobs=3 --output-format=terse | tee autoharness-verification.log
128+
gzip autoharness-verification.log
129+
130+
- name: Upload Autoharness Verification Log
131+
uses: actions/upload-artifact@v4
132+
with:
133+
name: ${{ matrix.os }}-autoharness-verification.log.gz
134+
path: autoharness-verification.log.gz
135+
if-no-files-found: error
136+
# Aggressively short retention: we don't really need these
137+
retention-days: 3
138+
139+
run_kani_metrics:
140+
name: Kani Metrics
141+
runs-on: ${{ matrix.os }}
142+
strategy:
143+
matrix:
144+
os: [ubuntu-latest, macos-latest]
145+
include:
146+
- os: ubuntu-latest
147+
base: ubuntu
148+
- os: macos-latest
149+
base: macos
150+
fail-fast: true
151+
152+
steps:
153+
# Step 1: Check out the repository
154+
- name: Checkout Repository
155+
uses: actions/checkout@v4
156+
with:
157+
submodules: true
158+
159+
# The Kani metrics collection uses a Python script (kani_std_analysis.py), so make sure Python is installed
160+
- name: Set up Python
161+
uses: actions/setup-python@v4
162+
with:
163+
python-version: '3.x'
164+
165+
# Step 2: Run list on the std library
166+
- name: Run Kani Metrics
167+
run: |
168+
scripts/run-kani.sh --run metrics --with-autoharness
169+
pushd /tmp/std_lib_analysis
170+
tar czf results.tar.gz results
171+
popd
172+
173+
- name: Upload kani-list.json
174+
uses: actions/upload-artifact@v4
175+
with:
176+
name: ${{ matrix.os }}-kani-list.json
177+
path: kani-list.json
178+
if-no-files-found: error
179+
# Aggressively short retention: we don't really need these
180+
retention-days: 3
181+
182+
- name: Upload scanner results
183+
uses: actions/upload-artifact@v4
184+
with:
185+
name: ${{ matrix.os }}-results.tar.gz
186+
path: /tmp/std_lib_analysis/results.tar.gz
187+
if-no-files-found: error
188+
# Aggressively short retention: we don't really need these
189+
retention-days: 3
190+
191+
run-log-analysis:
192+
name: Build JSON from logs
193+
needs: [run_kani_metrics, kani_autoharness]
194+
runs-on: ${{ matrix.os }}
195+
strategy:
196+
matrix:
197+
os: [ubuntu-latest, macos-latest]
198+
include:
199+
- os: ubuntu-latest
200+
base: ubuntu
201+
- os: macos-latest
202+
base: macos
203+
fail-fast: false
204+
205+
steps:
206+
- name: Checkout Repository
207+
uses: actions/checkout@v4
208+
with:
209+
submodules: false
210+
211+
- name: Download log
212+
uses: actions/download-artifact@v4
213+
with:
214+
name: ${{ matrix.os }}-autoharness-verification.log.gz
215+
216+
- name: Download kani-list.json
217+
uses: actions/download-artifact@v4
218+
with:
219+
name: ${{ matrix.os }}-kani-list.json
220+
221+
- name: Download scanner results
222+
uses: actions/download-artifact@v4
223+
with:
224+
name: ${{ matrix.os }}-results.tar.gz
225+
226+
- name: Run log parser
227+
run: |
228+
gunzip autoharness-verification.log.gz
229+
tar xzf results.tar.gz
230+
python3 scripts/kani-std-analysis/log_parser.py \
231+
--kani-list-file kani-list.json \
232+
--analysis-results-dir results/ \
233+
autoharness-verification.log \
234+
-o results.json
235+
236+
- name: Upload JSON
237+
uses: actions/upload-artifact@v4
238+
with:
239+
name: ${{ matrix.os }}-results.json
240+
path: results.json
241+
if-no-files-found: error
242+
56243
run-kani-list:
57244
name: Kani List
58245
runs-on: ubuntu-latest
@@ -66,8 +253,14 @@ jobs:
66253

67254
# Step 2: Run list on the std library
68255
- name: Run Kani List
69-
run: head/scripts/run-kani.sh --run list --path ${{github.workspace}}/head
70-
256+
run: |
257+
head/scripts/run-kani.sh --run list --with-autoharness --path ${{github.workspace}}/head
258+
# remove duplicate white space to reduce file size (GitHub permits at
259+
# most one 1MB)
260+
ls -l ${{github.workspace}}/head/kani-list.md
261+
perl -p -i -e 's/ +/ /g' ${{github.workspace}}/head/kani-list.md
262+
ls -l ${{github.workspace}}/head/kani-list.md
263+
71264
# Step 3: Add output to job summary
72265
- name: Add Kani List output to job summary
73266
uses: actions/github-script@v6
@@ -79,3 +272,30 @@ jobs:
79272
.addHeading('Kani List Output', 2)
80273
.addRaw(kaniOutput, false)
81274
.write();
275+
276+
run-autoharness-analyzer:
277+
name: Kani Autoharness Analyzer
278+
runs-on: ubuntu-latest
279+
steps:
280+
# Step 1: Check out the repository
281+
- name: Checkout Repository
282+
uses: actions/checkout@v4
283+
with:
284+
submodules: true
285+
286+
# Step 2: Run autoharness analyzer on the std library
287+
- name: Run Autoharness Analyzer
288+
run: scripts/run-kani.sh --run autoharness-analyzer
289+
290+
# Step 3: Add output to job summary
291+
- name: Add Autoharness Analyzer output to job summary
292+
run: |
293+
echo "# Autoharness Failure Summary" >> "$GITHUB_STEP_SUMMARY"
294+
echo "## Crate core, all functions" >> "$GITHUB_STEP_SUMMARY"
295+
cat autoharness_analyzer/core_autoharness_data.md >> "$GITHUB_STEP_SUMMARY"
296+
echo "## Crate core, unsafe functions" >> "$GITHUB_STEP_SUMMARY"
297+
cat autoharness_analyzer/core_autoharness_data.md >> "$GITHUB_STEP_SUMMARY"
298+
echo "## Crate std, all functions" >> "$GITHUB_STEP_SUMMARY"
299+
cat autoharness_analyzer/std_autoharness_data.md >> "$GITHUB_STEP_SUMMARY"
300+
echo "## Crate std, unsafe functions" >> "$GITHUB_STEP_SUMMARY"
301+
cat autoharness_analyzer/std_unsafe_autoharness_data.md >> "$GITHUB_STEP_SUMMARY"

.github/workflows/pr_approval.yml

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,21 @@ jobs:
7373
return;
7474
}
7575
76+
// Get the list of changed files
77+
const { data: changedFiles } = await github.rest.pulls.listFiles({
78+
owner,
79+
repo,
80+
pull_number,
81+
});
82+
83+
// Check if any files in doc/, library/ or verifast-proofs/ are modified
84+
const affectsDocs = changedFiles.some(file => file.filename.startsWith('doc/'));
85+
const affectsLibrary = changedFiles.some(file => file.filename.startsWith('library/'));
86+
const affectsVerifast = changedFiles.some(file => file.filename.startsWith('verifast-proofs/'));
87+
// Require two approvals iff one of the above folders are modified; otherwise, one is sufficient.
88+
const requiresTwoApprovals = affectsDocs || affectsLibrary || affectsVerifast;
89+
const requiredApprovals = requiresTwoApprovals ? 2 : 1;
90+
7691
// Get all reviews with pagination
7792
async function getAllReviews() {
7893
let allReviews = [];
@@ -113,23 +128,27 @@ jobs:
113128
.map(review => review.user.login)
114129
);
115130
116-
const requiredApprovals = 2;
117131
const committeeApprovers = Array.from(approvers)
118132
.filter(approver => requiredApprovers.includes(approver));
119133
const currentCountfromCommittee = committeeApprovers.length;
120134
121-
// Core logic that checks if the approvers are in the committee
122-
const conclusion = (currentCountfromCommittee >= 2) ? 'success' : 'failure';
135+
// Check if we have enough approvals
136+
const conclusion = (currentCountfromCommittee >= requiredApprovals) ? 'success' : 'failure';
123137
124138
console.log('PR Approval Status');
139+
console.log('Modified folders:');
140+
console.log(`- doc/: ${affectsDocs ? 'yes' : 'no'}`);
141+
console.log(`- library/: ${affectsLibrary ? 'yes' : 'no'}`);
142+
console.log(`- verifast-proofs/: ${affectsVerifast ? 'yes' : 'no'}`);
143+
console.log(`Required approvals from committee: ${requiredApprovals}`);
125144
console.log(`PR has ${approvers.size} total approvals and ${currentCountfromCommittee} required approvals from the committee.`);
126145
127146
console.log(`Committee Members: [${requiredApprovers.join(', ')}]`);
128147
console.log(`Committee Approvers: ${committeeApprovers.length === 0 ? 'NONE' : `[${committeeApprovers.join(', ')}]`}`);
129148
console.log(`All Approvers: ${approvers.size === 0 ? 'NONE' : `[${Array.from(approvers).join(', ')}]`}`);
130149
131150
if (conclusion === 'failure') {
132-
core.setFailed(`PR needs 2 approvals from committee members, but it has ${currentCountfromCommittee}`);
151+
core.setFailed(`PR needs ${requiredApprovals} approval${requiredApprovals > 1 ? 's' : ''} from committee members, but it has ${currentCountfromCommittee}`);
133152
} else {
134153
core.info('PR approval check passed successfully.');
135154
}

.github/workflows/update-subtree.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,14 @@ jobs:
126126
UPSTREAM_HEAD=$(git log --format=%H -n 1 rust-filtered/subtree/library)
127127
if [ "${UPSTREAM_HEAD}" = "${UPSTREAM_FROM}" ]; then
128128
echo "Nothing to do, ${UPSTREAM_FROM} matches ${UPSTREAM_HEAD} (${SUBTREE_HEAD_MSG})"
129-
echo "MERGE_CONFLICTS=noop" >> $GITHUB_ENV
129+
echo "SUBTREE_PR_REQUIRED=no" >> $GITHUB_ENV
130130
else
131131
git branch --set-upstream-to=origin/subtree/library
132-
echo "MERGE_CONFLICTS=maybe" >> $GITHUB_ENV
132+
echo "SUBTREE_PR_REQUIRED=yes" >> $GITHUB_ENV
133133
fi
134134
135135
- name: Create Pull Request to update subtree/library
136-
if: ${{ env.MERGE_CONFLICTS != 'noop' && env.SUBTREE_PR_EXISTS == 'no' }}
136+
if: ${{ env.SUBTREE_PR_REQUIRED == 'yes' && env.SUBTREE_PR_EXISTS == 'no' }}
137137
uses: peter-evans/create-pull-request@v7
138138
with:
139139
title: 'Update subtree/library to ${{ env.NEXT_TOOLCHAIN_DATE }}'
@@ -151,7 +151,7 @@ jobs:
151151
path: verify-rust-std
152152

153153
- name: Merge subtree/library changes
154-
if: ${{ env.MERGE_CONFLICTS != 'noop' && env.MERGE_PR_EXISTS == 'no' }}
154+
if: ${{ env.CURRENT_TOOLCHAIN_DATE != env.NEXT_TOOLCHAIN_DATE && env.MERGE_PR_EXISTS == 'no' }}
155155
run: |
156156
cd verify-rust-std
157157
# create-pull-request resets branches locally, implying that
@@ -160,7 +160,9 @@ jobs:
160160
git checkout -t -b subtree/library origin/update-subtree/library
161161
else
162162
git checkout subtree/library
163-
git reset --hard origin/update-subtree/library
163+
if [ "${SUBTREE_PR_REQUIRED}" = "yes" ]; then
164+
git reset --hard origin/update-subtree/library
165+
fi
164166
fi
165167
git checkout main
166168

.github/workflows/verifast-negative.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@ jobs:
4242
run: |
4343
export PATH=~/verifast-25.02/bin:$PATH
4444
cd verifast-proofs
45-
mysh check-verifast-proofs-negative.mysh
45+
bash check-verifast-proofs-negative.sh

.github/workflows/verifast.yml

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,29 @@ jobs:
3939
run: |
4040
export PATH=~/verifast-25.02/bin:$PATH
4141
cd verifast-proofs
42-
mysh check-verifast-proofs.mysh
42+
bash check-verifast-proofs.sh
43+
44+
notify-btj:
45+
name: Notify @btj
46+
runs-on: ubuntu-latest
47+
needs: check-verifast-on-std
48+
if: failure()
49+
permissions:
50+
id-token: write
51+
52+
steps:
53+
- name: Get GitHub OIDC token
54+
id: get_token
55+
uses: actions/github-script@v7
56+
with:
57+
script: |
58+
const audience = 'notify-bart-jacobs';
59+
return await core.getIDToken(audience);
60+
result-encoding: string
61+
62+
- name: Call notification endpoint
63+
run: |
64+
curl -X POST "https://verify-rust-std-verifast-monitor.bart-jacobs.workers.dev/" \
65+
-H "Authorization: Bearer ${{ steps.get_token.outputs.result }}" \
66+
-H "Content-Type: application/json" \
67+
-d '{}'

doc/src/SUMMARY.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,8 @@
3131
- [15: Contracts and Tests for SIMD Intrinsics](./challenges/0015-intrinsics-simd.md)
3232
- [16: Verify the safety of Iterator functions](./challenges/0016-iter.md)
3333
- [17: Verify the safety of slice functions](./challenges/0017-slice.md)
34-
- [18: Verify the safety of slice iter functions](./challenges/0018-slice-iter-pt1.md)
34+
- [18: Verify the safety of slice iter functions](./challenges/0018-slice-iter.md)
3535
- [19: Safety of `RawVec`](./challenges/0019-rawvec.md)
36+
- [20: Verify the safety of char-related functions in str::pattern](./challenges/0020-str-pattern-pt1.md)
37+
- [21: Verify the safety of substring-related functions in str::pattern](./challenges/0021-str-pattern-pt2.md)
38+
- [22: Verify the safety of str iter functions](./challenges/0022-str-iter.md)

0 commit comments

Comments
 (0)