Auto merge of #128378 - matthiaskrgr:rollup-i3qz9uo, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #127574 (elaborate unknowable goals) - #128141 (Set branch protection function attributes) - #128315 (Fix vita build of std and forbid unsafe in unsafe in the os/vita module) - #128339 ([rustdoc] Make the buttons remain when code example is clicked) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7e3a971870
@ -5,7 +5,7 @@
|
||||
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)
|
||||
|
@ -698,6 +698,18 @@ fn assemble_coherence_unknowable_candidates<G: GoalKind<D>>(
|
||||
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)
|
||||
}
|
||||
},
|
||||
|
@ -432,6 +432,7 @@ pub trait Predicate<I: Interner<Predicate = Self>>:
|
||||
+ UpcastFrom<I, ty::OutlivesPredicate<I, I::Ty>>
|
||||
+ UpcastFrom<I, ty::OutlivesPredicate<I, I::Region>>
|
||||
+ IntoKind<Kind = ty::Binder<I, ty::PredicateKind<I>>>
|
||||
+ Elaboratable<I>
|
||||
{
|
||||
fn as_clause(self) -> Option<I::Clause>;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! Definitions for vita
|
||||
|
||||
#![forbid(unsafe_op_in_unsafe_fn)]
|
||||
#![stable(feature = "raw_ext", since = "1.1.0")]
|
||||
|
||||
pub mod fs;
|
||||
|
@ -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 @@
|
||||
|
||||
#[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],
|
||||
}
|
||||
|
@ -166,6 +166,7 @@ unsafe fn reset_sigpipe(#[allow(unused_variables)] 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 @@ mod sigpipe {
|
||||
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 @@ mod sigpipe {
|
||||
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)
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
});
|
||||
}());
|
||||
|
45
tests/codegen/branch-protection-old-llvm.rs
Normal file
45
tests/codegen/branch-protection-old-llvm.rs
Normal file
@ -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
|
@ -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
|
||||
|
21
tests/rustdoc-gui/code-example-buttons.goml
Normal file
21
tests/rustdoc-gui/code-example-buttons.goml
Normal file
@ -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" })
|
@ -7,6 +7,7 @@ LL |
|
||||
LL | impl<S: Iterator> MyTrait<S> 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
|
||||
|
@ -18,5 +18,6 @@ impl<S: Iterator> MyTrait<S> 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() {}
|
||||
|
@ -0,0 +1,13 @@
|
||||
error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()`
|
||||
--> $DIR/super-trait-knowable-1.rs:16:1
|
||||
|
|
||||
LL | impl<T, U: Sub<T>> Overlap<T> for U {}
|
||||
| ----------------------------------- first implementation here
|
||||
LL | impl<T> Overlap<T> 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`.
|
19
tests/ui/coherence/super-traits/super-trait-knowable-1.rs
Normal file
19
tests/ui/coherence/super-traits/super-trait-knowable-1.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// Added in #124532. While `(): Super` is knowable, `(): Sub<?t>` 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<T>: Super {}
|
||||
|
||||
trait Overlap<T> {}
|
||||
impl<T, U: Sub<T>> Overlap<T> for U {}
|
||||
impl<T> Overlap<T> for () {}
|
||||
//[current]~^ ERROR conflicting implementations
|
||||
|
||||
fn main() {}
|
33
tests/ui/coherence/super-traits/super-trait-knowable-2.rs
Normal file
33
tests/ui/coherence/super-traits/super-trait-knowable-2.rs
Normal file
@ -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<?t2>`
|
||||
// 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 `<Tensor as TensorValue::Unmasked`
|
||||
// which caused the old solver to emit a `Tensor: TensorValue` goal in
|
||||
// `fn normalize_to_error` which then failed, causing this test to pass.
|
||||
|
||||
//@ revisions: current next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@ check-pass
|
||||
|
||||
pub trait TensorValue {
|
||||
type Unmasked;
|
||||
}
|
||||
|
||||
trait TensorCompare<T> {}
|
||||
pub trait TensorOp<T>: TensorValue {}
|
||||
|
||||
pub struct Tensor;
|
||||
impl<T2> TensorCompare<T2> for Tensor {}
|
||||
impl<T1, T2> TensorCompare<T2> for T1
|
||||
where
|
||||
T1: TensorOp<T2>,
|
||||
T1::Unmasked: Sized,
|
||||
{}
|
||||
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,13 @@
|
||||
error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()`
|
||||
--> $DIR/super-trait-knowable-3.rs:19:1
|
||||
|
|
||||
LL | impl<T, U: Bound<W<T>>> Overlap<T> for U {}
|
||||
| ---------------------------------------- first implementation here
|
||||
LL | impl<T> Overlap<T> 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`.
|
22
tests/ui/coherence/super-traits/super-trait-knowable-3.rs
Normal file
22
tests/ui/coherence/super-traits/super-trait-knowable-3.rs
Normal file
@ -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<T>: Super {}
|
||||
|
||||
struct W<T>(T);
|
||||
trait Bound<T> {}
|
||||
impl<T: Sub<U>, U> Bound<W<U>> for T {}
|
||||
|
||||
trait Overlap<T> {}
|
||||
impl<T, U: Bound<W<T>>> Overlap<T> for U {}
|
||||
impl<T> Overlap<T> for () {}
|
||||
//[current]~^ ERROR conflicting implementations of trait `Overlap<_>` for type `()`
|
||||
|
||||
fn main() {}
|
@ -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<[_]>`
|
@ -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<T: ?Sized>(Box<T>);
|
||||
|
||||
impl<T: Clone + ?Sized> Clone for Node<[T]> {
|
||||
|
Loading…
Reference in New Issue
Block a user