Skip to content

Commit a00e130

Browse files
committed
Auto merge of rust-lang#93457 - matthiaskrgr:rollup-e43ry1l, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#88205 (Add Explanation For Error E0772) - rust-lang#92274 (Add `intrinsics::const_deallocate`) - rust-lang#93236 (Make `NonNull::new` `const`) - rust-lang#93299 (Fix dot separator when there is no source link) - rust-lang#93410 (kmc-solid: Implement `net::FileDesc::duplicate`) - rust-lang#93424 (fix nit) - rust-lang#93431 (remove unused `jemallocator` crate) - rust-lang#93453 (Add GUI theme change test) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents d08e816 + d62b414 commit a00e130

33 files changed

+437
-30
lines changed

Cargo.lock

-11
Original file line numberDiff line numberDiff line change
@@ -3319,7 +3319,6 @@ dependencies = [
33193319
"rustc_codegen_ssa",
33203320
"rustc_driver",
33213321
"tikv-jemalloc-sys",
3322-
"tikv-jemallocator",
33233322
]
33243323

33253324
[[package]]
@@ -5164,16 +5163,6 @@ dependencies = [
51645163
"libc",
51655164
]
51665165

5167-
[[package]]
5168-
name = "tikv-jemallocator"
5169-
version = "0.4.1"
5170-
source = "registry+https://github.com/rust-lang/crates.io-index"
5171-
checksum = "3c14a5a604eb8715bc5785018a37d00739b180bcf609916ddf4393d33d49ccdf"
5172-
dependencies = [
5173-
"libc",
5174-
"tikv-jemalloc-sys",
5175-
]
5176-
51775166
[[package]]
51785167
name = "time"
51795168
version = "0.1.43"

compiler/rustc/Cargo.toml

+1-5
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@ version = '0.4.0'
1515
optional = true
1616
features = ['unprefixed_malloc_on_supported_platforms']
1717

18-
[dependencies.tikv-jemallocator]
19-
version = '0.4.0'
20-
optional = true
21-
2218
[features]
23-
jemalloc = ['tikv-jemalloc-sys', 'tikv-jemallocator']
19+
jemalloc = ['tikv-jemalloc-sys']
2420
llvm = ['rustc_driver/llvm']
2521
max_level_info = ['rustc_driver/max_level_info']

compiler/rustc_codegen_ssa/src/mir/intrinsic.rs

+10
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
369369
}
370370
}
371371

