-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Infer type in irrefutable slice patterns with fixed length as array #113199
Conversation
☔ The latest upstream changes (presumably #113086) made this pull request unmergeable. Please resolve the merge conflicts. |
b21cb57
to
96c16bc
Compare
@@ -19,19 +37,28 @@ pub(super) struct Declaration<'a> { | |||
pub span: Span, | |||
pub init: Option<&'a hir::Expr<'a>>, | |||
pub els: Option<&'a hir::Block<'a>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
feels like els
should be part of Origin
instead of being a separate field
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
happy with the changes to allow arrays, the changes with PatInfo
feel like they're only halfway '^^
pub(super) has_else: bool, | ||
pub(super) origin: DeclOrigin, | ||
impl<'a> DeclOrigin<'a> { | ||
pub(super) fn try_get_els(&self) -> Option<&'a hir::Block<'a>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pub(super) fn try_get_els(&self) -> Option<&'a hir::Block<'a>> { | |
pub(super) fn try_get_else(&self) -> Option<&'a hir::Block<'a>> { |
els
is only used because else
is a keyword and can't be the name of a local :>
compiler/rustc_hir_typeck/src/pat.rs
Outdated
) { | ||
#[instrument(level = "debug", skip(self, pat_info))] | ||
fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) { | ||
let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin } = pat_info; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please don't destructure pat_info
if you then rebuild it for nested calls
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that we create a new def_bm
in this method later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you in this case instead shaddow pat_info
after we have the new def_bm
?
compiler/rustc_hir_typeck/src/pat.rs
Outdated
) -> Ty<'tcx> { | ||
let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin } = pat_info; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
compiler/rustc_hir_typeck/src/pat.rs
Outdated
) -> Ty<'tcx> { | ||
let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin } = pat_info; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and here
☔ The latest upstream changes (presumably #113377) made this pull request unmergeable. Please resolve the merge conflicts. |
739205c
to
99882b4
Compare
This comment has been minimized.
This comment has been minimized.
compiler/rustc_hir_typeck/src/pat.rs
Outdated
) { | ||
#[instrument(level = "debug", skip(self, pat_info))] | ||
fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) { | ||
let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin } = pat_info; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you in this case instead shaddow pat_info
after we have the new def_bm
?
compiler/rustc_hir_typeck/src/pat.rs
Outdated
decl_origin.try_get_else().is_none() | ||
&& matches!(decl_origin, DeclOrigin::LocalDecl { .. }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
decl_origin.try_get_else().is_none() | |
&& matches!(decl_origin, DeclOrigin::LocalDecl { .. }) | |
match decl_origin { | |
DeclOrigin::LocalDecl { els: None } => true, | |
DeclOrigin::LOcalDecl { else: Some(_) } | DeclOrigin::LetExpr => false, | |
} |
@@ -0,0 +1,47 @@ | |||
#![allow(unused_variables)] | |||
|
|||
struct Zeroes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure whether this test tests anything specific 🤔 might make snese to only have this as a check-pass test for irrefutable let?
please add the test separately where we incompletely a pattern as an array even though it should be a slice #76342 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add the test separately where we incompletely a pattern as an array even though it should be a slice #76342 (comment)
Sorry, I don't understand what you're trying to say here. The quote does not seem to relate to the comment you link to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test:
struct Foo(u32);
struct Bar;
impl Into<&'static Foo> for Bar {
fn into(self) -> &'static Foo { &Foo(1) }
}
impl Into<Foo> for Bar {
fn into(self) -> Foo { Foo(1) }
}
fn ty<T>(_: T) {
println!("{}", std::any::type_name::<T>());
}
fn main() {
let Foo(i) = Bar.into();
ty(i); // u32
let Foo(j) = <Bar as Into<&'static Foo>>::into(Bar);
ty(j); // &u32
let Foo(k): Foo = Bar.into();
ty(k); // u32
let Foo(l): &Foo = Bar.into();
ty(l); // &u32
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
woops, replacing Foo
with an array 😓
#![allow(unused_variables)]
struct Zeroes;
impl Into<&'static [usize; 3]> for Zeroes {
fn into(self) -> &'static [usize; 3] { &[0; 3] }
}
impl Into<[usize; 3]> for Zeroes {
fn into(self) -> [usize; 3] { [0; 3] }
}
fn main() {
let [a, b, c] = Zeroes.into();
let [d, e, f] = <Zeroes as Into<&'static [usize; 3]>>::into(Zeroes);
let &[g, h, i] = Zeroes.into();
let [j, k, l]: [usize; _] = Zeroes.into();
let [m, n, o]: &[usize; _] = Zeroes.into();
// check the binding mode of these patterns:
let _: &[usize] = &[a, b, c, g, h, i, j, k, l];
let _: &[&usize] = &[d, e, f, m, n, o];
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let [d, e, f] = <Zeroes as Into<&'static [usize; 3]>::into();
Again not sure what you're trying to do here. This doesn't look like valid rust code to me. into
takes a receiver.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it can be valid by adding Zeroes
as a receiver
let [d, e, f] = <Zeroes as Into<&'static [usize; 3]>>::into(Zeroes);
) -> Ty<'tcx> { | ||
// If the pattern is irrefutable and `expected` is an infer ty, we try to equate it | ||
// to an array if the given pattern allows it. See issue #76342 | ||
if self.pat_is_irrefutable(pat_info.decl_origin) && expected.is_ty_var() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please move this if
until after the structurally_resolve_type
as it can otherwise miss info about the type of expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new tests previously failed because structurally_resolve_type
returned an inference error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, I guess we need try_structurally_resolve_type
here 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not convinced this is necessary. We only get into the demand_eqtype
call when the pattern is irrefutable, how exactly would trying to structurally resolve the type help here? Afaict either there's a type annotation and we ignore all the logic introduced in this PR or there is none, in which case expected
is just an unresolvable type variable afaict. Since we have to resolve the type after the demand_eqtype
call anyway (since we still have to resolve the inner type after hinting that we're looking for [_; n]
) I don't see why we want try_structurally_resolve_type
first. Can you explain why that would be helpful/necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we get into the demand_eqtype
call when the pattern is irrefutable and the expected type is an inference variable. Whether the expected type is an inference variable can depend on structrally resolving it.
I can't imagine how you'd get to a point where it matters, but generally looking at the kind()
of a type and then using structurally_resolve
or shallow_resolve
or whatever is always sus. Either the resolve
is a noop, in which case it should be removed, or it can change the kind()
of the type, in which case looking at the type before the resovle call is buggy.
Ah, nearly forgot: can you add tests for destructing assignments, i.e. what happens with the following
fn main() {
let a: i32;
let b;
[a, b] = Default::default();
}
we should treat these as also being irrefutable and this example should compile i think
99882b4
to
046d751
Compare
tests/ui/pattern/issue-76342.rs
Outdated
@@ -0,0 +1,25 @@ | |||
// check-pass | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, two more things:
- can you rename this file to
slice-patterns-irrefutable.rs
? - can you add the following function to this test
use std::array::TryFromSliceError;
fn array_try_from(x: &[usize]) -> Result<usize, TryFromSliceError> {
let [a, b] = x.try_into()?;
Ok(a + b)
}
This PR infers the type of slice pattern in irrefutable positions, i.e. let bindings, to an array with the length of the pattern. This inference incompletely assumes that no match ergonomics are taking place and the type of the pattern is an array, not a reference to an array. This matches the behavior of other patterns: #76342 (comment). We do not make inference progress if the slice pattern contains a This behavior is generally desirable when using #![allow(unused_variables)]
struct Zeroes;
impl Into<&'static [usize; 3]> for Zeroes {
fn into(self) -> &'static [usize; 3] { &[0; 3] }
}
impl Into<[usize; 3]> for Zeroes {
fn into(self) -> [usize; 3] { [0; 3] }
}
fn main() {
let [a, b, c] = Zeroes.into();
let [d, e, f] = <Zeroes as Into<&'static [usize; 3]>>::into(Zeroes);
let &[g, h, i] = Zeroes.into();
let [j, k, l]: [usize; _] = Zeroes.into();
let [m, n, o]: &[usize; _] = Zeroes.into();
// check the binding mode of these patterns:
let _: &[usize] = &[a, b, c, g, h, i, j, k, l];
let _: &[&usize] = &[d, e, f, m, n, o];
} This also works for nested slice pattern, see https://github.com/rust-lang/rust/blob/046d751e4f5351e40e1a7f96dc3ee73ab0fe5dc7/tests/ui/pattern/slice-patterns-nested.rs#L4-L15 Given that this is a detail of type inference, I think this is full t-types, cc @rust-lang/lang @rfcbot fcp merge |
Team member @lcnr has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
☔ The latest upstream changes (presumably #113591) made this pull request unmergeable. Please resolve the merge conflicts. |
046d751
to
e1e7553
Compare
🔔 This is now entering its final comment period, as per the review above. 🔔 |
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon. |
final nits, then r=me |
@bors r+ rollup=never |
☀️ Test successful - checks-actions |
Finished benchmarking commit (fcf3006): comparison URL. Overall result: ❌ regressions - no action needed@rustbot label: -perf-regression Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 649.925s -> 649.462s (-0.07%) |
Language -------- - [Uplift `clippy::fn_null_check` lint as `useless_ptr_null_checks`.] (rust-lang/rust#111717) - [Make `noop_method_call` warn by default.] (rust-lang/rust#111916) - [Support interpolated block for `try` and `async` in macros.] (rust-lang/rust#112953) - [Make `unconditional_recursion` lint detect recursive drops.] (rust-lang/rust#113902) - [Future compatibility warning for some impls being incorrectly considered not overlapping.] (rust-lang/rust#114023) - [The `invalid_reference_casting` lint is now **deny-by-default** (instead of allow-by-default)] (rust-lang/rust#112431) Compiler -------- - [Write version information in a `.comment` section like GCC/Clang.] (rust-lang/rust#97550) - [Add documentation on v0 symbol mangling.] (rust-lang/rust#97571) - [Stabilize `extern "thiscall"` and `"thiscall-unwind"` ABIs.] (rust-lang/rust#114562) - [Only check outlives goals on impl compared to trait.] (rust-lang/rust#109356) - [Infer type in irrefutable slice patterns with fixed length as array.] (rust-lang/rust#113199) - [Discard default auto trait impls if explicit ones exist.] (rust-lang/rust#113312) - Add several new tier 3 targets: - [`aarch64-unknown-teeos`] (rust-lang/rust#113480) - [`csky-unknown-linux-gnuabiv2`] (rust-lang/rust#113658) - [`riscv64-linux-android`] (rust-lang/rust#112858) - [`riscv64gc-unknown-hermit`] (rust-lang/rust#114004) - [`x86_64-unikraft-linux-musl`] (rust-lang/rust#113411) - [`x86_64-unknown-linux-ohos`] (rust-lang/rust#113061) - [Add `wasm32-wasi-preview1-threads` as a tier 2 target.] (rust-lang/rust#112922) Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries --------- - [Add `Read`, `Write` and `Seek` impls for `Arc<File>`.] (rust-lang/rust#94748) - [Merge functionality of `io::Sink` into `io::Empty`.] (rust-lang/rust#98154) - [Implement `RefUnwindSafe` for `Backtrace`] (rust-lang/rust#100455) - [Make `ExitStatus` implement `Default`] (rust-lang/rust#106425) - [`impl SliceIndex<str> for (Bound<usize>, Bound<usize>)`] (rust-lang/rust#111081) - [Change default panic handler message format.] (rust-lang/rust#112849) - [Cleaner `assert_eq!` & `assert_ne!` panic messages.] (rust-lang/rust#111071) - [Correct the (deprecated) Android `stat` struct definitions.] (rust-lang/rust#113130) Stabilized APIs --------------- - [Unsigned `{integer}::div_ceil`] (https://doc.rust-lang.org/stable/std/primitive.u32.html#method.div_ceil) - [Unsigned `{integer}::next_multiple_of`] (https://doc.rust-lang.org/stable/std/primitive.u32.html#method.next_multiple_of) - [Unsigned `{integer}::checked_next_multiple_of`] (https://doc.rust-lang.org/stable/std/primitive.u32.html#method.checked_next_multiple_of) - [`std::ffi::FromBytesUntilNulError`] (https://doc.rust-lang.org/stable/std/ffi/struct.FromBytesUntilNulError.html) - [`std::os::unix::fs::chown`] (https://doc.rust-lang.org/stable/std/os/unix/fs/fn.chown.html) - [`std::os::unix::fs::fchown`] (https://doc.rust-lang.org/stable/std/os/unix/fs/fn.fchown.html) - [`std::os::unix::fs::lfchown`] (https://doc.rust-lang.org/stable/std/os/unix/fs/fn.lchown.html) - [`LocalKey::<Cell<T>>::get`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.get) - [`LocalKey::<Cell<T>>::set`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.set) - [`LocalKey::<Cell<T>>::take`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.take) - [`LocalKey::<Cell<T>>::replace`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.replace) - [`LocalKey::<RefCell<T>>::with_borrow`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.with_borrow) - [`LocalKey::<RefCell<T>>::with_borrow_mut`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.with_borrow_mut) - [`LocalKey::<RefCell<T>>::set`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.set-1) - [`LocalKey::<RefCell<T>>::take`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.take-1) - [`LocalKey::<RefCell<T>>::replace`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.replace-1) These APIs are now stable in const contexts: - [`rc::Weak::new`] (https://doc.rust-lang.org/stable/alloc/rc/struct.Weak.html#method.new) - [`sync::Weak::new`] (https://doc.rust-lang.org/stable/alloc/sync/struct.Weak.html#method.new) - [`NonNull::as_ref`] (https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.as_ref) Cargo ----- - [Encode URL params correctly for `SourceId` in `Cargo.lock`.] (rust-lang/cargo#12280) - [Bail out an error when using `cargo::` in custom build script.] (rust-lang/cargo#12332) Compatibility Notes ------------------- - [Update the minimum external LLVM to 15.] (rust-lang/rust#114148) - [Check for non-defining uses of return position `impl Trait`.] (rust-lang/rust#112842) Internal Changes ---------------- These changes do not affect any public interfaces of Rust, but they represent significant improvements to the performance or internals of rustc and related tools. - [Remove LLVM pointee types, supporting only opaque pointers.] (rust-lang/rust#105545) - [Port PGO/LTO/BOLT optimized build pipeline to Rust.] (rust-lang/rust#112235) - [Replace in-tree `rustc_apfloat` with the new version of the crate.] (rust-lang/rust#113843) - [Update to LLVM 17.] (rust-lang/rust#114048) - [Add `internal_features` lint for internal unstable features.] (rust-lang/rust#108955) - [Mention style for new syntax in tracking issue template.] (rust-lang/rust#113586)
Pkgsrc changes: * Adjust patches and cargo checksums to new versions. * For an external LLVM, set dependency of llvm >= 15, in accordance with the upstream changes. * Add a patch with a backport from LLVM 17.0.3 fixing codegen for PPC, ref. rust-lang/rust#116845 Upstream changes: Version 1.73.0 (2023-10-05) ========================== Language -------- - [Uplift `clippy::fn_null_check` lint as `useless_ptr_null_checks`.] (rust-lang/rust#111717) - [Make `noop_method_call` warn by default.] (rust-lang/rust#111916) - [Support interpolated block for `try` and `async` in macros.] (rust-lang/rust#112953) - [Make `unconditional_recursion` lint detect recursive drops.] (rust-lang/rust#113902) - [Future compatibility warning for some impls being incorrectly considered not overlapping.] (rust-lang/rust#114023) - [The `invalid_reference_casting` lint is now **deny-by-default** (instead of allow-by-default)] (rust-lang/rust#112431 Compiler -------- - [Write version information in a `.comment` section like GCC/Clang.] (rust-lang/rust#97550) - [Add documentation on v0 symbol mangling.] (rust-lang/rust#97571) - [Stabilize `extern "thiscall"` and `"thiscall-unwind"` ABIs.] (rust-lang/rust#114562) - [Only check outlives goals on impl compared to trait.] (rust-lang/rust#109356) - [Infer type in irrefutable slice patterns with fixed length as array.] (rust-lang/rust#113199) - [Discard default auto trait impls if explicit ones exist.] (rust-lang/rust#113312) - Add several new tier 3 targets: - [`aarch64-unknown-teeos`] (rust-lang/rust#113480) - [`csky-unknown-linux-gnuabiv2`] (rust-lang/rust#113658) - [`riscv64-linux-android`] (rust-lang/rust#112858) - [`riscv64gc-unknown-hermit`] (rust-lang/rust#114004) - [`x86_64-unikraft-linux-musl`] (rust-lang/rust#113411) - [`x86_64-unknown-linux-ohos`] (rust-lang/rust#113061) - [Add `wasm32-wasi-preview1-threads` as a tier 2 target.] (rust-lang/rust#112922) Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. Libraries --------- - [Add `Read`, `Write` and `Seek` impls for `Arc<File>`.] (rust-lang/rust#94748) - [Merge functionality of `io::Sink` into `io::Empty`.] (rust-lang/rust#98154) - [Implement `RefUnwindSafe` for `Backtrace`] (rust-lang/rust#100455) - [Make `ExitStatus` implement `Default`] (rust-lang/rust#106425) - [`impl SliceIndex<str> for (Bound<usize>, Bound<usize>)`] (rust-lang/rust#111081) - [Change default panic handler message format.] (rust-lang/rust#112849) - [Cleaner `assert_eq!` & `assert_ne!` panic messages.] (rust-lang/rust#111071) - [Correct the (deprecated) Android `stat` struct definitions.] (rust-lang/rust#113130) Stabilized APIs --------------- - [Unsigned `{integer}::div_ceil`] (https://doc.rust-lang.org/stable/std/primitiv e.u32.html#method.div_ceil) - [Unsigned `{integer}::next_multiple_of`] (https://doc.rust-lang.org/stable/std/primitive.u32.html#method.next_multiple_of) - [Unsigned `{integer}::checked_next_multiple_of`] (https://doc.rust-lang.org/stable/std/primitive.u32.html#method.checked_next_multiple_of) - [`std::ffi::FromBytesUntilNulError`] (https://doc.rust-lang.org/stable/std/ffi/struct.FromBytesUntilNulError.html) - [`std::os::unix::fs::chown`] (https://doc.rust-lang.org/stable/std/os/unix/fs/fn.chown.html) - [`std::os::unix::fs::fchown`] (https://doc.rust-lang.org/stable/std/os/unix/fs/fn.fchown.html) - [`std::os::unix::fs::lfchown`] (https://doc.rust-lang.org/stable/std/os/unix/fs/fn.lchown.html) - [`LocalKey::<Cell<T>>::get`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.get) - [`LocalKey::<Cell<T>>::set`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.set) - [`LocalKey::<Cell<T>>::take`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.take) - [`LocalKey::<Cell<T>>::replace`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.replace) - [`LocalKey::<RefCell<T>>::with_borrow`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.with_borrow) - [`LocalKey::<RefCell<T>>::with_borrow_mut`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.with_borrow_mut) - [`LocalKey::<RefCell<T>>::set`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.set-1) - [`LocalKey::<RefCell<T>>::take`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.take-1) - [`LocalKey::<RefCell<T>>::replace`] (https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.replace-1) These APIs are now stable in const contexts: - [`rc::Weak::new`] (https://doc.rust-lang.org/stable/alloc/rc/struct.Weak.html#method.new) - [`sync::Weak::new`] (https://doc.rust-lang.org/stable/alloc/sync/struct.Weak.html#method.new) - [`NonNull::as_ref`] (https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.as_ref) Cargo ----- - [Encode URL params correctly for `SourceId` in `Cargo.lock`.] (rust-lang/cargo#12280) - [Bail out an error when using `cargo::` in custom build script.] (rust-lang/cargo#12332) Misc ---- Compatibility Notes ------------------- - [Update the minimum external LLVM to 15.] (rust-lang/rust#114148) - [Check for non-defining uses of return position `impl Trait`.] (rust-lang/rust#112842) Internal Changes ---------------- These changes do not affect any public interfaces of Rust, but they represent significant improvements to the performance or internals of rustc and related tools. - [Remove LLVM pointee types, supporting only opaque pointers.] (rust-lang/rust#105545) - [Port PGO/LTO/BOLT optimized build pipeline to Rust.] (rust-lang/rust#112235) - [Replace in-tree `rustc_apfloat` with the new version of the crate.] (rust-lang/rust#113843) - [Update to LLVM 17.] (rust-lang/rust#114048) - [Add `internal_features` lint for internal unstable features.] (rust-lang/rust#108955) - [Mention style for new syntax in tracking issue template.] (rust-lang/rust#113586)
Fixes #76342
In irrefutable slice patterns with a fixed length, we can infer the type as an array type. We now choose to prefer some implementations over others, e.g. in:
We now prefer the impl candidate
impl Into<&'static [usize; 2]> for Zeroes
, it's not entirely clear to me that this is correct, but given that the slice impl would require a type annotation anyway, this doesn't seem unreasonable.r? @lcnr