Skip to content

Commit 7e3a971

Browse files
committed
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
2 parents 710ce90 + c2b085b commit 7e3a971

21 files changed

+268
-45
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_codegen_ssa::traits::*;
55
use rustc_hir::def_id::DefId;
66
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry};
77
use rustc_middle::ty::{self, TyCtxt};
8-
use rustc_session::config::{FunctionReturn, OptLevel};
8+
use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet};
99
use rustc_span::symbol::sym;
1010
use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtector};
1111
use smallvec::SmallVec;
@@ -405,8 +405,33 @@ pub fn from_fn_attrs<'ll, 'tcx>(
405405
// And it is a module-level attribute, so the alternative is pulling naked functions into new LLVM modules.
406406
// Otherwise LLVM's "naked" functions come with endbr prefixes per https://github.com/rust-lang/rust/issues/98768
407407
to_add.push(AttributeKind::NoCfCheck.create_attr(cx.llcx));
408-
// Need this for AArch64.
409-
to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false"));
408+
if llvm_util::get_version() < (19, 0, 0) {
409+
// Prior to LLVM 19, branch-target-enforcement was disabled by setting the attribute to
410+
// the string "false". Now it is disabled by absence of the attribute.
411+
to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false"));
412+
}
413+
} else if llvm_util::get_version() >= (19, 0, 0) {
414+
// For non-naked functions, set branch protection attributes on aarch64.
415+
if let Some(BranchProtection { bti, pac_ret }) =
416+
cx.sess().opts.unstable_opts.branch_protection
417+
{
418+
assert!(cx.sess().target.arch == "aarch64");
419+
if bti {
420+
to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement"));
421+
}
422+
if let Some(PacRet { leaf, key }) = pac_ret {
423+
to_add.push(llvm::CreateAttrStringValue(
424+
cx.llcx,
425+
"sign-return-address",
426+
if leaf { "all" } else { "non-leaf" },
427+
));
428+
to_add.push(llvm::CreateAttrStringValue(
429+
cx.llcx,
430+
"sign-return-address-key",
431+
if key == PAuthKey::A { "a_key" } else { "b_key" },
432+
));
433+
}
434+
}
410435
}
411436
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR)
412437
|| codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR_ZEROED)

compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,18 @@ where
698698
if ecx.trait_ref_is_knowable(goal.param_env, trait_ref)? {
699699
Err(NoSolution)
700700
} else {
701+
// While the trait bound itself may be unknowable, we may be able to
702+
// prove that a super trait is not implemented. For this, we recursively
703+
// prove the super trait bounds of the current goal.
704+
//
705+
// We skip the goal itself as that one would cycle.
706+
let predicate: I::Predicate = trait_ref.upcast(cx);
707+
ecx.add_goals(
708+
GoalSource::Misc,
709+
elaborate::elaborate(cx, [predicate])
710+
.skip(1)
711+
.map(|predicate| goal.with(cx, predicate)),
712+
);
701713
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
702714
}
703715
},

compiler/rustc_type_ir/src/inherent.rs

+1
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ pub trait Predicate<I: Interner<Predicate = Self>>:
432432
+ UpcastFrom<I, ty::OutlivesPredicate<I, I::Ty>>
433433
+ UpcastFrom<I, ty::OutlivesPredicate<I, I::Region>>
434434
+ IntoKind<Kind = ty::Binder<I, ty::PredicateKind<I>>>
435+
+ Elaboratable<I>
435436
{
436437
fn as_clause(self) -> Option<I::Clause>;
437438

library/std/src/os/vita/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Definitions for vita
22
3+
#![forbid(unsafe_op_in_unsafe_fn)]
34
#![stable(feature = "raw_ext", since = "1.1.0")]
45

56
pub mod fs;

library/std/src/os/vita/raw.rs

-37
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010
)]
1111
#![allow(deprecated)]
1212

13-
use crate::os::raw::c_long;
14-
use crate::os::unix::raw::{gid_t, uid_t};
15-
1613
#[stable(feature = "pthread_t", since = "1.8.0")]
1714
pub type pthread_t = libc::pthread_t;
1815

@@ -34,37 +31,3 @@ pub type off_t = libc::off_t;
3431

