Skip to content
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

Rollup of 8 pull requests #93457

Merged
merged 22 commits into from
Jan 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
aa6795e
Add `intrinsics::const_deallocate`
lilasta Dec 25, 2021
5e97fc9
Make `NonNull::new` `const`
lilasta Jan 23, 2022
d442a37
Fix invalid extra dot after version if no source
GuillaumeGomez Jan 25, 2022
066fcb6
Add test when there is no source code link after version
GuillaumeGomez Jan 25, 2022
29932db
`const_deallocate`: Don't deallocate memory allocated in an another c…
lilasta Jan 26, 2022
da0d506
kmc-solid: Implement `FileDesc::duplicate`
kawadakk Jan 28, 2022
7a7144f
test_const_allocate_at_runtime
lilasta Jan 28, 2022
cdd0873
Add a test case for using NonNull::new in const context
lilasta Jan 28, 2022
9d65342
fix nit
lcnr Jan 28, 2022
f9e0eb3
remove unused `jemallocator` crate
lqd Jan 28, 2022
4f8b9a4
Add Explanation For Error E0772
danii Jan 28, 2022
fa11fb4
Update browser-ui-test version to 0.5.8
GuillaumeGomez Jan 29, 2022
aee9eba
Extend theme change GUI test
GuillaumeGomez Jan 29, 2022
9728cc4
Document about some behaviors of `const_(de)allocate` and add some te…
lilasta Jan 29, 2022
11898a5
Rollup merge of #88205 - danii:e0772, r=GuillaumeGomez
matthiaskrgr Jan 29, 2022
9e86a43
Rollup merge of #92274 - woppopo:const_deallocate, r=oli-obk
matthiaskrgr Jan 29, 2022
37e9cb3
Rollup merge of #93236 - woppopo:const_nonnull_new, r=oli-obk
matthiaskrgr Jan 29, 2022
f5f2d44
Rollup merge of #93299 - GuillaumeGomez:dot-separator-no-source, r=jsha
matthiaskrgr Jan 29, 2022
2836dcd
Rollup merge of #93410 - solid-rs:feat-kmc-solid-net-dup, r=dtolnay
matthiaskrgr Jan 29, 2022
6621ff4
Rollup merge of #93424 - lcnr:nit, r=spastorino
matthiaskrgr Jan 29, 2022
c866ae5
Rollup merge of #93431 - lqd:remove-jemallocator, r=Mark-Simulacrum
matthiaskrgr Jan 29, 2022
d62b414
Rollup merge of #93453 - GuillaumeGomez:theme-change-test, r=jsha
matthiaskrgr Jan 29, 2022
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
11 changes: 0 additions & 11 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3319,7 +3319,6 @@ dependencies = [
"rustc_codegen_ssa",
"rustc_driver",
"tikv-jemalloc-sys",
"tikv-jemallocator",
]

[[package]]
Expand Down Expand Up @@ -5164,16 +5163,6 @@ dependencies = [
"libc",
]

[[package]]
name = "tikv-jemallocator"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c14a5a604eb8715bc5785018a37d00739b180bcf609916ddf4393d33d49ccdf"
dependencies = [
"libc",
"tikv-jemalloc-sys",
]

[[package]]
name = "time"
version = "0.1.43"
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ version = '0.4.0'
optional = true
features = ['unprefixed_malloc_on_supported_platforms']

[dependencies.tikv-jemallocator]
version = '0.4.0'
optional = true

[features]
jemalloc = ['tikv-jemalloc-sys', 'tikv-jemallocator']
jemalloc = ['tikv-jemalloc-sys']
llvm = ['rustc_driver/llvm']
max_level_info = ['rustc_driver/max_level_info']
10 changes: 10 additions & 0 deletions compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}

sym::const_allocate => {
// returns a null pointer at runtime.
bx.const_null(bx.type_i8p())
}

sym::const_deallocate => {
// nop at runtime.
return;
}

