Skip to content

Rollup of 6 pull requests #128608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 12 additions & 30 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,11 +453,6 @@ impl<'a> AstValidator<'a> {
item_span: span,
block: Some(self.current_extern_span().shrink_to_lo()),
});
} else if !self.features.unsafe_extern_blocks {
self.dcx().emit_err(errors::InvalidSafetyOnExtern {
item_span: span,
block: None,
});
}
}
}
Expand Down Expand Up @@ -1054,32 +1049,19 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
errors::VisibilityNotPermittedNote::IndividualForeignItems,
);

if this.features.unsafe_extern_blocks {
if &Safety::Default == safety {
if item.span.at_least_rust_2024() {
this.dcx()
.emit_err(errors::MissingUnsafeOnExtern { span: item.span });
} else {
this.lint_buffer.buffer_lint(
MISSING_UNSAFE_ON_EXTERN,
item.id,
item.span,
BuiltinLintDiag::MissingUnsafeOnExtern {
suggestion: item.span.shrink_to_lo(),
},
);
}
if &Safety::Default == safety {
if item.span.at_least_rust_2024() {
this.dcx().emit_err(errors::MissingUnsafeOnExtern { span: item.span });
} else {
this.lint_buffer.buffer_lint(
MISSING_UNSAFE_ON_EXTERN,
item.id,
item.span,
BuiltinLintDiag::MissingUnsafeOnExtern {
suggestion: item.span.shrink_to_lo(),
},
);
}
} else if let &Safety::Unsafe(span) = safety {
let mut diag = this
.dcx()
.create_err(errors::UnsafeItem { span, kind: "extern block" });
rustc_session::parse::add_feature_diagnostics(
&mut diag,
self.session,
sym::unsafe_extern_blocks,
);
diag.emit();
}

if abi.is_none() {
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,10 +560,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental");
gate_all!(global_registration, "global registration is experimental");
gate_all!(unsafe_attributes, "`#[unsafe()]` markers for attributes are experimental");
gate_all!(
unsafe_extern_blocks,
"`unsafe extern {}` blocks and `safe` keyword are experimental"
);
gate_all!(return_type_notation, "return type notation is experimental");

if !visitor.features.never_patterns {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,8 @@ declare_features! (
(accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208)),
/// The `unsafe_op_in_unsafe_fn` lint (allowed by default): no longer treat an unsafe function as an unsafe block.
(accepted, unsafe_block_in_unsafe_fn, "1.52.0", Some(71668)),
/// Allows unsafe on extern declarations and safety qualifiers over internal items.
(accepted, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)),
/// Allows importing and reexporting macros with `use`,
/// enables macro modularization in general.
(accepted, use_extern_macros, "1.30.0", Some(35896)),
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,21 +703,21 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
EncodeCrossCrate::No, allocator_internals, experimental!(needs_allocator),
),
gated!(
panic_runtime, Normal, template!(Word), WarnFollowing,
panic_runtime, CrateLevel, template!(Word), WarnFollowing,
EncodeCrossCrate::No, experimental!(panic_runtime)
),
gated!(
needs_panic_runtime, Normal, template!(Word), WarnFollowing,
needs_panic_runtime, CrateLevel, template!(Word), WarnFollowing,
EncodeCrossCrate::No, experimental!(needs_panic_runtime)
),
gated!(
compiler_builtins, Normal, template!(Word), WarnFollowing,
compiler_builtins, CrateLevel, template!(Word), WarnFollowing,
EncodeCrossCrate::No,
"the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \
which contains compiler-rt intrinsics and will never be stable",
),
gated!(
profiler_runtime, Normal, template!(Word), WarnFollowing,
profiler_runtime, CrateLevel, template!(Word), WarnFollowing,
EncodeCrossCrate::No,
"the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \
which contains the profiler runtime and will never be stable",
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -631,8 +631,6 @@ declare_features! (
(incomplete, unnamed_fields, "1.74.0", Some(49804)),
/// Allows unsafe attributes.
(unstable, unsafe_attributes, "1.80.0", Some(123757)),
/// Allows unsafe on extern declarations and safety qualifiers over internal items.
(unstable, unsafe_extern_blocks, "1.80.0", Some(123743)),
/// Allows const generic parameters to be defined with types that
/// are not `Sized`, e.g. `fn foo<const N: [u8]>() {`.
(incomplete, unsized_const_params, "CURRENT_RUSTC_VERSION", Some(95174)),
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4934,7 +4934,6 @@ declare_lint! {
/// ### Example
///
/// ```rust
/// #![feature(unsafe_extern_blocks)]
/// #![warn(missing_unsafe_on_extern)]
/// #![allow(dead_code)]
///
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1250,9 +1250,6 @@ impl<'a> Parser<'a> {
if self.eat_keyword_case(kw::Unsafe, case) {
Safety::Unsafe(self.prev_token.uninterpolated_span())
} else if self.eat_keyword_case(kw::Safe, case) {
self.psess
.gated_spans
.gate(sym::unsafe_extern_blocks, self.prev_token.uninterpolated_span());
Safety::Safe(self.prev_token.uninterpolated_span())
} else {
Safety::Default
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ passes_continue_labeled_block =
.label = labeled blocks cannot be `continue`'d
.block_label = labeled block the `continue` points to
passes_coroutine_on_non_closure =
attribute should be applied to closures
.label = not a closure
passes_coverage_not_fn_or_closure =
attribute should be applied to a function definition or closure
.label = not a function or closure
Expand Down
66 changes: 64 additions & 2 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ use rustc_hir::{
TraitItem, CRATE_HIR_ID, CRATE_OWNER_ID,
};
use rustc_macros::LintDiagnostic;
use rustc_middle::bug;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
use rustc_middle::query::Providers;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_session::lint::builtin::{
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
Expand Down Expand Up @@ -239,7 +239,59 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.check_generic_attr(hir_id, attr, target, Target::Fn);
self.check_proc_macro(hir_id, target, ProcMacroKind::Derive)
}
_ => {}
[sym::coroutine] => {
self.check_coroutine(attr, target);
}
[
// ok
sym::allow
| sym::expect
| sym::warn
| sym::deny
| sym::forbid
| sym::cfg
// need to be fixed
| sym::cfi_encoding // FIXME(cfi_encoding)
| sym::may_dangle // FIXME(dropck_eyepatch)
| sym::pointee // FIXME(derive_smart_pointer)
| sym::linkage // FIXME(linkage)
| sym::no_sanitize // FIXME(no_sanitize)
| sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
| sym::used // handled elsewhere to restrict to static items
| sym::repr // handled elsewhere to restrict to type decls items
| sym::instruction_set // broken on stable!!!
| sym::windows_subsystem // broken on stable!!!
| sym::patchable_function_entry // FIXME(patchable_function_entry)
| sym::deprecated_safe // FIXME(deprecated_safe)
// internal
| sym::prelude_import
| sym::panic_handler
| sym::allow_internal_unsafe
| sym::fundamental
| sym::lang
| sym::needs_allocator
| sym::default_lib_allocator
| sym::start
| sym::custom_mir,
] => {}
[name, ..] => {
match BUILTIN_ATTRIBUTE_MAP.get(name) {
// checked below
Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
Some(_) => {
// FIXME: differentiate between unstable and internal attributes just like we do with features instead
// of just accepting `rustc_` attributes by name. That should allow trimming the above list, too.
if !name.as_str().starts_with("rustc_") {
span_bug!(
attr.span,
"builtin attribute {name:?} not handled by `CheckAttrVisitor`"
)
}
}
None => (),
}
}
[] => unreachable!(),
}

let builtin = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
Expand Down Expand Up @@ -376,6 +428,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {

/// Checks that `#[optimize(..)]` is applied to a function/closure/method,
/// or to an impl block or module.
// FIXME(#128488): this should probably be elevated to an error?
fn check_optimize(&self, hir_id: HirId, attr: &Attribute, target: Target) {
match target {
Target::Fn
Expand Down Expand Up @@ -2279,6 +2332,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.abort.set(true);
}
}

fn check_coroutine(&self, attr: &Attribute, target: Target) {
match target {
Target::Closure => return,
_ => {
self.dcx().emit_err(errors::CoroutineOnNonClosure { span: attr.span });
}
}
}
}

impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,13 @@ pub struct Confusables {
pub attr_span: Span,
}

#[derive(Diagnostic)]
#[diag(passes_coroutine_on_non_closure)]
pub struct CoroutineOnNonClosure {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(passes_empty_confusables)]
pub(crate) struct EmptyConfusables {
Expand Down
33 changes: 20 additions & 13 deletions library/core/src/iter/sources/repeat_n.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,19 +114,12 @@ impl<A: Clone> Iterator for RepeatN<A> {

#[inline]
fn next(&mut self) -> Option<A> {
if self.count == 0 {
return None;
}

self.count -= 1;
Some(if self.count == 0 {
// SAFETY: the check above ensured that the count used to be non-zero,
// so element hasn't been dropped yet, and we just lowered the count to
// zero so it won't be dropped later, and thus it's okay to take it here.
unsafe { ManuallyDrop::take(&mut self.element) }
if self.count > 0 {
// SAFETY: Just checked it's not empty
unsafe { Some(self.next_unchecked()) }
} else {
A::clone(&self.element)
})
None
}
}

#[inline]
Expand Down Expand Up @@ -194,4 +187,18 @@ impl<A: Clone> FusedIterator for RepeatN<A> {}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A: Clone> TrustedLen for RepeatN<A> {}
#[unstable(feature = "trusted_len_next_unchecked", issue = "37572")]
impl<A: Clone> UncheckedIterator for RepeatN<A> {}
impl<A: Clone> UncheckedIterator for RepeatN<A> {
#[inline]
unsafe fn next_unchecked(&mut self) -> Self::Item {
// SAFETY: The caller promised the iterator isn't empty
self.count = unsafe { self.count.unchecked_sub(1) };
if self.count == 0 {
// SAFETY: the check above ensured that the count used to be non-zero,
// so element hasn't been dropped yet, and we just lowered the count to
// zero so it won't be dropped later, and thus it's okay to take it here.
unsafe { ManuallyDrop::take(&mut self.element) }
} else {
A::clone(&self.element)
}
}
}
2 changes: 1 addition & 1 deletion library/stdarch
Submodule stdarch updated 93 files
+8 −16 .github/workflows/main.yml
+1 −1 ci/docker/aarch64-unknown-linux-gnu/Dockerfile
+1 −1 ci/docker/arm-unknown-linux-gnueabihf/Dockerfile
+1 −1 ci/docker/i586-unknown-linux-gnu/Dockerfile
+1 −1 ci/docker/i686-unknown-linux-gnu/Dockerfile
+1 −1 ci/docker/mips-unknown-linux-gnu/Dockerfile
+1 −1 ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile
+1 −1 ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile
+1 −1 ci/docker/mipsel-unknown-linux-musl/Dockerfile
+1 −1 ci/docker/nvptx64-nvidia-cuda/Dockerfile
+1 −1 ci/docker/powerpc-unknown-linux-gnu/Dockerfile
+1 −1 ci/docker/powerpc64-unknown-linux-gnu/Dockerfile
+1 −1 ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile
+1 −1 ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile
+1 −1 ci/docker/s390x-unknown-linux-gnu/Dockerfile
+1 −1 ci/docker/wasm32-wasip1/Dockerfile
+7 −6 ci/docker/x86_64-unknown-linux-gnu-emulated/Dockerfile
+61 −0 ci/docker/x86_64-unknown-linux-gnu-emulated/cpuid.def
+1 −1 ci/docker/x86_64-unknown-linux-gnu/Dockerfile
+0 −764 crates/core_arch/avx512bw.md
+0 −2,633 crates/core_arch/avx512f.md
+319 −0 crates/core_arch/missing-x86.md
+3 −1 crates/core_arch/src/lib.rs
+12 −0 crates/core_arch/src/mod.rs
+17 −17 crates/core_arch/src/powerpc/altivec.rs
+205 −1 crates/core_arch/src/simd.rs
+1 −1 crates/core_arch/src/wasm32/mod.rs
+70 −30 crates/core_arch/src/wasm32/relaxed_simd.rs
+17 −47 crates/core_arch/src/wasm32/simd128.rs
+9 −3 crates/core_arch/src/x86/adx.rs
+133 −48 crates/core_arch/src/x86/avx.rs
+55 −65 crates/core_arch/src/x86/avx2.rs
+356 −1 crates/core_arch/src/x86/avx512bf16.rs
+19 −36 crates/core_arch/src/x86/avx512bitalg.rs
+3,264 −1,749 crates/core_arch/src/x86/avx512bw.rs
+6 −20 crates/core_arch/src/x86/avx512cd.rs
+10,701 −0 crates/core_arch/src/x86/avx512dq.rs
+3,385 −2,350 crates/core_arch/src/x86/avx512f.rs
+26,998 −0 crates/core_arch/src/x86/avx512fp16.rs
+569 −26 crates/core_arch/src/x86/avx512ifma.rs
+49 −121 crates/core_arch/src/x86/avx512vbmi2.rs
+876 −0 crates/core_arch/src/x86/avx512vnni.rs
+19 −42 crates/core_arch/src/x86/avx512vpopcntdq.rs
+409 −0 crates/core_arch/src/x86/avxneconvert.rs
+20 −0 crates/core_arch/src/x86/bmi1.rs
+8 −0 crates/core_arch/src/x86/bt.rs
+0 −86 crates/core_arch/src/x86/cpuid.rs
+8 −0 crates/core_arch/src/x86/f16c.rs
+78 −89 crates/core_arch/src/x86/fma.rs
+1 −1 crates/core_arch/src/x86/fxsr.rs
+21 −21 crates/core_arch/src/x86/gfni.rs
+30 −0 crates/core_arch/src/x86/macros.rs
+117 −5 crates/core_arch/src/x86/mod.rs
+1 −5 crates/core_arch/src/x86/pclmulqdq.rs
+4 −4 crates/core_arch/src/x86/rtm.rs
+21 −45 crates/core_arch/src/x86/sse.rs
+169 −40 crates/core_arch/src/x86/sse2.rs
+31 −10 crates/core_arch/src/x86/sse41.rs
+61 −3 crates/core_arch/src/x86/sse4a.rs
+20 −255 crates/core_arch/src/x86/tbm.rs
+31 −16 crates/core_arch/src/x86/test.rs
+10 −31 crates/core_arch/src/x86/xsave.rs
+9 −3 crates/core_arch/src/x86_64/adx.rs
+21 −1 crates/core_arch/src/x86_64/avx.rs
+0 −48 crates/core_arch/src/x86_64/avx2.rs
+45 −0 crates/core_arch/src/x86_64/avx512bw.rs
+698 −85 crates/core_arch/src/x86_64/avx512f.rs
+309 −0 crates/core_arch/src/x86_64/avx512fp16.rs
+8 −0 crates/core_arch/src/x86_64/bt.rs
+1 −1 crates/core_arch/src/x86_64/fxsr.rs
+10 −2 crates/core_arch/src/x86_64/mod.rs
+11 −9 crates/core_arch/src/x86_64/sse2.rs
+1 −1 crates/core_arch/src/x86_64/sse41.rs
+225 −0 crates/core_arch/src/x86_64/tbm.rs
+11 −23 crates/core_arch/src/x86_64/xsave.rs
+184 −86 crates/std_detect/src/detect/arch/aarch64.rs
+41 −0 crates/std_detect/src/detect/arch/x86.rs
+19 −11 crates/std_detect/src/detect/cache.rs
+190 −8 crates/std_detect/src/detect/os/linux/aarch64.rs
+39 −12 crates/std_detect/src/detect/os/x86.rs
+0 −4 crates/std_detect/src/lib.rs
+53 −0 crates/std_detect/tests/cpu-detection.rs
+1 −0 crates/std_detect/tests/macro_trailing_commas.rs
+45 −19 crates/std_detect/tests/x86-specific.rs
+14 −26 crates/stdarch-gen-arm/src/main.rs
+23 −29 crates/stdarch-test/src/disassembly.rs
+2 −2 crates/stdarch-test/src/lib.rs
+1 −1 crates/stdarch-verify/Cargo.toml
+28 −1 crates/stdarch-verify/src/lib.rs
+1 −0 crates/stdarch-verify/tests/arm.rs
+2 −1 crates/stdarch-verify/tests/mips.rs
+241 −228 crates/stdarch-verify/tests/x86-intel.rs
+122,236 −111,951 crates/stdarch-verify/x86-intel.xml
3 changes: 2 additions & 1 deletion src/tools/run-make-support/src/external_deps/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ impl LlvmReadobj {
self
}

/// Pass `--symbols` to display the symbol.
/// Pass `--symbols` to display the symbol table, including both local
/// and global symbols.
pub fn symbols(&mut self) -> &mut Self {
self.cmd.arg("--symbols");
self
Expand Down
26 changes: 21 additions & 5 deletions src/tools/run-make-support/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@ pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
if link.as_ref().exists() {
std::fs::remove_dir(link.as_ref()).unwrap();
}
std::os::windows::fs::symlink_file(original.as_ref(), link.as_ref()).expect(&format!(
"failed to create symlink {:?} for {:?}",
link.as_ref().display(),
original.as_ref().display(),
));
if original.as_ref().is_file() {
std::os::windows::fs::symlink_file(original.as_ref(), link.as_ref()).expect(&format!(
"failed to create symlink {:?} for {:?}",
link.as_ref().display(),
original.as_ref().display(),
));
} else {
std::os::windows::fs::symlink_dir(original.as_ref(), link.as_ref()).expect(&format!(
"failed to create symlink {:?} for {:?}",
link.as_ref().display(),
original.as_ref().display(),
));
}
}

/// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
Expand Down Expand Up @@ -41,6 +49,8 @@ pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
let ty = entry.file_type()?;
if ty.is_dir() {
copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?;
} else if ty.is_symlink() {
copy_symlink(entry.path(), dst.join(entry.file_name()))?;
} else {
std::fs::copy(entry.path(), dst.join(entry.file_name()))?;
}
Expand All @@ -59,6 +69,12 @@ pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
}
}

fn copy_symlink<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
let target_path = std::fs::read_link(from).unwrap();
create_symlink(target_path, to);
Ok(())
}

/// Helper for reading entries in a given directory.
pub fn read_dir_entries<P: AsRef<Path>, F: FnMut(&Path)>(dir: P, mut callback: F) {
for entry in read_dir(dir) {
Expand Down
2 changes: 0 additions & 2 deletions src/tools/tidy/src/allowed_run_make_makefiles.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,10 @@ run-make/raw-dylib-alt-calling-convention/Makefile
run-make/raw-dylib-c/Makefile
run-make/redundant-libs/Makefile
run-make/remap-path-prefix-dwarf/Makefile
run-make/reproducible-build-2/Makefile
run-make/reproducible-build/Makefile
run-make/rlib-format-packed-bundled-libs/Makefile
run-make/simd-ffi/Makefile
run-make/split-debuginfo/Makefile
run-make/stable-symbol-names/Makefile
run-make/staticlib-dylib-linkage/Makefile
run-make/symbol-mangling-hashed/Makefile
run-make/sysroot-crates-are-unstable/Makefile
Expand Down
15 changes: 14 additions & 1 deletion tests/codegen/iter-repeat-n-trivial-drop.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
//@ compile-flags: -O
//@ compile-flags: -C opt-level=3
//@ only-x86_64

#![crate_type = "lib"]
#![feature(iter_repeat_n)]
#![feature(array_repeat)]

#[derive(Clone)]
pub struct NotCopy(u16);
Expand Down Expand Up @@ -54,3 +55,15 @@ pub fn vec_extend_via_iter_repeat_n() -> Vec<u8> {
v.extend(std::iter::repeat_n(42_u8, n));
v
}

// Array repeat uses `RepeatN::next_unchecked` internally,
// so also check that the distinction disappears there.

#[no_mangle]
// CHECK-LABEL: @array_repeat_not_copy
pub unsafe fn array_repeat_not_copy(item: NotCopy) -> [NotCopy; 8] {
// CHECK: insertelement {{.+}} i16 %item
// CHECK: shufflevector <8 x i16> {{.+}} zeroinitializer
// CHECK: store <8 x i16>
std::array::repeat(item)
}
Loading
Loading