3532
#[stable(feature = "raw_ext", since = "1.1.0")]
3633
pub type time_t = libc::time_t;
37-
38-
#[repr(C)]
39-
#[derive(Clone)]
40-
#[stable(feature = "raw_ext", since = "1.1.0")]
41-
pub struct stat {
42-
#[stable(feature = "raw_ext", since = "1.1.0")]
43-
pub st_dev: dev_t,
44-
#[stable(feature = "raw_ext", since = "1.1.0")]
45-
pub st_ino: ino_t,
46-
#[stable(feature = "raw_ext", since = "1.1.0")]
47-
pub st_mode: mode_t,
48-
#[stable(feature = "raw_ext", since = "1.1.0")]
49-
pub st_nlink: nlink_t,
50-
#[stable(feature = "raw_ext", since = "1.1.0")]
51-
pub st_uid: uid_t,
52-
#[stable(feature = "raw_ext", since = "1.1.0")]
53-
pub st_gid: gid_t,
54-
#[stable(feature = "raw_ext", since = "1.1.0")]
55-
pub st_rdev: dev_t,
56-
#[stable(feature = "raw_ext", since = "1.1.0")]
57-
pub st_size: off_t,
58-
#[stable(feature = "raw_ext", since = "1.1.0")]
59-
pub st_atime: time_t,
60-
#[stable(feature = "raw_ext", since = "1.1.0")]
61-
pub st_mtime: time_t,
62-
#[stable(feature = "raw_ext", since = "1.1.0")]
63-
pub st_ctime: time_t,
64-
#[stable(feature = "raw_ext", since = "1.1.0")]
65-
pub st_blksize: blksize_t,
66-
#[stable(feature = "raw_ext", since = "1.1.0")]
67-
pub st_blocks: blkcnt_t,
68-
#[stable(feature = "raw_ext", since = "1.1.0")]
69-
pub st_spare4: [c_long; 2usize],
70-
}