// This requires that atomic intrinsics follow a specific naming pattern:
// "atomic_<operation>[_<ordering>]", and no ordering means SeqCst
name if name_str.starts_with("atomic_") => {
Expand Down
27 changes: 27 additions & 0 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,33 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
)?;
ecx.write_pointer(ptr, dest)?;
}
sym::const_deallocate => {
let ptr = ecx.read_pointer(&args[0])?;
let size = ecx.read_scalar(&args[1])?.to_machine_usize(ecx)?;
let align = ecx.read_scalar(&args[2])?.to_machine_usize(ecx)?;

let size = Size::from_bytes(size);
let align = match Align::from_bytes(align) {
Ok(a) => a,
Err(err) => throw_ub_format!("align has to be a power of 2, {}", err),
};

// If an allocation is created in an another const,
// we don't deallocate it.
let (alloc_id, _, _) = ecx.memory.ptr_get_alloc(ptr)?;
let is_allocated_in_another_const = matches!(
ecx.tcx.get_global_alloc(alloc_id),
Some(interpret::GlobalAlloc::Memory(_))
);

if !is_allocated_in_another_const {
ecx.memory.deallocate(
ptr,
Some((size, align)),
interpret::MemoryKind::Machine(MemoryKind::Heap),
)?;
}
}
_ => {
return Err(ConstEvalErrKind::NeedsRfc(format!(
"calling intrinsic `{}`",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ E0768: include_str!("./error_codes/E0768.md"),
E0769: include_str!("./error_codes/E0769.md"),
E0770: include_str!("./error_codes/E0770.md"),
E0771: include_str!("./error_codes/E0771.md"),
E0772: include_str!("./error_codes/E0772.md"),
E0773: include_str!("./error_codes/E0773.md"),
E0774: include_str!("./error_codes/E0774.md"),
E0775: include_str!("./error_codes/E0775.md"),
Expand Down Expand Up @@ -642,5 +643,4 @@ E0787: include_str!("./error_codes/E0787.md"),
// E0723, // unstable feature in `const` context
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
// E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
E0772, // `'static' obligation coming from `impl dyn Trait {}` or `impl Foo for dyn Bar {}`.
}
89 changes: 89 additions & 0 deletions compiler/rustc_error_codes/src/error_codes/E0772.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
A trait object has some specific lifetime `'1`, but it was used in a way that
requires it to have a `'static` lifetime.

Example of erroneous code:

```compile_fail,E0772
trait BooleanLike {}
trait Person {}

impl BooleanLike for bool {}

impl dyn Person {
fn is_cool(&self) -> bool {
// hey you, you're pretty cool
true
}
}

fn get_is_cool<'p>(person: &'p dyn Person) -> impl BooleanLike {
// error: `person` has an anonymous lifetime `'p` but calling
// `print_cool_fn` introduces an implicit `'static` lifetime
// requirement
person.is_cool()
}
```

The trait object `person` in the function `get_is_cool`, while already being
behind a reference with lifetime `'p`, also has it's own implicit lifetime,
`'2`.

Lifetime `'2` represents the data the trait object might hold inside, for
example:

```
trait MyTrait {}

struct MyStruct<'a>(&'a i32);

impl<'a> MyTrait for MyStruct<'a> {}
```

With this scenario, if a trait object of `dyn MyTrait + '2` was made from
`MyStruct<'a>`, `'a` must live as long, if not longer than `'2`. This allows the
trait object's internal data to be accessed safely from any trait methods. This
rule also goes for any lifetime any struct made into a trait object may have.

In the implementation for `dyn Person`, the `'2` lifetime representing the
internal data was ommitted, meaning that the compiler inferred the lifetime
`'static`. As a result, the implementation's `is_cool` is inferred by the
compiler to look like this:

```
# trait Person {}
#
# impl dyn Person {
fn is_cool<'a>(self: &'a (dyn Person + 'static)) -> bool {unimplemented!()}
# }
```

While the `get_is_cool` function is inferred to look like this:

```
# trait Person {}
# trait BooleanLike {}
#
fn get_is_cool<'p, R: BooleanLike>(person: &'p (dyn Person + 'p)) -> R {
unimplemented!()
}
```

Which brings us to the core of the problem; the assignment of type
`&'_ (dyn Person + '_)` to type `&'_ (dyn Person + 'static)` is impossible.

Fixing it is as simple as being generic over lifetime `'2`, as to prevent the
compiler from inferring it as `'static`:

```
# trait Person {}
#
impl<'d> dyn Person + 'd {/* ... */}

// This works too, and is more elegant:
//impl dyn Person + '_ {/* ... */}
```

See the [Rust Reference on Trait Object Lifetime Bounds][trait-objects] for
more information on trait object lifetimes.

[trait-object-lifetime-bounds]: https://doc.rust-lang.org/reference/types/trait-object.html#trait-object-lifetime-bounds
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1810,7 +1810,7 @@ impl<'tcx> TyS<'tcx> {
pub fn sequence_element_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match self.kind() {
Array(ty, _) | Slice(ty) => ty,
Str => tcx.mk_mach_uint(ty::UintTy::U8),
Str => tcx.types.u8,
_ => bug!("`sequence_element_type` called on non-sequence value: {}", self),
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ symbols! {
const_async_blocks,
const_compare_raw_pointers,
const_constructor,
const_deallocate,
const_eval_limit,
const_eval_select,
const_eval_select_ct,
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_typeck/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,11 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
sym::const_allocate => {
(0, vec![tcx.types.usize, tcx.types.usize], tcx.mk_mut_ptr(tcx.types.u8))
}
sym::const_deallocate => (
0,
vec![tcx.mk_mut_ptr(tcx.types.u8), tcx.types.usize, tcx.types.usize],
tcx.mk_unit(),
),

sym::ptr_offset_from => {
(1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.isize)
Expand Down
23 changes: 22 additions & 1 deletion library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1914,10 +1914,31 @@ extern "rust-intrinsic" {
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
pub fn ptr_guaranteed_ne<T>(ptr: *const T, other: *const T) -> bool;

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

/// Deallocates a memory which allocated by `intrinsics::const_allocate` at compile time.
/// At runtime, does nothing.
///
/// # Safety
///
/// - The `align` argument must be a power of two.
/// - At compile time, a compile error occurs if this constraint is violated.
/// - At runtime, it is not checked.
/// - If the `ptr` is created in an another const, this intrinsic doesn't deallocate it.
/// - If the `ptr` is pointing to a local variable, this intrinsic doesn't deallocate it.
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
#[cfg(not(bootstrap))]
pub fn const_deallocate(ptr: *mut u8, size: usize, align: usize);

/// Determines whether the raw bytes of the two values are equal.
///
/// This is particularly handy for arrays, since it allows things like just
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,9 @@ impl<T: ?Sized> NonNull<T> {
/// }
/// ```
#[stable(feature = "nonnull", since = "1.25.0")]
#[rustc_const_unstable(feature = "const_nonnull_new", issue = "93235")]
#[inline]
pub fn new(ptr: *mut T) -> Option<Self> {
pub const fn new(ptr: *mut T) -> Option<Self> {
if !ptr.is_null() {
// SAFETY: The pointer is already checked and is not null
Some(unsafe { Self::new_unchecked(ptr) })
Expand Down
22 changes: 22 additions & 0 deletions library/core/tests/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,25 @@ fn test_hints_in_const_contexts() {
assert!(42u32 == core::hint::black_box(42u32));
}
}

#[cfg(not(bootstrap))]
#[test]
fn test_const_allocate_at_runtime() {
use core::intrinsics::const_allocate;
unsafe {
assert!(const_allocate(4, 4).is_null());
}
}

#[cfg(not(bootstrap))]
#[test]
fn test_const_deallocate_at_runtime() {
use core::intrinsics::const_deallocate;
const X: &u32 = &42u32;
let x = &0u32;
unsafe {
const_deallocate(X as *const _ as *mut u8, 4, 4); // nop
const_deallocate(x as *const _ as *mut u8, 4, 4); // nop
const_deallocate(core::ptr::null_mut(), 1, 1); // nop
}
}
3 changes: 3 additions & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
#![feature(const_bool_to_option)]
#![feature(const_cell_into_inner)]
#![feature(const_convert)]
#![feature(const_heap)]
#![feature(const_maybe_uninit_as_mut_ptr)]
#![feature(const_maybe_uninit_assume_init)]
#![feature(const_maybe_uninit_assume_init_read)]
#![feature(const_nonnull_new)]
#![feature(const_num_from_num)]
#![feature(const_ptr_as_ref)]
#![feature(const_ptr_read)]
#![feature(const_ptr_write)]
#![feature(const_ptr_offset)]
Expand Down
15 changes: 15 additions & 0 deletions library/core/tests/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,21 @@ fn test_unsized_nonnull() {
assert!(ys == zs);
}

#[test]
fn test_const_nonnull_new() {
const {
assert!(NonNull::new(core::ptr::null_mut::<()>()).is_none());

let value = &mut 0u32;
let mut ptr = NonNull::new(value).unwrap();
unsafe { *ptr.as_mut() = 42 };

let reference = unsafe { &*ptr.as_ref() };
assert!(*reference == *value);
assert!(*reference == 42);
};
}

#[test]
#[allow(warnings)]
// Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the
Expand Down
3 changes: 3 additions & 0 deletions library/std/src/sys/solid/abi/sockets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ extern "C" {
#[link_name = "SOLID_NET_Close"]
pub fn close(s: c_int) -> c_int;

#[link_name = "SOLID_NET_Dup"]
pub fn dup(s: c_int) -> c_int;

#[link_name = "SOLID_NET_GetPeerName"]
pub fn getpeername(s: c_int, name: *mut sockaddr, namelen: *mut socklen_t) -> c_int;

Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/solid/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl FileDesc {
}

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

Expand Down
2 changes: 1 addition & 1 deletion src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ ENV PATH="/node-v14.4.0-linux-x64/bin:${PATH}"
# https://github.com/puppeteer/puppeteer/issues/375
#
# We also specify the version in case we need to update it to go around cache limitations.
RUN npm install -g [email protected].3 --unsafe-perm=true
RUN npm install -g [email protected].8 --unsafe-perm=true

ENV RUST_CONFIGURE_ARGS \
--build=x86_64-unknown-linux-gnu \
Expand Down
7 changes: 4 additions & 3 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1676,11 +1676,12 @@ fn render_rightside(
containing_item.stable_since(tcx),
const_stable_since,
);
if has_stability {
let mut tmp_buf = Buffer::empty_from(w);
write_srclink(cx, item, &mut tmp_buf);
if has_stability && !tmp_buf.is_empty() {
w.write_str(" · ");
}

write_srclink(cx, item, w);
w.push_buffer(tmp_buf);
w.write_str("</div>");
}

Expand Down
16 changes: 16 additions & 0 deletions src/test/rustdoc-gui/theme-change.goml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,19 @@ click: "#theme-choices > button:last-child"
wait-for: 500
// should be the light theme so let's check the color
assert-css: ("body", { "background-color": "rgb(255, 255, 255)" })

goto: file://|DOC_PATH|/settings.html
click: "#theme-light"
wait-for: 500
assert-css: ("body", { "background-color": "rgb(255, 255, 255)" })
assert-local-storage: { "rustdoc-theme": "light" }

click: "#theme-dark"
wait-for: 500
assert-css: ("body", { "background-color": "rgb(53, 53, 53)" })
assert-local-storage: { "rustdoc-theme": "dark" }

click: "#theme-ayu"
wait-for: 500
assert-css: ("body", { "background-color": "rgb(15, 20, 25)" })
assert-local-storage: { "rustdoc-theme": "ayu" }
Loading