diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 4ef8cd7ce3000..ad38814a68b6d 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -5,7 +5,7 @@ use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry}; use rustc_middle::ty::{self, TyCtxt}; -use rustc_session::config::{FunctionReturn, OptLevel}; +use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet}; use rustc_span::symbol::sym; use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtector}; use smallvec::SmallVec; @@ -405,8 +405,33 @@ pub fn from_fn_attrs<'ll, 'tcx>( // And it is a module-level attribute, so the alternative is pulling naked functions into new LLVM modules. // Otherwise LLVM's "naked" functions come with endbr prefixes per https://github.com/rust-lang/rust/issues/98768 to_add.push(AttributeKind::NoCfCheck.create_attr(cx.llcx)); - // Need this for AArch64. - to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false")); + if llvm_util::get_version() < (19, 0, 0) { + // Prior to LLVM 19, branch-target-enforcement was disabled by setting the attribute to + // the string "false". Now it is disabled by absence of the attribute. + to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false")); + } + } else if llvm_util::get_version() >= (19, 0, 0) { + // For non-naked functions, set branch protection attributes on aarch64. + if let Some(BranchProtection { bti, pac_ret }) = + cx.sess().opts.unstable_opts.branch_protection + { + assert!(cx.sess().target.arch == "aarch64"); + if bti { + to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement")); + } + if let Some(PacRet { leaf, key }) = pac_ret { + to_add.push(llvm::CreateAttrStringValue( + cx.llcx, + "sign-return-address", + if leaf { "all" } else { "non-leaf" }, + )); + to_add.push(llvm::CreateAttrStringValue( + cx.llcx, + "sign-return-address-key", + if key == PAuthKey::A { "a_key" } else { "b_key" }, + )); + } + } } if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) || codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR_ZEROED) diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 4aba7ab5e6190..84921e87fb3f4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -698,6 +698,18 @@ where if ecx.trait_ref_is_knowable(goal.param_env, trait_ref)? { Err(NoSolution) } else { + // While the trait bound itself may be unknowable, we may be able to + // prove that a super trait is not implemented. For this, we recursively + // prove the super trait bounds of the current goal. + // + // We skip the goal itself as that one would cycle. + let predicate: I::Predicate = trait_ref.upcast(cx); + ecx.add_goals( + GoalSource::Misc, + elaborate::elaborate(cx, [predicate]) + .skip(1) + .map(|predicate| goal.with(cx, predicate)), + ); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } }, diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 63ad36efc8529..e1a3764fa76b4 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -432,6 +432,7 @@ pub trait Predicate>: + UpcastFrom> + UpcastFrom> + IntoKind>> + + Elaboratable { fn as_clause(self) -> Option; diff --git a/library/std/src/os/vita/mod.rs b/library/std/src/os/vita/mod.rs index da9edd12f7b03..92a2bf0a59ab5 100644 --- a/library/std/src/os/vita/mod.rs +++ b/library/std/src/os/vita/mod.rs @@ -1,5 +1,6 @@ //! Definitions for vita +#![forbid(unsafe_op_in_unsafe_fn)] #![stable(feature = "raw_ext", since = "1.1.0")] pub mod fs; diff --git a/library/std/src/os/vita/raw.rs b/library/std/src/os/vita/raw.rs index 74cae4d4135d1..e4b65ef1ed767 100644 --- a/library/std/src/os/vita/raw.rs +++ b/library/std/src/os/vita/raw.rs @@ -10,9 +10,6 @@ )] #![allow(deprecated)] -use crate::os::raw::c_long; -use crate::os::unix::raw::{gid_t, uid_t}; - #[stable(feature = "pthread_t", since = "1.8.0")] pub type pthread_t = libc::pthread_t; @@ -34,37 +31,3 @@ pub type off_t = libc::off_t; #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = libc::time_t; - -#[repr(C)] -#[derive(Clone)] -#[stable(feature = "raw_ext", since = "1.1.0")] -pub struct stat { - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_dev: dev_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ino: ino_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mode: mode_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_nlink: nlink_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_uid: uid_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_gid: gid_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_rdev: dev_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_size: off_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_atime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_mtime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_ctime: time_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_blksize: blksize_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_blocks: blkcnt_t, - #[stable(feature = "raw_ext", since = "1.1.0")] - pub st_spare4: [c_long; 2usize], -} diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 4898bdd2fa392..3fc51ff59a936 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -166,6 +166,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { target_os = "fuchsia", target_os = "horizon", target_os = "vxworks", + target_os = "vita", // Unikraft's `signal` implementation is currently broken: // https://github.com/unikraft/lib-musl/issues/57 target_vendor = "unikraft", @@ -212,6 +213,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { target_os = "fuchsia", target_os = "horizon", target_os = "vxworks", + target_os = "vita", )))] static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::AtomicBool = crate::sync::atomic::AtomicBool::new(false); @@ -222,6 +224,7 @@ static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::AtomicBool = target_os = "fuchsia", target_os = "horizon", target_os = "vxworks", + target_os = "vita", )))] pub(crate) fn on_broken_pipe_flag_used() -> bool { ON_BROKEN_PIPE_FLAG_USED.load(crate::sync::atomic::Ordering::Relaxed) diff --git a/library/std/src/sys/pal/unix/process/process_common.rs b/library/std/src/sys/pal/unix/process/process_common.rs index ecb5ca58db692..fec825054195a 100644 --- a/library/std/src/sys/pal/unix/process/process_common.rs +++ b/library/std/src/sys/pal/unix/process/process_common.rs @@ -124,6 +124,7 @@ pub struct StdioPipes { // passed to do_exec() with configuration of what the child stdio should look // like +#[cfg_attr(target_os = "vita", allow(dead_code))] pub struct ChildPipes { pub stdin: ChildStdio, pub stdout: ChildStdio, diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index cafe5fe4c8779..f4e231327a8c2 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1477,7 +1477,20 @@ a.test-arrow:hover { .example-wrap:hover > .test-arrow { padding: 2px 7px; } -.example-wrap:hover > .test-arrow, .example-wrap:hover > .button-holder { +/* +On iPad, the ":hover" state sticks around, making things work not greatly. Do work around +it, we move it into this media query. More information can be found at: +https://css-tricks.com/solving-sticky-hover-states-with-media-hover-hover/ + +However, using `@media (hover: hover)` makes this rule never to be applied in GUI tests, so +instead, we check that it's not a "finger" cursor. +*/ +@media not (pointer: coarse) { + .example-wrap:hover > .test-arrow, .example-wrap:hover > .button-holder { + visibility: visible; + } +} +.example-wrap .button-holder.keep-visible { visibility: visible; } .example-wrap .button-holder .copy-button { diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 40d65ae7910e2..e0ea234f9e710 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1829,14 +1829,22 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm copyContentToClipboard(codeElem.textContent); } - function addCopyButton(event) { + function getExampleWrap(event) { let elem = event.target; while (!hasClass(elem, "example-wrap")) { elem = elem.parentElement; if (elem.tagName === "body" || hasClass(elem, "docblock")) { - return; + return null; } } + return elem; + } + + function addCopyButton(event) { + const elem = getExampleWrap(event); + if (elem === null) { + return; + } // Since the button will be added, no need to keep this listener around. elem.removeEventListener("mouseover", addCopyButton); @@ -1858,7 +1866,20 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm parent.appendChild(copyButton); } + function showHideCodeExampleButtons(event) { + const elem = getExampleWrap(event); + if (elem === null) { + return; + } + const buttons = elem.querySelector(".button-holder"); + if (buttons === null) { + return; + } + buttons.classList.toggle("keep-visible"); + } + onEachLazy(document.querySelectorAll(".docblock .example-wrap"), elem => { elem.addEventListener("mouseover", addCopyButton); + elem.addEventListener("click", showHideCodeExampleButtons); }); }()); diff --git a/tests/codegen/branch-protection-old-llvm.rs b/tests/codegen/branch-protection-old-llvm.rs new file mode 100644 index 0000000000000..bb3c7a4b70c3c --- /dev/null +++ b/tests/codegen/branch-protection-old-llvm.rs @@ -0,0 +1,45 @@ +// Test that the correct module flags are emitted with different branch protection flags. + +//@ revisions: BTI PACRET LEAF BKEY NONE +//@ needs-llvm-components: aarch64 +//@ [BTI] compile-flags: -Z branch-protection=bti +//@ [PACRET] compile-flags: -Z branch-protection=pac-ret +//@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf +//@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key +//@ compile-flags: --target aarch64-unknown-linux-gnu +//@ ignore-llvm-version: 19 - 99 + +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +// A basic test function. +pub fn test() {} + +// BTI: !"branch-target-enforcement", i32 1 +// BTI: !"sign-return-address", i32 0 +// BTI: !"sign-return-address-all", i32 0 +// BTI: !"sign-return-address-with-bkey", i32 0 + +// PACRET: !"branch-target-enforcement", i32 0 +// PACRET: !"sign-return-address", i32 1 +// PACRET: !"sign-return-address-all", i32 0 +// PACRET: !"sign-return-address-with-bkey", i32 0 + +// LEAF: !"branch-target-enforcement", i32 0 +// LEAF: !"sign-return-address", i32 1 +// LEAF: !"sign-return-address-all", i32 1 +// LEAF: !"sign-return-address-with-bkey", i32 0 + +// BKEY: !"branch-target-enforcement", i32 0 +// BKEY: !"sign-return-address", i32 1 +// BKEY: !"sign-return-address-all", i32 0 +// BKEY: !"sign-return-address-with-bkey", i32 1 + +// NONE-NOT: branch-target-enforcement +// NONE-NOT: sign-return-address +// NONE-NOT: sign-return-address-all +// NONE-NOT: sign-return-address-with-bkey diff --git a/tests/codegen/branch-protection.rs b/tests/codegen/branch-protection.rs index a29ec67d578b8..2f5ff9e98c22d 100644 --- a/tests/codegen/branch-protection.rs +++ b/tests/codegen/branch-protection.rs @@ -7,6 +7,7 @@ //@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf //@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key //@ compile-flags: --target aarch64-unknown-linux-gnu +//@ min-llvm-version: 19 #![crate_type = "lib"] #![feature(no_core, lang_items)] @@ -16,23 +17,32 @@ trait Sized {} // A basic test function. +// CHECK: @test(){{.*}} [[ATTR:#[0-9]+]] { +#[no_mangle] pub fn test() {} +// BTI: attributes [[ATTR]] = {{.*}} "branch-target-enforcement" // BTI: !"branch-target-enforcement", i32 1 // BTI: !"sign-return-address", i32 0 // BTI: !"sign-return-address-all", i32 0 // BTI: !"sign-return-address-with-bkey", i32 0 +// PACRET: attributes [[ATTR]] = {{.*}} "sign-return-address"="non-leaf" +// PACRET-SAME: "sign-return-address-key"="a_key" // PACRET: !"branch-target-enforcement", i32 0 // PACRET: !"sign-return-address", i32 1 // PACRET: !"sign-return-address-all", i32 0 // PACRET: !"sign-return-address-with-bkey", i32 0 +// LEAF: attributes [[ATTR]] = {{.*}} "sign-return-address"="all" +// LEAF-SAME: "sign-return-address-key"="a_key" // LEAF: !"branch-target-enforcement", i32 0 // LEAF: !"sign-return-address", i32 1 // LEAF: !"sign-return-address-all", i32 1 // LEAF: !"sign-return-address-with-bkey", i32 0 +// BKEY: attributes [[ATTR]] = {{.*}} "sign-return-address"="non-leaf" +// BKEY-SAME: "sign-return-address-key"="b_key" // BKEY: !"branch-target-enforcement", i32 0 // BKEY: !"sign-return-address", i32 1 // BKEY: !"sign-return-address-all", i32 0 diff --git a/tests/rustdoc-gui/code-example-buttons.goml b/tests/rustdoc-gui/code-example-buttons.goml new file mode 100644 index 0000000000000..57ea2970072e6 --- /dev/null +++ b/tests/rustdoc-gui/code-example-buttons.goml @@ -0,0 +1,21 @@ +// This test ensures that code blocks buttons are displayed on hover and when you click on them. +go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html" + +// First we check we "hover". +move-cursor-to: ".example-wrap" +assert-css: (".example-wrap .copy-button", { "visibility": "visible" }) +move-cursor-to: ".search-input" +assert-css: (".example-wrap .copy-button", { "visibility": "hidden" }) + +// Now we check the click. +assert-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 0) +click: ".example-wrap" +move-cursor-to: ".search-input" +// It should have a new class and be visible. +wait-for-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 1) +wait-for-css: (".example-wrap:not(:hover) .button-holder.keep-visible", { "visibility": "visible" }) +// Clicking again will remove the class. +click: ".example-wrap" +move-cursor-to: ".search-input" +assert-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 0) +assert-css: (".example-wrap .copy-button", { "visibility": "hidden" }) diff --git a/tests/ui/coherence/normalize-for-errors.next.stderr b/tests/ui/coherence/normalize-for-errors.next.stderr index 6c56a9177414b..634a10b7a14c3 100644 --- a/tests/ui/coherence/normalize-for-errors.next.stderr +++ b/tests/ui/coherence/normalize-for-errors.next.stderr @@ -7,6 +7,7 @@ LL | LL | impl MyTrait for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, <_ as Iterator>::Item)` | + = note: upstream crates may add a new impl of trait `std::clone::Clone` for type `(MyType,)` in future versions = note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions error: aborting due to 1 previous error diff --git a/tests/ui/coherence/normalize-for-errors.rs b/tests/ui/coherence/normalize-for-errors.rs index 2288118676ab3..4188389a3ad5b 100644 --- a/tests/ui/coherence/normalize-for-errors.rs +++ b/tests/ui/coherence/normalize-for-errors.rs @@ -18,5 +18,6 @@ impl MyTrait for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {} //~^ ERROR conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, //~| NOTE conflicting implementation for `(Box<(MyType,)>, //~| NOTE upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions +//[next]~| NOTE upstream crates may add a new impl of trait `std::clone::Clone` for type `(MyType,)` in future versions fn main() {} diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-1.current.stderr b/tests/ui/coherence/super-traits/super-trait-knowable-1.current.stderr new file mode 100644 index 0000000000000..fb01cf158d980 --- /dev/null +++ b/tests/ui/coherence/super-traits/super-trait-knowable-1.current.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()` + --> $DIR/super-trait-knowable-1.rs:16:1 + | +LL | impl> Overlap for U {} + | ----------------------------------- first implementation here +LL | impl Overlap for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` + | + = note: downstream crates may implement trait `Sub<_>` for type `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-1.rs b/tests/ui/coherence/super-traits/super-trait-knowable-1.rs new file mode 100644 index 0000000000000..80df8c19ee51f --- /dev/null +++ b/tests/ui/coherence/super-traits/super-trait-knowable-1.rs @@ -0,0 +1,19 @@ +// Added in #124532. While `(): Super` is knowable, `(): Sub` is not. +// +// We therefore elaborate super trait bounds in the implicit negative +// overlap check. + +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +trait Super {} +trait Sub: Super {} + +trait Overlap {} +impl> Overlap for U {} +impl Overlap for () {} +//[current]~^ ERROR conflicting implementations + +fn main() {} diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-2.rs b/tests/ui/coherence/super-traits/super-trait-knowable-2.rs new file mode 100644 index 0000000000000..d1f2e8d1c1a15 --- /dev/null +++ b/tests/ui/coherence/super-traits/super-trait-knowable-2.rs @@ -0,0 +1,33 @@ +// A regression test for pyella-0.1.5 which broke when +// enabling the new solver in coherence. +// +// `Tensor: TensorValue` is knowable while `Tensor: TensorOp` +// may be implemented downstream. We previously didn't check the +// super trait bound in coherence, causing these impls to overlap. +// +// However, we did fail to normalize ` {} +pub trait TensorOp: TensorValue {} + +pub struct Tensor; +impl TensorCompare for Tensor {} +impl TensorCompare for T1 +where + T1: TensorOp, + T1::Unmasked: Sized, +{} + + +fn main() {} diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-3.current.stderr b/tests/ui/coherence/super-traits/super-trait-knowable-3.current.stderr new file mode 100644 index 0000000000000..542edb8b7f674 --- /dev/null +++ b/tests/ui/coherence/super-traits/super-trait-knowable-3.current.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()` + --> $DIR/super-trait-knowable-3.rs:19:1 + | +LL | impl>> Overlap for U {} + | ---------------------------------------- first implementation here +LL | impl Overlap for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` + | + = note: downstream crates may implement trait `Sub<_>` for type `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-3.rs b/tests/ui/coherence/super-traits/super-trait-knowable-3.rs new file mode 100644 index 0000000000000..295d7ac48d8cc --- /dev/null +++ b/tests/ui/coherence/super-traits/super-trait-knowable-3.rs @@ -0,0 +1,22 @@ +// Unlike in `super-trait-knowable-1.rs`, the knowable +// super trait bound is in a nested goal so this would not +// compile if we were to only elaborate root goals. + +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +trait Super {} +trait Sub: Super {} + +struct W(T); +trait Bound {} +impl, U> Bound> for T {} + +trait Overlap {} +impl>> Overlap for U {} +impl Overlap for () {} +//[current]~^ ERROR conflicting implementations of trait `Overlap<_>` for type `()` + +fn main() {} diff --git a/tests/ui/issues/issue-48728.stderr b/tests/ui/issues/issue-48728.current.stderr similarity index 95% rename from tests/ui/issues/issue-48728.stderr rename to tests/ui/issues/issue-48728.current.stderr index 6b4247f1d7965..2a1b4ff781854 100644 --- a/tests/ui/issues/issue-48728.stderr +++ b/tests/ui/issues/issue-48728.current.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Clone` for type `Node<[_]>` - --> $DIR/issue-48728.rs:4:10 + --> $DIR/issue-48728.rs:9:10 | LL | #[derive(Clone)] | ^^^^^ conflicting implementation for `Node<[_]>` diff --git a/tests/ui/issues/issue-48728.rs b/tests/ui/issues/issue-48728.rs index cbdc10bd2e1ea..7ef05f4277b27 100644 --- a/tests/ui/issues/issue-48728.rs +++ b/tests/ui/issues/issue-48728.rs @@ -1,7 +1,12 @@ // Regression test for #48728, an ICE that occurred computing // coherence "help" information. -#[derive(Clone)] //~ ERROR conflicting implementations of trait `Clone` +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +#[derive(Clone)] //[current]~ ERROR conflicting implementations of trait `Clone` struct Node(Box); impl Clone for Node<[T]> {