about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs12
-rw-r--r--compiler/rustc_resolve/src/lib.rs5
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs7
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs7
-rw-r--r--library/core/src/cell.rs11
-rw-r--r--library/core/src/marker.rs1
-rw-r--r--library/core/src/mem/maybe_uninit.rs20
-rw-r--r--library/core/src/ptr/non_null.rs4
-rw-r--r--library/std/src/fs.rs17
-rw-r--r--src/tools/compiletest/src/lib.rs29
-rw-r--r--tests/ui/dyn-star/cell.rs34
-rw-r--r--tests/ui/dyn-star/error.rs2
-rw-r--r--tests/ui/dyn-star/float-as-dyn-star.stderr4
13 files changed, 125 insertions, 28 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index caea53d9200..2303d777ddb 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -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>,
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 7b950b97d30..cc9ed566eda 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -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 {
diff --git a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs
index 4fc395c221c..173977b77bd 100644
--- a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs
@@ -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),
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs
index f42188ec61a..2eceb688108 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_win7_windows_msvc.rs
@@ -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),
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index cfa4c1fb564..306d565a77e 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -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>,
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index d0d8609f43f..29fc01d37fe 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -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,
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 9b3d6902098..58fb5be5812 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -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"]
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 3eeb9129347..e0ba469272e 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -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 {
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 0178691c0e5..9b752ed1443 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -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.
     ///
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index d3b4631a212..250ef0794ad 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -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());
diff --git a/tests/ui/dyn-star/cell.rs b/tests/ui/dyn-star/cell.rs
new file mode 100644
index 00000000000..f4c7927a39d
--- /dev/null
+++ b/tests/ui/dyn-star/cell.rs
@@ -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);
+}
diff --git a/tests/ui/dyn-star/error.rs b/tests/ui/dyn-star/error.rs
index 7288596f3fa..1d252d2ce42 100644
--- a/tests/ui/dyn-star/error.rs
+++ b/tests/ui/dyn-star/error.rs
@@ -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
 }
 
diff --git a/tests/ui/dyn-star/float-as-dyn-star.stderr b/tests/ui/dyn-star/float-as-dyn-star.stderr
index 9caba512e5f..06071a27afc 100644
--- a/tests/ui/dyn-star/float-as-dyn-star.stderr
+++ b/tests/ui/dyn-star/float-as-dyn-star.stderr
@@ -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