library/std/src/sys/pal/unix/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
166166
target_os = "fuchsia",
167167
target_os = "horizon",
168168
target_os = "vxworks",
169+
target_os = "vita",
169170
// Unikraft's `signal` implementation is currently broken:
170171
// https://github.com/unikraft/lib-musl/issues/57
171172
target_vendor = "unikraft",
@@ -212,6 +213,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
212213
target_os = "fuchsia",
213214
target_os = "horizon",
214215
target_os = "vxworks",
216+
target_os = "vita",
215217
)))]
216218
static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::AtomicBool =
217219
crate::sync::atomic::AtomicBool::new(false);
@@ -222,6 +224,7 @@ static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::AtomicBool =
222224
target_os = "fuchsia",
223225
target_os = "horizon",
224226
target_os = "vxworks",
227+
target_os = "vita",
225228
)))]
226229
pub(crate) fn on_broken_pipe_flag_used() -> bool {
227230
ON_BROKEN_PIPE_FLAG_USED.load(crate::sync::atomic::Ordering::Relaxed)

library/std/src/sys/pal/unix/process/process_common.rs

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ pub struct StdioPipes {
124124

125125
// passed to do_exec() with configuration of what the child stdio should look
126126
// like
127+
#[cfg_attr(target_os = "vita", allow(dead_code))]
127128
pub struct ChildPipes {
128129
pub stdin: ChildStdio,
129130
pub stdout: ChildStdio,

src/librustdoc/html/static/css/rustdoc.css

+14-1
Original file line numberDiff line numberDiff line change
@@ -1477,7 +1477,20 @@ a.test-arrow:hover {
14771477
.example-wrap:hover > .test-arrow {
14781478
padding: 2px 7px;
14791479
}
1480-
.example-wrap:hover > .test-arrow, .example-wrap:hover > .button-holder {
1480+
/*
1481+
On iPad, the ":hover" state sticks around, making things work not greatly. Do work around
1482+
it, we move it into this media query. More information can be found at:
1483+
https://css-tricks.com/solving-sticky-hover-states-with-media-hover-hover/
1484+
1485+
However, using `@media (hover: hover)` makes this rule never to be applied in GUI tests, so
1486+
instead, we check that it's not a "finger" cursor.
1487+
*/
1488+
@media not (pointer: coarse) {
1489+
.example-wrap:hover > .test-arrow, .example-wrap:hover > .button-holder {
1490+
visibility: visible;
1491+
}
1492+
}
1493+
.example-wrap .button-holder.keep-visible {
14811494
visibility: visible;
14821495
}
14831496
.example-wrap .button-holder .copy-button {

src/librustdoc/html/static/js/main.js

+23-2
Original file line numberDiff line numberDiff line change
@@ -1829,14 +1829,22 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
18291829
copyContentToClipboard(codeElem.textContent);
18301830
}
18311831

1832-
function addCopyButton(event) {
1832+
function getExampleWrap(event) {
18331833
let elem = event.target;
18341834
while (!hasClass(elem, "example-wrap")) {
18351835
elem = elem.parentElement;
18361836
if (elem.tagName === "body" || hasClass(elem, "docblock")) {
1837-
return;
1837+
return null;
18381838
}
18391839
}
1840+
return elem;
1841+
}
1842+
1843+
function addCopyButton(event) {
1844+
const elem = getExampleWrap(event);
1845+
if (elem === null) {
1846+
return;
1847+
}
18401848
// Since the button will be added, no need to keep this listener around.
18411849
elem.removeEventListener("mouseover", addCopyButton);
18421850

@@ -1858,7 +1866,20 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
18581866
parent.appendChild(copyButton);
18591867
}
18601868

1869+
function showHideCodeExampleButtons(event) {
1870+
const elem = getExampleWrap(event);
1871+
if (elem === null) {
1872+
return;
1873+
}
1874+
const buttons = elem.querySelector(".button-holder");
1875+
if (buttons === null) {
1876+
return;
1877+
}
1878+
buttons.classList.toggle("keep-visible");
1879+
}
1880+
18611881
onEachLazy(document.querySelectorAll(".docblock .example-wrap"), elem => {
18621882
elem.addEventListener("mouseover", addCopyButton);
1883+
elem.addEventListener("click", showHideCodeExampleButtons);
18631884
});
18641885
}());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Test that the correct module flags are emitted with different branch protection flags.
2+
3+
//@ revisions: BTI PACRET LEAF BKEY NONE
4+
//@ needs-llvm-components: aarch64
5+
//@ [BTI] compile-flags: -Z branch-protection=bti
6+
//@ [PACRET] compile-flags: -Z branch-protection=pac-ret
7+
//@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf
8+
//@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key
9+
//@ compile-flags: --target aarch64-unknown-linux-gnu
10+
//@ ignore-llvm-version: 19 - 99
11+
12+
#![crate_type = "lib"]
13+
#![feature(no_core, lang_items)]
14+
#![no_core]
15+
16+
#[lang = "sized"]
17+
trait Sized {}
18+
19+
// A basic test function.
20+
pub fn test() {}
21+
22+
// BTI: !"branch-target-enforcement", i32 1
23+
// BTI: !"sign-return-address", i32 0
24+
// BTI: !"sign-return-address-all", i32 0
25+
// BTI: !"sign-return-address-with-bkey", i32 0
26+
27+
// PACRET: !"branch-target-enforcement", i32 0
28+
// PACRET: !"sign-return-address", i32 1
29+
// PACRET: !"sign-return-address-all", i32 0
30+
// PACRET: !"sign-return-address-with-bkey", i32 0
31+
32+
// LEAF: !"branch-target-enforcement", i32 0
33+
// LEAF: !"sign-return-address", i32 1
34+
// LEAF: !"sign-return-address-all", i32 1
35+
// LEAF: !"sign-return-address-with-bkey", i32 0
36+
37+
// BKEY: !"branch-target-enforcement", i32 0
38+
// BKEY: !"sign-return-address", i32 1
39+
// BKEY: !"sign-return-address-all", i32 0
40+
// BKEY: !"sign-return-address-with-bkey", i32 1
41+
42+
// NONE-NOT: branch-target-enforcement
43+
// NONE-NOT: sign-return-address
44+
// NONE-NOT: sign-return-address-all
45+
// NONE-NOT: sign-return-address-with-bkey

tests/codegen/branch-protection.rs

+10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf
88
//@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key
99
//@ compile-flags: --target aarch64-unknown-linux-gnu
10+
//@ min-llvm-version: 19
1011

1112
#![crate_type = "lib"]
1213
#![feature(no_core, lang_items)]
@@ -16,23 +17,32 @@
1617
trait Sized {}
1718

1819
// A basic test function.
20+
// CHECK: @test(){{.*}} [[ATTR:#[0-9]+]] {
21+
#[no_mangle]
1922
pub fn test() {}
2023

24+
// BTI: attributes [[ATTR]] = {{.*}} "branch-target-enforcement"
2125
// BTI: !"branch-target-enforcement", i32 1
2226
// BTI: !"sign-return-address", i32 0
2327
// BTI: !"sign-return-address-all", i32 0
2428
// BTI: !"sign-return-address-with-bkey", i32 0
2529

30+
// PACRET: attributes [[ATTR]] = {{.*}} "sign-return-address"="non-leaf"
31+
// PACRET-SAME: "sign-return-address-key"="a_key"
2632
// PACRET: !"branch-target-enforcement", i32 0
2733
// PACRET: !"sign-return-address", i32 1
2834
// PACRET: !"sign-return-address-all", i32 0
2935
// PACRET: !"sign-return-address-with-bkey", i32 0
3036

37+
// LEAF: attributes [[ATTR]] = {{.*}} "sign-return-address"="all"
38+
// LEAF-SAME: "sign-return-address-key"="a_key"
3139
// LEAF: !"branch-target-enforcement", i32 0
3240
// LEAF: !"sign-return-address", i32 1
3341
// LEAF: !"sign-return-address-all", i32 1
3442
// LEAF: !"sign-return-address-with-bkey", i32 0
3543

44+
// BKEY: attributes [[ATTR]] = {{.*}} "sign-return-address"="non-leaf"
45+
// BKEY-SAME: "sign-return-address-key"="b_key"
3646
// BKEY: !"branch-target-enforcement", i32 0
3747
// BKEY: !"sign-return-address", i32 1
3848
// BKEY: !"sign-return-address-all", i32 0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// This test ensures that code blocks buttons are displayed on hover and when you click on them.
2+
go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
3+
4+
// First we check we "hover".
5+
move-cursor-to: ".example-wrap"
6+
assert-css: (".example-wrap .copy-button", { "visibility": "visible" })
7+
move-cursor-to: ".search-input"
8+
assert-css: (".example-wrap .copy-button", { "visibility": "hidden" })
9+
10+
// Now we check the click.
11+
assert-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 0)
12+
click: ".example-wrap"
13+
move-cursor-to: ".search-input"
14+
// It should have a new class and be visible.
15+
wait-for-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 1)
16+
wait-for-css: (".example-wrap:not(:hover) .button-holder.keep-visible", { "visibility": "visible" })
17+
// Clicking again will remove the class.
18+
click: ".example-wrap"
19+
move-cursor-to: ".search-input"
20+
assert-count: (".example-wrap:not(:hover) .button-holder.keep-visible", 0)
21+
assert-css: (".example-wrap .copy-button", { "visibility": "hidden" })

tests/ui/coherence/normalize-for-errors.next.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ LL |
77
LL | impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
88
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, <_ as Iterator>::Item)`
99
|
10+
= note: upstream crates may add a new impl of trait `std::clone::Clone` for type `(MyType,)` in future versions
1011
= note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
1112

1213
error: aborting due to 1 previous error

tests/ui/coherence/normalize-for-errors.rs

+1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
1818
//~^ ERROR conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>,
1919
//~| NOTE conflicting implementation for `(Box<(MyType,)>,
2020
//~| NOTE upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
21+
//[next]~| NOTE upstream crates may add a new impl of trait `std::clone::Clone` for type `(MyType,)` in future versions
2122

2223
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()`
2+
--> $DIR/super-trait-knowable-1.rs:16:1
3+
|
4+
LL | impl<T, U: Sub<T>> Overlap<T> for U {}
5+
| ----------------------------------- first implementation here
6+
LL | impl<T> Overlap<T> for () {}
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
8+
|
9+
= note: downstream crates may implement trait `Sub<_>` for type `()`
10+
11+
error: aborting due to 1 previous error
12+
13+
For more information about this error, try `rustc --explain E0119`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Added in #124532. While `(): Super` is knowable, `(): Sub<?t>` is not.
2+
//
3+
// We therefore elaborate super trait bounds in the implicit negative
4+
// overlap check.
5+
6+
//@ revisions: current next
7+
//@ ignore-compare-mode-next-solver (explicit revisions)
8+
//@[next] compile-flags: -Znext-solver
9+
//@[next] check-pass
10+
11+
trait Super {}
12+
trait Sub<T>: Super {}
13+
14+
trait Overlap<T> {}
15+
impl<T, U: Sub<T>> Overlap<T> for U {}
16+
impl<T> Overlap<T> for () {}
17+
//[current]~^ ERROR conflicting implementations
18+
19+
fn main() {}

0 commit comments

Comments
 (0)