diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 9926cca2f51c6..9c7de250c29b1 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -699,7 +699,6 @@ impl<'tcx> ty::TyS<'tcx> { /// optimization as well as the rules around static values. Note /// that the `Freeze` trait is not exposed to end users and is /// effectively an implementation detail. - // FIXME: use `TyCtxtAt` instead of separate `Span`. pub fn is_freeze(&'tcx self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { self.is_trivially_freeze() || tcx_at.is_freeze_raw(param_env.and(self)) } diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index b5e66d37ab494..bf9f7432fb536 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -958,6 +958,27 @@ impl BinaryHeap { self.data.shrink_to(min_capacity) } + /// Returns a slice of all values in the underlying vector, in arbitrary + /// order. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(binary_heap_as_slice)] + /// use std::collections::BinaryHeap; + /// use std::io::{self, Write}; + /// + /// let heap = BinaryHeap::from(vec![1, 2, 3, 4, 5, 6, 7]); + /// + /// io::sink().write(heap.as_slice()).unwrap(); + /// ``` + #[unstable(feature = "binary_heap_as_slice", issue = "83659")] + pub fn as_slice(&self) -> &[T] { + self.data.as_slice() + } + /// Consumes the `BinaryHeap` and returns the underlying vector /// in arbitrary order. /// diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index c75a6c1f61990..7e1194cc4aa20 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -14,6 +14,7 @@ #![feature(binary_heap_drain_sorted)] #![feature(slice_ptr_get)] #![feature(binary_heap_retain)] +#![feature(binary_heap_as_slice)] #![feature(inplace_iteration)] #![feature(iter_map_while)] #![feature(vecdeque_binary_search)] diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index f0bd976ba83d5..6032dc9a2d371 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -2,6 +2,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::ascii; use crate::intrinsics; use crate::mem; use crate::str::FromStr; @@ -661,6 +662,31 @@ impl u8 { pub const fn is_ascii_control(&self) -> bool { matches!(*self, b'\0'..=b'\x1F' | b'\x7F') } + + /// Returns an iterator that produces an escaped version of a `u8`, + /// treating it as an ASCII character. + /// + /// The behavior is identical to [`ascii::escape_default`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(inherent_ascii_escape)] + /// + /// assert_eq!("0", b'0'.escape_ascii().to_string()); + /// assert_eq!("\\t", b'\t'.escape_ascii().to_string()); + /// assert_eq!("\\r", b'\r'.escape_ascii().to_string()); + /// assert_eq!("\\n", b'\n'.escape_ascii().to_string()); + /// assert_eq!("\\'", b'\''.escape_ascii().to_string()); + /// assert_eq!("\\\"", b'"'.escape_ascii().to_string()); + /// assert_eq!("\\\\", b'\\'.escape_ascii().to_string()); + /// assert_eq!("\\x9d", b'\x9d'.escape_ascii().to_string()); + /// ``` + #[unstable(feature = "inherent_ascii_escape", issue = "77174")] + #[inline] + pub fn escape_ascii(&self) -> ascii::EscapeDefault { + ascii::escape_default(*self) + } } #[lang = "u16"] diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 009ef9e0a9c1f..22fa08b979570 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -1,7 +1,10 @@ //! Operations on ASCII `[u8]`. +use crate::ascii; +use crate::fmt::{self, Write}; use crate::iter; use crate::mem; +use crate::ops; #[lang = "slice_u8"] #[cfg(not(test))] @@ -56,6 +59,95 @@ impl [u8] { byte.make_ascii_lowercase(); } } + + /// Returns an iterator that produces an escaped version of this slice, + /// treating it as an ASCII string. + /// + /// # Examples + /// + /// ``` + /// #![feature(inherent_ascii_escape)] + /// + /// let s = b"0\t\r\n'\"\\\x9d"; + /// let escaped = s.escape_ascii().to_string(); + /// assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d"); + /// ``` + #[unstable(feature = "inherent_ascii_escape", issue = "77174")] + pub fn escape_ascii(&self) -> EscapeAscii<'_> { + EscapeAscii { inner: self.iter().flat_map(EscapeByte) } + } +} + +impl_fn_for_zst! { + #[derive(Clone)] + struct EscapeByte impl Fn = |byte: &u8| -> ascii::EscapeDefault { + ascii::escape_default(*byte) + }; +} + +/// An iterator over the escaped version of a byte slice. +/// +/// This `struct` is created by the [`slice::escape_ascii`] method. See its +/// documentation for more information. +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +#[derive(Clone)] +pub struct EscapeAscii<'a> { + inner: iter::FlatMap, ascii::EscapeDefault, EscapeByte>, +} + +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +impl<'a> iter::Iterator for EscapeAscii<'a> { + type Item = u8; + #[inline] + fn next(&mut self) -> Option { + self.inner.next() + } + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } + #[inline] + fn try_fold(&mut self, init: Acc, fold: Fold) -> R + where + Fold: FnMut(Acc, Self::Item) -> R, + R: ops::Try, + { + self.inner.try_fold(init, fold) + } + #[inline] + fn fold(self, init: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + { + self.inner.fold(init, fold) + } + #[inline] + fn last(mut self) -> Option { + self.next_back() + } +} + +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +impl<'a> iter::DoubleEndedIterator for EscapeAscii<'a> { + fn next_back(&mut self) -> Option { + self.inner.next_back() + } +} +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +impl<'a> iter::ExactSizeIterator for EscapeAscii<'a> {} +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +impl<'a> iter::FusedIterator for EscapeAscii<'a> {} +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +impl<'a> fmt::Display for EscapeAscii<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.clone().try_for_each(|b| f.write_char(b as char)) + } +} +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +impl<'a> fmt::Debug for EscapeAscii<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.pad("EscapeAscii { .. }") + } } /// Returns `true` if any byte in the word `v` is nonascii (>= 128). Snarfed diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index d7a28c8d08f78..59fad8c813c73 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -81,6 +81,9 @@ pub use index::SliceIndex; #[unstable(feature = "slice_range", issue = "76393")] pub use index::range; +#[unstable(feature = "inherent_ascii_escape", issue = "77174")] +pub use ascii::EscapeAscii; + #[lang = "slice"] #[cfg(not(test))] impl [T] { diff --git a/library/std/src/sys/unix/ext/net/ancillary.rs b/library/std/src/sys/unix/ext/net/ancillary.rs index 33d6a39af07f6..011ae643f8712 100644 --- a/library/std/src/sys/unix/ext/net/ancillary.rs +++ b/library/std/src/sys/unix/ext/net/ancillary.rs @@ -5,9 +5,7 @@ use crate::marker::PhantomData; use crate::mem::{size_of, zeroed}; use crate::os::unix::io::RawFd; use crate::path::Path; -#[cfg(target_os = "android")] -use crate::ptr::eq; -use crate::ptr::read_unaligned; +use crate::ptr::{eq, read_unaligned}; use crate::slice::from_raw_parts; use crate::sys::net::Socket; @@ -30,12 +28,10 @@ pub(super) fn recv_vectored_with_ancillary_from( ) -> io::Result<(usize, bool, io::Result)> { unsafe { let mut msg_name: libc::sockaddr_un = zeroed(); - let mut msg: libc::msghdr = zeroed(); msg.msg_name = &mut msg_name as *mut _ as *mut _; msg.msg_namelen = size_of::() as libc::socklen_t; msg.msg_iov = bufs.as_mut_ptr().cast(); - msg.msg_control = ancillary.buffer.as_mut_ptr().cast(); cfg_if::cfg_if! { if #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] { msg.msg_iovlen = bufs.len() as libc::size_t; @@ -45,6 +41,7 @@ pub(super) fn recv_vectored_with_ancillary_from( target_os = "emscripten", target_os = "freebsd", all(target_os = "linux", target_env = "musl",), + target_os = "macos", target_os = "netbsd", target_os = "openbsd", ))] { @@ -52,6 +49,10 @@ pub(super) fn recv_vectored_with_ancillary_from( msg.msg_controllen = ancillary.buffer.len() as libc::socklen_t; } } + // macos requires that the control pointer is NULL when the len is 0. + if msg.msg_controllen > 0 { + msg.msg_control = ancillary.buffer.as_mut_ptr().cast(); + } let count = socket.recv_msg(&mut msg)?; @@ -79,7 +80,6 @@ pub(super) fn send_vectored_with_ancillary_to( msg.msg_name = &mut msg_name as *mut _ as *mut _; msg.msg_namelen = msg_namelen; msg.msg_iov = bufs.as_ptr() as *mut _; - msg.msg_control = ancillary.buffer.as_mut_ptr().cast(); cfg_if::cfg_if! { if #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] { msg.msg_iovlen = bufs.len() as libc::size_t; @@ -89,6 +89,7 @@ pub(super) fn send_vectored_with_ancillary_to( target_os = "emscripten", target_os = "freebsd", all(target_os = "linux", target_env = "musl",), + target_os = "macos", target_os = "netbsd", target_os = "openbsd", ))] { @@ -96,6 +97,10 @@ pub(super) fn send_vectored_with_ancillary_to( msg.msg_controllen = ancillary.length as libc::socklen_t; } } + // macos requires that the control pointer is NULL when the len is 0. + if msg.msg_controllen > 0 { + msg.msg_control = ancillary.buffer.as_mut_ptr().cast(); + } ancillary.truncated = false; @@ -147,6 +152,7 @@ fn add_to_ancillary_data( target_os = "emscripten", target_os = "freebsd", all(target_os = "linux", target_env = "musl",), + target_os = "macos", target_os = "netbsd", target_os = "openbsd", ))] { @@ -159,14 +165,12 @@ fn add_to_ancillary_data( while !cmsg.is_null() { previous_cmsg = cmsg; cmsg = libc::CMSG_NXTHDR(&msg, cmsg); - cfg_if::cfg_if! { - // Android return the same pointer if it is the last cmsg. - // Therefore, check it if the previous pointer is the same as the current one. - if #[cfg(target_os = "android")] { - if cmsg == previous_cmsg { - break; - } - } + + // Most operating systems, but not Linux or emscripten, return the previous pointer + // when its length is zero. Therefore, check if the previous pointer is the same as + // the current one. + if eq(cmsg, previous_cmsg) { + break; } } @@ -184,6 +188,7 @@ fn add_to_ancillary_data( target_os = "emscripten", target_os = "freebsd", all(target_os = "linux", target_env = "musl",), + target_os = "macos", target_os = "netbsd", target_os = "openbsd", ))] { @@ -371,6 +376,7 @@ impl<'a> AncillaryData<'a> { target_os = "emscripten", target_os = "freebsd", all(target_os = "linux", target_env = "musl",), + target_os = "macos", target_os = "netbsd", target_os = "openbsd", ))] { @@ -421,6 +427,7 @@ impl<'a> Iterator for Messages<'a> { target_os = "emscripten", target_os = "freebsd", all(target_os = "linux", target_env = "musl",), + target_os = "macos", target_os = "netbsd", target_os = "openbsd", ))] { @@ -435,15 +442,13 @@ impl<'a> Iterator for Messages<'a> { }; let cmsg = cmsg.as_ref()?; - cfg_if::cfg_if! { - // Android return the same pointer if it is the last cmsg. - // Therefore, check it if the previous pointer is the same as the current one. - if #[cfg(target_os = "android")] { - if let Some(current) = self.current { - if eq(current, cmsg) { - return None; - } - } + + // Most operating systems, but not Linux or emscripten, return the previous pointer + // when its length is zero. Therefore, check if the previous pointer is the same as + // the current one. + if let Some(current) = self.current { + if eq(current, cmsg) { + return None; } } @@ -514,6 +519,12 @@ impl<'a> SocketAncillary<'a> { self.buffer.len() } + /// Returns `true` if the ancillary data is empty. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn is_empty(&self) -> bool { + self.length == 0 + } + /// Returns the number of used bytes. #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub fn len(&self) -> usize { diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index b39f9f878921a..c44514ed3cb83 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1162,6 +1162,7 @@ crate fn plain_text_summary(md: &str) -> String { s } +#[derive(Debug)] crate struct MarkdownLink { pub kind: LinkType, pub link: String, diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 499931f7e9631..55978ca551b05 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -950,6 +950,7 @@ impl LinkCollector<'_, '_> { } let link = ori_link.link.replace("`", ""); + let no_backticks_range = range_between_backticks(&ori_link); let parts = link.split('#').collect::>(); let (link, extra_fragment) = if parts.len() > 2 { // A valid link can't have multiple #'s @@ -973,10 +974,15 @@ impl LinkCollector<'_, '_> { }; // Parse and strip the disambiguator from the link, if present. - let (mut path_str, disambiguator) = if let Ok((d, path)) = Disambiguator::from_str(&link) { - (path.trim(), Some(d)) - } else { - (link.trim(), None) + let (mut path_str, disambiguator) = match Disambiguator::from_str(&link) { + Ok(Some((d, path))) => (path.trim(), Some(d)), + Ok(None) => (link.trim(), None), + Err((err_msg, relative_range)) => { + let disambiguator_range = (no_backticks_range.start + relative_range.start) + ..(no_backticks_range.start + relative_range.end); + disambiguator_error(self.cx, &item, dox, disambiguator_range, &err_msg); + return None; + } }; if path_str.contains(|ch: char| !(ch.is_alphanumeric() || ":_<>, !*&;".contains(ch))) { @@ -1488,6 +1494,27 @@ impl LinkCollector<'_, '_> { } } +/// Get the section of a link between the backticks, +/// or the whole link if there aren't any backticks. +/// +/// For example: +/// +/// ```text +/// [`Foo`] +/// ^^^ +/// ``` +fn range_between_backticks(ori_link: &MarkdownLink) -> Range { + let after_first_backtick_group = ori_link.link.bytes().position(|b| b != b'`').unwrap_or(0); + let before_second_backtick_group = ori_link + .link + .bytes() + .skip(after_first_backtick_group) + .position(|b| b == b'`') + .unwrap_or(ori_link.link.len()); + (ori_link.range.start + after_first_backtick_group) + ..(ori_link.range.start + before_second_backtick_group) +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] /// Disambiguators for a link. enum Disambiguator { @@ -1514,27 +1541,14 @@ impl Disambiguator { } } - /// Given a link, parse and return `(disambiguator, path_str)` - fn from_str(link: &str) -> Result<(Self, &str), ()> { + /// Given a link, parse and return `(disambiguator, path_str)`. + /// + /// This returns `Ok(Some(...))` if a disambiguator was found, + /// `Ok(None)` if no disambiguator was found, or `Err(...)` + /// if there was a problem with the disambiguator. + fn from_str(link: &str) -> Result, (String, Range)> { use Disambiguator::{Kind, Namespace as NS, Primitive}; - let find_suffix = || { - let suffixes = [ - ("!()", DefKind::Macro(MacroKind::Bang)), - ("()", DefKind::Fn), - ("!", DefKind::Macro(MacroKind::Bang)), - ]; - for &(suffix, kind) in &suffixes { - if let Some(link) = link.strip_suffix(suffix) { - // Avoid turning `!` or `()` into an empty string - if !link.is_empty() { - return Ok((Kind(kind), link)); - } - } - } - Err(()) - }; - if let Some(idx) = link.find('@') { let (prefix, rest) = link.split_at(idx); let d = match prefix { @@ -1551,11 +1565,24 @@ impl Disambiguator { "value" => NS(Namespace::ValueNS), "macro" => NS(Namespace::MacroNS), "prim" | "primitive" => Primitive, - _ => return find_suffix(), + _ => return Err((format!("unknown disambiguator `{}`", prefix), 0..idx)), }; - Ok((d, &rest[1..])) + Ok(Some((d, &rest[1..]))) } else { - find_suffix() + let suffixes = [ + ("!()", DefKind::Macro(MacroKind::Bang)), + ("()", DefKind::Fn), + ("!", DefKind::Macro(MacroKind::Bang)), + ]; + for &(suffix, kind) in &suffixes { + if let Some(link) = link.strip_suffix(suffix) { + // Avoid turning `!` or `()` into an empty string + if !link.is_empty() { + return Ok(Some((Kind(kind), link))); + } + } + } + Ok(None) } } @@ -1979,6 +2006,17 @@ fn anchor_failure( }); } +/// Report an error in the link disambiguator. +fn disambiguator_error( + cx: &DocContext<'_>, + item: &Item, + dox: &str, + link_range: Range, + msg: &str, +) { + report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, item, dox, &link_range, |_diag, _sp| {}); +} + /// Report an ambiguity error, where there were multiple possible resolutions. fn ambiguity_error( cx: &DocContext<'_>, diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs new file mode 100644 index 0000000000000..925fc515a3e65 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs @@ -0,0 +1,13 @@ +#![deny(warnings)] + +//! Linking to [foo@banana] and [`bar@banana!()`]. +//~^ ERROR unknown disambiguator `foo` +//~| ERROR unknown disambiguator `bar` +//! And to [no disambiguator](@nectarine) and [another](@apricot!()). +//~^ ERROR unknown disambiguator `` +//~| ERROR unknown disambiguator `` +//! And with weird backticks: [``foo@hello``] [foo`@`hello]. +//~^ ERROR unknown disambiguator `foo` +//~| ERROR unknown disambiguator `foo` + +fn main() {} diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr new file mode 100644 index 0000000000000..195aaca32a27d --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr @@ -0,0 +1,45 @@ +error: unknown disambiguator `foo` + --> $DIR/unknown-disambiguator.rs:3:17 + | +LL | //! Linking to [foo@banana] and [`bar@banana!()`]. + | ^^^ + | +note: the lint level is defined here + --> $DIR/unknown-disambiguator.rs:1:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]` + +error: unknown disambiguator `bar` + --> $DIR/unknown-disambiguator.rs:3:35 + | +LL | //! Linking to [foo@banana] and [`bar@banana!()`]. + | ^^^ + +error: unknown disambiguator `foo` + --> $DIR/unknown-disambiguator.rs:9:34 + | +LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello]. + | ^^^ + +error: unknown disambiguator `foo` + --> $DIR/unknown-disambiguator.rs:9:48 + | +LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello]. + | ^^^ + +error: unknown disambiguator `` + --> $DIR/unknown-disambiguator.rs:6:31 + | +LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). + | ^ + +error: unknown disambiguator `` + --> $DIR/unknown-disambiguator.rs:6:57 + | +LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()). + | ^ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/const-generics/defaults/complex-unord-param.rs b/src/test/ui/const-generics/defaults/complex-unord-param.rs index 82b3627d22ff8..d24e403e017ef 100644 --- a/src/test/ui/const-generics/defaults/complex-unord-param.rs +++ b/src/test/ui/const-generics/defaults/complex-unord-param.rs @@ -6,16 +6,16 @@ #![allow(dead_code)] struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> { - //[min]~^ ERROR type parameters must be declared prior to const parameters - args: &'a [&'a [T; M]; N], - specifier: A, + //[min]~^ ERROR type parameters must be declared prior to const parameters + args: &'a [&'a [T; M]; N], + specifier: A, } fn main() { - let array = [1, 2, 3]; - let nest = [&array]; - let _ = NestedArrays { - args: &nest, - specifier: true, - }; + let array = [1, 2, 3]; + let nest = [&array]; + let _ = NestedArrays { + args: &nest, + specifier: true, + }; } diff --git a/src/test/ui/const-generics/defaults/default-annotation.rs b/src/test/ui/const-generics/defaults/default-annotation.rs index e6e8d732beef3..3febb7cffbf15 100644 --- a/src/test/ui/const-generics/defaults/default-annotation.rs +++ b/src/test/ui/const-generics/defaults/default-annotation.rs @@ -13,8 +13,8 @@ pub struct ConstDefaultUnstable; #[stable(feature = "const_default_unstable", since="none")] pub struct ConstDefaultStable; fn main() {} diff --git a/src/test/ui/const-generics/defaults/mismatch.rs b/src/test/ui/const-generics/defaults/mismatch.rs index bf578468bb617..d85b756f538dc 100644 --- a/src/test/ui/const-generics/defaults/mismatch.rs +++ b/src/test/ui/const-generics/defaults/mismatch.rs @@ -8,16 +8,16 @@ pub struct Example3(T); pub struct Example4; fn main() { - let e: Example::<13> = (); - //~^ Error: mismatched types - let e: Example2:: = (); - //~^ Error: mismatched types - let e: Example3::<13, u32> = (); - //~^ Error: mismatched types - let e: Example3::<7> = (); - //~^ Error: mismatched types - // FIXME(const_generics_defaults): There should be a note for the error below, but it is - // missing. - let e: Example4::<7> = (); - //~^ Error: mismatched types + let e: Example::<13> = (); + //~^ Error: mismatched types + let e: Example2:: = (); + //~^ Error: mismatched types + let e: Example3::<13, u32> = (); + //~^ Error: mismatched types + let e: Example3::<7> = (); + //~^ Error: mismatched types + // FIXME(const_generics_defaults): There should be a note for the error below, but it is + // missing. + let e: Example4::<7> = (); + //~^ Error: mismatched types } diff --git a/src/test/ui/const-generics/defaults/mismatch.stderr b/src/test/ui/const-generics/defaults/mismatch.stderr index c66eb4cd64594..ff72c71c40f0f 100644 --- a/src/test/ui/const-generics/defaults/mismatch.stderr +++ b/src/test/ui/const-generics/defaults/mismatch.stderr @@ -1,51 +1,51 @@ error[E0308]: mismatched types - --> $DIR/mismatch.rs:11:26 + --> $DIR/mismatch.rs:11:28 | -LL | let e: Example::<13> = (); - | ------------- ^^ expected struct `Example`, found `()` - | | - | expected due to this +LL | let e: Example::<13> = (); + | ------------- ^^ expected struct `Example`, found `()` + | | + | expected due to this error[E0308]: mismatched types - --> $DIR/mismatch.rs:13:32 + --> $DIR/mismatch.rs:13:34 | -LL | let e: Example2:: = (); - | ------------------- ^^ expected struct `Example2`, found `()` - | | - | expected due to this +LL | let e: Example2:: = (); + | ------------------- ^^ expected struct `Example2`, found `()` + | | + | expected due to this | = note: expected struct `Example2` found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:15:32 + --> $DIR/mismatch.rs:15:34 | -LL | let e: Example3::<13, u32> = (); - | ------------------- ^^ expected struct `Example3`, found `()` - | | - | expected due to this +LL | let e: Example3::<13, u32> = (); + | ------------------- ^^ expected struct `Example3`, found `()` + | | + | expected due to this | = note: expected struct `Example3` found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:17:26 + --> $DIR/mismatch.rs:17:28 | -LL | let e: Example3::<7> = (); - | ------------- ^^ expected struct `Example3`, found `()` - | | - | expected due to this +LL | let e: Example3::<7> = (); + | ------------- ^^ expected struct `Example3`, found `()` + | | + | expected due to this | = note: expected struct `Example3<7_usize>` found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:21:26 + --> $DIR/mismatch.rs:21:28 | -LL | let e: Example4::<7> = (); - | ------------- ^^ expected struct `Example4`, found `()` - | | - | expected due to this +LL | let e: Example4::<7> = (); + | ------------- ^^ expected struct `Example4`, found `()` + | | + | expected due to this error: aborting due to 5 previous errors diff --git a/src/test/ui/const-generics/defaults/needs-feature.rs b/src/test/ui/const-generics/defaults/needs-feature.rs index 7eb7764a64449..b58dee0712a76 100644 --- a/src/test/ui/const-generics/defaults/needs-feature.rs +++ b/src/test/ui/const-generics/defaults/needs-feature.rs @@ -10,5 +10,5 @@ struct A(T); //[min]~^ ERROR type parameters must be declared prior fn main() { - let _: A<3> = A(0); + let _: A<3> = A(0); } diff --git a/src/test/ui/const-generics/defaults/repr-c-issue-82792.rs b/src/test/ui/const-generics/defaults/repr-c-issue-82792.rs new file mode 100644 index 0000000000000..18ecf46729977 --- /dev/null +++ b/src/test/ui/const-generics/defaults/repr-c-issue-82792.rs @@ -0,0 +1,14 @@ +// Regression test for #82792. + +// run-pass + +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] + +#[repr(C)] +pub struct Loaf { + head: [T; N], + slice: [T], +} + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/simple-defaults.rs b/src/test/ui/const-generics/defaults/simple-defaults.rs index 1f1b6c2260db6..cb66c7769bb23 100644 --- a/src/test/ui/const-generics/defaults/simple-defaults.rs +++ b/src/test/ui/const-generics/defaults/simple-defaults.rs @@ -6,12 +6,12 @@ #![allow(dead_code)] struct FixedOutput<'a, const N: usize, T=u32> { - //[min]~^ ERROR type parameters must be declared prior to const parameters - out: &'a [T; N], + //[min]~^ ERROR type parameters must be declared prior to const parameters + out: &'a [T; N], } trait FixedOutputter { - fn out(&self) -> FixedOutput<'_, 10>; + fn out(&self) -> FixedOutput<'_, 10>; } fn main() {} diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index 858ad554374a8..bb1d925dab363 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit 858ad554374a8b1ad67692558a0878391abfdd86 +Subproject commit bb1d925dab36372c6bd1fb5671bb68ce938ff009