Auto merge of #97180 - Dylan-DPC:rollup-aa5j2yw, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #96539 (Add release notes for 1.61.0) - #97142 (move processing of `source_scope_data` into `MutVisitor`'s impl of `Integrator` when inline) - #97155 (Fix doc typo) - #97169 (Improve `u32 as char` cast diagnostic) - #97170 (Remove unnecessay .report() on ExitCode) - #97171 (Add regression test for #88119) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
a09d36deae
9 changed files with 216 additions and 59 deletions
126
RELEASES.md
126
RELEASES.md
|
@ -1,3 +1,129 @@
|
|||
Version 1.61.0 (2022-05-19)
|
||||
==========================
|
||||
|
||||
Language
|
||||
--------
|
||||
|
||||
- [`const fn` signatures can now include generic trait bounds][93827]
|
||||
- [`const fn` signatures can now use `impl Trait` in argument and return position][93827]
|
||||
- [Function pointers can now be created, cast, and passed around in a `const fn`][93827]
|
||||
- [Recursive calls can now set the value of a function's opaque `impl Trait` return type][94081]
|
||||
|
||||
Compiler
|
||||
--------
|
||||
|
||||
- [Linking modifier syntax in `#[link]` attributes and on the command line, as well as the `whole-archive` modifier specifically, are now supported][93901]
|
||||
- [The `char` type is now described as UTF-32 in debuginfo][89887]
|
||||
- The [`#[target_feature]`][target_feature] attribute [can now be used with aarch64 features][90621]
|
||||
- X86 [`#[target_feature = "adx"]` is now stable][93745]
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
||||
- [`ManuallyDrop<T>` is now documented to have the same layout as `T`][88375]
|
||||
- [`#[ignore = "…"]` messages are printed when running tests][92714]
|
||||
- [Consistently show absent stdio handles on Windows as NULL handles][93263]
|
||||
- [Make `std::io::stdio::lock()` return `'static` handles.][93965] Previously, the creation of locked handles to stdin/stdout/stderr would borrow the handles being locked, which prevented writing `let out = std::io::stdout().lock();` because `out` would outlive the return value of `stdout()`. Such code now works, eliminating a common pitfall that affected many Rust users.
|
||||
- [`Vec::from_raw_parts` is now less restrictive about its inputs][95016]
|
||||
- [`std::thread::available_parallelism` now takes cgroup quotas into account.][92697] Since `available_parallelism` is often used to create a thread pool for parallel computation, which may be CPU-bound for performance, `available_parallelism` will return a value consistent with the ability to use that many threads continuously, if possible. For instance, in a container with 8 virtual CPUs but quotas only allowing for 50% usage, `available_parallelism` will return 4.
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
|
||||
- [`Pin::static_mut`]
|
||||
- [`Pin::static_ref`]
|
||||
- [`Vec::retain_mut`]
|
||||
- [`VecDeque::retain_mut`]
|
||||
- [`Write` for `Cursor<[u8; N]>`][cursor-write-array]
|
||||
- [`std::os::unix::net::SocketAddr::from_pathname`]
|
||||
- [`std::process::ExitCode`] and [`std::process::Termination`]. The stabilization of these two APIs now makes it possible for programs to return errors from `main` with custom exit codes.
|
||||
- [`std::thread::JoinHandle::is_finished`]
|
||||
|
||||
These APIs are now usable in const contexts:
|
||||
|
||||
- [`<*const T>::offset` and `<*mut T>::offset`][ptr-offset]
|
||||
- [`<*const T>::wrapping_offset` and `<*mut T>::wrapping_offset`][ptr-wrapping_offset]
|
||||
- [`<*const T>::add` and `<*mut T>::add`][ptr-add]
|
||||
- [`<*const T>::sub` and `<*mut T>::sub`][ptr-sub]
|
||||
- [`<*const T>::wrapping_add` and `<*mut T>::wrapping_add`][ptr-wrapping_add]
|
||||
- [`<*const T>::wrapping_sub` and `<*mut T>::wrapping_sub`][ptr-wrapping_sub]
|
||||
- [`<[T]>::as_mut_ptr`][slice-as_mut_ptr]
|
||||
- [`<[T]>::as_ptr_range`][slice-as_ptr_range]
|
||||
- [`<[T]>::as_mut_ptr_range`][slice-as_mut_ptr_range]
|
||||
|
||||
Cargo
|
||||
-----
|
||||
|
||||
No feature changes, but see compatibility notes.
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
|
||||
- Previously native static libraries were linked as `whole-archive` in some cases, but now rustc tries not to use `whole-archive` unless explicitly requested. This [change][93901] may result in linking errors in some cases. To fix such errors, native libraries linked from the command line, build scripts, or [`#[link]` attributes][link-attr] need to
|
||||
- (more common) either be reordered to respect dependencies between them (if `a` depends on `b` then `a` should go first and `b` second)
|
||||
- (less common) or be updated to use the [`+whole-archive`] modifier.
|
||||
- [Catching a second unwind from FFI code while cleaning up from a Rust panic now causes the process to abort][92911]
|
||||
- [Proc macros no longer see `ident` matchers wrapped in groups][92472]
|
||||
- [The number of `#` in `r#` raw string literals is now required to be less than 256][95251]
|
||||
- [When checking that a dyn type satisfies a trait bound, supertrait bounds are now enforced][92285]
|
||||
- [`cargo vendor` now only accepts one value for each `--sync` flag][cargo/10448]
|
||||
- [`cfg` predicates in `all()` and `any()` are always evaluated to detect errors, instead of short-circuiting.][94295] The compatibility considerations here arise in nightly-only code that used the short-circuiting behavior of `all` to write something like `cfg(all(feature = "nightly", syntax-requiring-nightly))`, which will now fail to compile. Instead, use either `cfg_attr(feature = "nightly", ...)` or nested uses of `cfg`.
|
||||
- [bootstrap: static-libstdcpp is now enabled by default, and can now be disabled when llvm-tools is enabled][94832]
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
These changes provide no direct user facing benefits, but represent significant
|
||||
improvements to the internals and overall performance of rustc
|
||||
and related tools.
|
||||
|
||||
- [debuginfo: Refactor debuginfo generation for types][94261]
|
||||
- [Remove the everybody loops pass][93913]
|
||||
|
||||
[88375]: https://github.com/rust-lang/rust/pull/88375/
|
||||
[89887]: https://github.com/rust-lang/rust/pull/89887/
|
||||
[90621]: https://github.com/rust-lang/rust/pull/90621/
|
||||
[92285]: https://github.com/rust-lang/rust/pull/92285/
|
||||
[92472]: https://github.com/rust-lang/rust/pull/92472/
|
||||
[92697]: https://github.com/rust-lang/rust/pull/92697/
|
||||
[92714]: https://github.com/rust-lang/rust/pull/92714/
|
||||
[92911]: https://github.com/rust-lang/rust/pull/92911/
|
||||
[93263]: https://github.com/rust-lang/rust/pull/93263/
|
||||
[93745]: https://github.com/rust-lang/rust/pull/93745/
|
||||
[93827]: https://github.com/rust-lang/rust/pull/93827/
|
||||
[93901]: https://github.com/rust-lang/rust/pull/93901/
|
||||
[93913]: https://github.com/rust-lang/rust/pull/93913/
|
||||
[93965]: https://github.com/rust-lang/rust/pull/93965/
|
||||
[94081]: https://github.com/rust-lang/rust/pull/94081/
|
||||
[94261]: https://github.com/rust-lang/rust/pull/94261/
|
||||
[94295]: https://github.com/rust-lang/rust/pull/94295/
|
||||
[94832]: https://github.com/rust-lang/rust/pull/94832/
|
||||
[95016]: https://github.com/rust-lang/rust/pull/95016/
|
||||
[95251]: https://github.com/rust-lang/rust/pull/95251/
|
||||
[`+whole-archive`]: https://doc.rust-lang.org/stable/rustc/command-line-arguments.html#linking-modifiers-whole-archive
|
||||
[`Pin::static_mut`]: https://doc.rust-lang.org/stable/std/pin/struct.Pin.html#method.static_mut
|
||||
[`Pin::static_ref`]: https://doc.rust-lang.org/stable/std/pin/struct.Pin.html#method.static_ref
|
||||
[`Vec::retain_mut`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.retain_mut
|
||||
[`VecDeque::retain_mut`]: https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.retain_mut
|
||||
[`std::os::unix::net::SocketAddr::from_pathname`]: https://doc.rust-lang.org/stable/std/os/unix/net/struct.SocketAddr.html#method.from_pathname
|
||||
[`std::process::ExitCode`]: https://doc.rust-lang.org/stable/std/process/struct.ExitCode.html
|
||||
[`std::process::Termination`]: https://doc.rust-lang.org/stable/std/process/trait.Termination.html
|
||||
[`std::thread::JoinHandle::is_finished`]: https://doc.rust-lang.org/stable/std/thread/struct.JoinHandle.html#method.is_finished
|
||||
[cargo/10448]: https://github.com/rust-lang/cargo/pull/10448/
|
||||
[cursor-write-array]: https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#impl-Write-4
|
||||
[link-attr]: https://doc.rust-lang.org/stable/reference/items/external-blocks.html#the-link-attribute
|
||||
[ptr-add]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.add
|
||||
[ptr-offset]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset
|
||||
[ptr-sub]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.sub
|
||||
[ptr-wrapping_add]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.wrapping_add
|
||||
[ptr-wrapping_offset]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.wrapping_offset
|
||||
[ptr-wrapping_sub]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.wrapping_sub
|
||||
[slice-as_mut_ptr]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_mut_ptr
|
||||
[slice-as_mut_ptr_range]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_mut_ptr_range
|
||||
[slice-as_ptr_range]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_ptr_range
|
||||
[target_feature]: https://doc.rust-lang.org/reference/attributes/codegen.html#the-target_feature-attribute
|
||||
|
||||
|
||||
Version 1.60.0 (2022-04-07)
|
||||
==========================
|
||||
|
||||
|
|
|
@ -554,7 +554,8 @@ impl<'tcx> Inliner<'tcx> {
|
|||
new_scopes: SourceScope::new(caller_body.source_scopes.len())..,
|
||||
new_blocks: BasicBlock::new(caller_body.basic_blocks().len())..,
|
||||
destination: dest,
|
||||
return_block: callsite.target,
|
||||
callsite_scope: caller_body.source_scopes[callsite.source_info.scope].clone(),
|
||||
callsite,
|
||||
cleanup_block: cleanup,
|
||||
in_cleanup_block: false,
|
||||
tcx: self.tcx,
|
||||
|
@ -566,31 +567,6 @@ impl<'tcx> Inliner<'tcx> {
|
|||
// (or existing ones, in a few special cases) in the caller.
|
||||
integrator.visit_body(&mut callee_body);
|
||||
|
||||
for scope in &mut callee_body.source_scopes {
|
||||
// FIXME(eddyb) move this into a `fn visit_scope_data` in `Integrator`.
|
||||
if scope.parent_scope.is_none() {
|
||||
let callsite_scope = &caller_body.source_scopes[callsite.source_info.scope];
|
||||
|
||||
// Attach the outermost callee scope as a child of the callsite
|
||||
// scope, via the `parent_scope` and `inlined_parent_scope` chains.
|
||||
scope.parent_scope = Some(callsite.source_info.scope);
|
||||
assert_eq!(scope.inlined_parent_scope, None);
|
||||
scope.inlined_parent_scope = if callsite_scope.inlined.is_some() {
|
||||
Some(callsite.source_info.scope)
|
||||
} else {
|
||||
callsite_scope.inlined_parent_scope
|
||||
};
|
||||
|
||||
// Mark the outermost callee scope as an inlined one.
|
||||
assert_eq!(scope.inlined, None);
|
||||
scope.inlined = Some((callsite.callee, callsite.source_info.span));
|
||||
} else if scope.inlined_parent_scope.is_none() {
|
||||
// Make it easy to find the scope with `inlined` set above.
|
||||
scope.inlined_parent_scope =
|
||||
Some(integrator.map_scope(OUTERMOST_SOURCE_SCOPE));
|
||||
}
|
||||
}
|
||||
|
||||
// If there are any locals without storage markers, give them storage only for the
|
||||
// duration of the call.
|
||||
for local in callee_body.vars_and_temps_iter() {
|
||||
|
@ -786,7 +762,8 @@ struct Integrator<'a, 'tcx> {
|
|||
new_scopes: RangeFrom<SourceScope>,
|
||||
new_blocks: RangeFrom<BasicBlock>,
|
||||
destination: Place<'tcx>,
|
||||
return_block: Option<BasicBlock>,
|
||||
callsite_scope: SourceScopeData<'tcx>,
|
||||
callsite: &'a CallSite<'tcx>,
|
||||
cleanup_block: Option<BasicBlock>,
|
||||
in_cleanup_block: bool,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -832,6 +809,28 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
|
|||
*local = self.map_local(*local);
|
||||
}
|
||||
|
||||
fn visit_source_scope_data(&mut self, scope_data: &mut SourceScopeData<'tcx>) {
|
||||
self.super_source_scope_data(scope_data);
|
||||
if scope_data.parent_scope.is_none() {
|
||||
// Attach the outermost callee scope as a child of the callsite
|
||||
// scope, via the `parent_scope` and `inlined_parent_scope` chains.
|
||||
scope_data.parent_scope = Some(self.callsite.source_info.scope);
|
||||
assert_eq!(scope_data.inlined_parent_scope, None);
|
||||
scope_data.inlined_parent_scope = if self.callsite_scope.inlined.is_some() {
|
||||
Some(self.callsite.source_info.scope)
|
||||
} else {
|
||||
self.callsite_scope.inlined_parent_scope
|
||||
};
|
||||
|
||||
// Mark the outermost callee scope as an inlined one.
|
||||
assert_eq!(scope_data.inlined, None);
|
||||
scope_data.inlined = Some((self.callsite.callee, self.callsite.source_info.span));
|
||||
} else if scope_data.inlined_parent_scope.is_none() {
|
||||
// Make it easy to find the scope with `inlined` set above.
|
||||
scope_data.inlined_parent_scope = Some(self.map_scope(OUTERMOST_SOURCE_SCOPE));
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_source_scope(&mut self, scope: &mut SourceScope) {
|
||||
*scope = self.map_scope(*scope);
|
||||
}
|
||||
|
@ -938,7 +937,7 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
TerminatorKind::Return => {
|
||||
terminator.kind = if let Some(tgt) = self.return_block {
|
||||
terminator.kind = if let Some(tgt) = self.callsite.target {
|
||||
TerminatorKind::Goto { target: tgt }
|
||||
} else {
|
||||
TerminatorKind::Unreachable
|
||||
|
|
|
@ -347,16 +347,22 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
);
|
||||
err.span_label(self.span, "invalid cast");
|
||||
if self.expr_ty.is_numeric() {
|
||||
err.span_help(
|
||||
self.span,
|
||||
if self.expr_ty == fcx.tcx.types.i8 {
|
||||
"try casting from `u8` instead"
|
||||
} else if self.expr_ty == fcx.tcx.types.u32 {
|
||||
"try `char::from_u32` instead"
|
||||
} else {
|
||||
"try `char::from_u32` instead (via a `u32`)"
|
||||
},
|
||||
);
|
||||
if self.expr_ty == fcx.tcx.types.u32 {
|
||||
match fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) {
|
||||
Ok(snippet) => err.span_suggestion(
|
||||
self.span,
|
||||
"try `char::from_u32` instead",
|
||||
format!("char::from_u32({snippet})"),
|
||||
Applicability::MachineApplicable,
|
||||
),
|
||||
|
||||
Err(_) => err.span_help(self.span, "try `char::from_u32` instead"),
|
||||
};
|
||||
} else if self.expr_ty == fcx.tcx.types.i8 {
|
||||
err.span_help(self.span, "try casting from `u8` instead");
|
||||
} else {
|
||||
err.span_help(self.span, "try `char::from_u32` instead (via a `u32`)");
|
||||
};
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
|
|
@ -2830,7 +2830,7 @@ unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
|
|||
/// A fence 'A' which has (at least) [`Release`] ordering semantics, synchronizes
|
||||
/// with a fence 'B' with (at least) [`Acquire`] semantics, if and only if there
|
||||
/// exist operations X and Y, both operating on some atomic object 'M' such
|
||||
/// that A is sequenced before X, Y is synchronized before B and Y observes
|
||||
/// that A is sequenced before X, Y is sequenced before B and Y observes
|
||||
/// the change to M. This provides a happens-before dependence between A and B.
|
||||
///
|
||||
/// ```text
|
||||
|
|
|
@ -2136,7 +2136,7 @@ pub trait Termination {
|
|||
impl Termination for () {
|
||||
#[inline]
|
||||
fn report(self) -> ExitCode {
|
||||
ExitCode::SUCCESS.report()
|
||||
ExitCode::SUCCESS
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2162,7 +2162,7 @@ impl<E: fmt::Debug> Termination for Result<!, E> {
|
|||
fn report(self) -> ExitCode {
|
||||
let Err(err) = self;
|
||||
eprintln!("Error: {err:?}");
|
||||
ExitCode::FAILURE.report()
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
}
|
||||
|
||||
|
|
35
src/test/ui/const-generics/issues/issue-88119.rs
Normal file
35
src/test/ui/const-generics/issues/issue-88119.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
// check-pass
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(const_trait_impl, generic_const_exprs)]
|
||||
|
||||
trait ConstName {
|
||||
const NAME_BYTES: &'static [u8];
|
||||
}
|
||||
|
||||
impl const ConstName for u8 {
|
||||
const NAME_BYTES: &'static [u8] = b"u8";
|
||||
}
|
||||
|
||||
const fn name_len<T: ?Sized + ConstName>() -> usize {
|
||||
T::NAME_BYTES.len()
|
||||
}
|
||||
|
||||
impl<T: ?Sized + ConstName> const ConstName for &T
|
||||
where
|
||||
[(); name_len::<T>()]:,
|
||||
{
|
||||
const NAME_BYTES: &'static [u8] = b"&T";
|
||||
}
|
||||
|
||||
impl<T: ?Sized + ConstName> const ConstName for &mut T
|
||||
where
|
||||
[(); name_len::<T>()]:,
|
||||
{
|
||||
const NAME_BYTES: &'static [u8] = b"&mut T";
|
||||
}
|
||||
|
||||
pub const ICE_1: &'static [u8] = <&&mut u8 as ConstName>::NAME_BYTES;
|
||||
pub const ICE_2: &'static [u8] = <&mut &u8 as ConstName>::NAME_BYTES;
|
||||
|
||||
fn main() {}
|
|
@ -1,14 +1,11 @@
|
|||
error[E0604]: only `u8` can be cast as `char`, not `u32`
|
||||
--> $DIR/E0604.rs:2:5
|
||||
|
|
||||
LL | 1u32 as char;
|
||||
| ^^^^^^^^^^^^ invalid cast
|
||||
|
|
||||
help: try `char::from_u32` instead
|
||||
--> $DIR/E0604.rs:2:5
|
||||
|
|
||||
LL | 1u32 as char;
|
||||
| ^^^^^^^^^^^^
|
||||
| |
|
||||
| invalid cast
|
||||
| help: try `char::from_u32` instead: `char::from_u32(1u32)`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
@ -56,14 +56,11 @@ LL | | }
|
|||
error[E0604]: only `u8` can be cast as `char`, not `u32`
|
||||
--> $DIR/error-festival.rs:25:5
|
||||
|
|
||||
LL | 0u32 as char;
|
||||
| ^^^^^^^^^^^^ invalid cast
|
||||
|
|
||||
help: try `char::from_u32` instead
|
||||
--> $DIR/error-festival.rs:25:5
|
||||
|
|
||||
LL | 0u32 as char;
|
||||
| ^^^^^^^^^^^^
|
||||
| |
|
||||
| invalid cast
|
||||
| help: try `char::from_u32` instead: `char::from_u32(0u32)`
|
||||
|
||||
error[E0605]: non-primitive cast: `u8` as `Vec<u8>`
|
||||
--> $DIR/error-festival.rs:29:5
|
||||
|
|
|
@ -97,14 +97,11 @@ LL | let _ = E::A as bool;
|
|||
error[E0604]: only `u8` can be cast as `char`, not `u32`
|
||||
--> $DIR/cast-rfc0401.rs:41:13
|
||||
|
|
||||
LL | let _ = 0x61u32 as char;
|
||||
| ^^^^^^^^^^^^^^^ invalid cast
|
||||
|
|
||||
help: try `char::from_u32` instead
|
||||
--> $DIR/cast-rfc0401.rs:41:13
|
||||
|
|
||||
LL | let _ = 0x61u32 as char;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| invalid cast
|
||||
| help: try `char::from_u32` instead: `char::from_u32(0x61u32)`
|
||||
|
||||
error[E0606]: casting `bool` as `f32` is invalid
|
||||
--> $DIR/cast-rfc0401.rs:43:13
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue