Auto merge of #150848 - cuviper:beta-next, r=cuviper
[beta] backports - Revert "Rollup merge of rust-lang/rust#149147 - chenyukang:yukang-fix-unused_assignments-macro-gen-147648, r=JonathanBrouwer" rust-lang/rust#149657 - Don't lint on interior mutable `const` item coming from derefs rust-lang/rust#150166 - stdarch subtree update rust-lang/rust#150639 (partial) - Update bors configuration rust-lang/rust#150308 - Update bors e-mail lookup rust-lang/rust#150783 - Make verify-channel.sh script compatible with new bors rust-lang/rust#150759 r? cuviper
This commit is contained in:
commit
7bea8c6cf1
18 changed files with 225 additions and 68 deletions
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
|
|
@ -15,6 +15,7 @@ on:
|
|||
- try
|
||||
- try-perf
|
||||
- automation/bors/try
|
||||
- automation/bors/auto
|
||||
pull_request:
|
||||
branches:
|
||||
- "**"
|
||||
|
|
@ -56,7 +57,7 @@ jobs:
|
|||
- name: Test citool
|
||||
# Only test citool on the auto branch, to reduce latency of the calculate matrix job
|
||||
# on PR/try builds.
|
||||
if: ${{ github.ref == 'refs/heads/auto' }}
|
||||
if: ${{ github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto' }}
|
||||
run: |
|
||||
cd src/ci/citool
|
||||
CARGO_INCREMENTAL=0 cargo test
|
||||
|
|
@ -79,7 +80,7 @@ jobs:
|
|||
# access the environment.
|
||||
#
|
||||
# We only enable the environment for the rust-lang/rust repository, so that CI works on forks.
|
||||
environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto')) && 'bors') || '' }}
|
||||
environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }}
|
||||
env:
|
||||
CI_JOB_NAME: ${{ matrix.name }}
|
||||
CI_JOB_DOC_URL: ${{ matrix.doc_url }}
|
||||
|
|
@ -313,7 +314,7 @@ jobs:
|
|||
needs: [ calculate_matrix, job ]
|
||||
# !cancelled() executes the job regardless of whether the previous jobs passed or failed
|
||||
if: ${{ !cancelled() && contains(fromJSON('["auto", "try"]'), needs.calculate_matrix.outputs.run_type) }}
|
||||
environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto')) && 'bors') || '' }}
|
||||
environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto' || github.ref == 'refs/heads/automation/bors/auto')) && 'bors') || '' }}
|
||||
steps:
|
||||
- name: checkout the source code
|
||||
uses: actions/checkout@v5
|
||||
|
|
|
|||
2
.github/workflows/post-merge.yml
vendored
2
.github/workflows/post-merge.yml
vendored
|
|
@ -29,7 +29,7 @@ jobs:
|
|||
sleep 60
|
||||
|
||||
# Get closest bors merge commit
|
||||
PARENT_COMMIT=`git rev-list --author='bors <bors@rust-lang.org>' -n1 --first-parent HEAD^1`
|
||||
PARENT_COMMIT=`git rev-list --author='122020455+rust-bors\[bot\]@users.noreply.github.com' -n1 --first-parent HEAD^1`
|
||||
echo "Parent: ${PARENT_COMMIT}"
|
||||
|
||||
# Find PR for the current commit
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_hir::attrs::AttributeKind;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{Expr, ExprKind, ItemKind, Node, find_attr};
|
||||
use rustc_middle::ty::adjustment::Adjust;
|
||||
use rustc_session::{declare_lint, declare_lint_pass};
|
||||
|
||||
use crate::lints::{ConstItemInteriorMutationsDiag, ConstItemInteriorMutationsSuggestionStatic};
|
||||
|
|
@ -77,6 +78,13 @@ impl<'tcx> LateLintPass<'tcx> for InteriorMutableConsts {
|
|||
if let ExprKind::Path(qpath) = &receiver.kind
|
||||
&& let Res::Def(DefKind::Const | DefKind::AssocConst, const_did) =
|
||||
typeck.qpath_res(qpath, receiver.hir_id)
|
||||
// Don't consider derefs as those can do arbitrary things
|
||||
// like using thread local (see rust-lang/rust#150157)
|
||||
&& !cx
|
||||
.typeck_results()
|
||||
.expr_adjustments(receiver)
|
||||
.into_iter()
|
||||
.any(|adj| matches!(adj.kind, Adjust::Deref(_)))
|
||||
// Let's do the attribute check after the other checks for perf reasons
|
||||
&& find_attr!(
|
||||
cx.tcx.get_all_attrs(method_did),
|
||||
|
|
|
|||
|
|
@ -75,11 +75,6 @@ pub(crate) fn check_liveness<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Den
|
|||
return DenseBitSet::new_empty(0);
|
||||
}
|
||||
|
||||
// Don't run unused pass for items generated by foreign macros
|
||||
if tcx.def_span(parent).in_external_macro(tcx.sess.source_map()) {
|
||||
return DenseBitSet::new_empty(0);
|
||||
}
|
||||
|
||||
let mut body = &*tcx.mir_promoted(def_id).0.borrow();
|
||||
let mut body_mem;
|
||||
|
||||
|
|
|
|||
|
|
@ -1754,12 +1754,19 @@ pub fn _mm256_inserti128_si256<const IMM1: i32>(a: __m256i, b: __m128i) -> __m25
|
|||
#[cfg_attr(test, assert_instr(vpmaddwd))]
|
||||
#[stable(feature = "simd_x86", since = "1.27.0")]
|
||||
pub fn _mm256_madd_epi16(a: __m256i, b: __m256i) -> __m256i {
|
||||
unsafe {
|
||||
let r: i32x16 = simd_mul(simd_cast(a.as_i16x16()), simd_cast(b.as_i16x16()));
|
||||
let even: i32x8 = simd_shuffle!(r, r, [0, 2, 4, 6, 8, 10, 12, 14]);
|
||||
let odd: i32x8 = simd_shuffle!(r, r, [1, 3, 5, 7, 9, 11, 13, 15]);
|
||||
simd_add(even, odd).as_m256i()
|
||||
}
|
||||
// It's a trick used in the Adler-32 algorithm to perform a widening addition.
|
||||
//
|
||||
// ```rust
|
||||
// #[target_feature(enable = "avx2")]
|
||||
// unsafe fn widening_add(mad: __m256i) -> __m256i {
|
||||
// _mm256_madd_epi16(mad, _mm256_set1_epi16(1))
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// If we implement this using generic vector intrinsics, the optimizer
|
||||
// will eliminate this pattern, and `vpmaddwd` will no longer be emitted.
|
||||
// For this reason, we use x86 intrinsics.
|
||||
unsafe { transmute(pmaddwd(a.as_i16x16(), b.as_i16x16())) }
|
||||
}
|
||||
|
||||
/// Vertically multiplies each unsigned 8-bit integer from `a` with the
|
||||
|
|
@ -3701,6 +3708,8 @@ unsafe extern "C" {
|
|||
fn phaddsw(a: i16x16, b: i16x16) -> i16x16;
|
||||
#[link_name = "llvm.x86.avx2.phsub.sw"]
|
||||
fn phsubsw(a: i16x16, b: i16x16) -> i16x16;
|
||||
#[link_name = "llvm.x86.avx2.pmadd.wd"]
|
||||
fn pmaddwd(a: i16x16, b: i16x16) -> i32x8;
|
||||
#[link_name = "llvm.x86.avx2.pmadd.ub.sw"]
|
||||
fn pmaddubsw(a: u8x32, b: i8x32) -> i16x16;
|
||||
#[link_name = "llvm.x86.avx2.mpsadbw"]
|
||||
|
|
|
|||
|
|
@ -5847,20 +5847,19 @@ pub unsafe fn _mm_mask_storeu_epi8(mem_addr: *mut i8, mask: __mmask16, a: __m128
|
|||
#[stable(feature = "stdarch_x86_avx512", since = "1.89")]
|
||||
#[cfg_attr(test, assert_instr(vpmaddwd))]
|
||||
pub fn _mm512_madd_epi16(a: __m512i, b: __m512i) -> __m512i {
|
||||
unsafe {
|
||||
let r: i32x32 = simd_mul(simd_cast(a.as_i16x32()), simd_cast(b.as_i16x32()));
|
||||
let even: i32x16 = simd_shuffle!(
|
||||
r,
|
||||
r,
|
||||
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]
|
||||
);
|
||||
let odd: i32x16 = simd_shuffle!(
|
||||
r,
|
||||
r,
|
||||
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31]
|
||||
);
|
||||
simd_add(even, odd).as_m512i()
|
||||
}
|
||||
// It's a trick used in the Adler-32 algorithm to perform a widening addition.
|
||||
//
|
||||
// ```rust
|
||||
// #[target_feature(enable = "avx512bw")]
|
||||
// unsafe fn widening_add(mad: __m512i) -> __m512i {
|
||||
// _mm512_madd_epi16(mad, _mm512_set1_epi16(1))
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// If we implement this using generic vector intrinsics, the optimizer
|
||||
// will eliminate this pattern, and `vpmaddwd` will no longer be emitted.
|
||||
// For this reason, we use x86 intrinsics.
|
||||
unsafe { transmute(vpmaddwd(a.as_i16x32(), b.as_i16x32())) }
|
||||
}
|
||||
|
||||
/// Multiply packed signed 16-bit integers in a and b, producing intermediate signed 32-bit integers. Horizontally add adjacent pairs of intermediate 32-bit integers, and pack the results in dst using writemask k (elements are copied from src when the corresponding mask bit is not set).
|
||||
|
|
@ -11687,6 +11686,8 @@ unsafe extern "C" {
|
|||
#[link_name = "llvm.x86.avx512.pmul.hr.sw.512"]
|
||||
fn vpmulhrsw(a: i16x32, b: i16x32) -> i16x32;
|
||||
|
||||
#[link_name = "llvm.x86.avx512.pmaddw.d.512"]
|
||||
fn vpmaddwd(a: i16x32, b: i16x32) -> i32x16;
|
||||
#[link_name = "llvm.x86.avx512.pmaddubs.w.512"]
|
||||
fn vpmaddubsw(a: u8x64, b: i8x64) -> i16x32;
|
||||
|
||||
|
|
|
|||
|
|
@ -201,12 +201,19 @@ pub fn _mm_avg_epu16(a: __m128i, b: __m128i) -> __m128i {
|
|||
#[cfg_attr(test, assert_instr(pmaddwd))]
|
||||
#[stable(feature = "simd_x86", since = "1.27.0")]
|
||||
pub fn _mm_madd_epi16(a: __m128i, b: __m128i) -> __m128i {
|
||||
unsafe {
|
||||
let r: i32x8 = simd_mul(simd_cast(a.as_i16x8()), simd_cast(b.as_i16x8()));
|
||||
let even: i32x4 = simd_shuffle!(r, r, [0, 2, 4, 6]);
|
||||
let odd: i32x4 = simd_shuffle!(r, r, [1, 3, 5, 7]);
|
||||
simd_add(even, odd).as_m128i()
|
||||
}
|
||||
// It's a trick used in the Adler-32 algorithm to perform a widening addition.
|
||||
//
|
||||
// ```rust
|
||||
// #[target_feature(enable = "sse2")]
|
||||
// unsafe fn widening_add(mad: __m128i) -> __m128i {
|
||||
// _mm_madd_epi16(mad, _mm_set1_epi16(1))
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// If we implement this using generic vector intrinsics, the optimizer
|
||||
// will eliminate this pattern, and `pmaddwd` will no longer be emitted.
|
||||
// For this reason, we use x86 intrinsics.
|
||||
unsafe { transmute(pmaddwd(a.as_i16x8(), b.as_i16x8())) }
|
||||
}
|
||||
|
||||
/// Compares packed 16-bit integers in `a` and `b`, and returns the packed
|
||||
|
|
@ -3054,6 +3061,8 @@ unsafe extern "C" {
|
|||
fn lfence();
|
||||
#[link_name = "llvm.x86.sse2.mfence"]
|
||||
fn mfence();
|
||||
#[link_name = "llvm.x86.sse2.pmadd.wd"]
|
||||
fn pmaddwd(a: i16x8, b: i16x8) -> i32x4;
|
||||
#[link_name = "llvm.x86.sse2.psad.bw"]
|
||||
fn psadbw(a: u8x16, b: u8x16) -> u64x2;
|
||||
#[link_name = "llvm.x86.sse2.psll.w"]
|
||||
|
|
|
|||
|
|
@ -25,3 +25,42 @@ labels_blocking_approval = [
|
|||
"S-waiting-on-t-rustdoc-frontend",
|
||||
"S-waiting-on-t-clippy"
|
||||
]
|
||||
|
||||
# If CI runs quicker than this duration, consider it to be a failure
|
||||
min_ci_time = 600
|
||||
|
||||
[labels]
|
||||
approved = [
|
||||
"+S-waiting-on-bors",
|
||||
"-S-blocked",
|
||||
"-S-waiting-on-author",
|
||||
"-S-waiting-on-crater",
|
||||
"-S-waiting-on-review",
|
||||
"-S-waiting-on-team"
|
||||
]
|
||||
unapproved = [
|
||||
"+S-waiting-on-author",
|
||||
"-S-blocked",
|
||||
"-S-waiting-on-bors",
|
||||
"-S-waiting-on-crater",
|
||||
"-S-waiting-on-review",
|
||||
"-S-waiting-on-team"
|
||||
]
|
||||
try_failed = [
|
||||
"+S-waiting-on-author",
|
||||
"-S-waiting-on-review",
|
||||
"-S-waiting-on-crater"
|
||||
]
|
||||
auto_build_succeeded = ["+merged-by-bors"]
|
||||
auto_build_failed = [
|
||||
"+S-waiting-on-review",
|
||||
"-S-blocked",
|
||||
"-S-waiting-on-bors",
|
||||
"-S-waiting-on-author",
|
||||
"-S-waiting-on-crater",
|
||||
"-S-waiting-on-team"
|
||||
]
|
||||
|
||||
# Flip this two once new bors is used for actual merges on this repository
|
||||
merge_queue_enabled = false
|
||||
report_merge_conflicts = true
|
||||
|
|
|
|||
|
|
@ -152,6 +152,14 @@ pub fn has_changed_since(git_dir: &Path, base: &str, paths: &[&str]) -> bool {
|
|||
})
|
||||
}
|
||||
|
||||
const LEGACY_BORS_EMAIL: &str = "bors@rust-lang.org";
|
||||
|
||||
/// Escape characters from the git user e-mail, so that git commands do not interpret it as regex
|
||||
/// special characters.
|
||||
fn escape_email_git_regex(text: &str) -> String {
|
||||
text.replace("[", "\\[").replace("]", "\\]").replace(".", "\\.")
|
||||
}
|
||||
|
||||
/// Returns the latest upstream commit that modified `target_paths`, or `None` if no such commit
|
||||
/// was found.
|
||||
fn get_latest_upstream_commit_that_modified_files(
|
||||
|
|
@ -182,9 +190,15 @@ fn get_latest_upstream_commit_that_modified_files(
|
|||
"-n1",
|
||||
&upstream,
|
||||
"--author",
|
||||
git_config.git_merge_commit_email,
|
||||
&escape_email_git_regex(git_config.git_merge_commit_email),
|
||||
]);
|
||||
|
||||
// Also search for legacy bors account, before we accrue enough commits to
|
||||
// have changes to all relevant file paths done by new bors.
|
||||
if git_config.git_merge_commit_email != LEGACY_BORS_EMAIL {
|
||||
git.args(["--author", LEGACY_BORS_EMAIL]);
|
||||
}
|
||||
|
||||
if !target_paths.is_empty() {
|
||||
git.arg("--").args(target_paths);
|
||||
}
|
||||
|
|
@ -229,11 +243,17 @@ pub fn get_closest_upstream_commit(
|
|||
git.args([
|
||||
"rev-list",
|
||||
"--author-date-order",
|
||||
&format!("--author={}", config.git_merge_commit_email),
|
||||
&format!("--author={}", &escape_email_git_regex(config.git_merge_commit_email),),
|
||||
"-n1",
|
||||
base,
|
||||
]);
|
||||
|
||||
// Also search for legacy bors account, before we accrue enough commits to
|
||||
// have changes to all relevant file paths done by new bors.
|
||||
if config.git_merge_commit_email != LEGACY_BORS_EMAIL {
|
||||
git.args(["--author", LEGACY_BORS_EMAIL]);
|
||||
}
|
||||
|
||||
let output = output_result(&mut git)?.trim().to_owned();
|
||||
if output.is_empty() { Ok(None) } else { Ok(Some(output)) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,9 @@ impl GitHubContext {
|
|||
let patterns = if !patterns.is_empty() { Some(patterns) } else { None };
|
||||
Some(RunType::TryJob { job_patterns: patterns })
|
||||
}
|
||||
("push", "refs/heads/auto") => Some(RunType::AutoJob),
|
||||
("push", "refs/heads/auto" | "refs/heads/automation/bors/auto") => {
|
||||
Some(RunType::AutoJob)
|
||||
}
|
||||
("push", "refs/heads/main") => Some(RunType::MainJob),
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -312,16 +312,6 @@ else
|
|||
command=(/checkout/src/ci/run.sh)
|
||||
fi
|
||||
|
||||
if isCI; then
|
||||
# Get some needed information for $BASE_COMMIT
|
||||
#
|
||||
# This command gets the last merge commit which we'll use as base to list
|
||||
# deleted files since then.
|
||||
BASE_COMMIT="$(git log --author=bors@rust-lang.org -n 2 --pretty=format:%H | tail -n 1)"
|
||||
else
|
||||
BASE_COMMIT=""
|
||||
fi
|
||||
|
||||
SUMMARY_FILE=github-summary.md
|
||||
touch $objdir/${SUMMARY_FILE}
|
||||
|
||||
|
|
@ -359,7 +349,6 @@ docker \
|
|||
--env RUST_CI_OVERRIDE_RELEASE_CHANNEL \
|
||||
--env CI_JOB_NAME="${CI_JOB_NAME-$image}" \
|
||||
--env CI_JOB_DOC_URL="${CI_JOB_DOC_URL}" \
|
||||
--env BASE_COMMIT="$BASE_COMMIT" \
|
||||
--env DIST_TRY_BUILD \
|
||||
--env PR_CI_JOB \
|
||||
--env OBJDIR_ON_HOST="$objdir" \
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ IFS=$'\n\t'
|
|||
|
||||
source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
|
||||
|
||||
if isCiBranch auto || isCiBranch try || isCiBranch try-perf || isCiBranch automation/bors/try; then
|
||||
if isCiBranch auto || isCiBranch try || isCiBranch try-perf || \
|
||||
isCiBranch automation/bors/try || isCiBranch automation/bors/auto; then
|
||||
echo "channel verification is only executed on PR builds"
|
||||
exit
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
dist_server=https://static.rust-lang.org
|
||||
artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds
|
||||
artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt
|
||||
git_merge_commit_email=bors@rust-lang.org
|
||||
git_merge_commit_email=122020455+rust-bors[bot]@users.noreply.github.com
|
||||
nightly_branch=main
|
||||
|
||||
# The configuration above this comment is editable, and can be changed
|
||||
|
|
|
|||
|
|
@ -245,6 +245,42 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
shift_simd_by_scalar(this, left, right, which, dest)?;
|
||||
}
|
||||
// Used to implement the _mm256_madd_epi16 function.
|
||||
// Multiplies packed signed 16-bit integers in `left` and `right`, producing
|
||||
// intermediate signed 32-bit integers. Horizontally add adjacent pairs of
|
||||
// intermediate 32-bit integers, and pack the results in `dest`.
|
||||
"pmadd.wd" => {
|
||||
let [left, right] =
|
||||
this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
let (dest, dest_len) = this.project_to_simd(dest)?;
|
||||
|
||||
assert_eq!(left_len, right_len);
|
||||
assert_eq!(dest_len.strict_mul(2), left_len);
|
||||
|
||||
for i in 0..dest_len {
|
||||
let j1 = i.strict_mul(2);
|
||||
let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_i16()?;
|
||||
let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i16()?;
|
||||
|
||||
let j2 = j1.strict_add(1);
|
||||
let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_i16()?;
|
||||
let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i16()?;
|
||||
|
||||
let dest = this.project_index(&dest, i)?;
|
||||
|
||||
// Multiplications are i16*i16->i32, which will not overflow.
|
||||
let mul1 = i32::from(left1).strict_mul(right1.into());
|
||||
let mul2 = i32::from(left2).strict_mul(right2.into());
|
||||
// However, this addition can overflow in the most extreme case
|
||||
// (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000
|
||||
let res = mul1.wrapping_add(mul2);
|
||||
|
||||
this.write_scalar(Scalar::from_i32(res), &dest)?;
|
||||
}
|
||||
}
|
||||
_ => return interp_ok(EmulateItemResult::NotSupported),
|
||||
}
|
||||
interp_ok(EmulateItemResult::NeedsReturn)
|
||||
|
|
|
|||
|
|
@ -278,6 +278,42 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.copy_op(&this.project_index(&left, i)?, &this.project_index(&dest, i)?)?;
|
||||
}
|
||||
}
|
||||
// Used to implement the _mm_madd_epi16 function.
|
||||
// Multiplies packed signed 16-bit integers in `left` and `right`, producing
|
||||
// intermediate signed 32-bit integers. Horizontally add adjacent pairs of
|
||||
// intermediate 32-bit integers, and pack the results in `dest`.
|
||||
"pmadd.wd" => {
|
||||
let [left, right] =
|
||||
this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
let (dest, dest_len) = this.project_to_simd(dest)?;
|
||||
|
||||
assert_eq!(left_len, right_len);
|
||||
assert_eq!(dest_len.strict_mul(2), left_len);
|
||||
|
||||
for i in 0..dest_len {
|
||||
let j1 = i.strict_mul(2);
|
||||
let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_i16()?;
|
||||
let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i16()?;
|
||||
|
||||
let j2 = j1.strict_add(1);
|
||||
let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_i16()?;
|
||||
let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i16()?;
|
||||
|
||||
let dest = this.project_index(&dest, i)?;
|
||||
|
||||
// Multiplications are i16*i16->i32, which will not overflow.
|
||||
let mul1 = i32::from(left1).strict_mul(right1.into());
|
||||
let mul2 = i32::from(left2).strict_mul(right2.into());
|
||||
// However, this addition can overflow in the most extreme case
|
||||
// (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000
|
||||
let res = mul1.wrapping_add(mul2);
|
||||
|
||||
this.write_scalar(Scalar::from_i32(res), &dest)?;
|
||||
}
|
||||
}
|
||||
_ => return interp_ok(EmulateItemResult::NotSupported),
|
||||
}
|
||||
interp_ok(EmulateItemResult::NeedsReturn)
|
||||
|
|
|
|||
28
tests/ui/lint/const-item-interior-mutations-const-deref.rs
Normal file
28
tests/ui/lint/const-item-interior-mutations-const-deref.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Regression test for <https://github.com/rust-lang/rust/issues/150157>
|
||||
//
|
||||
// We shouldn't lint on user types, including through deref.
|
||||
|
||||
//@ check-pass
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::ops::Deref;
|
||||
|
||||
// Cut down version of the issue reproducer without the thread local to just a Deref
|
||||
pub struct LocalKey<T> {
|
||||
inner: T,
|
||||
}
|
||||
|
||||
impl<T> Deref for LocalKey<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
const LOCAL_COUNT: LocalKey<Cell<usize>> = LocalKey { inner: Cell::new(8) };
|
||||
|
||||
fn main() {
|
||||
let count = LOCAL_COUNT.get();
|
||||
LOCAL_COUNT.set(count);
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
#[macro_export]
|
||||
macro_rules! unused_assign {
|
||||
($x:ident) => {
|
||||
let mut $x = 1;
|
||||
$x = 2;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
//@ check-pass
|
||||
//@ aux-build:aux_issue_147648.rs
|
||||
|
||||
#![deny(unused_assignments)]
|
||||
|
||||
extern crate aux_issue_147648;
|
||||
|
||||
fn main() {
|
||||
aux_issue_147648::unused_assign!(y);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue