diff --git a/README.md b/README.md index 639789123d832..3399f7fe6c8b1 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ - + The Rust Programming Language This is the main source code repository for [Rust]. It contains the compiler, -standard library, and documentation. +standard library, and documentation. [Rust]: https://www.rust-lang.org @@ -23,7 +23,7 @@ Read ["Installation"] from [The Book]. section.** The Rust build system uses a Python script called `x.py` to build the compiler, -which manages the bootstrapping process. More information about it can be found +which manages the bootstrapping process. More information about it can be found by running `./x.py --help` or reading the [rustc dev guide][rustcguidebuild]. [gettingstarted]: https://rustc-dev-guide.rust-lang.org/getting-started.html @@ -157,17 +157,6 @@ by manually calling the appropriate vcvars file before running the bootstrap. > python x.py build ``` -### Building rustc with older host toolchains -It is still possible to build Rust with the older toolchain versions listed below, but only if the -LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN option is set to true in the config.toml file. - -* Clang 3.1 -* Apple Clang 3.1 -* GCC 4.8 -* Visual Studio 2015 (Update 3) - -Toolchain versions older than what is listed above cannot be used to build rustc. - #### Specifying an ABI Each specific ABI can also be used from either environment (for example, using diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index b83b3024295b4..a0b151a4496f1 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -239,7 +239,7 @@ //! println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56"); //! ``` //! -//! print two significantly different things: +//! print three significantly different things: //! //! ```text //! Hello, `1234.560` has 3 fractional digits diff --git a/library/std/src/os/android/fs.rs b/library/std/src/os/android/fs.rs index 9356e607c908e..6aeef330dfa24 100644 --- a/library/std/src/os/android/fs.rs +++ b/library/std/src/os/android/fs.rs @@ -8,7 +8,7 @@ use crate::os::android::raw; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/library/std/src/os/dragonfly/fs.rs b/library/std/src/os/dragonfly/fs.rs index 8552abb1cb977..e4c4e04cd30aa 100644 --- a/library/std/src/os/dragonfly/fs.rs +++ b/library/std/src/os/dragonfly/fs.rs @@ -8,7 +8,7 @@ use crate::os::dragonfly::raw; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/library/std/src/os/emscripten/fs.rs b/library/std/src/os/emscripten/fs.rs index f5e30dc8eefc9..d4f758a3457fe 100644 --- a/library/std/src/os/emscripten/fs.rs +++ b/library/std/src/os/emscripten/fs.rs @@ -8,7 +8,7 @@ use crate::os::emscripten::raw; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/library/std/src/os/freebsd/fs.rs b/library/std/src/os/freebsd/fs.rs index 6798e0d8f44fa..c6a00e179bd7f 100644 --- a/library/std/src/os/freebsd/fs.rs +++ b/library/std/src/os/freebsd/fs.rs @@ -8,7 +8,7 @@ use crate::os::freebsd::raw; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/library/std/src/os/fuchsia/fs.rs b/library/std/src/os/fuchsia/fs.rs index 1544bdfbe0cde..b48a46f9124a9 100644 --- a/library/std/src/os/fuchsia/fs.rs +++ b/library/std/src/os/fuchsia/fs.rs @@ -5,7 +5,7 @@ use crate::sys_common::AsInner; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { #[stable(feature = "metadata_ext2", since = "1.8.0")] diff --git a/library/std/src/os/haiku/fs.rs b/library/std/src/os/haiku/fs.rs index 13a4a92ae90e4..28015f6252633 100644 --- a/library/std/src/os/haiku/fs.rs +++ b/library/std/src/os/haiku/fs.rs @@ -8,7 +8,7 @@ use crate::os::haiku::raw; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/library/std/src/os/illumos/fs.rs b/library/std/src/os/illumos/fs.rs index b668aa2595d67..021d154ff5a8a 100644 --- a/library/std/src/os/illumos/fs.rs +++ b/library/std/src/os/illumos/fs.rs @@ -8,7 +8,7 @@ use crate::os::illumos::raw; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/library/std/src/os/ios/fs.rs b/library/std/src/os/ios/fs.rs index 08d3e4bcedfe2..2c5e38a803d30 100644 --- a/library/std/src/os/ios/fs.rs +++ b/library/std/src/os/ios/fs.rs @@ -8,7 +8,7 @@ use crate::os::ios::raw; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/library/std/src/os/linux/fs.rs b/library/std/src/os/linux/fs.rs index 657737394ab82..cae65f12187e2 100644 --- a/library/std/src/os/linux/fs.rs +++ b/library/std/src/os/linux/fs.rs @@ -8,7 +8,7 @@ use crate::os::linux::raw; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains @@ -18,7 +18,7 @@ pub trait MetadataExt { /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the /// cross-Unix abstractions contained within the raw stat. /// - /// [`stat`]: ../../../../std/os/linux/raw/struct.stat.html + /// [`stat`]: crate::os::linux::raw::stat /// /// # Examples /// diff --git a/library/std/src/os/macos/fs.rs b/library/std/src/os/macos/fs.rs index ad313a1240dfc..4152c3529361d 100644 --- a/library/std/src/os/macos/fs.rs +++ b/library/std/src/os/macos/fs.rs @@ -8,7 +8,7 @@ use crate::os::macos::raw; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/library/std/src/os/netbsd/fs.rs b/library/std/src/os/netbsd/fs.rs index 90980fdce8028..6b29a40d2b545 100644 --- a/library/std/src/os/netbsd/fs.rs +++ b/library/std/src/os/netbsd/fs.rs @@ -8,7 +8,7 @@ use crate::os::netbsd::raw; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/library/std/src/os/openbsd/fs.rs b/library/std/src/os/openbsd/fs.rs index 47da00ae26e72..3143dc95fdf44 100644 --- a/library/std/src/os/openbsd/fs.rs +++ b/library/std/src/os/openbsd/fs.rs @@ -8,7 +8,7 @@ use crate::os::openbsd::raw; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/library/std/src/os/redox/fs.rs b/library/std/src/os/redox/fs.rs index 61b5bff380518..94d65651daa3c 100644 --- a/library/std/src/os/redox/fs.rs +++ b/library/std/src/os/redox/fs.rs @@ -8,7 +8,7 @@ use crate::os::redox::raw; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains @@ -18,7 +18,7 @@ pub trait MetadataExt { /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the /// cross-Unix abstractions contained within the raw stat. /// - /// [`stat`]: ../../../../std/os/redox/raw/struct.stat.html + /// [`stat`]: crate::os::redox::raw::stat /// /// # Examples /// diff --git a/library/std/src/os/solaris/fs.rs b/library/std/src/os/solaris/fs.rs index 549d3d756362d..908c5c38a842e 100644 --- a/library/std/src/os/solaris/fs.rs +++ b/library/std/src/os/solaris/fs.rs @@ -8,7 +8,7 @@ use crate::os::solaris::raw; /// OS-specific extensions to [`fs::Metadata`]. /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Gain a reference to the underlying `stat` structure which contains diff --git a/library/std/src/os/vxworks/fs.rs b/library/std/src/os/vxworks/fs.rs index 57ab4fb943e43..5a7e5bcaa7600 100644 --- a/library/std/src/os/vxworks/fs.rs +++ b/library/std/src/os/vxworks/fs.rs @@ -4,7 +4,7 @@ use crate::fs::Metadata; use crate::sys_common::AsInner; /// -/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +/// [`fs::Metadata`]: crate::fs::Metadata #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { #[stable(feature = "metadata_ext2", since = "1.8.0")] diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs index 48f7cf169885f..710c616be73cb 100644 --- a/library/std/src/prelude/mod.rs +++ b/library/std/src/prelude/mod.rs @@ -17,7 +17,7 @@ //! such as [`std::io::prelude`]. Various libraries in the Rust ecosystem may //! also define their own preludes. //! -//! [`std::io::prelude`]: ../io/prelude/index.html +//! [`std::io::prelude`]: crate::io::prelude //! //! The difference between 'the prelude' and these other preludes is that they //! are not automatically `use`'d, and must be imported manually. This is still @@ -49,67 +49,34 @@ //! * [`std::iter`]::{[`Iterator`], [`Extend`], [`IntoIterator`], //! [`DoubleEndedIterator`], [`ExactSizeIterator`]}. Iterators of various //! kinds. -//! * [`std::option`]::[`Option`]::{`self`, `Some`, `None`}. A type which -//! expresses the presence or absence of a value. This type is so commonly -//! used, its variants are also exported. -//! * [`std::result`]::[`Result`]::{`self`, `Ok`, `Err`}. A type for functions -//! that may succeed or fail. Like [`Option`], its variants are exported as -//! well. +//! * [`std::option`]::[`Option`]::{[`self`][`Option`], [`Some`], [`None`]}. A +//! type which expresses the presence or absence of a value. This type is so +//! commonly used, its variants are also exported. +//! * [`std::result`]::[`Result`]::{[`self`][`Result`], [`Ok`], [`Err`]}. A type +//! for functions that may succeed or fail. Like [`Option`], its variants are +//! exported as well. //! * [`std::string`]::{[`String`], [`ToString`]}, heap allocated strings. -//! * [`std::vec`]::[`Vec`](../vec/struct.Vec.html), a growable, heap-allocated +//! * [`std::vec`]::[`Vec`], a growable, heap-allocated //! vector. //! -//! [`AsMut`]: ../convert/trait.AsMut.html -//! [`AsRef`]: ../convert/trait.AsRef.html -//! [`Box`]: ../boxed/struct.Box.html -//! [`Clone`]: ../clone/trait.Clone.html -//! [`Copy`]: ../marker/trait.Copy.html -//! [`Default`]: ../default/trait.Default.html -//! [`DoubleEndedIterator`]: ../iter/trait.DoubleEndedIterator.html -//! [`Drop`]: ../ops/trait.Drop.html -//! [`Eq`]: ../cmp/trait.Eq.html -//! [`ExactSizeIterator`]: ../iter/trait.ExactSizeIterator.html -//! [`Extend`]: ../iter/trait.Extend.html -//! [`FnMut`]: ../ops/trait.FnMut.html -//! [`FnOnce`]: ../ops/trait.FnOnce.html -//! [`Fn`]: ../ops/trait.Fn.html -//! [`From`]: ../convert/trait.From.html -//! [`IntoIterator`]: ../iter/trait.IntoIterator.html -//! [`Into`]: ../convert/trait.Into.html -//! [`Iterator`]: ../iter/trait.Iterator.html -//! [`Option`]: ../option/enum.Option.html -//! [`Ord`]: ../cmp/trait.Ord.html -//! [`PartialEq`]: ../cmp/trait.PartialEq.html -//! [`PartialOrd`]: ../cmp/trait.PartialOrd.html -//! [`Result`]: ../result/enum.Result.html -//! [`Send`]: ../marker/trait.Send.html -//! [`Sized`]: ../marker/trait.Sized.html -//! [`SliceConcatExt`]: ../slice/trait.SliceConcatExt.html -//! [`String`]: ../string/struct.String.html -//! [`Sync`]: ../marker/trait.Sync.html -//! [`ToOwned`]: ../borrow/trait.ToOwned.html -//! [`ToString`]: ../string/trait.ToString.html -//! [`Unpin`]: ../marker/trait.Unpin.html -//! [`Vec`]: ../vec/struct.Vec.html -//! [`Clone::clone`]: ../clone/trait.Clone.html#tymethod.clone -//! [`mem::drop`]: ../mem/fn.drop.html -//! [`std::borrow`]: ../borrow/index.html -//! [`std::boxed`]: ../boxed/index.html -//! [`std::clone`]: ../clone/index.html -//! [`std::cmp`]: ../cmp/index.html -//! [`std::convert`]: ../convert/index.html -//! [`std::default`]: ../default/index.html -//! [`std::iter`]: ../iter/index.html -//! [`std::marker`]: ../marker/index.html -//! [`std::mem`]: ../mem/index.html -//! [`std::ops`]: ../ops/index.html -//! [`std::option`]: ../option/index.html -//! [`std::prelude::v1`]: v1/index.html -//! [`std::result`]: ../result/index.html -//! [`std::slice`]: ../slice/index.html -//! [`std::string`]: ../string/index.html +//! [`mem::drop`]: crate::mem::drop +//! [`std::borrow`]: crate::borrow +//! [`std::boxed`]: crate::boxed +//! [`std::clone`]: crate::clone +//! [`std::cmp`]: crate::cmp +//! [`std::convert`]: crate::convert +//! [`std::default`]: crate::default +//! [`std::iter`]: crate::iter +//! [`std::marker`]: crate::marker +//! [`std::mem`]: crate::mem +//! [`std::ops`]: crate::ops +//! [`std::option`]: crate::option +//! [`std::prelude::v1`]: v1 +//! [`std::result`]: crate::result +//! [`std::slice`]: crate::slice +//! [`std::string`]: crate::string //! [`std::vec`]: ../vec/index.html -//! [`to_owned`]: ../borrow/trait.ToOwned.html#tymethod.to_owned +//! [`to_owned`]: crate::borrow::ToOwned::to_owned //! [book-closures]: ../../book/ch13-01-closures.html //! [book-dtor]: ../../book/ch15-03-drop.html //! [book-enums]: ../../book/ch06-01-defining-an-enum.html diff --git a/library/std/src/time.rs b/library/std/src/time.rs index 9f4fa89cd5506..969c442884df2 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -97,7 +97,6 @@ pub use core::time::Duration; /// [clock_time_get (Monotonic Clock)]: https://nuxi.nl/cloudabi/#clock_time_get /// /// **Disclaimer:** These system calls might change over time. -/// #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[stable(feature = "time2", since = "1.8.0")] pub struct Instant(time::Instant); @@ -125,11 +124,6 @@ pub struct Instant(time::Instant); /// The size of a `SystemTime` struct may vary depending on the target operating /// system. /// -/// [`Instant`]: ../../std/time/struct.Instant.html -/// [`Result`]: ../../std/result/enum.Result.html -/// [`Duration`]: ../../std/time/struct.Duration.html -/// [`UNIX_EPOCH`]: ../../std/time/constant.UNIX_EPOCH.html -/// /// Example: /// /// ```no_run @@ -176,7 +170,6 @@ pub struct Instant(time::Instant); /// [GetSystemTimeAsFileTime]: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimeasfiletime /// /// **Disclaimer:** These system calls might change over time. -/// #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[stable(feature = "time2", since = "1.8.0")] pub struct SystemTime(time::SystemTime); @@ -368,7 +361,7 @@ impl Add for Instant { /// This function may panic if the resulting point in time cannot be represented by the /// underlying data structure. See [`checked_add`] for a version without panic. /// - /// [`checked_add`]: ../../std/time/struct.Instant.html#method.checked_add + /// [`checked_add`]: Instant::checked_add fn add(self, other: Duration) -> Instant { self.checked_add(other).expect("overflow when adding duration to instant") } @@ -463,11 +456,6 @@ impl SystemTime { /// Returns an [`Err`] if `earlier` is later than `self`, and the error /// contains how far from `self` the time is. /// - /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok - /// [`Duration`]: ../../std/time/struct.Duration.html - /// [`Err`]: ../../std/result/enum.Result.html#variant.Err - /// [`Instant`]: ../../std/time/struct.Instant.html - /// /// # Examples /// /// ``` @@ -497,11 +485,6 @@ impl SystemTime { /// Returns an [`Err`] if `self` is later than the current system time, and /// the error contains how far from the current system time `self` is. /// - /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok - /// [`Duration`]: ../../std/time/struct.Duration.html - /// [`Err`]: ../../std/result/enum.Result.html#variant.Err - /// [`Instant`]: ../../std/time/struct.Instant.html - /// /// # Examples /// /// ```no_run @@ -544,7 +527,7 @@ impl Add for SystemTime { /// This function may panic if the resulting point in time cannot be represented by the /// underlying data structure. See [`checked_add`] for a version without panic. /// - /// [`checked_add`]: ../../std/time/struct.SystemTime.html#method.checked_add + /// [`checked_add`]: SystemTime::checked_add fn add(self, dur: Duration) -> SystemTime { self.checked_add(dur).expect("overflow when adding duration to instant") } @@ -589,8 +572,6 @@ impl fmt::Debug for SystemTime { /// measurement lies, and using `UNIX_EPOCH + duration` can be used to create a /// [`SystemTime`] instance to represent another fixed point in time. /// -/// [`SystemTime`]: ../../std/time/struct.SystemTime.html -/// /// # Examples /// /// ```no_run @@ -608,13 +589,9 @@ impl SystemTimeError { /// Returns the positive duration which represents how far forward the /// second system time was from the first. /// - /// A `SystemTimeError` is returned from the [`duration_since`] and [`elapsed`] - /// methods of [`SystemTime`] whenever the second system time represents a point later - /// in time than the `self` of the method call. - /// - /// [`duration_since`]: ../../std/time/struct.SystemTime.html#method.duration_since - /// [`elapsed`]: ../../std/time/struct.SystemTime.html#method.elapsed - /// [`SystemTime`]: ../../std/time/struct.SystemTime.html + /// A `SystemTimeError` is returned from the [`SystemTime::duration_since`] + /// and [`SystemTime::elapsed`] methods whenever the second system time + /// represents a point later in time than the `self` of the method call. /// /// # Examples /// diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index c4c985dd134ba..28a5fe31fc4b5 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -18,7 +18,15 @@ It can be used to embed handwritten assembly in the assembly output generated by Generally this should not be necessary, but might be where the required performance or timing cannot be otherwise achieved. Accessing low level hardware primitives, e.g. in kernel code, may also demand this functionality. -> **Note**: the examples here are given in x86/x86-64 assembly, but ARM, AArch64 and RISC-V are also supported. +> **Note**: the examples here are given in x86/x86-64 assembly, but other architectures are also supported. + +Inline assembly is currently supported on the following architectures: +- x86 and x86-64 +- ARM +- AArch64 +- RISC-V +- NVPTX +- Hexagon ## Basic usage @@ -606,6 +614,10 @@ Some registers cannot be used for input or output operands: | RISC-V | `gp`, `tp` | These registers are reserved and cannot be used as inputs or outputs. | | Hexagon | `lr` | This is the link register which cannot be used as an input or output. | +In some cases LLVM will allocate a "reserved register" for `reg` operands even though this register cannot be explicitly specified. Assembly code making use of reserved registers should be careful since `reg` operands may alias with those registers. Reserved registers are: +- The frame pointer on all architectures. +- `r6` on ARM. + ## Template modifiers The placeholders can be augmented by modifiers which are specified after the `:` in the curly braces. These modifiers do not affect register allocation, but change the way operands are formatted when inserted into the template string. Only one modifier is allowed per template placeholder. diff --git a/src/librustc_middle/mir/interpret/queries.rs b/src/librustc_middle/mir/interpret/queries.rs index 442e7f6b0f45e..dcc1f8b1a4b3c 100644 --- a/src/librustc_middle/mir/interpret/queries.rs +++ b/src/librustc_middle/mir/interpret/queries.rs @@ -74,4 +74,27 @@ impl<'tcx> TyCtxt<'tcx> { self.const_eval_validated(inputs) } } + + /// Evaluate a static's initializer, returning the allocation of the initializer's memory. + pub fn eval_static_initializer( + self, + def_id: DefId, + ) -> Result<&'tcx mir::Allocation, ErrorHandled> { + trace!("eval_static_initializer: Need to compute {:?}", def_id); + assert!(self.is_static(def_id)); + let instance = ty::Instance::mono(self, def_id); + let gid = GlobalId { instance, promoted: None }; + self.eval_to_allocation(gid, ty::ParamEnv::reveal_all()) + } + + /// Evaluate anything constant-like, returning the allocation of the final memory. + fn eval_to_allocation( + self, + gid: GlobalId<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) -> Result<&'tcx mir::Allocation, ErrorHandled> { + trace!("eval_to_allocation: Need to compute {:?}", gid); + let raw_const = self.const_eval_raw(param_env.and(gid))?; + Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory()) + } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 705a547262f02..49d97ff7ceccc 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -14,13 +14,12 @@ use std::ptr; use rustc_ast::ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::def_id::DefId; -use rustc_middle::ty::{self, Instance, ParamEnv, TyCtxt}; +use rustc_middle::ty::{Instance, ParamEnv, TyCtxt}; use rustc_target::abi::{Align, HasDataLayout, Size, TargetDataLayout}; use super::{ - AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, GlobalAlloc, GlobalId, - InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Scalar, + AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, GlobalAlloc, InterpResult, + Machine, MayLeak, Pointer, PointerArithmetic, Scalar, }; use crate::util::pretty; @@ -119,17 +118,6 @@ pub struct Memory<'mir, 'tcx, M: Machine<'mir, 'tcx>> { pub tcx: TyCtxt<'tcx>, } -/// Return the `tcx` allocation containing the initial value of the given static -pub fn get_static(tcx: TyCtxt<'tcx>, def_id: DefId) -> InterpResult<'tcx, &'tcx Allocation> { - trace!("get_static: Need to compute {:?}", def_id); - let instance = Instance::mono(tcx, def_id); - let gid = GlobalId { instance, promoted: None }; - // Use the raw query here to break validation cycles. Later uses of the static - // will call the full query anyway. - let raw_const = tcx.const_eval_raw(ty::ParamEnv::reveal_all().and(gid))?; - Ok(tcx.global_alloc(raw_const.alloc_id).unwrap_memory()) -} - impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for Memory<'mir, 'tcx, M> { #[inline] fn data_layout(&self) -> &TargetDataLayout { @@ -489,7 +477,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { throw_unsup!(ReadExternStatic(def_id)); } - (get_static(tcx, def_id)?, Some(def_id)) + (tcx.eval_static_initializer(def_id)?, Some(def_id)) } }; M::before_access_global(memory_extra, id, alloc, def_id, is_write)?; diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 5218b03d65ecc..a931b0bbe9777 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -21,7 +21,7 @@ pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in pub use self::eval_context::{Frame, FrameInfo, InterpCx, LocalState, LocalValue, StackPopCleanup}; pub use self::intern::{intern_const_alloc_recursive, InternKind}; pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, StackPopJump}; -pub use self::memory::{get_static, AllocCheck, FnVal, Memory, MemoryKind}; +pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind}; pub use self::operand::{ImmTy, Immediate, OpTy, Operand}; pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy}; pub use self::validity::RefTracking; diff --git a/src/librustc_typeck/check/place_op.rs b/src/librustc_typeck/check/place_op.rs index 84f34c0039a0a..4bef9aecd2ecb 100644 --- a/src/librustc_typeck/check/place_op.rs +++ b/src/librustc_typeck/check/place_op.rs @@ -9,6 +9,7 @@ use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use rustc_trait_selection::autoderef::Autoderef; +use std::slice; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Type-check `*oprnd_expr` with `oprnd_expr` type-checked already. @@ -243,19 +244,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } match expr.kind { - hir::ExprKind::Index(ref base_expr, ref index_expr) => { - // We need to get the final type in case dereferences were needed for the trait - // to apply (#72002). - let index_expr_ty = self.typeck_results.borrow().expr_ty_adjusted(index_expr); - self.convert_place_op_to_mutable( - PlaceOp::Index, - expr, - base_expr, - &[index_expr_ty], - ); + hir::ExprKind::Index(ref base_expr, ..) => { + self.convert_place_op_to_mutable(PlaceOp::Index, expr, base_expr); } hir::ExprKind::Unary(hir::UnOp::UnDeref, ref base_expr) => { - self.convert_place_op_to_mutable(PlaceOp::Deref, expr, base_expr, &[]); + self.convert_place_op_to_mutable(PlaceOp::Deref, expr, base_expr); } _ => {} } @@ -267,9 +260,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { op: PlaceOp, expr: &hir::Expr<'_>, base_expr: &hir::Expr<'_>, - arg_tys: &[Ty<'tcx>], ) { - debug!("convert_place_op_to_mutable({:?}, {:?}, {:?}, {:?})", op, expr, base_expr, arg_tys); + debug!("convert_place_op_to_mutable({:?}, {:?}, {:?})", op, expr, base_expr); if !self.typeck_results.borrow().is_method_call(expr) { debug!("convert_place_op_to_mutable - builtin, nothing to do"); return; @@ -284,6 +276,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .expect("place op takes something that is not a ref") .ty; + let arg_ty = match op { + PlaceOp::Deref => None, + PlaceOp::Index => { + // We would need to recover the `T` used when we resolve `<_ as Index>::index` + // in try_index_step. This is the subst at index 1. + // + // Note: we should *not* use `expr_ty` of index_expr here because autoderef + // during coercions can cause type of index_expr to differ from `T` (#72002). + // We also could not use `expr_ty_adjusted` of index_expr because reborrowing + // during coercions can also cause type of index_expr to differ from `T`, + // which can potentially cause regionck failure (#74933). + Some(self.typeck_results.borrow().node_substs(expr.hir_id).type_at(1)) + } + }; + let arg_tys = match arg_ty { + None => &[], + Some(ref ty) => slice::from_ref(ty), + }; + let method = self.try_mutable_overloaded_place_op(expr.span, base_ty, arg_tys, op); let method = match method { Some(ok) => self.register_infer_ok_obligations(ok), diff --git a/src/test/ui/typeck/issue-74933.rs b/src/test/ui/typeck/issue-74933.rs new file mode 100644 index 0000000000000..4b6c173b8ce58 --- /dev/null +++ b/src/test/ui/typeck/issue-74933.rs @@ -0,0 +1,38 @@ +// check-pass +// +// rust-lang/rust#74933: Lifetime error when indexing with borrowed index + +use std::ops::{Index, IndexMut}; + +struct S(V); +struct K<'a>(&'a ()); +struct V; + +impl<'a> Index<&'a K<'a>> for S { + type Output = V; + + fn index(&self, _: &'a K<'a>) -> &V { + &self.0 + } +} + +impl<'a> IndexMut<&'a K<'a>> for S { + fn index_mut(&mut self, _: &'a K<'a>) -> &mut V { + &mut self.0 + } +} + +impl V { + fn foo(&mut self) {} +} + +fn test(s: &mut S, k: &K<'_>) { + s[k] = V; + s[k].foo(); +} + +fn main() { + let mut s = S(V); + let k = K(&()); + test(&mut s, &k); +} diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 9c27a8a6f8876..bce3cf06b0751 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -263,7 +263,7 @@ pub fn check(path: &Path, bad: &mut bool) { suppressible_tidy_err!(err, skip_undocumented_unsafe, "undocumented unsafe"); } } - if line.contains("// SAFETY: ") || line.contains("// Safety: ") { + if line.contains("// SAFETY:") || line.contains("// Safety:") { last_safety_comment = true; } else if line.trim().starts_with("//") || line.trim().is_empty() { // keep previous value