diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 2ff6573744442..19c7c479f0429 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -115,6 +115,10 @@ impl NestedMetaItem { pub fn is_meta_item_list(&self) -> bool { self.meta_item_list().is_some() } + + pub fn name_value_literal_span(&self) -> Option { + self.meta_item()?.name_value_literal_span() + } } impl Attribute { @@ -175,6 +179,22 @@ impl Attribute { pub fn is_value_str(&self) -> bool { self.value_str().is_some() } + + /// This is used in case you want the value span instead of the whole attribute. Example: + /// + /// ```text + /// #[doc(alias = "foo")] + /// ``` + /// + /// In here, it'll return a span for `"foo"`. + pub fn name_value_literal_span(&self) -> Option { + match self.kind { + AttrKind::Normal(ref item, _) => { + item.meta(self.span).and_then(|meta| meta.name_value_literal_span()) + } + AttrKind::DocComment(..) => None, + } + } } impl MetaItem { @@ -227,6 +247,17 @@ impl MetaItem { pub fn is_value_str(&self) -> bool { self.value_str().is_some() } + + /// This is used in case you want the value span instead of the whole attribute. Example: + /// + /// ```text + /// #[doc(alias = "foo")] + /// ``` + /// + /// In here, it'll return a span for `"foo"`. + pub fn name_value_literal_span(&self) -> Option { + Some(self.name_value_literal()?.span) + } } impl AttrItem { diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 364a3a1eeb5e7..bb7562bc80c7c 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -294,7 +294,7 @@ where or \"none\"", ) .span_label( - mi.name_value_literal().unwrap().span, + mi.name_value_literal_span().unwrap(), msg, ) .emit(); diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 22e2aa3b5c8b4..70cf876a08a51 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -643,15 +643,16 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( } } + fn escape_string(s: &[u8]) -> String { + str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| { + let mut x = "Non-UTF-8 output: ".to_string(); + x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from)); + x + }) + } + match prog { Ok(prog) => { - fn escape_string(s: &[u8]) -> String { - str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| { - let mut x = "Non-UTF-8 output: ".to_string(); - x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from)); - x - }) - } if !prog.status.success() { let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); @@ -760,8 +761,21 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( && sess.opts.debuginfo != DebugInfo::None && !preserve_objects_for_their_debuginfo(sess) { - if let Err(e) = Command::new("dsymutil").arg(out_filename).output() { - sess.fatal(&format!("failed to run dsymutil: {}", e)) + let prog = Command::new("dsymutil").arg(out_filename).output(); + match prog { + Ok(prog) => { + if !prog.status.success() { + let mut output = prog.stderr.clone(); + output.extend_from_slice(&prog.stdout); + sess.struct_warn(&format!( + "processing debug info with `dsymutil` failed: {}", + prog.status + )) + .note(&escape_string(&output)) + .emit(); + } + } + Err(e) => sess.fatal(&format!("unable to run `dsymutil`: {}", e)), } } } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 4ba75c21cf058..37ff6b9b368e7 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1603,23 +1603,22 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { items.push(ast::NestedMetaItem::MetaItem(item)); } Err(e) => { - let lit = - it.meta_item().and_then(|item| item.name_value_literal()).unwrap(); + let lit_span = it.name_value_literal_span().unwrap(); if e.kind() == ErrorKind::InvalidData { self.cx .struct_span_err( - lit.span, + lit_span, &format!("{} wasn't a utf-8 file", filename.display()), ) - .span_label(lit.span, "contains invalid utf-8") + .span_label(lit_span, "contains invalid utf-8") .emit(); } else { let mut err = self.cx.struct_span_err( - lit.span, + lit_span, &format!("couldn't read {}: {}", filename.display(), e), ); - err.span_label(lit.span, "couldn't read file"); + err.span_label(lit_span, "couldn't read file"); err.emit(); } diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index 41342764ba773..61f850c2fc166 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -43,8 +43,7 @@ fn update_limit( let value_span = attr .meta() - .and_then(|meta| meta.name_value_literal().cloned()) - .map(|lit| lit.span) + .and_then(|meta| meta.name_value_literal_span()) .unwrap_or(attr.span); let error_str = match e.kind() { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 9c0234953bba9..c9e02d56f4b28 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -319,7 +319,7 @@ impl CheckAttrVisitor<'tcx> { self.tcx .sess .struct_span_err( - meta.span(), + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), &format!( "{:?} character isn't allowed in `#[doc(alias = \"...\")]`", c, @@ -332,7 +332,7 @@ impl CheckAttrVisitor<'tcx> { self.tcx .sess .struct_span_err( - meta.span(), + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), "`#[doc(alias = \"...\")]` cannot start or end with ' '", ) .emit(); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index db16a90cc60fa..b648e14360c00 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -214,7 +214,7 @@ pub enum SymbolManglingVersion { impl_stable_hash_via_hash!(SymbolManglingVersion); -#[derive(Clone, Copy, PartialEq, Hash)] +#[derive(Clone, Copy, Debug, PartialEq, Hash)] pub enum DebugInfo { None, Limited, diff --git a/library/std/src/sys/unix/kernel_copy.rs b/library/std/src/sys/unix/kernel_copy.rs index 1dc16ef099367..f08c828ecfff0 100644 --- a/library/std/src/sys/unix/kernel_copy.rs +++ b/library/std/src/sys/unix/kernel_copy.rs @@ -56,6 +56,7 @@ use crate::mem::ManuallyDrop; use crate::net::TcpStream; use crate::os::unix::fs::FileTypeExt; use crate::os::unix::io::{AsRawFd, FromRawFd, RawFd}; +use crate::os::unix::net::UnixStream; use crate::process::{ChildStderr, ChildStdin, ChildStdout}; use crate::ptr; use crate::sync::atomic::{AtomicBool, Ordering}; @@ -320,6 +321,34 @@ impl CopyWrite for &TcpStream { } } +impl CopyRead for UnixStream { + fn properties(&self) -> CopyParams { + // avoid the stat syscall since we can be fairly sure it's a socket + CopyParams(FdMeta::Socket, Some(self.as_raw_fd())) + } +} + +impl CopyRead for &UnixStream { + fn properties(&self) -> CopyParams { + // avoid the stat syscall since we can be fairly sure it's a socket + CopyParams(FdMeta::Socket, Some(self.as_raw_fd())) + } +} + +impl CopyWrite for UnixStream { + fn properties(&self) -> CopyParams { + // avoid the stat syscall since we can be fairly sure it's a socket + CopyParams(FdMeta::Socket, Some(self.as_raw_fd())) + } +} + +impl CopyWrite for &UnixStream { + fn properties(&self) -> CopyParams { + // avoid the stat syscall since we can be fairly sure it's a socket + CopyParams(FdMeta::Socket, Some(self.as_raw_fd())) + } +} + impl CopyWrite for ChildStdin { fn properties(&self) -> CopyParams { CopyParams(FdMeta::Pipe, Some(self.as_raw_fd())) diff --git a/library/std/src/sys/unix/kernel_copy/tests.rs b/library/std/src/sys/unix/kernel_copy/tests.rs index 21b121c26fffc..554ebd9402234 100644 --- a/library/std/src/sys/unix/kernel_copy/tests.rs +++ b/library/std/src/sys/unix/kernel_copy/tests.rs @@ -118,6 +118,35 @@ fn bench_file_to_socket_copy(b: &mut test::Bencher) { }); } +#[bench] +fn bench_file_to_uds_copy(b: &mut test::Bencher) { + const BYTES: usize = 128 * 1024; + let src_path = temp_dir().join("uds-copy-bench-src"); + let mut src = OpenOptions::new() + .create(true) + .truncate(true) + .read(true) + .write(true) + .open(src_path) + .unwrap(); + src.write(&vec![0u8; BYTES]).unwrap(); + + let (mut sink, mut sink_drainer) = crate::os::unix::net::UnixStream::pair().unwrap(); + + crate::thread::spawn(move || { + let mut sink_buf = vec![0u8; 1024 * 1024]; + loop { + sink_drainer.read(&mut sink_buf[..]).unwrap(); + } + }); + + b.bytes = BYTES as u64; + b.iter(|| { + src.seek(SeekFrom::Start(0)).unwrap(); + assert_eq!(BYTES as u64, io::copy(&mut src, &mut sink).unwrap()); + }); +} + #[cfg(any(target_os = "linux", target_os = "android"))] #[bench] fn bench_socket_pipe_socket_copy(b: &mut test::Bencher) { diff --git a/src/test/rustdoc-ui/check-doc-alias-attr.stderr b/src/test/rustdoc-ui/check-doc-alias-attr.stderr index 8a729b02e72bf..3ba0ba6107531 100644 --- a/src/test/rustdoc-ui/check-doc-alias-attr.stderr +++ b/src/test/rustdoc-ui/check-doc-alias-attr.stderr @@ -17,42 +17,42 @@ LL | #[doc(alias("bar"))] | ^^^^^^^^^^^^ error: '\"' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:9:7 + --> $DIR/check-doc-alias-attr.rs:9:15 | LL | #[doc(alias = "\"")] - | ^^^^^^^^^^^^ + | ^^^^ error: '\n' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:10:7 + --> $DIR/check-doc-alias-attr.rs:10:15 | LL | #[doc(alias = "\n")] - | ^^^^^^^^^^^^ + | ^^^^ error: '\n' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:11:7 + --> $DIR/check-doc-alias-attr.rs:11:15 | LL | #[doc(alias = " - | _______^ + | _______________^ LL | | ")] | |_^ error: '\t' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:13:7 + --> $DIR/check-doc-alias-attr.rs:13:15 | LL | #[doc(alias = "\t")] - | ^^^^^^^^^^^^ + | ^^^^ error: `#[doc(alias = "...")]` cannot start or end with ' ' - --> $DIR/check-doc-alias-attr.rs:14:7 + --> $DIR/check-doc-alias-attr.rs:14:15 | LL | #[doc(alias = " hello")] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: `#[doc(alias = "...")]` cannot start or end with ' ' - --> $DIR/check-doc-alias-attr.rs:15:7 + --> $DIR/check-doc-alias-attr.rs:15:15 | LL | #[doc(alias = "hello ")] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: aborting due to 9 previous errors diff --git a/src/test/rustdoc-ui/doc-alias-crate-level.stderr b/src/test/rustdoc-ui/doc-alias-crate-level.stderr index fc14266cd714c..a58e91c5aa74a 100644 --- a/src/test/rustdoc-ui/doc-alias-crate-level.stderr +++ b/src/test/rustdoc-ui/doc-alias-crate-level.stderr @@ -1,8 +1,8 @@ error: '\'' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/doc-alias-crate-level.rs:5:7 + --> $DIR/doc-alias-crate-level.rs:5:15 | LL | #[doc(alias = "shouldn't work!")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ error: `#![doc(alias = "...")]` isn't allowed as a crate level attribute --> $DIR/doc-alias-crate-level.rs:3:8 diff --git a/src/test/ui/check-doc-alias-attr.stderr b/src/test/ui/check-doc-alias-attr.stderr index 2c417a3bb65b5..a92298d163380 100644 --- a/src/test/ui/check-doc-alias-attr.stderr +++ b/src/test/ui/check-doc-alias-attr.stderr @@ -17,42 +17,42 @@ LL | #[doc(alias("bar"))] | ^^^^^^^^^^^^ error: '\"' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:10:7 + --> $DIR/check-doc-alias-attr.rs:10:15 | LL | #[doc(alias = "\"")] - | ^^^^^^^^^^^^ + | ^^^^ error: '\n' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:11:7 + --> $DIR/check-doc-alias-attr.rs:11:15 | LL | #[doc(alias = "\n")] - | ^^^^^^^^^^^^ + | ^^^^ error: '\n' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:12:7 + --> $DIR/check-doc-alias-attr.rs:12:15 | LL | #[doc(alias = " - | _______^ + | _______________^ LL | | ")] | |_^ error: '\t' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/check-doc-alias-attr.rs:14:7 + --> $DIR/check-doc-alias-attr.rs:14:15 | LL | #[doc(alias = "\t")] - | ^^^^^^^^^^^^ + | ^^^^ error: `#[doc(alias = "...")]` cannot start or end with ' ' - --> $DIR/check-doc-alias-attr.rs:15:7 + --> $DIR/check-doc-alias-attr.rs:15:15 | LL | #[doc(alias = " hello")] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: `#[doc(alias = "...")]` cannot start or end with ' ' - --> $DIR/check-doc-alias-attr.rs:16:7 + --> $DIR/check-doc-alias-attr.rs:16:15 | LL | #[doc(alias = "hello ")] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: aborting due to 9 previous errors diff --git a/src/test/ui/doc-alias-crate-level.stderr b/src/test/ui/doc-alias-crate-level.stderr index 45756d6a04bd0..32b42cf9be766 100644 --- a/src/test/ui/doc-alias-crate-level.stderr +++ b/src/test/ui/doc-alias-crate-level.stderr @@ -1,8 +1,8 @@ error: '\'' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/doc-alias-crate-level.rs:7:8 + --> $DIR/doc-alias-crate-level.rs:7:16 | LL | #![doc(alias = "shouldn't work!")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ error: aborting due to previous error