mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
commit
b12ff66f2c
@ -5406,9 +5406,9 @@ checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ui_test"
|
name = "ui_test"
|
||||||
version = "0.11.6"
|
version = "0.11.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24a2e70adc9d18b9b4dd80ea57aeec447103c6fbb354a07c080adad451c645e1"
|
checksum = "c21899b59f53717dfad29e4f46e5b21a200a1b6888ab86532a07cfc8b48dd78c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr",
|
"bstr",
|
||||||
"cargo-platform",
|
"cargo-platform",
|
||||||
|
47
src/tools/miri/.github/workflows/ci.yml
vendored
47
src/tools/miri/.github/workflows/ci.yml
vendored
@ -15,6 +15,10 @@ on:
|
|||||||
env:
|
env:
|
||||||
CARGO_UNSTABLE_SPARSE_REGISTRY: 'true'
|
CARGO_UNSTABLE_SPARSE_REGISTRY: 'true'
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
@ -59,12 +63,9 @@ jobs:
|
|||||||
|
|
||||||
- name: Install rustup-toolchain-install-master
|
- name: Install rustup-toolchain-install-master
|
||||||
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
|
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
|
||||||
shell: bash
|
run: cargo install -f rustup-toolchain-install-master
|
||||||
run: |
|
|
||||||
cargo install -f rustup-toolchain-install-master
|
|
||||||
|
|
||||||
- name: Install "master" toolchain
|
- name: Install "master" toolchain
|
||||||
shell: bash
|
|
||||||
run: |
|
run: |
|
||||||
if [[ ${{ github.event_name }} == 'schedule' ]]; then
|
if [[ ${{ github.event_name }} == 'schedule' ]]; then
|
||||||
echo "Building against latest rustc git version"
|
echo "Building against latest rustc git version"
|
||||||
@ -79,7 +80,7 @@ jobs:
|
|||||||
cargo -V
|
cargo -V
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: bash ./ci.sh
|
run: ./ci.sh
|
||||||
|
|
||||||
style:
|
style:
|
||||||
name: style checks
|
name: style checks
|
||||||
@ -111,14 +112,10 @@ jobs:
|
|||||||
|
|
||||||
- name: Install rustup-toolchain-install-master
|
- name: Install rustup-toolchain-install-master
|
||||||
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
|
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
|
||||||
shell: bash
|
run: cargo install -f rustup-toolchain-install-master
|
||||||
run: |
|
|
||||||
cargo install -f rustup-toolchain-install-master
|
|
||||||
|
|
||||||
- name: Install "master" toolchain
|
- name: Install "master" toolchain
|
||||||
shell: bash
|
run: ./miri toolchain
|
||||||
run: |
|
|
||||||
./miri toolchain
|
|
||||||
|
|
||||||
- name: Show Rust version
|
- name: Show Rust version
|
||||||
run: |
|
run: |
|
||||||
@ -138,7 +135,6 @@ jobs:
|
|||||||
# workflow is successful listening to webhooks only.
|
# workflow is successful listening to webhooks only.
|
||||||
#
|
#
|
||||||
# ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
|
# ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
|
||||||
# (`fmt` is deliberately not listed, we want bors to ignore it.)
|
|
||||||
end-success:
|
end-success:
|
||||||
name: bors build finished
|
name: bors build finished
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -166,12 +162,12 @@ jobs:
|
|||||||
- name: Install zulip-send
|
- name: Install zulip-send
|
||||||
run: pip3 install zulip
|
run: pip3 install zulip
|
||||||
- name: Send Zulip notification
|
- name: Send Zulip notification
|
||||||
shell: bash
|
|
||||||
env:
|
env:
|
||||||
ZULIP_BOT_EMAIL: ${{ secrets.ZULIP_BOT_EMAIL }}
|
ZULIP_BOT_EMAIL: ${{ secrets.ZULIP_BOT_EMAIL }}
|
||||||
ZULIP_API_TOKEN: ${{ secrets.ZULIP_API_TOKEN }}
|
ZULIP_API_TOKEN: ${{ secrets.ZULIP_API_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
~/.local/bin/zulip-send --stream miri --subject "Cron Job Failure (miri, $(date -u +%Y-%m))" \
|
~/.local/bin/zulip-send --user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com \
|
||||||
|
--stream miri --subject "Cron Job Failure (miri, $(date -u +%Y-%m))" \
|
||||||
--message 'Dear @*T-miri*,
|
--message 'Dear @*T-miri*,
|
||||||
|
|
||||||
It would appear that the [Miri cron job build]('"https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"') failed.
|
It would appear that the [Miri cron job build]('"https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"') failed.
|
||||||
@ -183,9 +179,12 @@ jobs:
|
|||||||
|
|
||||||
Thanks in advance!
|
Thanks in advance!
|
||||||
Sincerely,
|
Sincerely,
|
||||||
The Miri Cronjobs Bot' \
|
The Miri Cronjobs Bot'
|
||||||
--user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com
|
|
||||||
# Attempt to auto-sync with rustc
|
# Attempt to auto-sync with rustc
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 256 # get a bit more of the history
|
||||||
- name: install josh-proxy
|
- name: install josh-proxy
|
||||||
run: cargo +stable install josh-proxy --git https://github.com/josh-project/josh --tag r22.12.06
|
run: cargo +stable install josh-proxy --git https://github.com/josh-project/josh --tag r22.12.06
|
||||||
- name: start josh-proxy
|
- name: start josh-proxy
|
||||||
@ -196,16 +195,24 @@ jobs:
|
|||||||
git config --global user.email 'miri@cron.bot'
|
git config --global user.email 'miri@cron.bot'
|
||||||
- name: get changes from rustc
|
- name: get changes from rustc
|
||||||
run: ./miri rustc-pull
|
run: ./miri rustc-pull
|
||||||
|
- name: Install rustup-toolchain-install-master
|
||||||
|
run: cargo install -f rustup-toolchain-install-master
|
||||||
- name: format changes (if any)
|
- name: format changes (if any)
|
||||||
run: |
|
run: |
|
||||||
./miri toolchain
|
./miri toolchain
|
||||||
./miri fmt --check || (./miri fmt && git commit -am "fmt")
|
./miri fmt --check || (./miri fmt && git commit -am "fmt")
|
||||||
- name: Push changes to a branch
|
- name: Push changes to a branch
|
||||||
run: |
|
run: |
|
||||||
git switch -c "rustup$(date -u +%Y-%m)"
|
BRANCH="rustup$(date -u +%Y-%m-%d)"
|
||||||
git push
|
git switch -c $BRANCH
|
||||||
|
git push -u origin $BRANCH
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
run: gh pr create -B master --title 'Automatic sync from rustc' --body ''
|
run: |
|
||||||
|
PR=$(gh pr create -B master --title 'Automatic sync from rustc' --body '')
|
||||||
|
~/.local/bin/zulip-send --user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com \
|
||||||
|
--stream miri --subject "Cron Job Failure (miri, $(date -u +%Y-%m))" \
|
||||||
|
--message "A PR doing a rustc-pull [has been automatically created]($PR) for your convenience."
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
ZULIP_BOT_EMAIL: ${{ secrets.ZULIP_BOT_EMAIL }}
|
||||||
|
ZULIP_API_TOKEN: ${{ secrets.ZULIP_API_TOKEN }}
|
||||||
|
@ -842,9 +842,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ui_test"
|
name = "ui_test"
|
||||||
version = "0.11.6"
|
version = "0.11.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24a2e70adc9d18b9b4dd80ea57aeec447103c6fbb354a07c080adad451c645e1"
|
checksum = "c21899b59f53717dfad29e4f46e5b21a200a1b6888ab86532a07cfc8b48dd78c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bstr",
|
"bstr",
|
||||||
"cargo-platform",
|
"cargo-platform",
|
||||||
|
@ -36,7 +36,7 @@ libloading = "0.7"
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
colored = "2"
|
colored = "2"
|
||||||
ui_test = "0.11.6"
|
ui_test = "0.11.7"
|
||||||
rustc_version = "0.4"
|
rustc_version = "0.4"
|
||||||
# Features chosen to match those required by env_logger, to avoid rebuilds
|
# Features chosen to match those required by env_logger, to avoid rebuilds
|
||||||
regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] }
|
regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] }
|
||||||
|
@ -80,7 +80,11 @@ fn main() {
|
|||||||
match first.as_str() {
|
match first.as_str() {
|
||||||
"miri" => phase_cargo_miri(args),
|
"miri" => phase_cargo_miri(args),
|
||||||
"runner" => phase_runner(args, RunnerPhase::Cargo),
|
"runner" => phase_runner(args, RunnerPhase::Cargo),
|
||||||
arg if arg == env::var("RUSTC").unwrap() => {
|
arg if arg == env::var("RUSTC").unwrap_or_else(|_| {
|
||||||
|
show_error!(
|
||||||
|
"`cargo-miri` called without RUSTC set; please only invoke this binary through `cargo miri`"
|
||||||
|
)
|
||||||
|
}) => {
|
||||||
// If the first arg is equal to the RUSTC env variable (which should be set at this
|
// If the first arg is equal to the RUSTC env variable (which should be set at this
|
||||||
// point), then we need to behave as rustc. This is the somewhat counter-intuitive
|
// point), then we need to behave as rustc. This is the somewhat counter-intuitive
|
||||||
// behavior of having both RUSTC and RUSTC_WRAPPER set
|
// behavior of having both RUSTC and RUSTC_WRAPPER set
|
||||||
|
@ -82,7 +82,7 @@ pub enum MiriCommand {
|
|||||||
pub fn escape_for_toml(s: &str) -> String {
|
pub fn escape_for_toml(s: &str) -> String {
|
||||||
// We want to surround this string in quotes `"`. So we first escape all quotes,
|
// We want to surround this string in quotes `"`. So we first escape all quotes,
|
||||||
// and also all backslashes (that are used to escape quotes).
|
// and also all backslashes (that are used to escape quotes).
|
||||||
let s = s.replace('\\', r#"\\"#).replace('"', r#"\""#);
|
let s = s.replace('\\', r"\\").replace('"', r#"\""#);
|
||||||
format!("\"{s}\"")
|
format!("\"{s}\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ pub fn exec(mut cmd: Command) -> ! {
|
|||||||
{
|
{
|
||||||
use std::os::unix::process::CommandExt;
|
use std::os::unix::process::CommandExt;
|
||||||
let error = cmd.exec();
|
let error = cmd.exec();
|
||||||
Err(error).expect("failed to run command")
|
panic!("failed to run command: {error}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ rustc-pull)
|
|||||||
git commit rust-version -m "Preparing for merge from rustc" || (echo "FAILED to commit rust-version file, something went wrong"; exit 1)
|
git commit rust-version -m "Preparing for merge from rustc" || (echo "FAILED to commit rust-version file, something went wrong"; exit 1)
|
||||||
# Fetch given rustc commit and note down which one that was
|
# Fetch given rustc commit and note down which one that was
|
||||||
git fetch http://localhost:8000/rust-lang/rust.git@$FETCH_COMMIT$JOSH_FILTER.git || (echo "FAILED to fetch new commits, something went wrong"; exit 1)
|
git fetch http://localhost:8000/rust-lang/rust.git@$FETCH_COMMIT$JOSH_FILTER.git || (echo "FAILED to fetch new commits, something went wrong"; exit 1)
|
||||||
git merge FETCH_HEAD --no-ff -m "Merge from rustc" || (echo "FAILED to merge new commits, something went wrong"; exit 1)
|
git merge FETCH_HEAD --no-ff -m "Merge from rustc" || (echo "FAILED to merge new commits ($(git rev-parse FETCH_HEAD)), something went wrong"; exit 1)
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
rustc-push)
|
rustc-push)
|
||||||
@ -325,6 +325,7 @@ run|run-dep)
|
|||||||
MIRIFLAGS="$MIRIFLAGS --target $MIRI_TEST_TARGET"
|
MIRIFLAGS="$MIRIFLAGS --target $MIRI_TEST_TARGET"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
CARGO="$CARGO --quiet"
|
||||||
# First build and get a sysroot.
|
# First build and get a sysroot.
|
||||||
$CARGO build $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/Cargo.toml
|
$CARGO build $CARGO_EXTRA_FLAGS --manifest-path "$MIRIDIR"/Cargo.toml
|
||||||
find_sysroot
|
find_sysroot
|
||||||
|
@ -1 +1 @@
|
|||||||
75726cae37317c7262b69d3e9fd11a3496a88d04
|
d4096e0412ac5de785d739a0aa2b1c1c7b9d3b7d
|
||||||
|
@ -67,7 +67,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
|
|||||||
if tcx.sess.compile_status().is_err() {
|
if tcx.sess.compile_status().is_err() {
|
||||||
tcx.sess.fatal("miri cannot be run on programs that fail compilation");
|
tcx.sess.fatal("miri cannot be run on programs that fail compilation");
|
||||||
}
|
}
|
||||||
;
|
|
||||||
init_late_loggers(handler, tcx);
|
init_late_loggers(handler, tcx);
|
||||||
if !tcx.sess.crate_types().contains(&CrateType::Executable) {
|
if !tcx.sess.crate_types().contains(&CrateType::Executable) {
|
||||||
tcx.sess.fatal("miri only makes sense on bin crates");
|
tcx.sess.fatal("miri only makes sense on bin crates");
|
||||||
|
@ -221,7 +221,10 @@ impl AllocHistory {
|
|||||||
impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {
|
impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {
|
||||||
pub fn start_grant(&mut self, perm: Permission) {
|
pub fn start_grant(&mut self, perm: Permission) {
|
||||||
let Operation::Retag(op) = &mut self.operation else {
|
let Operation::Retag(op) = &mut self.operation else {
|
||||||
unreachable!("start_grant must only be called during a retag, this is: {:?}", self.operation)
|
unreachable!(
|
||||||
|
"start_grant must only be called during a retag, this is: {:?}",
|
||||||
|
self.operation
|
||||||
|
)
|
||||||
};
|
};
|
||||||
op.permission = Some(perm);
|
op.permission = Some(perm);
|
||||||
|
|
||||||
@ -286,7 +289,8 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {
|
|||||||
tag: BorTag,
|
tag: BorTag,
|
||||||
protector_tag: Option<BorTag>,
|
protector_tag: Option<BorTag>,
|
||||||
) -> Option<TagHistory> {
|
) -> Option<TagHistory> {
|
||||||
let Some(created) = self.history
|
let Some(created) = self
|
||||||
|
.history
|
||||||
.creations
|
.creations
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
@ -315,18 +319,23 @@ impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}).or_else(|| {
|
})
|
||||||
|
.or_else(|| {
|
||||||
// If we didn't find a retag that created this tag, it might be the base tag of
|
// If we didn't find a retag that created this tag, it might be the base tag of
|
||||||
// this allocation.
|
// this allocation.
|
||||||
if self.history.base.0.tag() == tag {
|
if self.history.base.0.tag() == tag {
|
||||||
Some((
|
Some((
|
||||||
format!("{tag:?} was created here, as the base tag for {:?}", self.history.id),
|
format!(
|
||||||
self.history.base.1.data()
|
"{tag:?} was created here, as the base tag for {:?}",
|
||||||
|
self.history.id
|
||||||
|
),
|
||||||
|
self.history.base.1.data(),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}) else {
|
})
|
||||||
|
else {
|
||||||
// But if we don't have a creation event, this is related to a wildcard, and there
|
// But if we don't have a creation event, this is related to a wildcard, and there
|
||||||
// is really nothing we can do to help.
|
// is really nothing we can do to help.
|
||||||
return None;
|
return None;
|
||||||
|
@ -430,12 +430,15 @@ impl<'tcx> Stack {
|
|||||||
.find_granting(AccessKind::Write, derived_from, exposed_tags)
|
.find_granting(AccessKind::Write, derived_from, exposed_tags)
|
||||||
.map_err(|()| dcx.grant_error(self))?;
|
.map_err(|()| dcx.grant_error(self))?;
|
||||||
|
|
||||||
let (Some(granting_idx), ProvenanceExtra::Concrete(_)) = (granting_idx, derived_from) else {
|
let (Some(granting_idx), ProvenanceExtra::Concrete(_)) = (granting_idx, derived_from)
|
||||||
|
else {
|
||||||
// The parent is a wildcard pointer or matched the unknown bottom.
|
// The parent is a wildcard pointer or matched the unknown bottom.
|
||||||
// This is approximate. Nobody knows what happened, so forget everything.
|
// This is approximate. Nobody knows what happened, so forget everything.
|
||||||
// The new thing is SRW anyway, so we cannot push it "on top of the unknown part"
|
// The new thing is SRW anyway, so we cannot push it "on top of the unknown part"
|
||||||
// (for all we know, it might join an SRW group inside the unknown).
|
// (for all we know, it might join an SRW group inside the unknown).
|
||||||
trace!("reborrow: forgetting stack entirely due to SharedReadWrite reborrow from wildcard or unknown");
|
trace!(
|
||||||
|
"reborrow: forgetting stack entirely due to SharedReadWrite reborrow from wildcard or unknown"
|
||||||
|
);
|
||||||
self.set_unknown_bottom(global.next_ptr_tag);
|
self.set_unknown_bottom(global.next_ptr_tag);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
@ -196,8 +196,8 @@ impl<'tcx> Stack {
|
|||||||
let ProvenanceExtra::Concrete(tag) = tag else {
|
let ProvenanceExtra::Concrete(tag) = tag else {
|
||||||
// Handle the wildcard case.
|
// Handle the wildcard case.
|
||||||
// Go search the stack for an exposed tag.
|
// Go search the stack for an exposed tag.
|
||||||
if let Some(idx) =
|
if let Some(idx) = self
|
||||||
self.borrows
|
.borrows
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate() // we also need to know *where* in the stack
|
.enumerate() // we also need to know *where* in the stack
|
||||||
.rev() // search top-to-bottom
|
.rev() // search top-to-bottom
|
||||||
|
@ -570,9 +570,13 @@ impl DisplayRepr {
|
|||||||
extraction_aux(tree, tree.root, show_unnamed, &mut v);
|
extraction_aux(tree, tree.root, show_unnamed, &mut v);
|
||||||
let Some(root) = v.pop() else {
|
let Some(root) = v.pop() else {
|
||||||
if show_unnamed {
|
if show_unnamed {
|
||||||
unreachable!("This allocation contains no tags, not even a root. This should not happen.");
|
unreachable!(
|
||||||
|
"This allocation contains no tags, not even a root. This should not happen."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
eprintln!("This allocation does not contain named tags. Use `miri_print_borrow_state(_, true)` to also print unnamed tags.");
|
eprintln!(
|
||||||
|
"This allocation does not contain named tags. Use `miri_print_borrow_state(_, true)` to also print unnamed tags."
|
||||||
|
);
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
assert!(v.is_empty());
|
assert!(v.is_empty());
|
||||||
|
@ -256,7 +256,9 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
|
|||||||
ptr_size.bytes()
|
ptr_size.bytes()
|
||||||
);
|
);
|
||||||
|
|
||||||
let Some(new_perm) = new_perm else { return Ok(Some((alloc_id, orig_tag))); };
|
let Some(new_perm) = new_perm else {
|
||||||
|
return Ok(Some((alloc_id, orig_tag)));
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(protect) = new_perm.protector {
|
if let Some(protect) = new_perm.protector {
|
||||||
// We register the protection in two different places.
|
// We register the protection in two different places.
|
||||||
|
@ -313,9 +313,11 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
|||||||
argvs.push(arg_place.to_ref(&ecx));
|
argvs.push(arg_place.to_ref(&ecx));
|
||||||
}
|
}
|
||||||
// Make an array with all these pointers, in the Miri memory.
|
// Make an array with all these pointers, in the Miri memory.
|
||||||
let argvs_layout = ecx.layout_of(
|
let argvs_layout = ecx.layout_of(Ty::new_array(
|
||||||
Ty::new_array(tcx,Ty::new_imm_ptr(tcx,tcx.types.u8), u64::try_from(argvs.len()).unwrap()),
|
tcx,
|
||||||
)?;
|
Ty::new_imm_ptr(tcx, tcx.types.u8),
|
||||||
|
u64::try_from(argvs.len()).unwrap(),
|
||||||
|
))?;
|
||||||
let argvs_place = ecx.allocate(argvs_layout, MiriMemoryKind::Machine.into())?;
|
let argvs_place = ecx.allocate(argvs_layout, MiriMemoryKind::Machine.into())?;
|
||||||
for (idx, arg) in argvs.into_iter().enumerate() {
|
for (idx, arg) in argvs.into_iter().enumerate() {
|
||||||
let place = ecx.mplace_field(&argvs_place, idx)?;
|
let place = ecx.mplace_field(&argvs_place, idx)?;
|
||||||
@ -345,7 +347,8 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
|||||||
// Construct a command string with all the arguments.
|
// Construct a command string with all the arguments.
|
||||||
let cmd_utf16: Vec<u16> = args_to_utf16_command_string(config.args.iter());
|
let cmd_utf16: Vec<u16> = args_to_utf16_command_string(config.args.iter());
|
||||||
|
|
||||||
let cmd_type = Ty::new_array(tcx,tcx.types.u16, u64::try_from(cmd_utf16.len()).unwrap());
|
let cmd_type =
|
||||||
|
Ty::new_array(tcx, tcx.types.u16, u64::try_from(cmd_utf16.len()).unwrap());
|
||||||
let cmd_place =
|
let cmd_place =
|
||||||
ecx.allocate(ecx.layout_of(cmd_type)?, MiriMemoryKind::Machine.into())?;
|
ecx.allocate(ecx.layout_of(cmd_type)?, MiriMemoryKind::Machine.into())?;
|
||||||
ecx.machine.cmd_line = Some(*cmd_place);
|
ecx.machine.cmd_line = Some(*cmd_place);
|
||||||
@ -366,7 +369,11 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
|||||||
|
|
||||||
match entry_type {
|
match entry_type {
|
||||||
EntryFnType::Main { .. } => {
|
EntryFnType::Main { .. } => {
|
||||||
let start_id = tcx.lang_items().start_fn().unwrap();
|
let start_id = tcx.lang_items().start_fn().unwrap_or_else(|| {
|
||||||
|
tcx.sess.fatal(
|
||||||
|
"could not find start function. Make sure the entry point is marked with `#[start]`."
|
||||||
|
);
|
||||||
|
});
|
||||||
let main_ret_ty = tcx.fn_sig(entry_id).no_bound_vars().unwrap().output();
|
let main_ret_ty = tcx.fn_sig(entry_id).no_bound_vars().unwrap().output();
|
||||||
let main_ret_ty = main_ret_ty.no_bound_vars().unwrap();
|
let main_ret_ty = main_ret_ty.no_bound_vars().unwrap();
|
||||||
let start_instance = ty::Instance::resolve(
|
let start_instance = ty::Instance::resolve(
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#![feature(local_key_cell_methods)]
|
#![feature(local_key_cell_methods)]
|
||||||
#![feature(round_ties_even)]
|
#![feature(round_ties_even)]
|
||||||
#![feature(os_str_bytes)]
|
#![feature(os_str_bytes)]
|
||||||
|
#![feature(lint_reasons)]
|
||||||
// Configure clippy and other lints
|
// Configure clippy and other lints
|
||||||
#![allow(
|
#![allow(
|
||||||
clippy::collapsible_else_if,
|
clippy::collapsible_else_if,
|
||||||
|
@ -313,10 +313,12 @@ pub struct PrimitiveLayouts<'tcx> {
|
|||||||
impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
|
impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
|
||||||
fn new(layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, &'tcx LayoutError<'tcx>> {
|
fn new(layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, &'tcx LayoutError<'tcx>> {
|
||||||
let tcx = layout_cx.tcx;
|
let tcx = layout_cx.tcx;
|
||||||
let mut_raw_ptr = Ty::new_ptr(tcx,TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Mut });
|
let mut_raw_ptr =
|
||||||
let const_raw_ptr = Ty::new_ptr(tcx,TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Not });
|
Ty::new_ptr(tcx, TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Mut });
|
||||||
|
let const_raw_ptr =
|
||||||
|
Ty::new_ptr(tcx, TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Not });
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
unit: layout_cx.layout_of(Ty::new_unit(tcx,))?,
|
unit: layout_cx.layout_of(Ty::new_unit(tcx))?,
|
||||||
i8: layout_cx.layout_of(tcx.types.i8)?,
|
i8: layout_cx.layout_of(tcx.types.i8)?,
|
||||||
i16: layout_cx.layout_of(tcx.types.i16)?,
|
i16: layout_cx.layout_of(tcx.types.i16)?,
|
||||||
i32: layout_cx.layout_of(tcx.types.i32)?,
|
i32: layout_cx.layout_of(tcx.types.i32)?,
|
||||||
|
@ -5,8 +5,8 @@ use std::mem;
|
|||||||
|
|
||||||
use rustc_const_eval::interpret::Pointer;
|
use rustc_const_eval::interpret::Pointer;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_middle::ty::Ty;
|
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_target::abi::Size;
|
use rustc_target::abi::Size;
|
||||||
|
|
||||||
use crate::helpers::target_os_is_unix;
|
use crate::helpers::target_os_is_unix;
|
||||||
@ -449,9 +449,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
vars.push(Pointer::null());
|
vars.push(Pointer::null());
|
||||||
// Make an array with all these pointers inside Miri.
|
// Make an array with all these pointers inside Miri.
|
||||||
let tcx = this.tcx;
|
let tcx = this.tcx;
|
||||||
let vars_layout = this.layout_of(
|
let vars_layout = this.layout_of(Ty::new_array(
|
||||||
Ty::new_array(tcx.tcx,this.machine.layouts.mut_raw_ptr.ty, u64::try_from(vars.len()).unwrap()),
|
tcx.tcx,
|
||||||
)?;
|
this.machine.layouts.mut_raw_ptr.ty,
|
||||||
|
u64::try_from(vars.len()).unwrap(),
|
||||||
|
))?;
|
||||||
let vars_place = this.allocate(vars_layout, MiriMemoryKind::Runtime.into())?;
|
let vars_place = this.allocate(vars_layout, MiriMemoryKind::Runtime.into())?;
|
||||||
for (idx, var) in vars.into_iter().enumerate() {
|
for (idx, var) in vars.into_iter().enumerate() {
|
||||||
let place = this.mplace_field(&vars_place, idx)?;
|
let place = this.mplace_field(&vars_place, idx)?;
|
||||||
|
@ -763,6 +763,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
let ptr_dest = this.read_pointer(ptr_dest)?;
|
let ptr_dest = this.read_pointer(ptr_dest)?;
|
||||||
let ptr_src = this.read_pointer(ptr_src)?;
|
let ptr_src = this.read_pointer(ptr_src)?;
|
||||||
let n = this.read_target_usize(n)?;
|
let n = this.read_target_usize(n)?;
|
||||||
|
|
||||||
|
// C requires that this must always be a valid pointer, even if `n` is zero, so we better check that.
|
||||||
|
// (This is more than Rust requires, so `mem_copy` is not sufficient.)
|
||||||
|
this.ptr_get_alloc_id(ptr_dest)?;
|
||||||
|
this.ptr_get_alloc_id(ptr_src)?;
|
||||||
|
|
||||||
this.mem_copy(
|
this.mem_copy(
|
||||||
ptr_src,
|
ptr_src,
|
||||||
Align::ONE,
|
Align::ONE,
|
||||||
|
@ -483,7 +483,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
|
|
||||||
// `index` is an array, not a SIMD type
|
// `index` is an array, not a SIMD type
|
||||||
let ty::Array(_, index_len) = index.layout.ty.kind() else {
|
let ty::Array(_, index_len) = index.layout.ty.kind() else {
|
||||||
span_bug!(this.cur_span(), "simd_shuffle index argument has non-array type {}", index.layout.ty)
|
span_bug!(
|
||||||
|
this.cur_span(),
|
||||||
|
"simd_shuffle index argument has non-array type {}",
|
||||||
|
index.layout.ty
|
||||||
|
)
|
||||||
};
|
};
|
||||||
let index_len = index_len.eval_target_usize(*this.tcx, this.param_env());
|
let index_len = index_len.eval_target_usize(*this.tcx, this.param_env());
|
||||||
|
|
||||||
@ -622,9 +626,7 @@ fn fmax_op<'tcx>(
|
|||||||
right: &ImmTy<'tcx, Provenance>,
|
right: &ImmTy<'tcx, Provenance>,
|
||||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||||
assert_eq!(left.layout.ty, right.layout.ty);
|
assert_eq!(left.layout.ty, right.layout.ty);
|
||||||
let ty::Float(float_ty) = left.layout.ty.kind() else {
|
let ty::Float(float_ty) = left.layout.ty.kind() else { bug!("fmax operand is not a float") };
|
||||||
bug!("fmax operand is not a float")
|
|
||||||
};
|
|
||||||
let left = left.to_scalar();
|
let left = left.to_scalar();
|
||||||
let right = right.to_scalar();
|
let right = right.to_scalar();
|
||||||
Ok(match float_ty {
|
Ok(match float_ty {
|
||||||
@ -638,9 +640,7 @@ fn fmin_op<'tcx>(
|
|||||||
right: &ImmTy<'tcx, Provenance>,
|
right: &ImmTy<'tcx, Provenance>,
|
||||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||||
assert_eq!(left.layout.ty, right.layout.ty);
|
assert_eq!(left.layout.ty, right.layout.ty);
|
||||||
let ty::Float(float_ty) = left.layout.ty.kind() else {
|
let ty::Float(float_ty) = left.layout.ty.kind() else { bug!("fmin operand is not a float") };
|
||||||
bug!("fmin operand is not a float")
|
|
||||||
};
|
|
||||||
let left = left.to_scalar();
|
let left = left.to_scalar();
|
||||||
let right = right.to_scalar();
|
let right = right.to_scalar();
|
||||||
Ok(match float_ty {
|
Ok(match float_ty {
|
||||||
|
@ -7,8 +7,8 @@ use std::os::unix::ffi::{OsStrExt, OsStringExt};
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use std::os::windows::ffi::{OsStrExt, OsStringExt};
|
use std::os::windows::ffi::{OsStrExt, OsStringExt};
|
||||||
|
|
||||||
use rustc_middle::ty::Ty;
|
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
|
use rustc_middle::ty::Ty;
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
@ -181,6 +181,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
/// `EFD_SEMAPHORE` - miri does not support semaphore-like semantics.
|
/// `EFD_SEMAPHORE` - miri does not support semaphore-like semantics.
|
||||||
///
|
///
|
||||||
/// <https://linux.die.net/man/2/eventfd>
|
/// <https://linux.die.net/man/2/eventfd>
|
||||||
|
#[expect(clippy::needless_if)]
|
||||||
fn eventfd(
|
fn eventfd(
|
||||||
&mut self,
|
&mut self,
|
||||||
val: &OpTy<'tcx, Provenance>,
|
val: &OpTy<'tcx, Provenance>,
|
||||||
|
@ -145,7 +145,8 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R
|
|||||||
// The files we're actually interested in (all `.rs` files).
|
// The files we're actually interested in (all `.rs` files).
|
||||||
|path| {
|
|path| {
|
||||||
path.extension().is_some_and(|ext| ext == "rs")
|
path.extension().is_some_and(|ext| ext == "rs")
|
||||||
&& (filters.is_empty() || filters.iter().any(|f| path.starts_with(f)))
|
&& (filters.is_empty()
|
||||||
|
|| filters.iter().any(|f| path.display().to_string().contains(f)))
|
||||||
},
|
},
|
||||||
// This could be used to overwrite the `Config` on a per-test basis.
|
// This could be used to overwrite the `Config` on a per-test basis.
|
||||||
|_, _| None,
|
|_, _| None,
|
||||||
@ -274,13 +275,13 @@ fn main() -> Result<()> {
|
|||||||
fn run_dep_mode(target: String, mut args: impl Iterator<Item = OsString>) -> Result<()> {
|
fn run_dep_mode(target: String, mut args: impl Iterator<Item = OsString>) -> Result<()> {
|
||||||
let path = args.next().expect("./miri run-dep must be followed by a file name");
|
let path = args.next().expect("./miri run-dep must be followed by a file name");
|
||||||
let mut config = test_config(&target, "", Mode::Yolo, /* with dependencies */ true);
|
let mut config = test_config(&target, "", Mode::Yolo, /* with dependencies */ true);
|
||||||
config.program.args.remove(0); // remove the `--error-format=json` argument
|
config.program.args.clear(); // We want to give the user full control over flags
|
||||||
config.program.args.push("--color".into());
|
config.build_dependencies_and_link_them()?;
|
||||||
config.program.args.push("always".into());
|
|
||||||
let mut cmd = ui_test::test_command(config, Path::new(&path))?;
|
let mut cmd = config.program.build(&config.out_dir);
|
||||||
// Separate the arguments to the `cargo miri` invocation from
|
|
||||||
// the arguments to the interpreted prog
|
cmd.arg(path);
|
||||||
cmd.arg("--");
|
|
||||||
cmd.args(args);
|
cmd.args(args);
|
||||||
if cmd.spawn()?.wait()?.success() { Ok(()) } else { std::process::exit(1) }
|
if cmd.spawn()?.wait()?.success() { Ok(()) } else { std::process::exit(1) }
|
||||||
}
|
}
|
||||||
|
10
src/tools/miri/tests/fail/shims/memchr_null.rs
Normal file
10
src/tools/miri/tests/fail/shims/memchr_null.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
//@ignore-target-windows: No libc on Windows
|
||||||
|
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
// null is explicitly called out as UB in the C docs.
|
||||||
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
libc::memchr(ptr::null(), 0, 0); //~ERROR: dangling
|
||||||
|
}
|
||||||
|
}
|
15
src/tools/miri/tests/fail/shims/memchr_null.stderr
Normal file
15
src/tools/miri/tests/fail/shims/memchr_null.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance)
|
||||||
|
--> $DIR/memchr_null.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | libc::memchr(ptr::null(), 0, 0);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
|
||||||
|
|
|
||||||
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||||
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
|
= note: BACKTRACE:
|
||||||
|
= note: inside `main` at $DIR/memchr_null.rs:LL:CC
|
||||||
|
|
||||||
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
10
src/tools/miri/tests/fail/shims/memcmp_null.rs
Normal file
10
src/tools/miri/tests/fail/shims/memcmp_null.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
//@ignore-target-windows: No libc on Windows
|
||||||
|
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
// null is explicitly called out as UB in the C docs.
|
||||||
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
libc::memcmp(ptr::null(), ptr::null(), 0); //~ERROR: dangling
|
||||||
|
}
|
||||||
|
}
|
15
src/tools/miri/tests/fail/shims/memcmp_null.stderr
Normal file
15
src/tools/miri/tests/fail/shims/memcmp_null.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance)
|
||||||
|
--> $DIR/memcmp_null.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | libc::memcmp(ptr::null(), ptr::null(), 0);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
|
||||||
|
|
|
||||||
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||||
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
|
= note: BACKTRACE:
|
||||||
|
= note: inside `main` at $DIR/memcmp_null.rs:LL:CC
|
||||||
|
|
||||||
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
12
src/tools/miri/tests/fail/shims/memcpy_zero.rs
Normal file
12
src/tools/miri/tests/fail/shims/memcpy_zero.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
//@ignore-target-windows: No libc on Windows
|
||||||
|
//@compile-flags: -Zmiri-permissive-provenance
|
||||||
|
// C's memcpy is 0 bytes is UB for some pointers that are allowed in Rust's `copy_nonoverlapping`.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let from = 42 as *const u8;
|
||||||
|
let to = 23 as *mut u8;
|
||||||
|
unsafe {
|
||||||
|
to.copy_from(from, 0); // this is fine
|
||||||
|
libc::memcpy(to.cast(), from.cast(), 0); //~ERROR: dangling
|
||||||
|
}
|
||||||
|
}
|
15
src/tools/miri/tests/fail/shims/memcpy_zero.stderr
Normal file
15
src/tools/miri/tests/fail/shims/memcpy_zero.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error: Undefined Behavior: out-of-bounds pointer use: 0x17[noalloc] is a dangling pointer (it has no provenance)
|
||||||
|
--> $DIR/memcpy_zero.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | libc::memcpy(to.cast(), from.cast(), 0);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: 0x17[noalloc] is a dangling pointer (it has no provenance)
|
||||||
|
|
|
||||||
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||||
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
|
= note: BACKTRACE:
|
||||||
|
= note: inside `main` at $DIR/memcpy_zero.rs:LL:CC
|
||||||
|
|
||||||
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
11
src/tools/miri/tests/fail/shims/memrchr_null.rs
Normal file
11
src/tools/miri/tests/fail/shims/memrchr_null.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
//@ignore-target-windows: No libc on Windows
|
||||||
|
//@ignore-target-apple: No `memrchr` on some apple targets
|
||||||
|
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
// null is explicitly called out as UB in the C docs.
|
||||||
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
libc::memrchr(ptr::null(), 0, 0); //~ERROR: dangling
|
||||||
|
}
|
||||||
|
}
|
15
src/tools/miri/tests/fail/shims/memrchr_null.stderr
Normal file
15
src/tools/miri/tests/fail/shims/memrchr_null.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance)
|
||||||
|
--> $DIR/memrchr_null.rs:LL:CC
|
||||||
|
|
|
||||||
|
LL | libc::memrchr(ptr::null(), 0, 0);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
|
||||||
|
|
|
||||||
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||||
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
|
= note: BACKTRACE:
|
||||||
|
= note: inside `main` at $DIR/memrchr_null.rs:LL:CC
|
||||||
|
|
||||||
|
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
@ -100,7 +100,7 @@ fn vec_push_ptr_stable() {
|
|||||||
v.push(0);
|
v.push(0);
|
||||||
let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
|
let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
|
||||||
v.push(1);
|
v.push(1);
|
||||||
let _val = *v0;
|
*v0 = *v0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vec_extend_ptr_stable() {
|
fn vec_extend_ptr_stable() {
|
||||||
@ -109,23 +109,23 @@ fn vec_extend_ptr_stable() {
|
|||||||
let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
|
let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
|
||||||
// `slice::Iter` (with `T: Copy`) specialization
|
// `slice::Iter` (with `T: Copy`) specialization
|
||||||
v.extend(&[1]);
|
v.extend(&[1]);
|
||||||
let _val = *v0;
|
*v0 = *v0;
|
||||||
// `vec::IntoIter` specialization
|
// `vec::IntoIter` specialization
|
||||||
v.extend(vec![2]);
|
v.extend(vec![2]);
|
||||||
let _val = *v0;
|
*v0 = *v0;
|
||||||
// `TrustedLen` specialization
|
// `TrustedLen` specialization
|
||||||
v.extend(std::iter::once(3));
|
v.extend(std::iter::once(3));
|
||||||
let _val = *v0;
|
*v0 = *v0;
|
||||||
// base case
|
// base case
|
||||||
v.extend(std::iter::once(3).filter(|_| true));
|
v.extend(std::iter::once(3).filter(|_| true));
|
||||||
let _val = *v0;
|
*v0 = *v0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vec_truncate_ptr_stable() {
|
fn vec_truncate_ptr_stable() {
|
||||||
let mut v = vec![0; 10];
|
let mut v = vec![0; 10];
|
||||||
let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
|
let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
|
||||||
v.truncate(5);
|
v.truncate(5);
|
||||||
let _val = *v0;
|
*v0 = *v0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_str_ptr_stable() {
|
fn push_str_ptr_stable() {
|
||||||
|
Loading…
Reference in New Issue
Block a user