Auto merge of #84956 - RalfJung:rollup-m70mx2n, r=RalfJung
Rollup of 11 pull requests Successful merges: - #83553 (Update `ptr` docs with regards to `ptr::addr_of!`) - #84183 (Update RELEASES.md for 1.52.0) - #84709 (Add doc alias for `chdir` to `std::env::set_current_dir`) - #84803 (Reduce duplication in `impl_dep_tracking_hash` macros) - #84808 (Account for unsatisfied bounds in E0599) - #84843 (use else if in std library ) - #84865 (rustbuild: Pass a `threads` flag that works to windows-gnu lld) - #84878 (Clarify documentation for `[T]::contains`) - #84882 (platform-support: Center the contents of the `std` and `host` columns) - #84903 (Remove `rustc_middle::mir::interpret::CheckInAllocMsg::NullPointerTest`) - #84913 (Do not ICE on invalid const param) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
bacf770f29
16 changed files with 360 additions and 121 deletions
148
RELEASES.md
148
RELEASES.md
|
@ -1,3 +1,151 @@
|
|||
Version 1.52.0 (2021-05-06)
|
||||
============================
|
||||
|
||||
Language
|
||||
--------
|
||||
- [Added the `unsafe_op_in_unsafe_fn` lint, which checks whether the unsafe code
|
||||
in an `unsafe fn` is wrapped in a `unsafe` block.][79208] This lint
|
||||
is allowed by default, and may become a warning or hard error in a
|
||||
future edition.
|
||||
- [You can now cast mutable references to arrays to a pointer of the same type as
|
||||
the element.][81479]
|
||||
|
||||
Compiler
|
||||
--------
|
||||
- [Upgraded the default LLVM to LLVM 12.][81451]
|
||||
|
||||
Added tier 3\* support for the following targets.
|
||||
|
||||
- [`s390x-unknown-linux-musl`][82166]
|
||||
- [`riscv32gc-unknown-linux-musl` & `riscv64gc-unknown-linux-musl`][82202]
|
||||
- [`powerpc-unknown-openbsd`][82733]
|
||||
|
||||
\* Refer to Rust's [platform support page][platform-support-doc] for more
|
||||
information on Rust's tiered platform support.
|
||||
|
||||
Libraries
|
||||
---------
|
||||
- [`OsString` now implements `Extend` and `FromIterator`.][82121]
|
||||
- [`cmp::Reverse` now has `#[repr(transparent)]` representation.][81879]
|
||||
- [`Arc<impl Error>` now implements `error::Error`.][80553]
|
||||
- [All integer division and remainder operations are now `const`.][80962]
|
||||
|
||||
Stabilised APIs
|
||||
-------------
|
||||
- [`Arguments::as_str`]
|
||||
- [`char::MAX`]
|
||||
- [`char::REPLACEMENT_CHARACTER`]
|
||||
- [`char::UNICODE_VERSION`]
|
||||
- [`char::decode_utf16`]
|
||||
- [`char::from_digit`]
|
||||
- [`char::from_u32_unchecked`]
|
||||
- [`char::from_u32`]
|
||||
- [`slice::partition_point`]
|
||||
- [`str::rsplit_once`]
|
||||
- [`str::split_once`]
|
||||
|
||||
The following previously stable APIs are now `const`.
|
||||
|
||||
- [`char::len_utf8`]
|
||||
- [`char::len_utf16`]
|
||||
- [`char::to_ascii_uppercase`]
|
||||
- [`char::to_ascii_lowercase`]
|
||||
- [`char::eq_ignore_ascii_case`]
|
||||
- [`u8::to_ascii_uppercase`]
|
||||
- [`u8::to_ascii_lowercase`]
|
||||
- [`u8::eq_ignore_ascii_case`]
|
||||
|
||||
Rustdoc
|
||||
-------
|
||||
- [Rustdoc lints are now treated as a tool lint, meaning that
|
||||
lints are now prefixed with `rustdoc::` (e.g. `#[warn(rustdoc::non_autolinks)]`).][80527]
|
||||
Using the old style is still allowed, and will become a warning in
|
||||
a future release.
|
||||
- [Rustdoc now supports argument files.][82261]
|
||||
- [Rustdoc now generates smart punctuation for documentation.][79423]
|
||||
- [You can now use "task lists" in Rustdoc Markdown.][81766] E.g.
|
||||
```markdown
|
||||
- [x] Complete
|
||||
- [ ] Todo
|
||||
```
|
||||
|
||||
Misc
|
||||
----
|
||||
- [You can now pass multiple filters to tests.][81356] E.g.
|
||||
`cargo test -- foo bar` will run all tests that match `foo` and `bar`.
|
||||
- [Rustup now distributes PDB symbols for the `std` library on Windows,
|
||||
allowing you to see `std` symbols when debugging.][82218]
|
||||
|
||||
Internal Only
|
||||
-------------
|
||||
These changes provide no direct user facing benefits, but represent significant
|
||||
improvements to the internals and overall performance of rustc and
|
||||
related tools.
|
||||
|
||||
- [Check the result cache before the DepGraph when ensuring queries][81855]
|
||||
- [Try fast_reject::simplify_type in coherence before doing full check][81744]
|
||||
- [Only store a LocalDefId in some HIR nodes][81611]
|
||||
- [Store HIR attributes in a side table][79519]
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
- [Cargo build scripts are now forbidden from setting `RUSTC_BOOTSTRAP`.][cargo/9181]
|
||||
- [Removed support for the `x86_64-rumprun-netbsd` target.][82594]
|
||||
- [Deprecated the `x86_64-sun-solaris` target in favor of `x86_64-pc-solaris`.][82216]
|
||||
- [Rustdoc now only accepts `,`, ` `, and `\t` as delimiters for specifying
|
||||
languages in code blocks.][78429]
|
||||
- [Rustc now catches more cases of `pub_use_of_private_extern_crate`][80763]
|
||||
- [Changes in how proc macros handle whitespace may lead to panics when used
|
||||
with older `proc-macro-hack` versions. A `cargo update` should be sufficient to fix this in all cases.][84136]
|
||||
|
||||
[84136]: https://github.com/rust-lang/rust/issues/84136
|
||||
[80763]: https://github.com/rust-lang/rust/pull/80763
|
||||
[82166]: https://github.com/rust-lang/rust/pull/82166
|
||||
[82121]: https://github.com/rust-lang/rust/pull/82121
|
||||
[81879]: https://github.com/rust-lang/rust/pull/81879
|
||||
[82261]: https://github.com/rust-lang/rust/pull/82261
|
||||
[82218]: https://github.com/rust-lang/rust/pull/82218
|
||||
[82216]: https://github.com/rust-lang/rust/pull/82216
|
||||
[82202]: https://github.com/rust-lang/rust/pull/82202
|
||||
[81855]: https://github.com/rust-lang/rust/pull/81855
|
||||
[81766]: https://github.com/rust-lang/rust/pull/81766
|
||||
[81744]: https://github.com/rust-lang/rust/pull/81744
|
||||
[81611]: https://github.com/rust-lang/rust/pull/81611
|
||||
[81479]: https://github.com/rust-lang/rust/pull/81479
|
||||
[81451]: https://github.com/rust-lang/rust/pull/81451
|
||||
[81356]: https://github.com/rust-lang/rust/pull/81356
|
||||
[80962]: https://github.com/rust-lang/rust/pull/80962
|
||||
[80553]: https://github.com/rust-lang/rust/pull/80553
|
||||
[80527]: https://github.com/rust-lang/rust/pull/80527
|
||||
[79519]: https://github.com/rust-lang/rust/pull/79519
|
||||
[79423]: https://github.com/rust-lang/rust/pull/79423
|
||||
[79208]: https://github.com/rust-lang/rust/pull/79208
|
||||
[78429]: https://github.com/rust-lang/rust/pull/78429
|
||||
[82733]: https://github.com/rust-lang/rust/pull/82733
|
||||
[82594]: https://github.com/rust-lang/rust/pull/82594
|
||||
[cargo/9181]: https://github.com/rust-lang/cargo/pull/9181
|
||||
[`char::MAX`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.MAX
|
||||
[`char::REPLACEMENT_CHARACTER`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.REPLACEMENT_CHARACTER
|
||||
[`char::UNICODE_VERSION`]: https://doc.rust-lang.org/std/primitive.char.html#associatedconstant.UNICODE_VERSION
|
||||
[`char::decode_utf16`]: https://doc.rust-lang.org/std/primitive.char.html#method.decode_utf16
|
||||
[`char::from_u32`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_u32
|
||||
[`char::from_u32_unchecked`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_u32_unchecked
|
||||
[`char::from_digit`]: https://doc.rust-lang.org/std/primitive.char.html#method.from_digit
|
||||
[`Peekable::next_if`]: https://doc.rust-lang.org/stable/std/iter/struct.Peekable.html#method.next_if
|
||||
[`Peekable::next_if_eq`]: https://doc.rust-lang.org/stable/std/iter/struct.Peekable.html#method.next_if_eq
|
||||
[`Arguments::as_str`]: https://doc.rust-lang.org/stable/std/fmt/struct.Arguments.html#method.as_str
|
||||
[`str::split_once`]: https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_once
|
||||
[`str::rsplit_once`]: https://doc.rust-lang.org/stable/std/primitive.str.html#method.rsplit_once
|
||||
[`slice::partition_point`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.partition_point
|
||||
[`char::len_utf8`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.len_utf8
|
||||
[`char::len_utf16`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.len_utf16
|
||||
[`char::to_ascii_uppercase`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.to_ascii_uppercase
|
||||
[`char::to_ascii_lowercase`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.to_ascii_lowercase
|
||||
[`char::eq_ignore_ascii_case`]: https://doc.rust-lang.org/stable/std/primitive.char.html#method.eq_ignore_ascii_case
|
||||
[`u8::to_ascii_uppercase`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_ascii_uppercase
|
||||
[`u8::to_ascii_lowercase`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_ascii_lowercase
|
||||
[`u8::eq_ignore_ascii_case`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.eq_ignore_ascii_case
|
||||
|
||||
Version 1.51.0 (2021-03-25)
|
||||
============================
|
||||
|
||||
|
|
|
@ -171,7 +171,6 @@ impl fmt::Display for InvalidProgramInfo<'_> {
|
|||
#[derive(Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
|
||||
pub enum CheckInAllocMsg {
|
||||
MemoryAccessTest,
|
||||
NullPointerTest,
|
||||
PointerArithmeticTest,
|
||||
InboundsTest,
|
||||
}
|
||||
|
@ -185,7 +184,6 @@ impl fmt::Display for CheckInAllocMsg {
|
|||
"{}",
|
||||
match *self {
|
||||
CheckInAllocMsg::MemoryAccessTest => "memory access",
|
||||
CheckInAllocMsg::NullPointerTest => "null pointer test",
|
||||
CheckInAllocMsg::PointerArithmeticTest => "pointer arithmetic",
|
||||
CheckInAllocMsg::InboundsTest => "inbounds test",
|
||||
}
|
||||
|
@ -308,9 +306,6 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
|
|||
ptr.alloc_id,
|
||||
allocation_size.bytes()
|
||||
),
|
||||
DanglingIntPointer(_, CheckInAllocMsg::NullPointerTest) => {
|
||||
write!(f, "null pointer is not allowed for this operation")
|
||||
}
|
||||
DanglingIntPointer(i, msg) => {
|
||||
write!(f, "{} failed: 0x{:x} is not a valid pointer", msg, i)
|
||||
}
|
||||
|
|
|
@ -2332,17 +2332,17 @@ crate mod dep_tracking {
|
|||
}
|
||||
|
||||
macro_rules! impl_dep_tracking_hash_via_hash {
|
||||
($t:ty) => {
|
||||
($($t:ty),+ $(,)?) => {$(
|
||||
impl DepTrackingHash for $t {
|
||||
fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType) {
|
||||
Hash::hash(self, hasher);
|
||||
}
|
||||
}
|
||||
};
|
||||
)+};
|
||||
}
|
||||
|
||||
macro_rules! impl_dep_tracking_hash_for_sortable_vec_of {
|
||||
($t:ty) => {
|
||||
($($t:ty),+ $(,)?) => {$(
|
||||
impl DepTrackingHash for Vec<$t> {
|
||||
fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) {
|
||||
let mut elems: Vec<&$t> = self.iter().collect();
|
||||
|
@ -2354,61 +2354,65 @@ crate mod dep_tracking {
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
)+};
|
||||
}
|
||||
|
||||
impl_dep_tracking_hash_via_hash!(bool);
|
||||
impl_dep_tracking_hash_via_hash!(usize);
|
||||
impl_dep_tracking_hash_via_hash!(u64);
|
||||
impl_dep_tracking_hash_via_hash!(String);
|
||||
impl_dep_tracking_hash_via_hash!(PathBuf);
|
||||
impl_dep_tracking_hash_via_hash!(lint::Level);
|
||||
impl_dep_tracking_hash_via_hash!(Option<bool>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<u32>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<usize>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<NonZeroUsize>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<String>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<(String, u64)>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<Vec<String>>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<MergeFunctions>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<RelocModel>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<CodeModel>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<TlsModel>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<WasiExecModel>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<PanicStrategy>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<RelroLevel>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<InstrumentCoverage>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<lint::Level>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<PathBuf>);
|
||||
impl_dep_tracking_hash_via_hash!(CrateType);
|
||||
impl_dep_tracking_hash_via_hash!(MergeFunctions);
|
||||
impl_dep_tracking_hash_via_hash!(PanicStrategy);
|
||||
impl_dep_tracking_hash_via_hash!(RelroLevel);
|
||||
impl_dep_tracking_hash_via_hash!(Passes);
|
||||
impl_dep_tracking_hash_via_hash!(OptLevel);
|
||||
impl_dep_tracking_hash_via_hash!(LtoCli);
|
||||
impl_dep_tracking_hash_via_hash!(DebugInfo);
|
||||
impl_dep_tracking_hash_via_hash!(UnstableFeatures);
|
||||
impl_dep_tracking_hash_via_hash!(OutputTypes);
|
||||
impl_dep_tracking_hash_via_hash!(NativeLibKind);
|
||||
impl_dep_tracking_hash_via_hash!(SanitizerSet);
|
||||
impl_dep_tracking_hash_via_hash!(CFGuard);
|
||||
impl_dep_tracking_hash_via_hash!(TargetTriple);
|
||||
impl_dep_tracking_hash_via_hash!(Edition);
|
||||
impl_dep_tracking_hash_via_hash!(LinkerPluginLto);
|
||||
impl_dep_tracking_hash_via_hash!(Option<SplitDebuginfo>);
|
||||
impl_dep_tracking_hash_via_hash!(SwitchWithOptPath);
|
||||
impl_dep_tracking_hash_via_hash!(Option<SymbolManglingVersion>);
|
||||
impl_dep_tracking_hash_via_hash!(Option<SourceFileHashAlgorithm>);
|
||||
impl_dep_tracking_hash_via_hash!(TrimmedDefPaths);
|
||||
impl_dep_tracking_hash_via_hash!(
|
||||
bool,
|
||||
usize,
|
||||
u64,
|
||||
String,
|
||||
PathBuf,
|
||||
lint::Level,
|
||||
Option<bool>,
|
||||
Option<u32>,
|
||||
Option<usize>,
|
||||
Option<NonZeroUsize>,
|
||||
Option<String>,
|
||||
Option<(String, u64)>,
|
||||
Option<Vec<String>>,
|
||||
Option<MergeFunctions>,
|
||||
Option<RelocModel>,
|
||||
Option<CodeModel>,
|
||||
Option<TlsModel>,
|
||||
Option<WasiExecModel>,
|
||||
Option<PanicStrategy>,
|
||||
Option<RelroLevel>,
|
||||
Option<InstrumentCoverage>,
|
||||
Option<lint::Level>,
|
||||
Option<PathBuf>,
|
||||
CrateType,
|
||||
MergeFunctions,
|
||||
PanicStrategy,
|
||||
RelroLevel,
|
||||
Passes,
|
||||
OptLevel,
|
||||
LtoCli,
|
||||
DebugInfo,
|
||||
UnstableFeatures,
|
||||
OutputTypes,
|
||||
NativeLibKind,
|
||||
SanitizerSet,
|
||||
CFGuard,
|
||||
TargetTriple,
|
||||
Edition,
|
||||
LinkerPluginLto,
|
||||
Option<SplitDebuginfo>,
|
||||
SwitchWithOptPath,
|
||||
Option<SymbolManglingVersion>,
|
||||
Option<SourceFileHashAlgorithm>,
|
||||
TrimmedDefPaths,
|
||||
);
|
||||
|
||||
impl_dep_tracking_hash_for_sortable_vec_of!(String);
|
||||
impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
|
||||
impl_dep_tracking_hash_for_sortable_vec_of!((PathBuf, PathBuf));
|
||||
impl_dep_tracking_hash_for_sortable_vec_of!(CrateType);
|
||||
impl_dep_tracking_hash_for_sortable_vec_of!((String, lint::Level));
|
||||
impl_dep_tracking_hash_for_sortable_vec_of!((String, Option<String>, NativeLibKind));
|
||||
impl_dep_tracking_hash_for_sortable_vec_of!((String, u64));
|
||||
impl_dep_tracking_hash_for_sortable_vec_of!(
|
||||
String,
|
||||
PathBuf,
|
||||
(PathBuf, PathBuf),
|
||||
CrateType,
|
||||
(String, lint::Level),
|
||||
(String, Option<String>, NativeLibKind),
|
||||
(String, u64)
|
||||
);
|
||||
|
||||
impl<T1, T2> DepTrackingHash for (T1, T2)
|
||||
where
|
||||
|
|
|
@ -579,6 +579,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
let mut restrict_type_params = false;
|
||||
let mut unsatisfied_bounds = false;
|
||||
if !unsatisfied_predicates.is_empty() {
|
||||
let def_span = |def_id| {
|
||||
self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id))
|
||||
|
@ -739,6 +740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
err.note(&format!(
|
||||
"the following trait bounds were not satisfied:\n{bound_list}"
|
||||
));
|
||||
unsatisfied_bounds = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -752,6 +754,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
source,
|
||||
out_of_scope_traits,
|
||||
&unsatisfied_predicates,
|
||||
unsatisfied_bounds,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -984,9 +987,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
source: SelfSource<'tcx>,
|
||||
valid_out_of_scope_traits: Vec<DefId>,
|
||||
unsatisfied_predicates: &[(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)],
|
||||
unsatisfied_bounds: bool,
|
||||
) {
|
||||
let mut alt_rcvr_sugg = false;
|
||||
if let SelfSource::MethodCall(rcvr) = source {
|
||||
if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) {
|
||||
debug!(?span, ?item_name, ?rcvr_ty, ?rcvr);
|
||||
let skippable = [
|
||||
self.tcx.lang_items().clone_trait(),
|
||||
|
|
|
@ -191,7 +191,25 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
|
|||
Res::Def(DefKind::Ctor(..), def_id) => {
|
||||
tcx.generics_of(tcx.parent(def_id).unwrap())
|
||||
}
|
||||
Res::Def(_, def_id) => tcx.generics_of(def_id),
|
||||
// Other `DefKind`s don't have generics and would ICE when calling
|
||||
// `generics_of`.
|
||||
Res::Def(
|
||||
DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::TyAlias
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy
|
||||
| DefKind::Fn
|
||||
| DefKind::AssocFn
|
||||
| DefKind::AssocConst
|
||||
| DefKind::Impl,
|
||||
def_id,
|
||||
) => tcx.generics_of(def_id),
|
||||
Res::Err => {
|
||||
tcx.sess.delay_span_bug(tcx.def_span(def_id), "anon const with Res::Err");
|
||||
return None;
|
||||
|
|
|
@ -720,9 +720,6 @@ pub const unsafe fn read<T>(src: *const T) -> T {
|
|||
///
|
||||
/// ## On `packed` structs
|
||||
///
|
||||
/// It is currently impossible to create raw pointers to unaligned fields
|
||||
/// of a packed struct.
|
||||
///
|
||||
/// Attempting to create a raw pointer to an `unaligned` struct field with
|
||||
/// an expression such as `&packed.unaligned as *const FieldType` creates an
|
||||
/// intermediate unaligned reference before converting that to a raw pointer.
|
||||
|
@ -731,9 +728,13 @@ pub const unsafe fn read<T>(src: *const T) -> T {
|
|||
/// As a result, using `&packed.unaligned as *const FieldType` causes immediate
|
||||
/// *undefined behavior* in your program.
|
||||
///
|
||||
/// Instead you must use the [`ptr::addr_of!`](addr_of) macro to
|
||||
/// create the pointer. You may use that returned pointer together with this
|
||||
/// function.
|
||||
///
|
||||
/// An example of what not to do and how this relates to `read_unaligned` is:
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```
|
||||
/// #[repr(packed, C)]
|
||||
/// struct Packed {
|
||||
/// _padding: u8,
|
||||
|
@ -745,24 +746,15 @@ pub const unsafe fn read<T>(src: *const T) -> T {
|
|||
/// unaligned: 0x01020304,
|
||||
/// };
|
||||
///
|
||||
/// #[allow(unaligned_references)]
|
||||
/// let v = unsafe {
|
||||
/// // Here we attempt to take the address of a 32-bit integer which is not aligned.
|
||||
/// let unaligned =
|
||||
/// // A temporary unaligned reference is created here which results in
|
||||
/// // undefined behavior regardless of whether the reference is used or not.
|
||||
/// &packed.unaligned
|
||||
/// // Casting to a raw pointer doesn't help; the mistake already happened.
|
||||
/// as *const u32;
|
||||
/// // Take the address of a 32-bit integer which is not aligned.
|
||||
/// // In contrast to `&packed.unaligned as *const _`, this has no undefined behavior.
|
||||
/// let unaligned = std::ptr::addr_of!(packed.unaligned);
|
||||
///
|
||||
/// let v = std::ptr::read_unaligned(unaligned);
|
||||
///
|
||||
/// v
|
||||
/// };
|
||||
/// let v = unsafe { std::ptr::read_unaligned(unaligned) };
|
||||
/// assert_eq!(v, 0x01020304);
|
||||
/// ```
|
||||
///
|
||||
/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
|
||||
// FIXME: Update docs based on outcome of RFC #2582 and friends.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -916,9 +908,6 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
|
|||
///
|
||||
/// ## On `packed` structs
|
||||
///
|
||||
/// It is currently impossible to create raw pointers to unaligned fields
|
||||
/// of a packed struct.
|
||||
///
|
||||
/// Attempting to create a raw pointer to an `unaligned` struct field with
|
||||
/// an expression such as `&packed.unaligned as *const FieldType` creates an
|
||||
/// intermediate unaligned reference before converting that to a raw pointer.
|
||||
|
@ -927,36 +916,32 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
|
|||
/// As a result, using `&packed.unaligned as *const FieldType` causes immediate
|
||||
/// *undefined behavior* in your program.
|
||||
///
|
||||
/// An example of what not to do and how this relates to `write_unaligned` is:
|
||||
/// Instead you must use the [`ptr::addr_of_mut!`](addr_of_mut)
|
||||
/// macro to create the pointer. You may use that returned pointer together with
|
||||
/// this function.
|
||||
///
|
||||
/// ```no_run
|
||||
/// An example of how to do it and how this relates to `write_unaligned` is:
|
||||
///
|
||||
/// ```
|
||||
/// #[repr(packed, C)]
|
||||
/// struct Packed {
|
||||
/// _padding: u8,
|
||||
/// unaligned: u32,
|
||||
/// }
|
||||
///
|
||||
/// let v = 0x01020304;
|
||||
/// let mut packed: Packed = unsafe { std::mem::zeroed() };
|
||||
///
|
||||
/// #[allow(unaligned_references)]
|
||||
/// let v = unsafe {
|
||||
/// // Here we attempt to take the address of a 32-bit integer which is not aligned.
|
||||
/// let unaligned =
|
||||
/// // A temporary unaligned reference is created here which results in
|
||||
/// // undefined behavior regardless of whether the reference is used or not.
|
||||
/// &mut packed.unaligned
|
||||
/// // Casting to a raw pointer doesn't help; the mistake already happened.
|
||||
/// as *mut u32;
|
||||
/// // Take the address of a 32-bit integer which is not aligned.
|
||||
/// // In contrast to `&packed.unaligned as *mut _`, this has no undefined behavior.
|
||||
/// let unaligned = std::ptr::addr_of_mut!(packed.unaligned);
|
||||
///
|
||||
/// std::ptr::write_unaligned(unaligned, v);
|
||||
/// unsafe { std::ptr::write_unaligned(unaligned, 42) };
|
||||
///
|
||||
/// v
|
||||
/// };
|
||||
/// assert_eq!({packed.unaligned}, 42); // `{...}` forces copying the field instead of creating a reference.
|
||||
/// ```
|
||||
///
|
||||
/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.
|
||||
// FIXME: Update docs based on outcome of RFC #2582 and friends.
|
||||
/// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however
|
||||
/// (as can be seen in the `assert_eq!` above).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -1948,8 +1948,9 @@ impl<T> [T] {
|
|||
/// assert!(!v.contains(&50));
|
||||
/// ```
|
||||
///
|
||||
/// If you do not have an `&T`, but just an `&U` such that `T: Borrow<U>`
|
||||
/// (e.g. `String: Borrow<str>`), you can use `iter().any`:
|
||||
/// If you do not have a `&T`, but some other value that you can compare
|
||||
/// with one (for example, `String` implements `PartialEq<str>`), you can
|
||||
/// use `iter().any`:
|
||||
///
|
||||
/// ```
|
||||
/// let v = [String::from("hello"), String::from("world")]; // slice of `String`
|
||||
|
|
|
@ -518,13 +518,11 @@ impl Duration {
|
|||
if let Some(mut secs) = self.secs.checked_sub(rhs.secs) {
|
||||
let nanos = if self.nanos >= rhs.nanos {
|
||||
self.nanos - rhs.nanos
|
||||
} else if let Some(sub_secs) = secs.checked_sub(1) {
|
||||
secs = sub_secs;
|
||||
self.nanos + NANOS_PER_SEC - rhs.nanos
|
||||
} else {
|
||||
if let Some(sub_secs) = secs.checked_sub(1) {
|
||||
secs = sub_secs;
|
||||
self.nanos + NANOS_PER_SEC - rhs.nanos
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
return None;
|
||||
};
|
||||
debug_assert!(nanos < NANOS_PER_SEC);
|
||||
Some(Duration { secs, nanos })
|
||||
|
|
|
@ -61,6 +61,7 @@ pub fn current_dir() -> io::Result<PathBuf> {
|
|||
/// assert!(env::set_current_dir(&root).is_ok());
|
||||
/// println!("Successfully changed working directory to {}!", root.display());
|
||||
/// ```
|
||||
#[doc(alias = "chdir")]
|
||||
#[stable(feature = "env", since = "1.0.0")]
|
||||
pub fn set_current_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
|
||||
os_imp::chdir(path.as_ref())
|
||||
|
|
|
@ -445,7 +445,27 @@ mod prim_unit {}
|
|||
/// Note that here the call to [`drop`] is for clarity - it indicates
|
||||
/// that we are done with the given value and it should be destroyed.
|
||||
///
|
||||
/// ## 3. Get it from C.
|
||||
/// ## 3. Create it using `ptr::addr_of!`
|
||||
///
|
||||
/// Instead of coercing a reference to a raw pointer, you can use the macros
|
||||
/// [`ptr::addr_of!`] (for `*const T`) and [`ptr::addr_of_mut!`] (for `*mut T`).
|
||||
/// These macros allow you to create raw pointers to fields to which you cannot
|
||||
/// create a reference (without causing undefined behaviour), such as an
|
||||
/// unaligned field. This might be necessary if packed structs or uninitialized
|
||||
/// memory is involved.
|
||||
///
|
||||
/// ```
|
||||
/// #[derive(Debug, Default, Copy, Clone)]
|
||||
/// #[repr(C, packed)]
|
||||
/// struct S {
|
||||
/// aligned: u8,
|
||||
/// unaligned: u32,
|
||||
/// }
|
||||
/// let s = S::default();
|
||||
/// let p = std::ptr::addr_of!(s.unaligned); // not allowed with coercion
|
||||
/// ```
|
||||
///
|
||||
/// ## 4. Get it from C.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rustc_private)]
|
||||
|
|
|
@ -1110,6 +1110,19 @@ struct Compiletest {
|
|||
compare_mode: Option<&'static str>,
|
||||
}
|
||||
|
||||
impl Compiletest {
|
||||
fn add_lld_flags(builder: &Builder<'_>, target: TargetSelection, flags: &mut Vec<String>) {
|
||||
if builder.config.use_lld {
|
||||
if builder.is_fuse_ld_lld(target) {
|
||||
flags.push("-Clink-arg=-fuse-ld=lld".to_string());
|
||||
}
|
||||
|
||||
let threads = if target.contains("windows") { "/threads:1" } else { "--threads=1" };
|
||||
flags.push(format!("-Clink-arg=-Wl,{}", threads));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Step for Compiletest {
|
||||
type Output = ();
|
||||
|
||||
|
@ -1250,18 +1263,12 @@ note: if you're sure you want to do this, please open an issue as to why. In the
|
|||
|
||||
let mut hostflags = flags.clone();
|
||||
hostflags.push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display()));
|
||||
if builder.is_fuse_ld_lld(compiler.host) {
|
||||
hostflags.push("-Clink-args=-fuse-ld=lld".to_string());
|
||||
hostflags.push("-Clink-arg=-Wl,--threads=1".to_string());
|
||||
}
|
||||
Self::add_lld_flags(builder, compiler.host, &mut hostflags);
|
||||
cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
|
||||
|
||||
let mut targetflags = flags;
|
||||
targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display()));
|
||||
if builder.is_fuse_ld_lld(target) {
|
||||
targetflags.push("-Clink-args=-fuse-ld=lld".to_string());
|
||||
targetflags.push("-Clink-arg=-Wl,--threads=1".to_string());
|
||||
}
|
||||
Self::add_lld_flags(builder, target, &mut targetflags);
|
||||
cmd.arg("--target-rustcflags").arg(targetflags.join(" "));
|
||||
|
||||
cmd.arg("--docck-python").arg(builder.python());
|
||||
|
|
|
@ -113,7 +113,7 @@ The `std` column in the table below has the following meanings:
|
|||
[`no_std`]: https://rust-embedded.github.io/book/intro/no-std.html
|
||||
|
||||
target | std | notes
|
||||
-------|-----|-------
|
||||
-------|:---:|-------
|
||||
`aarch64-apple-ios` | ✓ | ARM64 iOS
|
||||
`aarch64-fuchsia` | ✓ | ARM64 Fuchsia
|
||||
`aarch64-linux-android` | ✓ | ARM64 Android
|
||||
|
@ -194,7 +194,7 @@ The `host` column indicates whether the codebase includes support for building
|
|||
host tools.
|
||||
|
||||
target | std | host | notes
|
||||
-------|-----|------|-------
|
||||
-------|:---:|:----:|-------
|
||||
`aarch64-apple-ios-macabi` | ? | | Apple Catalyst on ARM64
|
||||
`aarch64-apple-ios-sim` | ? | | Apple iOS Simulator on ARM64
|
||||
`aarch64-apple-tvos` | * | | ARM64 tvOS
|
||||
|
|
|
@ -6,4 +6,11 @@ fn next_u64() -> u64 {
|
|||
h.finish() //~ ERROR no method named `finish` found for struct `DefaultHasher`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
trait Bar {}
|
||||
impl Bar for String {}
|
||||
|
||||
fn main() {
|
||||
let s = String::from("hey");
|
||||
let x: &dyn Bar = &s;
|
||||
x.as_ref(); //~ ERROR the method `as_ref` exists for reference `&dyn Bar`, but its trait bounds
|
||||
}
|
||||
|
|
|
@ -15,6 +15,22 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f
|
|||
LL | use std::hash::Hasher;
|
||||
|
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0599]: the method `as_ref` exists for reference `&dyn Bar`, but its trait bounds were not satisfied
|
||||
--> $DIR/import-trait-for-method-call.rs:15:7
|
||||
|
|
||||
LL | trait Bar {}
|
||||
| --------- doesn't satisfy `dyn Bar: AsRef<_>`
|
||||
...
|
||||
LL | x.as_ref();
|
||||
| ^^^^^^ method cannot be called on `&dyn Bar` due to unsatisfied trait bounds
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`dyn Bar: AsRef<_>`
|
||||
which is required by `&dyn Bar: AsRef<_>`
|
||||
= help: items from traits can only be used if the trait is implemented and in scope
|
||||
= note: the following trait defines an item `as_ref`, perhaps you need to implement it:
|
||||
candidate #1: `AsRef`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
||||
|
|
9
src/test/ui/typeck/issue-84831.rs
Normal file
9
src/test/ui/typeck/issue-84831.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
fn f() {
|
||||
std::<0>; //~ ERROR expected value
|
||||
}
|
||||
fn j() {
|
||||
std::<_ as _>; //~ ERROR expected value
|
||||
//~^ ERROR expected one of `,` or `>`, found keyword `as`
|
||||
}
|
||||
|
||||
fn main () {}
|
26
src/test/ui/typeck/issue-84831.stderr
Normal file
26
src/test/ui/typeck/issue-84831.stderr
Normal file
|
@ -0,0 +1,26 @@
|
|||
error: expected one of `,` or `>`, found keyword `as`
|
||||
--> $DIR/issue-84831.rs:5:13
|
||||
|
|
||||
LL | std::<_ as _>;
|
||||
| ^^ expected one of `,` or `>`
|
||||
|
|
||||
help: expressions must be enclosed in braces to be used as const generic arguments
|
||||
|
|
||||
LL | std::<{ _ as _ }>;
|
||||
| ^ ^
|
||||
|
||||
error[E0423]: expected value, found crate `std`
|
||||
--> $DIR/issue-84831.rs:2:5
|
||||
|
|
||||
LL | std::<0>;
|
||||
| ^^^^^^^^ not a value
|
||||
|
||||
error[E0423]: expected value, found crate `std`
|
||||
--> $DIR/issue-84831.rs:5:5
|
||||
|
|
||||
LL | std::<_ as _>;
|
||||
| ^^^^^^^^^^^^^ not a value
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0423`.
|
Loading…
Add table
Reference in a new issue