From 3db6d1cc168d6a2be8048c34012526af1ec24213 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 20 Mar 2020 11:36:57 -0400 Subject: [PATCH 1/9] For issue 53957: revise unit tests to focus on underlying bug of 23076. Namely, this version focuses on the end-to-end behavior that the attempt to create the UDP binding will fail, regardless of the semantics of how particular DNS servers handle junk inputs. (I spent some time trying to create a second more-focused test that would sidestep the DNS resolution, but this is not possible without more invasive changes to the internal infrastructure of `ToSocketAddrs` and what not. It is not worth it.) --- src/libstd/net/addr.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 57cba6b1f7a1b..de6360cf020f5 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -989,11 +989,26 @@ mod tests { // s has been moved into the tsa call } - // FIXME: figure out why this fails on openbsd and fix it #[test] - #[cfg(not(any(windows, target_os = "openbsd")))] - fn to_socket_addr_str_bad() { - assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err()); + fn bind_udp_socket_bad() { + // rust-lang/rust#53957: This is a regression test for a parsing problem + // discovered as part of issue rust-lang/rust#23076, where we were + // incorrectly parsing invalid input and then that would result in a + // successful `UdpSocket` binding when we would expect failure. + // + // At one time, this test was written as a call to `tsa` with + // INPUT_23076. However, that structure yields an unreliable test, + // because it ends up passing junk input to the DNS server, and some DNS + // servers will respond with `Ok` to such input, with the ip address of + // the DNS server itself. + // + // This form of the test is more robust: even when the DNS server + // returns its own address, it is still an error to bind a UDP socket to + // a non-local address, and so we still get an error here in that case. + + const INPUT_23076: &'static str = "1200::AB00:1234::2552:7777:1313:34300"; + + assert!(crate::net::UdpSocket::bind(INPUT_23076).is_err()) } #[test] From 745eb7a87be1b4d2327fc880b606466d291b5b34 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 20 Mar 2020 15:28:26 -0700 Subject: [PATCH 2/9] Use split_at in slice's ToOwned::clone_into It appears to codegen slightly more efficiently with `split_at` taking two slices at once, rather than slicing across different calls. --- src/liballoc/slice.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 7b83658fca60d..702ae166f3264 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -735,14 +735,14 @@ impl ToOwned for [T] { fn clone_into(&self, target: &mut Vec) { // drop anything in target that will not be overwritten target.truncate(self.len()); - let len = target.len(); - - // reuse the contained values' allocations/resources. - target.clone_from_slice(&self[..len]); // target.len <= self.len due to the truncate above, so the - // slice here is always in-bounds. - target.extend_from_slice(&self[len..]); + // slices here are always in-bounds. + let (init, tail) = self.split_at(target.len()); + + // reuse the contained values' allocations/resources. + target.clone_from_slice(init); + target.extend_from_slice(tail); } } From 9ab454af290392aa3cb79d3301a70bf8856729c0 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 20 Mar 2020 15:42:56 -0700 Subject: [PATCH 3/9] Implement ToOwned::clone_into for CStr It can try to keep its allocation by converting the inner `Box` to `Vec`, using `clone_into` on the bytes, then convert back to `Box`. --- src/libstd/ffi/c_str.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 04eaba515ff22..af9275933f6c4 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -1329,6 +1329,12 @@ impl ToOwned for CStr { fn to_owned(&self) -> CString { CString { inner: self.to_bytes_with_nul().into() } } + + fn clone_into(&self, target: &mut CString) { + let mut b = Vec::from(mem::take(&mut target.inner)); + self.to_bytes_with_nul().clone_into(&mut b); + target.inner = b.into_boxed_slice(); + } } #[stable(feature = "cstring_asref", since = "1.7.0")] @@ -1510,6 +1516,17 @@ mod tests { assert_eq!(boxed.to_bytes_with_nul(), &[0]); } + #[test] + fn test_c_str_clone_into() { + let mut c_string = CString::new("bonjour").unwrap(); + let c_ptr = c_string.as_ptr(); + let c_str = CStr::from_bytes_with_nul(b"hello\0").unwrap(); + c_str.clone_into(&mut c_string); + assert_eq!(c_str, c_string.as_c_str()); + // It shouldn't have needed to move its allocation + assert_eq!(c_ptr, c_string.as_ptr()); + } + #[test] fn into_rc() { let orig: &[u8] = b"Hello, world!\0"; From 28791f69a2f472da6d8733eb74f75e10eaaab705 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 20 Mar 2020 15:46:40 -0700 Subject: [PATCH 4/9] Forward OsStr::clone_into to the inner Vec Despite OS differences, they're all just `Vec` inside, so we can just forward `clone_into` calls to that optimized implementation. --- src/libstd/ffi/os_str.rs | 3 +-- src/libstd/sys/windows/os_str.rs | 4 ++++ src/libstd/sys_common/os_str_bytes.rs | 4 ++++ src/libstd/sys_common/wtf8.rs | 4 ++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 77da97219b147..aae7e0366d231 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -952,8 +952,7 @@ impl ToOwned for OsStr { self.to_os_string() } fn clone_into(&self, target: &mut OsString) { - target.clear(); - target.push(self); + self.inner.clone_into(&mut target.inner) } } diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs index ef260f9c5d21f..8e0169821c8ab 100644 --- a/src/libstd/sys/windows/os_str.rs +++ b/src/libstd/sys/windows/os_str.rs @@ -147,6 +147,10 @@ impl Slice { Buf { inner: buf } } + pub fn clone_into(&self, buf: &mut Buf) { + self.inner.clone_into(&mut buf.inner) + } + #[inline] pub fn into_box(&self) -> Box { unsafe { mem::transmute(self.inner.into_box()) } diff --git a/src/libstd/sys_common/os_str_bytes.rs b/src/libstd/sys_common/os_str_bytes.rs index e965ea79aa039..e3f9508069d9b 100644 --- a/src/libstd/sys_common/os_str_bytes.rs +++ b/src/libstd/sys_common/os_str_bytes.rs @@ -162,6 +162,10 @@ impl Slice { Buf { inner: self.inner.to_vec() } } + pub fn clone_into(&self, buf: &mut Buf) { + self.inner.clone_into(&mut buf.inner) + } + #[inline] pub fn into_box(&self) -> Box { let boxed: Box<[u8]> = self.inner.into(); diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index 498950e682101..c809fb463c7ca 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -613,6 +613,10 @@ impl Wtf8 { } } + pub fn clone_into(&self, buf: &mut Wtf8Buf) { + self.bytes.clone_into(&mut buf.bytes) + } + /// Boxes this `Wtf8`. #[inline] pub fn into_box(&self) -> Box { From 1d004bddee33fcae51611b0a83569052692ce15b Mon Sep 17 00:00:00 2001 From: Marti Raudsepp Date: Sat, 21 Mar 2020 12:33:52 +0200 Subject: [PATCH 5/9] Fix deprecated Error.description() usage in docs --- src/libstd/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 2a370f192964f..b394f2efc2e35 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -88,7 +88,7 @@ pub trait Error: Debug + Display { /// fn main() { /// match get_super_error() { /// Err(e) => { - /// println!("Error: {}", e.description()); + /// println!("Error: {}", e); /// println!("Caused by: {}", e.source().unwrap()); /// } /// _ => println!("No error"), From 14e0aad9909d35195c5725962a4c97697235759d Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 14 Mar 2020 18:48:10 +0200 Subject: [PATCH 6/9] symbol_names: treat ReifyShim like VtableShim. --- src/librustc/ty/instance.rs | 4 ---- src/librustc_symbol_mangling/legacy.rs | 9 +++++++-- src/librustc_symbol_mangling/v0.rs | 13 +++++++++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 13d58ea73ac6b..46372701a9254 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -406,10 +406,6 @@ impl<'tcx> Instance<'tcx> { | InstanceDef::VtableShim(..) => Some(self.substs), } } - - pub fn is_vtable_shim(&self) -> bool { - if let InstanceDef::VtableShim(..) = self.def { true } else { false } - } } fn needs_fn_once_adapter_shim( diff --git a/src/librustc_symbol_mangling/legacy.rs b/src/librustc_symbol_mangling/legacy.rs index 0dedda9bb6b73..7b082309f34b5 100644 --- a/src/librustc_symbol_mangling/legacy.rs +++ b/src/librustc_symbol_mangling/legacy.rs @@ -59,10 +59,14 @@ pub(super) fn mangle( .print_def_path(def_id, &[]) .unwrap(); - if instance.is_vtable_shim() { + if let ty::InstanceDef::VtableShim(..) = instance.def { let _ = printer.write_str("{{vtable-shim}}"); } + if let ty::InstanceDef::ReifyShim(..) = instance.def { + let _ = printer.write_str("{{reify-shim}}"); + } + printer.path.finish(hash) } @@ -123,7 +127,8 @@ fn get_symbol_hash<'tcx>( } // We want to avoid accidental collision between different types of instances. - // Especially, VtableShim may overlap with its original instance without this. + // Especially, `VtableShim`s and `ReifyShim`s may overlap with their original + // instances without this. discriminant(&instance.def).hash_stable(&mut hcx, &mut hasher); }); diff --git a/src/librustc_symbol_mangling/v0.rs b/src/librustc_symbol_mangling/v0.rs index ce6d0d9dc5ba8..e22a49061bb19 100644 --- a/src/librustc_symbol_mangling/v0.rs +++ b/src/librustc_symbol_mangling/v0.rs @@ -34,8 +34,17 @@ pub(super) fn mangle( binders: vec![], out: String::from(prefix), }; - cx = if instance.is_vtable_shim() { - cx.path_append_ns(|cx| cx.print_def_path(def_id, substs), 'S', 0, "").unwrap() + + // Append `::{shim:...#0}` to shims that can coexist with a non-shim instance. + let shim_kind = match instance.def { + ty::InstanceDef::VtableShim(_) => Some("vtable"), + ty::InstanceDef::ReifyShim(_) => Some("reify"), + + _ => None, + }; + + cx = if let Some(shim_kind) = shim_kind { + cx.path_append_ns(|cx| cx.print_def_path(def_id, substs), 'S', 0, shim_kind).unwrap() } else { cx.print_def_path(def_id, substs).unwrap() }; From a39e96407a579abbf4c273dc41692b69717b2aa8 Mon Sep 17 00:00:00 2001 From: lzutao Date: Sat, 21 Mar 2020 21:54:01 +0700 Subject: [PATCH 7/9] Remove CARGO_BUILD_TARGET from bootstrap.py --- src/bootstrap/bootstrap.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 50e1726240fff..d5efed61b541e 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -664,6 +664,10 @@ def build_bootstrap(self): if self.clean and os.path.exists(build_dir): shutil.rmtree(build_dir) env = os.environ.copy() + # `CARGO_BUILD_TARGET` breaks bootstrap build. + # See also: . + if "CARGO_BUILD_TARGET" in env: + del env["CARGO_BUILD_TARGET"] env["RUSTC_BOOTSTRAP"] = '1' env["CARGO_TARGET_DIR"] = build_dir env["RUSTC"] = self.rustc() From 97aa2704ec109002b513b99e925c891bc8461217 Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Sat, 21 Mar 2020 15:43:12 +0000 Subject: [PATCH 8/9] Add explanation message for E0224 --- src/librustc_error_codes/error_codes.rs | 2 +- src/librustc_error_codes/error_codes/E0224.md | 15 +++++++++++++++ src/test/ui/parser/issue-68890-2.stderr | 1 + .../macro/trait-object-macro-matcher.stderr | 1 + .../trait-alias-only-maybe-bound.stderr | 1 + .../ui/traits/trait-object-macro-matcher.stderr | 3 ++- .../ui/traits/trait-object-vs-lifetime-2.stderr | 1 + .../ui/traits/trait-object-vs-lifetime.stderr | 2 +- .../wf-trait-object-only-maybe-bound.stderr | 1 + 9 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 src/librustc_error_codes/error_codes/E0224.md diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 85339ab9aa15b..33bfaddc39c9d 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -118,6 +118,7 @@ E0220: include_str!("./error_codes/E0220.md"), E0221: include_str!("./error_codes/E0221.md"), E0222: include_str!("./error_codes/E0222.md"), E0223: include_str!("./error_codes/E0223.md"), +E0224: include_str!("./error_codes/E0224.md"), E0225: include_str!("./error_codes/E0225.md"), E0229: include_str!("./error_codes/E0229.md"), E0230: include_str!("./error_codes/E0230.md"), @@ -469,7 +470,6 @@ E0748: include_str!("./error_codes/E0748.md"), // E0217, // ambiguous associated type, defined in multiple supertraits // E0218, // no associated type defined // E0219, // associated type defined in higher-ranked supertrait - E0224, // at least one non-builtin train is required for an object type E0226, // only a single explicit lifetime bound is permitted E0227, // ambiguous lifetime bound, explicit lifetime bound required E0228, // explicit lifetime bound required diff --git a/src/librustc_error_codes/error_codes/E0224.md b/src/librustc_error_codes/error_codes/E0224.md new file mode 100644 index 0000000000000..fd89c1d52560f --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0224.md @@ -0,0 +1,15 @@ +A trait object was declaired with no traits. + +Erroneous code example: + +```compile_fail,E0224 +type Foo = dyn 'static +; +``` + +Rust does not currently support this. + +To solve ensure the the trait object has at least one trait: + +``` +type Foo = dyn 'static + Copy; +``` diff --git a/src/test/ui/parser/issue-68890-2.stderr b/src/test/ui/parser/issue-68890-2.stderr index d475c79cb27b4..967eee06e282f 100644 --- a/src/test/ui/parser/issue-68890-2.stderr +++ b/src/test/ui/parser/issue-68890-2.stderr @@ -20,3 +20,4 @@ LL | type X<'a> = (?'a) +; error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0224`. diff --git a/src/test/ui/parser/macro/trait-object-macro-matcher.stderr b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr index 230733371ddd8..a6fa9f8dddc27 100644 --- a/src/test/ui/parser/macro/trait-object-macro-matcher.stderr +++ b/src/test/ui/parser/macro/trait-object-macro-matcher.stderr @@ -20,3 +20,4 @@ LL | m!('static); error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0224`. diff --git a/src/test/ui/traits/trait-alias/trait-alias-only-maybe-bound.stderr b/src/test/ui/traits/trait-alias/trait-alias-only-maybe-bound.stderr index 6de79fa917b16..594115d980c8b 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-only-maybe-bound.stderr +++ b/src/test/ui/traits/trait-alias/trait-alias-only-maybe-bound.stderr @@ -12,3 +12,4 @@ LL | type _T1 = dyn _2; error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0224`. diff --git a/src/test/ui/traits/trait-object-macro-matcher.stderr b/src/test/ui/traits/trait-object-macro-matcher.stderr index a8511f63c16a5..cb48bd1258ea2 100644 --- a/src/test/ui/traits/trait-object-macro-matcher.stderr +++ b/src/test/ui/traits/trait-object-macro-matcher.stderr @@ -14,4 +14,5 @@ LL | m!(dyn Copy + Send + 'static); error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0038, E0224. +For more information about an error, try `rustc --explain E0038`. diff --git a/src/test/ui/traits/trait-object-vs-lifetime-2.stderr b/src/test/ui/traits/trait-object-vs-lifetime-2.stderr index 014d380b63ca5..28b8e11f1330c 100644 --- a/src/test/ui/traits/trait-object-vs-lifetime-2.stderr +++ b/src/test/ui/traits/trait-object-vs-lifetime-2.stderr @@ -6,3 +6,4 @@ LL | dyn 'static +: 'static + Copy, error: aborting due to previous error +For more information about this error, try `rustc --explain E0224`. diff --git a/src/test/ui/traits/trait-object-vs-lifetime.stderr b/src/test/ui/traits/trait-object-vs-lifetime.stderr index 04529fb8cfab3..ff3fc2a197c66 100644 --- a/src/test/ui/traits/trait-object-vs-lifetime.stderr +++ b/src/test/ui/traits/trait-object-vs-lifetime.stderr @@ -32,5 +32,5 @@ LL | let _: S; error: aborting due to 5 previous errors -Some errors have detailed explanations: E0107, E0747. +Some errors have detailed explanations: E0107, E0224, E0747. For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/traits/wf-trait-object-only-maybe-bound.stderr b/src/test/ui/traits/wf-trait-object-only-maybe-bound.stderr index 8cc97addc7dd4..482410886329e 100644 --- a/src/test/ui/traits/wf-trait-object-only-maybe-bound.stderr +++ b/src/test/ui/traits/wf-trait-object-only-maybe-bound.stderr @@ -12,3 +12,4 @@ LL | type _0 = dyn ?Sized; error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0224`. From 0b307f7a9f00878325f8c2c2573ea49e7a9c4353 Mon Sep 17 00:00:00 2001 From: adrian5 Date: Sat, 21 Mar 2020 17:06:10 +0100 Subject: [PATCH 9/9] Tweak wording for std::io::Read::read function --- src/libstd/io/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index dc831432c176f..83c492fecf974 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -502,7 +502,7 @@ pub trait Read { /// how many bytes were read. /// /// This function does not provide any guarantees about whether it blocks - /// waiting for data, but if an object needs to block for a read but cannot + /// waiting for data, but if an object needs to block for a read and cannot, /// it will typically signal this via an [`Err`] return value. /// /// If the return value of this method is [`Ok(n)`], then it must be