diff --git a/RELEASES.md b/RELEASES.md index b923f87abfd47..b89178a6f68fe 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,105 @@ +Version 1.69.0 (2023-04-20) +========================== + + + +Language +-------- + +- [Deriving built-in traits on packed structs works with `Copy` fields.](https://github.com/rust-lang/rust/pull/104429/) +- [Stabilize the `cmpxchg16b` target feature on x86 and x86_64.](https://github.com/rust-lang/rust/pull/106774/) +- [Improve analysis of trait bounds for associated types.](https://github.com/rust-lang/rust/pull/103695/) +- [Allow associated types to be used as union fields.](https://github.com/rust-lang/rust/pull/106938/) +- [Allow `Self: Autotrait` bounds on dyn-safe trait methods.](https://github.com/rust-lang/rust/pull/107082/) +- [Treat `str` as containing `[u8]` for auto trait purposes.](https://github.com/rust-lang/rust/pull/107941/) + + + +Compiler +-------- + +- [Upgrade `*-pc-windows-gnu` on CI to mingw-w64 v10 and GCC 12.2.](https://github.com/rust-lang/rust/pull/100178/) +- [Rework min_choice algorithm of member constraints.](https://github.com/rust-lang/rust/pull/105300/) +- [Support `true` and `false` as boolean flags in compiler arguments.](https://github.com/rust-lang/rust/pull/107043/) +- [Default `repr(C)` enums to `c_int` size.](https://github.com/rust-lang/rust/pull/107592/) + + + +Libraries +--------- + +- [Implement the unstable `DispatchFromDyn` for cell types, allowing downstream experimentation with custom method receivers.](https://github.com/rust-lang/rust/pull/97373/) +- [Document that `fmt::Arguments::as_str()` may return `Some(_)` in more cases after optimization, subject to change.](https://github.com/rust-lang/rust/pull/106823/) +- [Implement `AsFd` and `AsRawFd` for `Rc`.](https://github.com/rust-lang/rust/pull/107317/) + + + +Stabilized APIs +--------------- + +- [`CStr::from_bytes_until_nul`](https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html#method.from_bytes_until_nul) +- [`core::ffi::FromBytesUntilNulError`](https://doc.rust-lang.org/stable/core/ffi/struct.FromBytesUntilNulError.html) + +These APIs are now stable in const contexts: + +- [`SocketAddr::new`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.new) +- [`SocketAddr::ip`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.ip) +- [`SocketAddr::port`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.port) +- [`SocketAddr::is_ipv4`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.is_ipv4) +- [`SocketAddr::is_ipv6`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.is_ipv6) +- [`SocketAddrV4::new`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.new) +- [`SocketAddrV4::ip`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.ip) +- [`SocketAddrV4::port`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.port) +- [`SocketAddrV6::new`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.new) +- [`SocketAddrV6::ip`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.ip) +- [`SocketAddrV6::port`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.port) +- [`SocketAddrV6::flowinfo`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.flowinfo) +- [`SocketAddrV6::scope_id`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.scope_id) + + + +Cargo +----- + +- [Cargo now suggests `cargo fix` or `cargo clippy --fix` when compilation warnings are auto-fixable.](https://github.com/rust-lang/cargo/pull/11558/) +- [Cargo now suggests `cargo add` if you try to install a library crate.](https://github.com/rust-lang/cargo/pull/11410/) +- [Cargo now sets the `CARGO_BIN_NAME` environment variable also for binary examples.](https://github.com/rust-lang/cargo/pull/11705/) + + + +Rustdoc +----- + +- [Vertically compact trait bound formatting.](https://github.com/rust-lang/rust/pull/102842/) +- [Only include stable lints in `rustdoc::all` group.](https://github.com/rust-lang/rust/pull/106316/) +- [Compute maximum Levenshtein distance based on the query.](https://github.com/rust-lang/rust/pull/107141/) +- [Remove inconsistently-present sidebar tooltips.](https://github.com/rust-lang/rust/pull/107490/) +- [Search by macro when query ends with `!`.](https://github.com/rust-lang/rust/pull/108143/) + + + +Compatibility Notes +------------------- + +- [The `rust-analysis` component from `rustup` now only contains a warning placeholder.](https://github.com/rust-lang/rust/pull/101841/) This was primarily intended for RLS, and the corresponding `-Zsave-analysis` flag has been removed from the compiler as well. +- [Unaligned references to packed fields are now a hard error.](https://github.com/rust-lang/rust/pull/102513/) This has been a warning since 1.53, and denied by default with a future-compatibility warning since 1.62. +- [Update the minimum external LLVM to 14.](https://github.com/rust-lang/rust/pull/107573/) +- [Cargo now emits errors on invalid characters in a registry token.](https://github.com/rust-lang/cargo/pull/11600/) +- [When `default-features` is set to false of a workspace dependency, and an inherited dependency of a member has `default-features = true`, Cargo will enable default features of that dependency.](https://github.com/rust-lang/cargo/pull/11409/) +- [Cargo denies `CARGO_HOME` in the `[env]` configuration table. Cargo itself doesn't pick up this value, but recursive calls to cargo would, which was not intended.](https://github.com/rust-lang/cargo/pull/11644/) +- [Debuginfo for build dependencies is now off if not explicitly set. This is expected to improve the overall build time.](https://github.com/rust-lang/cargo/pull/11252/) + + + +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. + +- [Move `format_args!()` into AST (and expand it during AST lowering)](https://github.com/rust-lang/rust/pull/106745/) + Version 1.68.2 (2023-03-28) =========================== diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index a4b285a34fa46..70d0a101b4ed9 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -528,7 +528,7 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> { where F: Fn() -> RegionCtxt, { - let next_region = self.infcx.next_nll_region_var(origin.clone()); + let next_region = self.infcx.next_nll_region_var(origin); let vid = next_region.as_var(); if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 9358ed612921f..8c414521b7653 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -645,9 +645,8 @@ pub(super) fn implied_predicates_with_filter( }; // Combine the two lists to form the complete set of superbounds: - let implied_bounds = &*tcx - .arena - .alloc_from_iter(superbounds.predicates().into_iter().chain(where_bounds_that_match)); + let implied_bounds = + &*tcx.arena.alloc_from_iter(superbounds.predicates().chain(where_bounds_that_match)); debug!(?implied_bounds); // Now require that immediate supertraits are converted, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index f879ccbb3af11..c3e5f9cb745fc 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -164,24 +164,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] + .into_iter() + .flatten() { - if let Some(param) = param { - let refined_expr = self.point_at_field_if_possible( - def_id, - param, - variant_def_id, - fields, - ); - - match refined_expr { - None => {} - Some((refined_expr, _)) => { - error.obligation.cause.span = refined_expr - .span - .find_ancestor_in_same_ctxt(error.obligation.cause.span) - .unwrap_or(refined_expr.span); - return true; - } + let refined_expr = + self.point_at_field_if_possible(def_id, param, variant_def_id, fields); + + match refined_expr { + None => {} + Some((refined_expr, _)) => { + error.obligation.cause.span = refined_expr + .span + .find_ancestor_in_same_ctxt(error.obligation.cause.span) + .unwrap_or(refined_expr.span); + return true; } } } diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 482b78d42e377..769e12f77bf2d 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -89,7 +89,7 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { } PreInliningPartitioning { - codegen_units: codegen_units.into_values().map(|codegen_unit| codegen_unit).collect(), + codegen_units: codegen_units.into_values().collect(), roots, internalization_candidates, } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index e03ce5d712056..c14c7f2fa0dcc 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -570,15 +570,13 @@ impl<'a> Parser<'a> { let expect = tokens_to_string(&expected); let actual = super::token_descr(&self.token); let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 { + let fmt = format!("expected one of {expect}, found {actual}"); let short_expect = if expected.len() > 6 { format!("{} possible tokens", expected.len()) } else { - expect.clone() + expect }; - ( - format!("expected one of {expect}, found {actual}"), - (self.prev_token.span.shrink_to_hi(), format!("expected one of {short_expect}")), - ) + (fmt, (self.prev_token.span.shrink_to_hi(), format!("expected one of {short_expect}"))) } else if expected.is_empty() { ( format!("unexpected token: {actual}"), diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index 4743170e9bfd8..579a789244bd6 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -231,7 +231,7 @@ pub(crate) fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>( // locked while doing so. Instead we copy out the // `(query_key, dep_node_index)` pairs and release the lock again. let mut query_keys_and_indices = Vec::new(); - query_cache.iter(&mut |k, _, i| query_keys_and_indices.push((k.clone(), i))); + query_cache.iter(&mut |k, _, i| query_keys_and_indices.push((*k, i))); // Now actually allocate the strings. If allocating the strings // generates new entries in the query cache, we'll miss them but diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 1b741b7302b67..cef982fcb41ef 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2944,22 +2944,25 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { rustc_transmute::Answer::No(reason) => { let dst = trait_ref.skip_binder().substs.type_at(0); let src = trait_ref.skip_binder().substs.type_at(1); - let custom_err_msg = format!("`{src}` cannot be safely transmuted into `{dst}` in the defining scope of `{scope}`").to_string(); + let custom_err_msg = format!( + "`{src}` cannot be safely transmuted into `{dst}` in the defining scope of `{scope}`" + ); let reason_msg = match reason { rustc_transmute::Reason::SrcIsUnspecified => { - format!("`{src}` does not have a well-specified layout").to_string() + format!("`{src}` does not have a well-specified layout") } + rustc_transmute::Reason::DstIsUnspecified => { - format!("`{dst}` does not have a well-specified layout").to_string() + format!("`{dst}` does not have a well-specified layout") } + rustc_transmute::Reason::DstIsBitIncompatible => { format!("At least one value of `{src}` isn't a bit-valid value of `{dst}`") - .to_string() } + rustc_transmute::Reason::DstIsPrivate => format!( "`{dst}` is or contains a type or field that is not visible in that scope" - ) - .to_string(), + ), // FIXME(bryangarza): Include the number of bytes of src and dst rustc_transmute::Reason::DstIsTooBig => { format!("The size of `{src}` is smaller than the size of `{dst}`") diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index cff3d277a78fb..e01a57ea4fee8 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -55,7 +55,18 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { ) -> Vec> { let ty = self.resolve_vars_if_possible(ty); let ty = OpportunisticRegionResolver::new(self).fold_ty(ty); - assert!(!ty.needs_infer()); + + // We do not expect existential variables in implied bounds. + // We may however encounter unconstrained lifetime variables in invalid + // code. See #110161 for context. + assert!(!ty.has_non_region_infer()); + if ty.needs_infer() { + self.tcx.sess.delay_span_bug( + self.tcx.def_span(body_id), + "skipped implied_outlives_bounds due to unconstrained lifetimes", + ); + return vec![]; + } let span = self.tcx.def_span(body_id); let result = param_env diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index a67df7ed557a1..30ec73cabf849 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -170,7 +170,7 @@ pub fn forget_unsized(t: T) { /// /// The following table gives the size for primitives. /// -/// Type | size_of::\() +/// Type | `size_of::()` /// ---- | --------------- /// () | 0 /// bool | 1 @@ -190,8 +190,8 @@ pub fn forget_unsized(t: T) { /// /// Furthermore, `usize` and `isize` have the same size. /// -/// The types `*const T`, `&T`, `Box`, `Option<&T>`, and `Option>` all have -/// the same size. If `T` is Sized, all of those types have the same size as `usize`. +/// The types [`*const T`], `&T`, [`Box`], [`Option<&T>`], and `Option>` all have +/// the same size. If `T` is `Sized`, all of those types have the same size as `usize`. /// /// The mutability of a pointer does not change its size. As such, `&T` and `&mut T` /// have the same size. Likewise for `*const T` and `*mut T`. @@ -203,7 +203,7 @@ pub fn forget_unsized(t: T) { /// /// ## Size of Structs /// -/// For `structs`, the size is determined by the following algorithm. +/// For `struct`s, the size is determined by the following algorithm. /// /// For each field in the struct ordered by declaration order: /// @@ -299,6 +299,10 @@ pub fn forget_unsized(t: T) { /// ``` /// /// [alignment]: align_of +/// [`*const T`]: primitive@pointer +/// [`Box`]: ../../std/boxed/struct.Box.html +/// [`Option<&T>`]: crate::option::Option +/// #[inline(always)] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] @@ -311,7 +315,7 @@ pub const fn size_of() -> usize { /// Returns the size of the pointed-to value in bytes. /// -/// This is usually the same as `size_of::()`. However, when `T` *has* no +/// This is usually the same as [`size_of::()`]. However, when `T` *has* no /// statically-known size, e.g., a slice [`[T]`][slice] or a [trait object], /// then `size_of_val` can be used to get the dynamically-known size. /// @@ -328,6 +332,8 @@ pub const fn size_of() -> usize { /// let y: &[u8] = &x; /// assert_eq!(13, mem::size_of_val(y)); /// ``` +/// +/// [`size_of::()`]: size_of #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] @@ -340,7 +346,7 @@ pub const fn size_of_val(val: &T) -> usize { /// Returns the size of the pointed-to value in bytes. /// -/// This is usually the same as `size_of::()`. However, when `T` *has* no +/// This is usually the same as [`size_of::()`]. However, when `T` *has* no /// statically-known size, e.g., a slice [`[T]`][slice] or a [trait object], /// then `size_of_val_raw` can be used to get the dynamically-known size. /// @@ -363,6 +369,7 @@ pub const fn size_of_val(val: &T) -> usize { /// [`size_of_val`] on a reference to a type with an extern type tail. /// - otherwise, it is conservatively not allowed to call this function. /// +/// [`size_of::()`]: size_of /// [trait object]: ../../book/ch17-02-trait-objects.html /// [extern type]: ../../unstable-book/language-features/extern-types.html /// diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index cc3b3bc25f3d5..ca6dcaf495743 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -1009,7 +1009,9 @@ impl Config { }); config.initial_cargo = build .cargo - .map(PathBuf::from) + .map(|cargo| { + t!(PathBuf::from(cargo).canonicalize(), "`initial_cargo` not found on disk") + }) .unwrap_or_else(|| config.out.join(config.build.triple).join("stage0/bin/cargo")); // NOTE: it's important this comes *after* we set `initial_rustc` just above. diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 2cd9c8a878187..a835bd2de3b14 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1349,7 +1349,7 @@ impl LinkCollector<'_, '_> { if has_derive_trait_collision { candidates.macro_ns = None; } - candidates.into_iter().filter_map(|res| res).flatten().collect::>() + candidates.into_iter().flatten().flatten().collect::>() } } } diff --git a/tests/ui/generics/issue-79605.rs b/tests/ui/generics/issue-79605.rs new file mode 100644 index 0000000000000..6f4c31e57a374 --- /dev/null +++ b/tests/ui/generics/issue-79605.rs @@ -0,0 +1,6 @@ +struct X<'a, T>(&'a T); + +impl X<'_, _> {} +//~^ ERROR the placeholder `_` is not allowed within types on item signatures for implementations + +fn main() {} diff --git a/tests/ui/generics/issue-79605.stderr b/tests/ui/generics/issue-79605.stderr new file mode 100644 index 0000000000000..c5584962dc9e2 --- /dev/null +++ b/tests/ui/generics/issue-79605.stderr @@ -0,0 +1,14 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for implementations + --> $DIR/issue-79605.rs:3:12 + | +LL | impl X<'_, _> {} + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | impl X<'_, T> {} + | +++ ~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/implied-bounds/issue-110161.rs b/tests/ui/implied-bounds/issue-110161.rs new file mode 100644 index 0000000000000..e52c8356b52b3 --- /dev/null +++ b/tests/ui/implied-bounds/issue-110161.rs @@ -0,0 +1,26 @@ +// ICE regression relating to unconstrained lifetimes in implied +// bounds. See #110161. + +// compile-flags: --crate-type=lib + +trait LtTrait { + type Ty; +} + +// erroneous `Ty` impl +impl LtTrait for () { +//~^ ERROR not all trait items implemented, missing: `Ty` [E0046] +} + +// `'lt` is not constrained by the erroneous `Ty` +impl<'lt, T> LtTrait for Box +where + T: LtTrait, +{ + type Ty = &'lt (); +} + +// unconstrained lifetime appears in implied bounds +fn test(_: as LtTrait>::Ty) {} + +fn test2<'x>(_: &'x as LtTrait>::Ty) {} diff --git a/tests/ui/implied-bounds/issue-110161.stderr b/tests/ui/implied-bounds/issue-110161.stderr new file mode 100644 index 0000000000000..9e0188694ed9c --- /dev/null +++ b/tests/ui/implied-bounds/issue-110161.stderr @@ -0,0 +1,12 @@ +error[E0046]: not all trait items implemented, missing: `Ty` + --> $DIR/issue-110161.rs:11:1 + | +LL | type Ty; + | ------- `Ty` from trait +... +LL | impl LtTrait for () { + | ^^^^^^^^^^^^^^^^^^^ missing `Ty` in implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/triagebot.toml b/triagebot.toml index 58f51959e1f81..917acce901bda 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -11,6 +11,7 @@ allow-unauthenticated = [ "S-*", "T-*", "WG-*", + "beta-nominated", "const-hack", "llvm-main", "needs-fcp",