372+
sym::const_allocate => {
373+
// returns a null pointer at runtime.
374+
bx.const_null(bx.type_i8p())
375+
}
376+
377+
sym::const_deallocate => {
378+
// nop at runtime.
379+
return;
380+
}
381+
372382
// This requires that atomic intrinsics follow a specific naming pattern:
373383
// "atomic_<operation>[_<ordering>]", and no ordering means SeqCst
374384
name if name_str.starts_with("atomic_") => {

compiler/rustc_const_eval/src/const_eval/machine.rs

+27
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,33 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
347347
)?;
348348
ecx.write_pointer(ptr, dest)?;
349349
}
350+
sym::const_deallocate => {
351+
let ptr = ecx.read_pointer(&args[0])?;
352+
let size = ecx.read_scalar(&args[1])?.to_machine_usize(ecx)?;
353+
let align = ecx.read_scalar(&args[2])?.to_machine_usize(ecx)?;
354+
355+
let size = Size::from_bytes(size);
356+
let align = match Align::from_bytes(align) {
357+
Ok(a) => a,
358+
Err(err) => throw_ub_format!("align has to be a power of 2, {}", err),
359+
};
360+
361+
// If an allocation is created in an another const,
362+
// we don't deallocate it.
363+
let (alloc_id, _, _) = ecx.memory.ptr_get_alloc(ptr)?;
364+
let is_allocated_in_another_const = matches!(
365+
ecx.tcx.get_global_alloc(alloc_id),
366+
Some(interpret::GlobalAlloc::Memory(_))
367+
);
368+
369+
if !is_allocated_in_another_const {
370+
ecx.memory.deallocate(
371+
ptr,
372+
Some((size, align)),
373+
interpret::MemoryKind::Machine(MemoryKind::Heap),
374+
)?;
375+
}
376+
}
350377
_ => {
351378
return Err(ConstEvalErrKind::NeedsRfc(format!(
352379
"calling intrinsic `{}`",

compiler/rustc_error_codes/src/error_codes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ E0768: include_str!("./error_codes/E0768.md"),
472472
E0769: include_str!("./error_codes/E0769.md"),
473473
E0770: include_str!("./error_codes/E0770.md"),
474474
E0771: include_str!("./error_codes/E0771.md"),
475+
E0772: include_str!("./error_codes/E0772.md"),
475476
E0773: include_str!("./error_codes/E0773.md"),
476477
E0774: include_str!("./error_codes/E0774.md"),
477478
E0775: include_str!("./error_codes/E0775.md"),
@@ -642,5 +643,4 @@ E0787: include_str!("./error_codes/E0787.md"),
642643
// E0723, // unstable feature in `const` context
643644
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
644645
// E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
645-
E0772, // `'static' obligation coming from `impl dyn Trait {}` or `impl Foo for dyn Bar {}`.
646646
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
A trait object has some specific lifetime `'1`, but it was used in a way that
2+
requires it to have a `'static` lifetime.
3+
4+
Example of erroneous code:
5+
6+
```compile_fail,E0772
7+
trait BooleanLike {}
8+
trait Person {}
9+
10+
impl BooleanLike for bool {}
11+
12+
impl dyn Person {
13+
fn is_cool(&self) -> bool {
14+
// hey you, you're pretty cool
15+
true
16+
}
17+
}
18+
19+
fn get_is_cool<'p>(person: &'p dyn Person) -> impl BooleanLike {
20+
// error: `person` has an anonymous lifetime `'p` but calling
21+
// `print_cool_fn` introduces an implicit `'static` lifetime
22+
// requirement
23+
person.is_cool()
24+
}
25+
```
26+
27+
The trait object `person` in the function `get_is_cool`, while already being
28+
behind a reference with lifetime `'p`, also has it's own implicit lifetime,
29+
`'2`.
30+
31+
Lifetime `'2` represents the data the trait object might hold inside, for
32+
example:
33+
34+
```
35+
trait MyTrait {}
36+
37+
struct MyStruct<'a>(&'a i32);
38+
39+
impl<'a> MyTrait for MyStruct<'a> {}
40+
```
41+
42+
With this scenario, if a trait object of `dyn MyTrait + '2` was made from
43+
`MyStruct<'a>`, `'a` must live as long, if not longer than `'2`. This allows the
44+
trait object's internal data to be accessed safely from any trait methods. This
45+
rule also goes for any lifetime any struct made into a trait object may have.
46+
47+
In the implementation for `dyn Person`, the `'2` lifetime representing the
48+
internal data was ommitted, meaning that the compiler inferred the lifetime
49+
`'static`. As a result, the implementation's `is_cool` is inferred by the
50+
compiler to look like this:
51+
52+
```
53+
# trait Person {}
54+
#
55+
# impl dyn Person {
56+
fn is_cool<'a>(self: &'a (dyn Person + 'static)) -> bool {unimplemented!()}
57+
# }
58+
```
59+
60+
While the `get_is_cool` function is inferred to look like this:
61+
62+
```
63+
# trait Person {}
64+
# trait BooleanLike {}
65+
#
66+
fn get_is_cool<'p, R: BooleanLike>(person: &'p (dyn Person + 'p)) -> R {
67+
unimplemented!()
68+
}
69+
```
70+
71+
Which brings us to the core of the problem; the assignment of type
72+
`&'_ (dyn Person + '_)` to type `&'_ (dyn Person + 'static)` is impossible.
73+
74+
Fixing it is as simple as being generic over lifetime `'2`, as to prevent the
75+
compiler from inferring it as `'static`:
76+
77+
```
78+
# trait Person {}
79+
#
80+
impl<'d> dyn Person + 'd {/* ... */}
81+
82+
// This works too, and is more elegant:
83+
//impl dyn Person + '_ {/* ... */}
84+
```
85+
86+
See the [Rust Reference on Trait Object Lifetime Bounds][trait-objects] for
87+
more information on trait object lifetimes.
88+
89+
[trait-object-lifetime-bounds]: https://doc.rust-lang.org/reference/types/trait-object.html#trait-object-lifetime-bounds

compiler/rustc_middle/src/ty/sty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1810,7 +1810,7 @@ impl<'tcx> TyS<'tcx> {
18101810
pub fn sequence_element_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
18111811
match self.kind() {
18121812
Array(ty, _) | Slice(ty) => ty,
1813-
Str => tcx.mk_mach_uint(ty::UintTy::U8),
1813+
Str => tcx.types.u8,
18141814
_ => bug!("`sequence_element_type` called on non-sequence value: {}", self),
18151815
}
18161816
}

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ symbols! {
461461
const_async_blocks,
462462
const_compare_raw_pointers,
463463
const_constructor,
464+
const_deallocate,
464465
const_eval_limit,
465466
const_eval_select,
466467
const_eval_select_ct,

compiler/rustc_typeck/src/check/intrinsic.rs

+5
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,11 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
297297
sym::const_allocate => {
298298
(0, vec![tcx.types.usize, tcx.types.usize], tcx.mk_mut_ptr(tcx.types.u8))
299299
}
300+
sym::const_deallocate => (
301+
0,
302+
vec![tcx.mk_mut_ptr(tcx.types.u8), tcx.types.usize, tcx.types.usize],
303+
tcx.mk_unit(),
304+
),
300305

301306
sym::ptr_offset_from => {
302307
(1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.isize)

library/core/src/intrinsics.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -1914,10 +1914,31 @@ extern "rust-intrinsic" {
19141914
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
19151915
pub fn ptr_guaranteed_ne<T>(ptr: *const T, other: *const T) -> bool;
19161916

1917-
/// Allocate at compile time. Should not be called at runtime.
1917+
/// Allocates a block of memory at compile time.
1918+
/// At runtime, just returns a null pointer.
1919+
///
1920+
/// # Safety
1921+
///
1922+
/// - The `align` argument must be a power of two.
1923+
/// - At compile time, a compile error occurs if this constraint is violated.
1924+
/// - At runtime, it is not checked.
19181925
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
19191926
pub fn const_allocate(size: usize, align: usize) -> *mut u8;
19201927

1928+
/// Deallocates a memory which allocated by `intrinsics::const_allocate` at compile time.
1929+
/// At runtime, does nothing.
1930+
///
1931+
/// # Safety
1932+
///
1933+
/// - The `align` argument must be a power of two.
1934+
/// - At compile time, a compile error occurs if this constraint is violated.
1935+
/// - At runtime, it is not checked.
1936+
/// - If the `ptr` is created in an another const, this intrinsic doesn't deallocate it.
1937+
/// - If the `ptr` is pointing to a local variable, this intrinsic doesn't deallocate it.
1938+
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
1939+
#[cfg(not(bootstrap))]
1940+
pub fn const_deallocate(ptr: *mut u8, size: usize, align: usize);
1941+
19211942
/// Determines whether the raw bytes of the two values are equal.
19221943
///
19231944
/// This is particularly handy for arrays, since it allows things like just

library/core/src/ptr/non_null.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,9 @@ impl<T: ?Sized> NonNull<T> {
211211
/// }
212212
/// ```
213213
#[stable(feature = "nonnull", since = "1.25.0")]
214+
#[rustc_const_unstable(feature = "const_nonnull_new", issue = "93235")]
214215
#[inline]
215-
pub fn new(ptr: *mut T) -> Option<Self> {
216+
pub const fn new(ptr: *mut T) -> Option<Self> {
216217
if !ptr.is_null() {
217218
// SAFETY: The pointer is already checked and is not null
218219
Some(unsafe { Self::new_unchecked(ptr) })

library/core/tests/intrinsics.rs

+22
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,25 @@ fn test_hints_in_const_contexts() {
8080
assert!(42u32 == core::hint::black_box(42u32));
8181
}
8282
}
83+
84+
#[cfg(not(bootstrap))]
85+
#[test]
86+
fn test_const_allocate_at_runtime() {
87+
use core::intrinsics::const_allocate;
88+
unsafe {
89+
assert!(const_allocate(4, 4).is_null());
90+
}
91+
}
92+
93+
#[cfg(not(bootstrap))]
94+
#[test]
95+
fn test_const_deallocate_at_runtime() {
96+
use core::intrinsics::const_deallocate;
97+
const X: &u32 = &42u32;
98+
let x = &0u32;
99+
unsafe {
100+
const_deallocate(X as *const _ as *mut u8, 4, 4); // nop
101+
const_deallocate(x as *const _ as *mut u8, 4, 4); // nop
102+
const_deallocate(core::ptr::null_mut(), 1, 1); // nop
103+
}
104+
}

library/core/tests/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@
1313
#![feature(const_bool_to_option)]
1414
#![feature(const_cell_into_inner)]
1515
#![feature(const_convert)]
16+
#![feature(const_heap)]
1617
#![feature(const_maybe_uninit_as_mut_ptr)]
1718
#![feature(const_maybe_uninit_assume_init)]
1819
#![feature(const_maybe_uninit_assume_init_read)]
20+
#![feature(const_nonnull_new)]
1921
#![feature(const_num_from_num)]
22+
#![feature(const_ptr_as_ref)]
2023
#![feature(const_ptr_read)]
2124
#![feature(const_ptr_write)]
2225
#![feature(const_ptr_offset)]

library/core/tests/ptr.rs

+15
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,21 @@ fn test_unsized_nonnull() {
274274
assert!(ys == zs);
275275
}
276276

277+
#[test]
278+
fn test_const_nonnull_new() {
279+
const {
280+
assert!(NonNull::new(core::ptr::null_mut::<()>()).is_none());
281+
282+
let value = &mut 0u32;
283+
let mut ptr = NonNull::new(value).unwrap();
284+
unsafe { *ptr.as_mut() = 42 };
285+
286+
let reference = unsafe { &*ptr.as_ref() };
287+
assert!(*reference == *value);
288+
assert!(*reference == 42);
289+
};
290+
}
291+
277292
#[test]
278293
#[allow(warnings)]
279294
// Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the

library/std/src/sys/solid/abi/sockets.rs

+3
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ extern "C" {
175175
#[link_name = "SOLID_NET_Close"]
176176
pub fn close(s: c_int) -> c_int;
177177

178+
#[link_name = "SOLID_NET_Dup"]
179+
pub fn dup(s: c_int) -> c_int;
180+
178181
#[link_name = "SOLID_NET_GetPeerName"]
179182
pub fn getpeername(s: c_int, name: *mut sockaddr, namelen: *mut socklen_t) -> c_int;
180183

library/std/src/sys/solid/net.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl FileDesc {
107107
}
108108

109109
fn duplicate(&self) -> io::Result<FileDesc> {
110-
super::unsupported()
110+
cvt(unsafe { netc::dup(self.fd) }).map(Self::new)
111111
}
112112
}
113113

src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ ENV PATH="/node-v14.4.0-linux-x64/bin:${PATH}"
7272
# https://github.com/puppeteer/puppeteer/issues/375
7373
#
7474
# We also specify the version in case we need to update it to go around cache limitations.
75-
RUN npm install -g browser-ui-test@0.5.3 --unsafe-perm=true
75+
RUN npm install -g browser-ui-test@0.5.8 --unsafe-perm=true
7676

7777
ENV RUST_CONFIGURE_ARGS \
7878
--build=x86_64-unknown-linux-gnu \

src/librustdoc/html/render/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1676,11 +1676,12 @@ fn render_rightside(
16761676
containing_item.stable_since(tcx),
16771677
const_stable_since,
16781678
);
1679-
if has_stability {
1679+
let mut tmp_buf = Buffer::empty_from(w);
1680+
write_srclink(cx, item, &mut tmp_buf);
1681+
if has_stability && !tmp_buf.is_empty() {
16801682
w.write_str(" · ");
16811683
}
1682-
1683-
write_srclink(cx, item, w);
1684+
w.push_buffer(tmp_buf);
16841685
w.write_str("</div>");
16851686
}
16861687

src/test/rustdoc-gui/theme-change.goml

+16
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,19 @@ click: "#theme-choices > button:last-child"
99
wait-for: 500
1010
// should be the light theme so let's check the color
1111
assert-css: ("body", { "background-color": "rgb(255, 255, 255)" })
12+
13+
goto: file://|DOC_PATH|/settings.html
14+
click: "#theme-light"
15+
wait-for: 500
16+
assert-css: ("body", { "background-color": "rgb(255, 255, 255)" })
17+
assert-local-storage: { "rustdoc-theme": "light" }
18+
19+
click: "#theme-dark"
20+
wait-for: 500
21+
assert-css: ("body", { "background-color": "rgb(53, 53, 53)" })
22+
assert-local-storage: { "rustdoc-theme": "dark" }
23+
24+
click: "#theme-ayu"
25+
wait-for: 500
26+
assert-css: ("body", { "background-color": "rgb(15, 20, 25)" })
27+
assert-local-storage: { "rustdoc-theme": "ayu" }

0 commit comments

Comments
 (0)