Auto merge of #134666 - matthiaskrgr:rollup-whe0chp, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #130289 (docs: Permissions.readonly() also ignores root user special permissions) - #134583 (docs: `transmute<&mut T, &mut MaybeUninit<T>>` is unsound when exposed to safe code) - #134611 (Align `{i686,x86_64}-win7-windows-msvc` to their parent targets) - #134629 (compiletest: Allow using a specific debugger when running debuginfo tests) - #134642 (Implement `PointerLike` for `isize`, `NonNull`, `Cell`, `UnsafeCell`, and `SyncUnsafeCell`.) - #134660 (Fix spacing of markdown code block fences in compiler rustdoc) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
908af5ba4a
13 changed files with 125 additions and 28 deletions
|
@ -2720,12 +2720,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// Check field access expressions, this works for both structs and tuples.
|
||||
/// Returns the Ty of the field.
|
||||
///
|
||||
/// ```not_rust
|
||||
/// base.field
|
||||
/// ^^^^^^^^^^ expr
|
||||
/// ^^^^ base
|
||||
/// ^^^^^ field
|
||||
/// ```
|
||||
/// ```ignore (illustrative)
|
||||
/// base.field
|
||||
/// ^^^^^^^^^^ expr
|
||||
/// ^^^^ base
|
||||
/// ^^^^^ field
|
||||
/// ```
|
||||
fn check_expr_field(
|
||||
&self,
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
|
|
|
@ -193,8 +193,10 @@ enum ImplTraitContext {
|
|||
}
|
||||
|
||||
/// Used for tracking import use types which will be used for redundant import checking.
|
||||
///
|
||||
/// ### Used::Scope Example
|
||||
/// ```rust,compile_fail
|
||||
///
|
||||
/// ```rust,compile_fail
|
||||
/// #![deny(redundant_imports)]
|
||||
/// use std::mem::drop;
|
||||
/// fn main() {
|
||||
|
@ -202,6 +204,7 @@ enum ImplTraitContext {
|
|||
/// drop(s);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Used::Other is for other situations like module-relative uses.
|
||||
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
|
||||
enum Used {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use crate::spec::{LinkerFlavor, Lld, Target, base};
|
||||
use crate::spec::{LinkerFlavor, Lld, SanitizerSet, Target, base};
|
||||
|
||||
pub(crate) fn target() -> Target {
|
||||
let mut base = base::windows_msvc::opts();
|
||||
base.vendor = "win7".into();
|
||||
base.cpu = "pentium4".into();
|
||||
base.max_atomic_width = Some(64);
|
||||
base.vendor = "win7".into();
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS;
|
||||
|
||||
base.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &[
|
||||
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address
|
||||
|
@ -19,7 +20,7 @@ pub(crate) fn target() -> Target {
|
|||
Target {
|
||||
llvm_target: "i686-pc-windows-msvc".into(),
|
||||
metadata: crate::spec::TargetMetadata {
|
||||
description: Some("32-bit Windows 7 support".into()),
|
||||
description: Some("32-bit MSVC (Windows 7+)".into()),
|
||||
tier: Some(3),
|
||||
host_tools: Some(false),
|
||||
std: Some(true),
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
use crate::spec::{Target, base};
|
||||
use crate::spec::{SanitizerSet, Target, base};
|
||||
|
||||
pub(crate) fn target() -> Target {
|
||||
let mut base = base::windows_msvc::opts();
|
||||
base.vendor = "win7".into();
|
||||
base.cpu = "x86-64".into();
|
||||
base.plt_by_default = false;
|
||||
base.max_atomic_width = Some(64);
|
||||
base.vendor = "win7".into();
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS;
|
||||
|
||||
Target {
|
||||
llvm_target: "x86_64-pc-windows-msvc".into(),
|
||||
metadata: crate::spec::TargetMetadata {
|
||||
description: Some("64-bit Windows 7 support".into()),
|
||||
description: Some("64-bit MSVC (Windows 7+)".into()),
|
||||
tier: Some(3),
|
||||
host_tools: Some(false),
|
||||
std: Some(true),
|
||||
|
|
|
@ -252,7 +252,7 @@
|
|||
|
||||
use crate::cmp::Ordering;
|
||||
use crate::fmt::{self, Debug, Display};
|
||||
use crate::marker::{PhantomData, Unsize};
|
||||
use crate::marker::{PhantomData, PointerLike, Unsize};
|
||||
use crate::mem;
|
||||
use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
|
||||
use crate::pin::PinCoerceUnsized;
|
||||
|
@ -677,6 +677,9 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<Cell<U>> for Cell<T> {}
|
|||
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
|
||||
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Cell<U>> for Cell<T> {}
|
||||
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
impl<T: PointerLike> PointerLike for Cell<T> {}
|
||||
|
||||
impl<T> Cell<[T]> {
|
||||
/// Returns a `&[Cell<T>]` from a `&Cell<[T]>`
|
||||
///
|
||||
|
@ -2258,6 +2261,9 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}
|
|||
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
|
||||
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T> {}
|
||||
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
impl<T: PointerLike> PointerLike for UnsafeCell<T> {}
|
||||
|
||||
/// [`UnsafeCell`], but [`Sync`].
|
||||
///
|
||||
/// This is just an `UnsafeCell`, except it implements `Sync`
|
||||
|
@ -2364,6 +2370,9 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<SyncUnsafeCell<U>> for SyncUnsafeCell
|
|||
//#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
|
||||
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}
|
||||
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
impl<T: PointerLike> PointerLike for SyncUnsafeCell<T> {}
|
||||
|
||||
#[allow(unused)]
|
||||
fn assert_coerce_unsized(
|
||||
a: UnsafeCell<&i32>,
|
||||
|
|
|
@ -1003,6 +1003,7 @@ pub trait PointerLike {}
|
|||
marker_impls! {
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
PointerLike for
|
||||
isize,
|
||||
usize,
|
||||
{T} &T,
|
||||
{T} &mut T,
|
||||
|
|
|
@ -232,6 +232,26 @@ use crate::{fmt, intrinsics, ptr, slice};
|
|||
/// remain `#[repr(transparent)]`. That said, `MaybeUninit<T>` will *always* guarantee that it has
|
||||
/// the same size, alignment, and ABI as `T`; it's just that the way `MaybeUninit` implements that
|
||||
/// guarantee may evolve.
|
||||
///
|
||||
/// Note that even though `T` and `MaybeUninit<T>` are ABI compatible it is still unsound to
|
||||
/// transmute `&mut T` to `&mut MaybeUninit<T>` and expose that to safe code because it would allow
|
||||
/// safe code to access uninitialized memory:
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use core::mem::MaybeUninit;
|
||||
///
|
||||
/// fn unsound_transmute<T>(val: &mut T) -> &mut MaybeUninit<T> {
|
||||
/// unsafe { core::mem::transmute(val) }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let mut code = 0;
|
||||
/// let code = &mut code;
|
||||
/// let code2 = unsound_transmute(code);
|
||||
/// *code2 = MaybeUninit::uninit();
|
||||
/// std::process::exit(*code); // UB! Accessing uninitialized memory.
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "maybe_uninit", since = "1.36.0")]
|
||||
// Lang item so we can wrap other types in it. This is useful for coroutines.
|
||||
#[lang = "maybe_uninit"]
|
||||
|
|
|
@ -1555,6 +1555,10 @@ impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: U
|
|||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
unsafe impl<T: ?Sized> PinCoerceUnsized for NonNull<T> {}
|
||||
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
#[cfg(not(bootstrap))]
|
||||
impl<T> core::marker::PointerLike for NonNull<T> {}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> fmt::Debug for NonNull<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
|
|
@ -1869,8 +1869,10 @@ impl Permissions {
|
|||
///
|
||||
/// # Note
|
||||
///
|
||||
/// This function does not take Access Control Lists (ACLs) or Unix group
|
||||
/// membership into account.
|
||||
/// This function does not take Access Control Lists (ACLs), Unix group
|
||||
/// membership and other nuances into account.
|
||||
/// Therefore the return value of this function cannot be relied upon
|
||||
/// to predict whether attempts to read or write the file will actually succeed.
|
||||
///
|
||||
/// # Windows
|
||||
///
|
||||
|
@ -1885,10 +1887,13 @@ impl Permissions {
|
|||
/// # Unix (including macOS)
|
||||
///
|
||||
/// On Unix-based platforms this checks if *any* of the owner, group or others
|
||||
/// write permission bits are set. It does not check if the current
|
||||
/// user is in the file's assigned group. It also does not check ACLs.
|
||||
/// Therefore the return value of this function cannot be relied upon
|
||||
/// to predict whether attempts to read or write the file will actually succeed.
|
||||
/// write permission bits are set. It does not consider anything else, including:
|
||||
///
|
||||
/// * Whether the current user is in the file's assigned group.
|
||||
/// * Permissions granted by ACL.
|
||||
/// * That `root` user can write to files that do not have any write bits set.
|
||||
/// * Writable files on a filesystem that is mounted read-only.
|
||||
///
|
||||
/// The [`PermissionsExt`] trait gives direct access to the permission bits but
|
||||
/// also does not read ACLs.
|
||||
///
|
||||
|
|
|
@ -37,7 +37,7 @@ use walkdir::WalkDir;
|
|||
|
||||
use self::header::{EarlyProps, make_test_description};
|
||||
use crate::common::{
|
||||
CompareMode, Config, Mode, PassMode, TestPaths, UI_EXTENSIONS, expected_output_path,
|
||||
CompareMode, Config, Debugger, Mode, PassMode, TestPaths, UI_EXTENSIONS, expected_output_path,
|
||||
output_base_dir, output_relative_path,
|
||||
};
|
||||
use crate::header::HeadersCache;
|
||||
|
@ -183,7 +183,13 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
"What custom diff tool to use for displaying compiletest tests.",
|
||||
"COMMAND",
|
||||
)
|
||||
.reqopt("", "minicore-path", "path to minicore aux library", "PATH");
|
||||
.reqopt("", "minicore-path", "path to minicore aux library", "PATH")
|
||||
.optopt(
|
||||
"",
|
||||
"debugger",
|
||||
"only test a specific debugger in debuginfo tests",
|
||||
"gdb | lldb | cdb",
|
||||
);
|
||||
|
||||
let (argv0, args_) = args.split_first().unwrap();
|
||||
if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
|
||||
|
@ -302,7 +308,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
stage_id: matches.opt_str("stage-id").unwrap(),
|
||||
mode,
|
||||
suite: matches.opt_str("suite").unwrap(),
|
||||
debugger: None,
|
||||
debugger: matches.opt_str("debugger").map(|debugger| {
|
||||
debugger
|
||||
.parse::<Debugger>()
|
||||
.unwrap_or_else(|_| panic!("unknown `--debugger` option `{debugger}` given"))
|
||||
}),
|
||||
run_ignored,
|
||||
with_rustc_debug_assertions,
|
||||
with_std_debug_assertions,
|
||||
|
@ -475,9 +485,16 @@ pub fn run_tests(config: Arc<Config>) {
|
|||
if let Mode::DebugInfo = config.mode {
|
||||
// Debugging emscripten code doesn't make sense today
|
||||
if !config.target.contains("emscripten") {
|
||||
configs.extend(debuggers::configure_cdb(&config));
|
||||
configs.extend(debuggers::configure_gdb(&config));
|
||||
configs.extend(debuggers::configure_lldb(&config));
|
||||
match config.debugger {
|
||||
Some(Debugger::Cdb) => configs.extend(debuggers::configure_cdb(&config)),
|
||||
Some(Debugger::Gdb) => configs.extend(debuggers::configure_gdb(&config)),
|
||||
Some(Debugger::Lldb) => configs.extend(debuggers::configure_lldb(&config)),
|
||||
None => {
|
||||
configs.extend(debuggers::configure_cdb(&config));
|
||||
configs.extend(debuggers::configure_gdb(&config));
|
||||
configs.extend(debuggers::configure_lldb(&config));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
configs.push(config.clone());
|
||||
|
|
34
tests/ui/dyn-star/cell.rs
Normal file
34
tests/ui/dyn-star/cell.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
// This test with Cell also indirectly exercises UnsafeCell in dyn*.
|
||||
//
|
||||
//@ run-pass
|
||||
|
||||
#![feature(dyn_star)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
trait Rw<T> {
|
||||
fn read(&self) -> T;
|
||||
fn write(&self, v: T);
|
||||
}
|
||||
|
||||
impl<T: Copy> Rw<T> for Cell<T> {
|
||||
fn read(&self) -> T {
|
||||
self.get()
|
||||
}
|
||||
fn write(&self, v: T) {
|
||||
self.set(v)
|
||||
}
|
||||
}
|
||||
|
||||
fn make_dyn_star() -> dyn* Rw<usize> {
|
||||
Cell::new(42usize) as dyn* Rw<usize>
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = make_dyn_star();
|
||||
|
||||
assert_eq!(x.read(), 42);
|
||||
x.write(24);
|
||||
assert_eq!(x.read(), 24);
|
||||
}
|
|
@ -6,7 +6,7 @@ use std::fmt::Debug;
|
|||
trait Foo {}
|
||||
|
||||
fn make_dyn_star() {
|
||||
let i = 42;
|
||||
let i = 42usize;
|
||||
let dyn_i: dyn* Foo = i; //~ ERROR trait bound `usize: Foo` is not satisfied
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,9 @@ LL | f32::from_bits(0x1) as f64
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `f64` needs to be a pointer-like type
|
||||
|
|
||||
= help: the trait `PointerLike` is not implemented for `f64`
|
||||
= help: the trait `PointerLike` is implemented for `usize`
|
||||
= help: the following other types implement trait `PointerLike`:
|
||||
isize
|
||||
usize
|
||||
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue